Analysis API: simplify scope hierarchy

This commit is contained in:
Ilya Kirillov
2021-11-04 21:57:34 +01:00
parent 0dca176e28
commit 6453f2bdbf
18 changed files with 133 additions and 202 deletions
@@ -29,11 +29,11 @@ import org.jetbrains.kotlin.analysis.api.fir.scopes.*
import org.jetbrains.kotlin.analysis.api.fir.symbols.*
import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
import org.jetbrains.kotlin.analysis.api.fir.utils.weakRef
import org.jetbrains.kotlin.analysis.api.impl.base.scopes.SimpleKtCompositeScope
import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtEmptyScope
import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtCompositeScope
import org.jetbrains.kotlin.analysis.api.scopes.*
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithDeclarations
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.types.KtType
@@ -54,11 +54,11 @@ internal class KtFirScopeProvider(
private val builder by weakRef(builder)
private val firResolveState by weakRef(firResolveState)
private val memberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtMemberScope>()
private val declaredMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtDeclaredMemberScope>()
private val delegatedMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtDelegatedMemberScope>()
private val fileScopeCache = IdentityHashMap<KtFileSymbol, KtDeclarationScope<KtSymbolWithDeclarations>>()
private val packageMemberScopeCache = IdentityHashMap<KtPackageSymbol, KtPackageScope>()
private val memberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtScope>()
private val declaredMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtScope>()
private val delegatedMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtScope>()
private val fileScopeCache = IdentityHashMap<KtFileSymbol, KtScope>()
private val packageMemberScopeCache = IdentityHashMap<KtPackageSymbol, KtScope>()
private inline fun <T> KtSymbolWithMembers.withFirForScope(crossinline body: (FirClass) -> T): T? = when (this) {
is KtFirNamedClassOrObjectSymbol -> firRef.withFir(FirResolvePhase.TYPES, body)
@@ -71,9 +71,8 @@ internal class KtFirScopeProvider(
else -> error { "Unknown KtSymbolWithDeclarations implementation ${this::class.qualifiedName}" }
}
override fun getMemberScope(classSymbol: KtSymbolWithMembers): KtMemberScope = withValidityAssertion {
override fun getMemberScope(classSymbol: KtSymbolWithMembers): KtScope = withValidityAssertion {
memberScopeCache.getOrPut(classSymbol) {
val firScope = classSymbol.withFirForScope { fir ->
val firSession = analysisSession.rootModuleSession
fir.unsubstitutedScope(
@@ -81,32 +80,32 @@ internal class KtFirScopeProvider(
ScopeSession(),
withForcedTypeCalculator = false
)
} ?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
} ?: return@getOrPut getEmptyScope()
KtFirMemberScope(classSymbol, firScope, token, builder)
KtFirMemberScope(firScope, token, builder)
}
}
override fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope {
val firScope = symbol.withFirForScope { fir ->
fir.scopeProvider.getStaticScope(fir, analysisSession.rootModuleSession, ScopeSession())
} ?: return KtFirEmptyMemberScope(symbol)
} ?: return getEmptyScope()
return KtFirDelegatingScopeImpl(firScope, builder, token)
}
override fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtDeclaredMemberScope = withValidityAssertion {
override fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtScope = withValidityAssertion {
declaredMemberScopeCache.getOrPut(classSymbol) {
val firScope = classSymbol.withFirForScope {
analysisSession.rootModuleSession.declaredMemberScope(it)
} ?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
} ?: return@getOrPut getEmptyScope()
KtFirDeclaredMemberScope(classSymbol, firScope, token, builder)
KtFirDeclaredMemberScope(firScope, token, builder)
}
}
override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtDelegatedMemberScope = withValidityAssertion {
override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtScope = withValidityAssertion {
val declaredScope = (getDeclaredMemberScope(classSymbol) as? KtFirDeclaredMemberScope)?.firScope
?: return delegatedMemberScopeCache.getOrPut(classSymbol) { KtFirEmptyMemberScope(classSymbol) }
?: return delegatedMemberScopeCache.getOrPut(classSymbol) { getEmptyScope() }
delegatedMemberScopeCache.getOrPut(classSymbol) {
val firScope = classSymbol.withFirForScope { fir ->
val delegateFields = fir.delegateFields
@@ -119,20 +118,24 @@ internal class KtFirScopeProvider(
delegateFields
)
} else null
} ?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
} ?: return@getOrPut getEmptyScope()
KtFirDelegatedMemberScope(classSymbol, firScope, token, builder)
KtFirDelegatedMemberScope(firScope, token, builder)
}
}
override fun getFileScope(fileSymbol: KtFileSymbol): KtDeclarationScope<KtSymbolWithDeclarations> = withValidityAssertion {
override fun getFileScope(fileSymbol: KtFileSymbol): KtScope = withValidityAssertion {
fileScopeCache.getOrPut(fileSymbol) {
check(fileSymbol is KtFirFileSymbol) { "KtFirScopeProvider can only work with KtFirFileSymbol, but ${fileSymbol::class} was provided" }
KtFirFileScope(fileSymbol, token, builder)
}
}
override fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope = withValidityAssertion {
override fun getEmptyScope(): KtScope = withValidityAssertion {
KtEmptyScope(token)
}
override fun getPackageScope(packageSymbol: KtPackageSymbol): KtScope = withValidityAssertion {
packageMemberScopeCache.getOrPut(packageSymbol) {
KtFirPackageScope(
packageSymbol.fqName,
@@ -146,8 +149,8 @@ internal class KtFirScopeProvider(
}
override fun getCompositeScope(subScopes: List<KtScope>): KtCompositeScope = withValidityAssertion {
SimpleKtCompositeScope(subScopes, token)
override fun getCompositeScope(subScopes: List<KtScope>): KtScope = withValidityAssertion {
KtCompositeScope(subScopes, token)
}
override fun getTypeScope(type: KtType): KtScope? {
@@ -5,18 +5,12 @@
package org.jetbrains.kotlin.analysis.api.fir.scopes
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.scopes.KtDeclaredMemberScope
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
internal class KtFirDeclaredMemberScope(
override val owner: KtSymbolWithMembers,
override val firScope: FirContainingNamesAwareScope,
token: ValidityToken,
builder: KtSymbolByFirBuilder
) : KtFirDelegatingScope<FirContainingNamesAwareScope>(builder, token),
KtDeclaredMemberScope,
ValidityTokenOwner
) : KtFirDelegatingScope<FirContainingNamesAwareScope>(builder, token)
@@ -5,24 +5,18 @@
package org.jetbrains.kotlin.analysis.api.fir.scopes
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.scopes.KtDelegatedMemberScope
import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
internal class KtFirDelegatedMemberScope(
override val owner: KtSymbolWithMembers,
override val firScope: FirContainingNamesAwareScope,
token: ValidityToken,
builder: KtSymbolByFirBuilder
) : KtFirDelegatingScope<FirContainingNamesAwareScope>(builder, token),
KtDelegatedMemberScope,
ValidityTokenOwner {
) : KtFirDelegatingScope<FirContainingNamesAwareScope>(builder, token) {
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> {
return super.getCallableSymbols(nameFilter).filter { it.origin == KtSymbolOrigin.DELEGATED }
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
@@ -54,6 +55,10 @@ internal abstract class KtFirDelegatingScope<S : FirContainingNamesAwareScope>(
firScope.getConstructors(builder)
}
override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence<KtPackageSymbol> = withValidityAssertion {
emptySequence()
}
override fun mayContainName(name: Name): Boolean = withValidityAssertion {
name in getAllPossibleNames()
}
@@ -1,40 +0,0 @@
/*
* Copyright 2010-2021 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.analysis.api.fir.scopes
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.scopes.KtDeclaredMemberScope
import org.jetbrains.kotlin.analysis.api.scopes.KtDelegatedMemberScope
import org.jetbrains.kotlin.analysis.api.scopes.KtMemberScope
import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.name.Name
internal class KtFirEmptyMemberScope(
override val owner: KtSymbolWithMembers
) : KtMemberScope, KtDeclaredMemberScope, KtDelegatedMemberScope, ValidityTokenOwner {
override fun getPossibleCallableNames(): Set<Name> = emptySet()
override fun getPossibleClassifierNames(): Set<Name> = emptySet()
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> =
emptySequence()
override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> =
emptySequence()
override fun getConstructors(): Sequence<KtConstructorSymbol> =
emptySequence()
override fun mayContainName(name: Name): Boolean = false
override val token: ValidityToken
get() = owner.token
}
@@ -9,25 +9,23 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirFileSymbol
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.scopes.KtDeclarationScope
import org.jetbrains.kotlin.analysis.api.scopes.KtScope
import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithDeclarations
import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirFileScope(
override val owner: KtFirFileSymbol,
private val owner: KtFirFileSymbol,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder
) : KtDeclarationScope<KtSymbolWithDeclarations>,
ValidityTokenOwner {
) : KtScope {
private val allNamesCached by cached {
_callableNames + _classifierNames
@@ -95,4 +93,8 @@ internal class KtFirFileScope(
}
override fun getConstructors(): Sequence<KtConstructorSymbol> = emptySequence()
override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence<KtPackageSymbol> = withValidityAssertion {
emptySequence()
}
}
@@ -5,17 +5,13 @@
package org.jetbrains.kotlin.analysis.api.fir.scopes
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.weakRef
import org.jetbrains.kotlin.analysis.api.scopes.KtMemberScope
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
internal class KtFirMemberScope(
override val owner: KtSymbolWithMembers,
override val firScope: FirTypeScope,
token: ValidityToken,
builder: KtSymbolByFirBuilder
) : KtFirDelegatingScope<FirTypeScope>(builder, token), KtMemberScope, ValidityTokenOwner
) : KtFirDelegatingScope<FirTypeScope>(builder, token), ValidityTokenOwner
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.analysis.api.fir.scopes
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.scopes.KtNonStarImportingScope
@@ -26,7 +25,7 @@ internal class KtFirNonStarImportingScope(
private val firScope: FirAbstractSimpleImportingScope,
private val builder: KtSymbolByFirBuilder,
override val token: ValidityToken,
) : KtNonStarImportingScope, ValidityTokenOwner {
) : KtNonStarImportingScope {
@OptIn(ExperimentalStdlibApi::class)
override val imports: List<NonStarImport> by cached {
@@ -9,10 +9,11 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.scopes.KtPackageScope
import org.jetbrains.kotlin.analysis.api.scopes.KtScope
import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
@@ -25,13 +26,13 @@ import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.jvm.isJvm
internal class KtFirPackageScope(
override val fqName: FqName,
private val fqName: FqName,
private val project: Project,
private val builder: KtSymbolByFirBuilder,
override val token: ValidityToken,
private val searchScope: GlobalSearchScope,
private val targetPlatform: TargetPlatform,
) : KtPackageScope {
) : KtScope {
private val declarationsProvider = project.createDeclarationProvider(searchScope)
private val packageProvider = project.createPackageProvider(searchScope)
@@ -66,6 +67,10 @@ internal class KtFirPackageScope(
firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder)
}
override fun getConstructors(): Sequence<KtConstructorSymbol> = withValidityAssertion {
emptySequence()
}
override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence<KtPackageSymbol> = withValidityAssertion {
sequence {
if (targetPlatform.isJvm()) {