FIR: move getCallableNames/getClassifierNames from scope to FirContainingNamesAwareScope

This commit is contained in:
Ilya Kirillov
2020-08-07 13:00:43 +03:00
parent 36a161080f
commit f62204fff1
27 changed files with 247 additions and 146 deletions
@@ -70,7 +70,7 @@ class FirJavaModuleBasedSession private constructor(
}
class FirLibrarySession private constructor(
moduleInfo: ModuleInfo,
override val moduleInfo: ModuleInfo,
sessionProvider: FirProjectSessionProvider,
) : FirSession(sessionProvider) {
companion object {
@@ -105,6 +105,10 @@ class JavaClassMembersEnhancementScope(
return useSiteMemberScope.getCallableNames()
}
override fun getClassifierNames(): Set<Name> {
return useSiteMemberScope.getClassifierNames()
}
override fun mayContainName(name: Name): Boolean {
return useSiteMemberScope.mayContainName(name)
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.java.scopes
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.Name
@@ -15,8 +16,8 @@ import org.jetbrains.kotlin.name.Name
class JavaClassStaticEnhancementScope(
session: FirSession,
owner: FirRegularClassSymbol,
private val useSiteStaticScope: FirScope,
) : FirScope() {
private val useSiteStaticScope: JavaClassStaticUseSiteScope,
) : FirScope(), FirContainingNamesAwareScope {
private val signatureEnhancement = FirSignatureEnhancement(owner.fir, session) {
emptyList()
}
@@ -53,6 +54,11 @@ class JavaClassStaticEnhancementScope(
return useSiteStaticScope.getCallableNames()
}
override fun getClassifierNames(): Set<Name> {
return useSiteStaticScope.getClassifierNames()
}
override fun mayContainName(name: Name): Boolean {
return useSiteStaticScope.mayContainName(name)
}
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.fir.java.scopes
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.getContainingCallableNamesIfPresent
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
@@ -21,7 +23,7 @@ class JavaClassStaticUseSiteScope internal constructor(
private val superClassScope: FirScope,
private val superTypesScopes: List<FirScope>,
javaTypeParameterStack: JavaTypeParameterStack,
) : FirScope() {
) : FirScope(), FirContainingNamesAwareScope {
private val functions = hashMapOf<Name, Collection<FirFunctionSymbol<*>>>()
private val properties = hashMapOf<Name, Collection<FirVariableSymbol<*>>>()
private val overrideChecker = JavaOverrideChecker(session, javaTypeParameterStack)
@@ -83,9 +85,19 @@ class JavaClassStaticUseSiteScope internal constructor(
@OptIn(ExperimentalStdlibApi::class)
override fun getCallableNames(): Set<Name> {
return buildSet {
addAll(declaredMemberScope.getCallableNames())
addAll(declaredMemberScope.getContainingCallableNamesIfPresent())
for (superTypesScope in superTypesScopes) {
addAll(superTypesScope.getCallableNames())
addAll(superTypesScope.getContainingCallableNamesIfPresent())
}
}
}
@OptIn(ExperimentalStdlibApi::class)
override fun getClassifierNames(): Set<Name> {
return buildSet {
addAll(declaredMemberScope.getContainingCallableNamesIfPresent())
for (superTypesScope in superTypesScopes) {
addAll(superTypesScope.getContainingCallableNamesIfPresent())
}
}
}
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.fir.java.declarations.*
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.getContainingCallableNamesIfPresent
import org.jetbrains.kotlin.fir.scopes.getContainingClassifierNamesIfPresent
import org.jetbrains.kotlin.fir.scopes.impl.AbstractFirUseSiteMemberScope
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -46,11 +48,11 @@ class JavaClassUseSiteMemberScope(
}
override fun getCallableNames(): Set<Name> {
return declaredMemberScope.getCallableNames() + superTypesScope.getCallableNames()
return declaredMemberScope.getContainingCallableNamesIfPresent() + superTypesScope.getCallableNames()
}
override fun getClassifierNames(): Set<Name> {
return declaredMemberScope.getClassifierNames() + superTypesScope.getClassifierNames()
return declaredMemberScope.getContainingClassifierNamesIfPresent() + superTypesScope.getClassifierNames()
}
private fun generateAccessorSymbol(
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.fir.scopes.jvm
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsSettings
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.Name
@@ -77,11 +75,11 @@ class JvmMappedScope(
}
override fun getCallableNames(): Set<Name> {
return declaredMemberScope.getCallableNames()
return declaredMemberScope.getContainingCallableNamesIfPresent()
}
override fun getClassifierNames(): Set<Name> {
return declaredMemberScope.getClassifierNames()
return declaredMemberScope.getContainingClassifierNamesIfPresent()
}
companion object {
@@ -9,10 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.Name
@@ -132,6 +129,10 @@ abstract class AbstractFirUseSiteMemberScope(
}
override fun getCallableNames(): Set<Name> {
return declaredMemberScope.getCallableNames() + superTypesScope.getCallableNames()
return declaredMemberScope.getContainingCallableNamesIfPresent() + superTypesScope.getCallableNames()
}
override fun getClassifierNames(): Set<Name> {
return declaredMemberScope.getContainingClassifierNamesIfPresent() + superTypesScope.getClassifierNames()
}
}
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.getContainingClassifierNamesIfPresent
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.Name
@@ -17,8 +19,8 @@ class FirClassDeclaredMemberScope(
useLazyNestedClassifierScope: Boolean = false,
existingNames: List<Name>? = null,
symbolProvider: FirSymbolProvider? = null
) : FirScope() {
private val nestedClassifierScope = if (useLazyNestedClassifierScope) {
) : FirScope(), FirContainingNamesAwareScope {
private val nestedClassifierScope: FirScope? = if (useLazyNestedClassifierScope) {
lazyNestedClassifierScope(klass.symbol.classId, existingNames!!, symbolProvider!!)
} else {
nestedClassifierScope(klass)
@@ -82,7 +84,7 @@ class FirClassDeclaredMemberScope(
}
override fun getClassifierNames(): Set<Name> {
return nestedClassifierScope?.getClassifierNames().orEmpty()
return nestedClassifierScope?.getContainingClassifierNamesIfPresent().orEmpty()
}
}
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.utils.getOrPutNullable
class FirDeclaredMemberScopeProvider : FirSessionComponent {
private val declaredMemberCache = mutableMapOf<FirClass<*>, FirScope>()
private val declaredMemberCache = mutableMapOf<FirClass<*>, FirClassDeclaredMemberScope>()
private val nestedClassifierCache = mutableMapOf<FirClass<*>, FirNestedClassifierScope?>()
fun getClassByClassId(classId: ClassId): FirClass<*>? {
@@ -43,7 +43,7 @@ class FirDeclaredMemberScopeProvider : FirSessionComponent {
useLazyNestedClassifierScope: Boolean,
existingNames: List<Name>?,
symbolProvider: FirSymbolProvider?
): FirScope {
): FirClassDeclaredMemberScope {
return declaredMemberCache.getOrPut(klass) {
FirClassDeclaredMemberScope(klass, useLazyNestedClassifierScope, existingNames, symbolProvider)
}
@@ -56,7 +56,7 @@ class FirDeclaredMemberScopeProvider : FirSessionComponent {
}
}
fun declaredMemberScope(klass: FirClass<*>): FirScope {
fun declaredMemberScope(klass: FirClass<*>): FirClassDeclaredMemberScope {
return klass
.session
.declaredMemberScopeProvider
@@ -106,6 +106,10 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction = ProcessorAction.NEXT
override fun getCallableNames(): Set<Name> = ALL_OPERATORS.keys
override fun getClassifierNames(): Set<Name> = emptySet()
}
@OptIn(FirImplementationDetail::class)
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.name.ClassId
@@ -19,7 +20,7 @@ class FirLazyNestedClassifierScope(
val classId: ClassId,
private val existingNames: List<Name>,
private val symbolProvider: FirSymbolProvider
) : FirScope() {
) : FirScope(), FirContainingNamesAwareScope {
override fun processClassifiersByNameWithSubstitution(
name: Name,
processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit
@@ -33,7 +34,7 @@ class FirLazyNestedClassifierScope(
processor(symbol, ConeSubstitutor.Empty)
}
override fun getClassifierNames(): Set<Name> {
return existingNames.toSet()
}
override fun getClassifierNames(): Set<Name> = existingNames.toSet()
override fun getCallableNames(): Set<Name> = emptySet()
}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.resolve.PersistentMultimap
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.Name
@@ -22,7 +23,7 @@ class FirLocalScope private constructor(
val properties: PersistentMap<Name, FirVariableSymbol<*>>,
val functions: PersistentMultimap<Name, FirFunctionSymbol<*>>,
val classes: PersistentMap<Name, FirRegularClassSymbol>
) : FirScope() {
) : FirScope(), FirContainingNamesAwareScope {
constructor() : this(persistentMapOf(), PersistentMultimap(), persistentMapOf())
fun storeClass(klass: FirRegularClass): FirLocalScope {
@@ -72,4 +73,5 @@ class FirLocalScope private constructor(
override fun mayContainName(name: Name) = properties.containsKey(name) || functions[name].isNotEmpty() || classes.containsKey(name)
override fun getCallableNames(): Set<Name> = properties.keys + functions.keys
override fun getClassifierNames(): Set<Name> = classes.keys
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
@@ -18,7 +19,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.Name
class FirNestedClassifierScope(val klass: FirClass<*>) : FirScope() {
class FirNestedClassifierScope(val klass: FirClass<*>) : FirScope(), FirContainingNamesAwareScope {
private val classIndex: Map<Name, FirRegularClassSymbol> = run {
val result = mutableMapOf<Name, FirRegularClassSymbol>()
for (declaration in klass.declarations) {
@@ -44,9 +45,9 @@ class FirNestedClassifierScope(val klass: FirClass<*>) : FirScope() {
fun getClassifierByName(name: Name): FirRegularClassSymbol? = classIndex[name]
override fun getClassifierNames(): Set<Name> {
return classIndex.keys
}
override fun getClassifierNames(): Set<Name> = classIndex.keys
override fun getCallableNames(): Set<Name> = emptySet()
}
fun FirTypeParameterRef.toConeType(): ConeKotlinType = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(symbol), isNullable = false)
@@ -56,8 +56,4 @@ class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirSc
}
}
}
override fun getCallableNames(): Set<Name> {
return symbolProvider.getAllCallableNamesInPackage(fqName)
}
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.isStatic
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.getContainingCallableNamesIfPresent
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
@@ -35,8 +36,4 @@ class FirStaticScope(private val delegateScope: FirScope) : FirScope() {
}
}
}
override fun getCallableNames(): Set<Name> {
return delegateScope.getCallableNames()
}
}
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.Name
class FirCompositeScope(val scopes: Iterable<FirScope>) : FirScope() {
class FirCompositeScope(val scopes: Iterable<FirScope>) : FirScope(), FirContainingNamesAwareScope {
override fun processClassifiersByNameWithSubstitution(
name: Name,
@@ -46,10 +46,10 @@ class FirCompositeScope(val scopes: Iterable<FirScope>) : FirScope() {
}
override fun getCallableNames(): Set<Name> {
return scopes.flatMapTo(mutableSetOf()) { it.getCallableNames() }
return scopes.flatMapTo(hashSetOf()) { it.getContainingCallableNamesIfPresent() }
}
override fun getClassifierNames(): Set<Name> {
return scopes.flatMapTo(hashSetOf()) { it.getClassifierNames() }
return scopes.flatMapTo(hashSetOf()) { it.getContainingClassifierNamesIfPresent() }
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.scopes
import org.jetbrains.kotlin.name.Name
interface FirContainingNamesAwareScope {
fun getCallableNames(): Set<Name>
fun getClassifierNames(): Set<Name>
}
fun FirScope.getContainingCallableNamesIfPresent(): Set<Name> =
if (this is FirContainingNamesAwareScope) getCallableNames() else emptySet()
fun FirScope.getContainingClassifierNamesIfPresent(): Set<Name> =
if (this is FirContainingNamesAwareScope) getClassifierNames() else emptySet()
@@ -33,10 +33,6 @@ abstract class FirScope {
) {}
open fun mayContainName(name: Name) = true
open fun getCallableNames(): Set<Name> = emptySet()
open fun getClassifierNames(): Set<Name> = emptySet()
}
fun FirTypeScope.processOverriddenFunctionsAndSelf(
@@ -8,8 +8,9 @@ package org.jetbrains.kotlin.fir.scopes
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.Name
abstract class FirTypeScope : FirScope() {
abstract class FirTypeScope : FirScope(), FirContainingNamesAwareScope {
// Currently, this function and its property brother both have very weak guarantees
// - It may silently do nothing on symbols originated from different scope instance
// - It may return the same overridden symbols more then once in case of substitution
@@ -96,5 +97,9 @@ abstract class FirTypeScope : FirScope() {
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction = ProcessorAction.NEXT
override fun getCallableNames(): Set<Name> = emptySet()
override fun getClassifierNames(): Set<Name> = emptySet()
}
}
@@ -7,21 +7,32 @@ package org.jetbrains.kotlin.idea.frontend.api.scopes
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
interface KtScope : ValidityTokenOwner {
// TODO check that names are accessible
// maybe return some kind of lazy set
fun getAllNames(): Set<Name>
fun getAllNames(): Set<Name> = withValidityAssertion { getCallableNames() + getClassLikeSymbolNames() }
fun getCallableNames(): Set<Name>
fun getClassLikeSymbolNames(): Set<Name>
fun getAllSymbols(): Sequence<KtSymbol>
fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion {
sequence {
yieldAll(getCallableSymbols())
yieldAll(getClassClassLikeSymbols())
}
}
fun getCallableSymbols(): Sequence<KtCallableSymbol>
fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol>
fun containsName(name: Name): Boolean
fun containsName(name: Name): Boolean = withValidityAssertion {
name in getCallableNames() || name in getClassLikeSymbolNames()
}
}
interface KtCompositeScope : KtScope {
@@ -37,7 +48,7 @@ interface KtDeclaredMemberScope : KtScope {
}
interface KtPackageScope : KtScope, KtSubstitutedScope<KtPackageScope> {
val owner: KtPackageSymbol
val fqName: FqName
}
interface KtUnsubstitutedScope<S : KtScope> : KtScope {
@@ -5,10 +5,9 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.scopes
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
@@ -17,13 +16,13 @@ import org.jetbrains.kotlin.idea.frontend.api.scopes.KtUnsubstitutedScope
internal class KtFirDeclaredMemberScope(
override val owner: KtFirClassOrObjectSymbol,
firScope: FirScope,
firScope: FirClassDeclaredMemberScope,
token: ValidityToken,
builder: KtSymbolByFirBuilder
) : KtFirDelegatingScope(builder, token),
) : KtFirDelegatingScope<FirClassDeclaredMemberScope>(builder, token),
KtDeclaredMemberScope,
KtUnsubstitutedScope<KtFirDelegatingScope>,
KtUnsubstitutedScope<KtFirDeclaredMemberScope>,
ValidityTokenOwner {
override val firScope: FirScope by weakRef(firScope)
override val firScope: FirClassDeclaredMemberScope by weakRef(firScope)
}
@@ -9,13 +9,13 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScope
@@ -25,12 +25,12 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal abstract class KtFirDelegatingScope(
internal abstract class KtFirDelegatingScope<S>(
private val builder: KtSymbolByFirBuilder,
final override val token: ValidityToken
) : KtScope {
) : KtScope where S : FirContainingNamesAwareScope, S : FirScope {
abstract val firScope: FirScope
abstract val firScope: S
private val allNamesCached by cached {
getCallableNames() + getClassLikeSymbolNames()
@@ -46,62 +46,58 @@ internal abstract class KtFirDelegatingScope(
firScope.getClassifierNames()
}
override fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion {
sequence {
yieldAll(getCallableSymbols())
yieldAll(getClassClassLikeSymbols())
}
}
override fun getCallableSymbols(): Sequence<KtCallableSymbol> = withValidityAssertion {
sequence {
getCallableNames().forEach { name ->
val callables = mutableListOf<KtCallableSymbol>()
firScope.processFunctionsByName(name) { firSymbol ->
(firSymbol.fir as? FirSimpleFunction)?.let { fir ->
callables.add(builder.buildFunctionSymbol(fir, firSymbol.realDeclarationOrigin()))
}
}
firScope.processPropertiesByName(name) { firSymbol ->
val symbol = when {
firSymbol is FirPropertySymbol && firSymbol.isFakeOverride -> {
builder.buildVariableSymbol(firSymbol.fir, firSymbol.realDeclarationOrigin())
}
else -> builder.buildCallableSymbol(firSymbol.fir)
}
callables.add(symbol)
}
yieldAll(callables)
}
}
firScope.getCallableSymbols(getCallableNames(), builder)
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
sequence {
getClassLikeSymbolNames().forEach { name ->
val classLikeSymbols = mutableListOf<KtClassLikeSymbol>()
firScope.processClassifiersByName(name) { firSymbol ->
(firSymbol.fir as? FirClassLikeDeclaration<*>)?.let {
classLikeSymbols.add(builder.buildClassLikeSymbol(it))
}
}
yieldAll(classLikeSymbols)
}
}
firScope.getClassLikeSymbols(getClassLikeSymbolNames(), builder)
}
override fun containsName(name: Name): Boolean = withValidityAssertion {
name in getAllNames()
}
companion object {
private fun FirBasedSymbol<*>.realDeclarationOrigin(): FirDeclarationOrigin? {
if (this !is PossiblyFirFakeOverrideSymbol<*, *> || !isFakeOverride) return null
var current: FirBasedSymbol<*>? = this.overriddenSymbol
while (current is PossiblyFirFakeOverrideSymbol<*, *> && current.isFakeOverride) {
current = current.overriddenSymbol
}
private fun FirBasedSymbol<*>.realDeclarationOrigin(): FirDeclarationOrigin? {
if (this !is PossiblyFirFakeOverrideSymbol<*, *> || !isFakeOverride) return null
var current: FirBasedSymbol<*>? = this.overriddenSymbol
while (current is PossiblyFirFakeOverrideSymbol<*, *> && current.isFakeOverride) {
current = current.overriddenSymbol
}
return (current?.fir as? FirDeclaration)?.origin
}
internal fun FirScope.getCallableSymbols(callableNames: Collection<Name>, builder: KtSymbolByFirBuilder) = sequence {
callableNames.forEach { name ->
val callables = mutableListOf<KtCallableSymbol>()
processFunctionsByName(name) { firSymbol ->
(firSymbol.fir as? FirSimpleFunction)?.let { fir ->
callables.add(builder.buildFunctionSymbol(fir, firSymbol.realDeclarationOrigin()))
}
return (current?.fir as? FirDeclaration)?.origin
}
processPropertiesByName(name) { firSymbol ->
val symbol = when {
firSymbol is FirPropertySymbol && firSymbol.isFakeOverride -> {
builder.buildVariableSymbol(firSymbol.fir, firSymbol.realDeclarationOrigin())
}
else -> builder.buildCallableSymbol(firSymbol.fir)
}
callables.add(symbol)
}
yieldAll(callables)
}
}
internal fun FirScope.getClassLikeSymbols(classLikeNames: Collection<Name>, builder: KtSymbolByFirBuilder) = sequence {
classLikeNames.forEach { name ->
val classLikeSymbols = mutableListOf<KtClassLikeSymbol>()
processClassifiersByName(name) { firSymbol ->
(firSymbol.fir as? FirClassLikeDeclaration<*>)?.let {
classLikeSymbols.add(builder.buildClassLikeSymbol(it))
}
}
yieldAll(classLikeSymbols)
}
}
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.scopes
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
@@ -16,10 +16,10 @@ import org.jetbrains.kotlin.idea.frontend.api.scopes.KtUnsubstitutedScope
internal class KtFirMemberScope(
override val owner: KtFirClassOrObjectSymbol,
firScope: FirScope,
firScope: FirTypeScope,
token: ValidityToken,
builder: KtSymbolByFirBuilder
) : KtFirDelegatingScope(builder, token), KtMemberScope, KtUnsubstitutedScope<KtMemberScope>, ValidityTokenOwner {
override val firScope: FirScope by weakRef(firScope)
) : KtFirDelegatingScope<FirTypeScope>(builder, token), KtMemberScope, KtUnsubstitutedScope<KtMemberScope>, ValidityTokenOwner {
override val firScope: FirTypeScope by weakRef(firScope)
}
@@ -11,17 +11,20 @@ import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtNonStarImportingScope
import org.jetbrains.kotlin.idea.frontend.api.scopes.NonStarImport
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirNonStarImportingScope(
firScope: FirAbstractSimpleImportingScope,
builder: KtSymbolByFirBuilder,
token: ValidityToken
) : KtFirDelegatingScope(builder, token), KtNonStarImportingScope, ValidityTokenOwner {
override val firScope: FirAbstractSimpleImportingScope = firScope
private val builder: KtSymbolByFirBuilder,
override val token: ValidityToken
) : KtNonStarImportingScope, ValidityTokenOwner {
private val firScope: FirAbstractSimpleImportingScope by weakRef(firScope)
@OptIn(ExperimentalStdlibApi::class)
override val imports: List<NonStarImport> by cached {
@@ -39,6 +42,14 @@ internal class KtFirNonStarImportingScope(
}
}
override fun getCallableSymbols(): Sequence<KtCallableSymbol> = withValidityAssertion {
firScope.getCallableSymbols(getCallableNames(), builder)
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
firScope.getClassLikeSymbols(getClassLikeSymbolNames(), builder)
}
override fun getCallableNames(): Set<Name> = withValidityAssertion {
imports.mapNotNullTo(hashSetOf()) { it.callableName }
@@ -48,6 +59,5 @@ internal class KtFirNonStarImportingScope(
imports.mapNotNullTo((hashSetOf())) { it.relativeClassName?.shortName() }
}
override val isDefaultImportingScope: Boolean = withValidityAssertion { firScope is FirDefaultSimpleImportingScope }
}
@@ -5,23 +5,44 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.scopes
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.scopes.FirScope
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirPackageSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtPackageScope
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
internal class KtFirPackageScope(
override val owner: KtFirPackageSymbol,
token: ValidityToken,
builder: KtSymbolByFirBuilder,
session: FirSession,
) : KtPackageScope, KtFirDelegatingScope(builder, token), ValidityTokenOwner {
override val firScope: FirScope by weakRef {
FirPackageMemberScope(owner.fqName, session)
firScope: FirPackageMemberScope,
private val builder: KtSymbolByFirBuilder,
override val token: ValidityToken,
) : KtPackageScope, ValidityTokenOwner {
private val firScope by weakRef(firScope)
override val fqName: FqName get() = firScope.fqName
private val provider get() = firScope.session.firProvider
override fun getCallableNames(): Set<Name> = withValidityAssertion {
provider.getAllCallableNamesInPackage(fqName)
}
override fun getClassLikeSymbolNames(): Set<Name> = withValidityAssertion {
provider.getClassNamesInPackage(fqName)
}
override fun getCallableSymbols(): Sequence<KtCallableSymbol> = withValidityAssertion {
firScope.getCallableSymbols(getCallableNames(), builder)
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
firScope.getClassLikeSymbols(getClassLikeSymbolNames(), builder)
}
}
@@ -9,12 +9,14 @@ import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractSimpleImportingScope
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractStarImportingScope
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.idea.fir.getOrBuildFirOfType
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade
@@ -23,7 +25,6 @@ import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.FirScopeRegistry
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirPackageSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.scopes.*
@@ -57,7 +58,7 @@ internal class KtFirScopeProvider(
override fun getMemberScope(classSymbol: KtClassOrObjectSymbol): KtMemberScope = withValidityAssertion {
memberScopeCache.getOrPut(classSymbol) {
check(classSymbol is KtFirClassOrObjectSymbol)
val firScope = classSymbol.fir.buildUseSiteMemberScope(classSymbol.fir.session, ScopeSession()).also(firScopeStorage::register)
val firScope = classSymbol.fir.unsubstitutedScope(classSymbol.fir.session, ScopeSession()).also(firScopeStorage::register)
KtFirMemberScope(classSymbol, firScope, token, builder)
}
}
@@ -72,8 +73,9 @@ internal class KtFirScopeProvider(
override fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope = withValidityAssertion {
packageMemberScopeCache.getOrPut(packageSymbol) {
check(packageSymbol is KtFirPackageSymbol)
KtFirPackageScope(packageSymbol, token, builder, session)
val firPackageScope = FirPackageMemberScope(packageSymbol.fqName, session/*TODO use correct session here*/)
.also(firScopeStorage::register)
KtFirPackageScope(firPackageScope, builder, token)
}
}
@@ -123,15 +125,16 @@ internal class KtFirScopeProvider(
return when (firScope) {
is FirAbstractSimpleImportingScope -> KtFirNonStarImportingScope(firScope, builder, token)
is FirAbstractStarImportingScope -> KtFirStarImportingScope(firScope, builder, project, token)
else -> {
// todo create concrete KtScope here instead of a generic one
KtFirDelegatingScopeImpl(firScope, builder, token)
}
is FirPackageMemberScope -> KtFirPackageScope(firScope, builder, token)
is FirContainingNamesAwareScope -> KtFirDelegatingScopeImpl(firScope, builder, token)
else -> TODO(firScope::class.toString())
}
}
}
private class KtFirDelegatingScopeImpl(firScope: FirScope, builder: KtSymbolByFirBuilder, token: ValidityToken) :
KtFirDelegatingScope(builder, token), ValidityTokenOwner {
override val firScope: FirScope by weakRef(firScope)
private class KtFirDelegatingScopeImpl<S>(
firScope: S, builder: KtSymbolByFirBuilder,
token: ValidityToken
) : KtFirDelegatingScope<S>(builder, token), ValidityTokenOwner where S : FirContainingNamesAwareScope, S : FirScope {
override val firScope: S by weakRef(firScope)
}
@@ -7,15 +7,21 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.scopes
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.fir.scopes.getContainingCallableNamesIfPresent
import org.jetbrains.kotlin.fir.scopes.getContainingClassifierNamesIfPresent
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractStarImportingScope
import org.jetbrains.kotlin.fir.scopes.impl.FirDefaultStarImportingScope
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.scopes.Import
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtStarImportingScope
import org.jetbrains.kotlin.idea.frontend.api.scopes.StarImport
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelClassByPackageIndex
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionByPackageIndex
@@ -27,11 +33,11 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
internal class KtFirStarImportingScope(
firScope: FirAbstractStarImportingScope,
builder: KtSymbolByFirBuilder,
private val builder: KtSymbolByFirBuilder,
project: Project,
token: ValidityToken,
) : KtFirDelegatingScope(builder, token), KtStarImportingScope, ValidityTokenOwner {
override val firScope: FirAbstractStarImportingScope = firScope
override val token: ValidityToken,
) : KtStarImportingScope, ValidityTokenOwner {
private val firScope: FirAbstractStarImportingScope by weakRef(firScope)
override val isDefaultImportingScope: Boolean = withValidityAssertion { firScope is FirDefaultStarImportingScope }
private val packageHelper = PackageIndexHelper(project)
@@ -45,6 +51,14 @@ internal class KtFirStarImportingScope(
}
}
override fun getCallableSymbols(): Sequence<KtCallableSymbol> = withValidityAssertion {
firScope.getCallableSymbols(getCallableNames(), builder)
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
firScope.getClassLikeSymbols(getClassLikeSymbolNames(), builder)
}
// todo cache?
@OptIn(ExperimentalStdlibApi::class)
override fun getCallableNames(): Set<Name> = withValidityAssertion {
@@ -53,7 +67,7 @@ internal class KtFirStarImportingScope(
packageHelper.getPackageTopLevelCallables(import.packageFqName)
} else { //member
val classId = import.resolvedClassId ?: error("Class id should not be null as relativeClassName is not null")
firScope.getStaticsScope(classId)?.getCallableNames().orEmpty()
firScope.getStaticsScope(classId)?.getContainingCallableNamesIfPresent().orEmpty()
}
}
}
@@ -64,7 +78,7 @@ internal class KtFirStarImportingScope(
packageHelper.getPackageTopLevelClassifiers(import.packageFqName)
} else {
val classId = import.resolvedClassId ?: error("Class id should not be null as relativeClassName is not null")
firScope.getStaticsScope(classId)?.getClassifierNames().orEmpty()
firScope.getStaticsScope(classId)?.getContainingClassifierNamesIfPresent().orEmpty()
}
}
}