From 2f4842b2719c20d8cb491a226c360bb86dae2b67 Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Mon, 14 Dec 2020 18:27:56 +0300 Subject: [PATCH] [FIR IDE] Add KtFileScope to support KtFileSymbol --- .../idea/frontend/api/KtAnalysisSession.kt | 7 +- .../api/components/KtScopeProvider.kt | 7 +- .../idea/frontend/api/scopes/KtScope.kt | 14 ++- .../api/symbols/KtAnonymousObjectSymbol.kt | 4 +- .../frontend/api/symbols/KtClassLikeSymbol.kt | 3 +- .../idea/frontend/api/symbols/KtFileSymbol.kt | 3 - .../api/symbols/KtVariableLikeSymbol.kt | 2 +- ...Declarations.kt => KtSymbolWithMembers.kt} | 2 + .../asJava/classes/FirLightClassForFacade.kt | 34 ++++--- .../idea/asJava/classes/firLightClassUtils.kt | 4 +- .../api/fir/components/KtFirScopeProvider.kt | 21 +++- .../fir/scopes/KtFirDeclaredMemberScope.kt | 5 +- .../api/fir/scopes/KtFirEmptyMemberScope.kt | 4 +- .../frontend/api/fir/scopes/KtFirFileScope.kt | 95 +++++++++++++++++++ .../api/fir/scopes/KtFirMemberScope.kt | 5 +- .../api/fir/symbols/KtFirFileSymbol.kt | 11 +-- 16 files changed, 167 insertions(+), 54 deletions(-) rename idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/{KtSymbolWithDeclarations.kt => KtSymbolWithMembers.kt} (86%) create mode 100644 idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirFileScope.kt diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt index cd6d5c9d1e7..5d59a9e9b6a 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.idea.frontend.api.components.* import org.jetbrains.kotlin.idea.frontend.api.scopes.* import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.types.KtType @@ -82,9 +83,11 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali fun KtSymbolWithKind.getContainingSymbol(): KtSymbolWithKind? = containingDeclarationProvider.getContainingDeclaration(this) - fun KtSymbolWithDeclarations.getMemberScope(): KtMemberScope = scopeProvider.getMemberScope(this) + fun KtSymbolWithMembers.getMemberScope(): KtMemberScope = scopeProvider.getMemberScope(this) - fun KtSymbolWithDeclarations.getDeclaredMemberScope(): KtDeclaredMemberScope = scopeProvider.getDeclaredMemberScope(this) + fun KtSymbolWithMembers.getDeclaredMemberScope(): KtDeclaredMemberScope = scopeProvider.getDeclaredMemberScope(this) + + fun KtFileSymbol.getFileScope(): KtDeclarationScope = scopeProvider.getFileScope(this) fun KtPackageSymbol.getPackageScope(): KtPackageScope = scopeProvider.getPackageScope(this) diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtScopeProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtScopeProvider.kt index 1a496ae71aa..169fe140677 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtScopeProvider.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtScopeProvider.kt @@ -6,15 +6,18 @@ package org.jetbrains.kotlin.idea.frontend.api.components import org.jetbrains.kotlin.idea.frontend.api.scopes.* +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPackageSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile abstract class KtScopeProvider : KtAnalysisSessionComponent() { - abstract fun getMemberScope(classSymbol: KtSymbolWithDeclarations): KtMemberScope - abstract fun getDeclaredMemberScope(classSymbol: KtSymbolWithDeclarations): KtDeclaredMemberScope + abstract fun getMemberScope(classSymbol: KtSymbolWithMembers): KtMemberScope + abstract fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtDeclaredMemberScope + abstract fun getFileScope(fileSymbol: KtFileSymbol): KtDeclarationScope abstract fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope abstract fun getCompositeScope(subScopes: List): KtCompositeScope diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/scopes/KtScope.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/scopes/KtScope.kt index 24c363c9026..83a4ab18b4b 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/scopes/KtScope.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/scopes/KtScope.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.idea.frontend.api.scopes -import org.jetbrains.kotlin.idea.frontend.api.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -43,12 +43,16 @@ interface KtCompositeScope : KtScope { val subScopes: List } -interface KtMemberScope : KtScope { - val owner: KtSymbolWithDeclarations +interface KtMemberScope : KtDeclarationScope { + override val owner: KtSymbolWithMembers } -interface KtDeclaredMemberScope : KtScope { - val owner: KtSymbolWithDeclarations +interface KtDeclaredMemberScope : KtDeclarationScope { + override val owner: KtSymbolWithMembers +} + +interface KtDeclarationScope : KtScope { + val owner: T } interface KtPackageScope : KtScope, KtSubstitutedScope { diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtAnonymousObjectSymbol.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtAnonymousObjectSymbol.kt index f2376418551..6c5db0b8210 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtAnonymousObjectSymbol.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtAnonymousObjectSymbol.kt @@ -6,12 +6,12 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol -import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.types.KtType -abstract class KtAnonymousObjectSymbol : KtSymbolWithKind, KtAnnotatedSymbol, KtSymbolWithDeclarations { +abstract class KtAnonymousObjectSymbol : KtSymbolWithKind, KtAnnotatedSymbol, KtSymbolWithMembers { abstract val superTypes: List abstract override fun createPointer(): KtSymbolPointer diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtClassLikeSymbol.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtClassLikeSymbol.kt index 74de4964757..3aa75dc4ca6 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtClassLikeSymbol.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtClassLikeSymbol.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.* import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer -import org.jetbrains.kotlin.idea.frontend.api.types.KtClassType import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.name.ClassId @@ -38,7 +37,7 @@ abstract class KtClassOrObjectSymbol : KtClassLikeSymbol(), KtSymbolWithModality, KtSymbolWithVisibility, KtAnnotatedSymbol, - KtSymbolWithDeclarations { + KtSymbolWithMembers { abstract val classKind: KtClassKind abstract val isInner: Boolean diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtFileSymbol.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtFileSymbol.kt index 8be87b279e5..ecc70c37c8b 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtFileSymbol.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtFileSymbol.kt @@ -9,8 +9,5 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer abstract class KtFileSymbol : KtAnnotatedSymbol { - - abstract val topLevelCallableSymbols: List - abstract override fun createPointer(): KtSymbolPointer } \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtVariableLikeSymbol.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtVariableLikeSymbol.kt index d21d0ecbcb6..f0ada480843 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtVariableLikeSymbol.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtVariableLikeSymbol.kt @@ -15,7 +15,7 @@ sealed class KtVariableLikeSymbol : KtCallableSymbol(), KtTypedSymbol, KtNamedSy abstract override fun createPointer(): KtSymbolPointer } -abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithDeclarations, KtSymbolWithKind { +abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithMembers, KtSymbolWithKind { final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER abstract val containingEnumClassIdIfNonLocal: ClassId? diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtSymbolWithDeclarations.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtSymbolWithMembers.kt similarity index 86% rename from idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtSymbolWithDeclarations.kt rename to idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtSymbolWithMembers.kt index 6b9fc49461f..38bb73b26ae 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtSymbolWithDeclarations.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers/KtSymbolWithMembers.kt @@ -7,4 +7,6 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols.markers import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol +interface KtSymbolWithMembers : KtSymbolWithDeclarations + interface KtSymbolWithDeclarations : KtSymbol \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/FirLightClassForFacade.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/FirLightClassForFacade.kt index 4dd067930bf..52850b5be27 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/FirLightClassForFacade.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/FirLightClassForFacade.kt @@ -22,11 +22,14 @@ import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.asJava.classes.createField import org.jetbrains.kotlin.idea.asJava.classes.createMethods import org.jetbrains.kotlin.idea.frontend.api.analyze +import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext +import org.jetbrains.kotlin.idea.frontend.api.scopes.KtDeclarationScope import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtKotlinPropertySymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithVisibility import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.name.FqName @@ -80,14 +83,17 @@ class FirLightClassForFacade( private val _ownMethods: List by lazyPub { val result = mutableListOf() + val methodsAndProperties = sequence { for (fileSymbol in fileSymbols) { - for (callableSymbol in fileSymbol.topLevelCallableSymbols) { - if (callableSymbol !is KtFunctionSymbol && callableSymbol !is KtPropertySymbol) continue - if (callableSymbol !is KtSymbolWithVisibility) continue - val isPrivate = callableSymbol.toPsiVisibilityForMember(isTopLevel = true) == PsiModifier.PRIVATE - if (isPrivate && multiFileClass) continue - yield(callableSymbol) + analyzeWithSymbolAsContext(fileSymbol) { + for (callableSymbol in fileSymbol.getFileScope().getCallableSymbols()) { + if (callableSymbol !is KtFunctionSymbol && callableSymbol !is KtKotlinPropertySymbol) continue + if (callableSymbol !is KtSymbolWithVisibility) continue + val isPrivate = callableSymbol.toPsiVisibilityForMember(isTopLevel = true) == PsiModifier.PRIVATE + if (isPrivate && multiFileClass) continue + yield(callableSymbol) + } } } } @@ -101,17 +107,17 @@ class FirLightClassForFacade( } private fun loadFieldsFromFile( - fileSymbol: KtFileSymbol, + fileScope: KtDeclarationScope, nameGenerator: FirLightField.FieldNameGenerator, result: MutableList ) { - for (propertySymbol in fileSymbol.topLevelCallableSymbols) { + for (propertySymbol in fileScope.getCallableSymbols()) { - if (propertySymbol !is KtPropertySymbol) continue + if (propertySymbol !is KtKotlinPropertySymbol) continue - if (propertySymbol is KtKotlinPropertySymbol && propertySymbol.isConst && multiFileClass) continue + if (propertySymbol.isConst && multiFileClass) continue - val isLateInitWithPublicAccessors = if (propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit) { + val isLateInitWithPublicAccessors = if (propertySymbol.isLateInit) { val getterIsPublic = propertySymbol.getter?.toPsiVisibilityForMember(isTopLevel = true) ?.let { it == PsiModifier.PUBLIC } ?: true val setterIsPublic = propertySymbol.setter?.toPsiVisibilityForMember(isTopLevel = true) @@ -120,7 +126,7 @@ class FirLightClassForFacade( } else false val forceStaticAndPropertyVisibility = isLateInitWithPublicAccessors || - (propertySymbol is KtKotlinPropertySymbol && propertySymbol.isConst) || + (propertySymbol.isConst) || propertySymbol.hasJvmFieldAnnotation() createField( @@ -139,7 +145,9 @@ class FirLightClassForFacade( val result = mutableListOf() val nameGenerator = FirLightField.FieldNameGenerator() for (fileSymbol in fileSymbols) { - loadFieldsFromFile(fileSymbol, nameGenerator, result) + analyzeWithSymbolAsContext(fileSymbol) { + loadFieldsFromFile(fileSymbol.getFileScope(), nameGenerator, result) + } } result } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/firLightClassUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/firLightClassUtils.kt index 269ab68bf8f..e7e95670fd4 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/firLightClassUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/firLightClassUtils.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtCommonSymbolModality import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility -import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.idea.frontend.api.types.KtClassType import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.lexer.KtTokens @@ -304,7 +304,7 @@ internal fun FirLightClassBase.createInheritanceList(forExtendsList: Boolean, su return listBuilder } -internal fun KtSymbolWithDeclarations.createInnerClasses(manager: PsiManager): List { +internal fun KtSymbolWithMembers.createInnerClasses(manager: PsiManager): List { val result = ArrayList() // workaround for ClassInnerStuffCache not supporting classes with null names, see KT-13927 diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt index ad299016598..e579f4860c3 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirScopeProvider.kt @@ -28,13 +28,16 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.* import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirAnonymousObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirEnumEntrySymbol +import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirFileSymbol import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType import org.jetbrains.kotlin.idea.frontend.api.fir.utils.EnclosingDeclarationContext import org.jetbrains.kotlin.idea.frontend.api.fir.utils.buildCompletionContext import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.scopes.* +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPackageSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.psi.KtElement @@ -53,11 +56,12 @@ internal class KtFirScopeProvider( private val firResolveState by weakRef(firResolveState) private val firScopeStorage = FirScopeRegistry() - private val memberScopeCache = IdentityHashMap() - private val declaredMemberScopeCache = IdentityHashMap() + private val memberScopeCache = IdentityHashMap() + private val declaredMemberScopeCache = IdentityHashMap() + private val fileScopeCache = IdentityHashMap>() private val packageMemberScopeCache = IdentityHashMap() - private inline fun KtSymbolWithDeclarations.withFirForScope(crossinline body: (FirClass<*>) -> T): T? = when (this) { + private inline fun KtSymbolWithMembers.withFirForScope(crossinline body: (FirClass<*>) -> T): T? = when (this) { is KtFirClassOrObjectSymbol -> firRef.withFir(FirResolvePhase.SUPER_TYPES, body) is KtFirAnonymousObjectSymbol -> firRef.withFir(FirResolvePhase.SUPER_TYPES, body) is KtFirEnumEntrySymbol -> firRef.withFir(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { @@ -68,7 +72,7 @@ internal class KtFirScopeProvider( else -> error { "Unknown KtSymbolWithDeclarations implementation ${this::class.qualifiedName}" } } - override fun getMemberScope(classSymbol: KtSymbolWithDeclarations): KtMemberScope = withValidityAssertion { + override fun getMemberScope(classSymbol: KtSymbolWithMembers): KtMemberScope = withValidityAssertion { memberScopeCache.getOrPut(classSymbol) { val firScope = classSymbol.withFirForScope { fir -> @@ -86,7 +90,7 @@ internal class KtFirScopeProvider( } } - override fun getDeclaredMemberScope(classSymbol: KtSymbolWithDeclarations): KtDeclaredMemberScope = withValidityAssertion { + override fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtDeclaredMemberScope = withValidityAssertion { declaredMemberScopeCache.getOrPut(classSymbol) { val firScope = classSymbol.withFirForScope { declaredMemberScope(it) @@ -98,6 +102,13 @@ internal class KtFirScopeProvider( } } + override fun getFileScope(fileSymbol: KtFileSymbol): KtDeclarationScope = 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 { packageMemberScopeCache.getOrPut(packageSymbol) { val firPackageScope = diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirDeclaredMemberScope.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirDeclaredMemberScope.kt index 3455178df3e..342e22d978d 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirDeclaredMemberScope.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirDeclaredMemberScope.kt @@ -9,14 +9,13 @@ 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 import org.jetbrains.kotlin.idea.frontend.api.scopes.KtDeclaredMemberScope import org.jetbrains.kotlin.idea.frontend.api.scopes.KtUnsubstitutedScope -import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers internal class KtFirDeclaredMemberScope( - override val owner: KtSymbolWithDeclarations, + override val owner: KtSymbolWithMembers, firScope: FirClassDeclaredMemberScope, token: ValidityToken, builder: KtSymbolByFirBuilder diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirEmptyMemberScope.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirEmptyMemberScope.kt index b356db91188..48dc5c95104 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirEmptyMemberScope.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirEmptyMemberScope.kt @@ -12,10 +12,10 @@ import org.jetbrains.kotlin.idea.frontend.api.scopes.KtMemberScope import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeNameFilter import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol -import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.name.Name -internal class KtFirEmptyMemberScope(override val owner: KtSymbolWithDeclarations) : KtMemberScope, KtDeclaredMemberScope, ValidityTokenOwner { +internal class KtFirEmptyMemberScope(override val owner: KtSymbolWithMembers) : KtMemberScope, KtDeclaredMemberScope, ValidityTokenOwner { override fun getCallableNames(): Set = emptySet() override fun getClassifierNames(): Set = emptySet() diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirFileScope.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirFileScope.kt new file mode 100644 index 00000000000..1a388473b9f --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirFileScope.kt @@ -0,0 +1,95 @@ +/* + * 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.idea.frontend.api.fir.scopes + +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.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.KtFirFileSymbol +import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached +import org.jetbrains.kotlin.idea.frontend.api.scopes.KtDeclarationScope +import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeNameFilter +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion +import org.jetbrains.kotlin.name.Name + +internal class KtFirFileScope( + override val owner: KtFirFileSymbol, + override val token: ValidityToken, + private val builder: KtSymbolByFirBuilder +) : KtDeclarationScope, + ValidityTokenOwner { + + private val allNamesCached by cached { + _callableNames + _classifierNames + } + + override fun getAllNames(): Set = allNamesCached + + private val _callableNames: Set by cached { + val result = mutableSetOf() + owner.firRef.withFir { + it.declarations.mapNotNullTo(result) { firDeclaration -> + when (firDeclaration) { + is FirSimpleFunction -> firDeclaration.name + is FirProperty -> firDeclaration.name + else -> null + } + } + } + result + } + + override fun getCallableNames(): Set = _callableNames + + private val _classifierNames: Set by cached { + val result = mutableSetOf() + owner.firRef.withFir { + it.declarations.mapNotNullTo(result) { firDeclaration -> + (firDeclaration as? FirRegularClass)?.name + } + } + result + } + + override fun getClassifierNames(): Set = _classifierNames + + override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { + owner.firRef.withFir { + sequence { + it.declarations.forEach { firDeclaration -> + val callableDeclaration = when (firDeclaration) { + is FirSimpleFunction -> firDeclaration.takeIf { nameFilter(firDeclaration.name) } + is FirProperty -> firDeclaration.takeIf { nameFilter(firDeclaration.name) } + else -> null + } + + if (callableDeclaration != null) { + yield(builder.buildCallableSymbol(callableDeclaration)) + } + } + } + } + } + + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { + owner.firRef.withFir { + sequence { + it.declarations.forEach { firDeclaration -> + val classLikeDeclaration = (firDeclaration as? FirRegularClass)?.takeIf { klass -> nameFilter(klass.name) } + if (classLikeDeclaration != null) { + yield(builder.buildClassLikeSymbol(classLikeDeclaration)) + } + } + } + } + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirMemberScope.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirMemberScope.kt index 20b9356aa25..6f8d327cbb7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirMemberScope.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirMemberScope.kt @@ -9,14 +9,13 @@ 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 -import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.scopes.KtMemberScope import org.jetbrains.kotlin.idea.frontend.api.scopes.KtUnsubstitutedScope -import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers internal class KtFirMemberScope( - override val owner: KtSymbolWithDeclarations, + override val owner: KtSymbolWithMembers, firScope: FirTypeScope, token: ValidityToken, builder: KtSymbolByFirBuilder diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt index 8e918f299dd..dadc3bff508 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.idea.fir.findPsi @@ -15,9 +14,9 @@ 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.convertAnnotation import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer @@ -26,17 +25,11 @@ internal class KtFirFileSymbol( resolveState: FirModuleResolveState, override val token: ValidityToken, private val builder: KtSymbolByFirBuilder -) : KtFileSymbol(), KtFirSymbol { +) : KtFileSymbol(), KtSymbolWithDeclarations, KtFirSymbol { override val firRef = firRef(fir, resolveState) override val psi: PsiElement? by firRef.withFirAndCache { fir -> fir.findPsi(fir.session) } - override val topLevelCallableSymbols: List by firRef.withFirAndCache { - it.declarations.mapNotNull { declaration -> - if (declaration is FirCallableDeclaration<*>) builder.buildCallableSymbol(declaration) else null - } - } - override fun createPointer(): KtSymbolPointer { KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } TODO("Creating pointers for files from library is not supported yet")