From 17b8d59e4bec0f072f9345d7bbc0920af0991def Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Fri, 22 Sep 2023 16:11:15 +0200 Subject: [PATCH] [AA] Include inner classes in non-static Java declared member scopes - `FirNoClassifiersScope` erroneously filtered out inner classes from non-static Java declared member scopes. ^KT-61800 --- .../api/fir/components/KtFirScopeProvider.kt | 4 ++-- ...ope.kt => FirExcludingNonInnerClassesScope.kt} | 7 +++++-- .../fir/scopes/FirJavaDeclaredMembersOnlyScope.kt | 12 +++++++++--- .../api/fir/scopes/FirNonStaticMembersScope.kt | 15 ++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) rename analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/{FirNoClassifiersScope.kt => FirExcludingNonInnerClassesScope.kt} (70%) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirScopeProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirScopeProvider.kt index f66369df2b5..485761fe9b7 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirScopeProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirScopeProvider.kt @@ -115,8 +115,8 @@ internal class KtFirScopeProvider( val scopeSession = getScopeSession() val firScope = when (kind) { - // `FirNoClassifiersScope` is a workaround for non-static member scopes containing classifiers (see KT-61900). - DeclaredMemberScopeKind.NON_STATIC -> FirNoClassifiersScope( + // `FirExcludingNonInnerClassesScope` is a workaround for non-static member scopes containing static classes (see KT-61900). + DeclaredMemberScopeKind.NON_STATIC -> FirExcludingNonInnerClassesScope( JavaScopeProvider.getUseSiteMemberScope( firJavaClass, useSiteSession, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNoClassifiersScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirExcludingNonInnerClassesScope.kt similarity index 70% rename from analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNoClassifiersScope.kt rename to analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirExcludingNonInnerClassesScope.kt index 0bf67e20954..3d02d0a963d 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNoClassifiersScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirExcludingNonInnerClassesScope.kt @@ -11,9 +11,12 @@ import org.jetbrains.kotlin.fir.scopes.FirDelegatingContainingNamesAwareScope import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.name.Name -internal class FirNoClassifiersScope(delegate: FirContainingNamesAwareScope) : FirDelegatingContainingNamesAwareScope(delegate) { - override fun getClassifierNames(): Set = emptySet() +internal class FirExcludingNonInnerClassesScope( + private val delegate: FirContainingNamesAwareScope, +) : FirDelegatingContainingNamesAwareScope(delegate) { + override fun getClassifierNames(): Set = delegate.getClassifierNames() override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { + delegate.processInnerClassesByName(name, processor) } } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirJavaDeclaredMembersOnlyScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirJavaDeclaredMembersOnlyScope.kt index 65a05fa463a..2fbd8c965da 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirJavaDeclaredMembersOnlyScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirJavaDeclaredMembersOnlyScope.kt @@ -32,6 +32,8 @@ internal class FirJavaDeclaredMembersOnlyScope( && origin !is FirDeclarationOrigin.SubstitutionOverride && origin != FirDeclarationOrigin.IntersectionOverride + private fun FirRegularClass.isDeclared(): Boolean = symbol.classId.parentClassId == owner.classId + override fun isTargetCallable(callable: FirCallableSymbol<*>): Boolean = callable.callableId.callableName != SpecialNames.INIT && callable.fir.isDeclared() @@ -42,9 +44,13 @@ internal class FirJavaDeclaredMembersOnlyScope( override fun getClassifierNames(): Set = delegate.getClassifierNames() override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { - // We do not need to filter classifiers, because for both Kotlin and Java classes, a static base scope cannot contain classifiers - // inherited from supertypes. See `getStaticMemberScope` in `KtScopeProvider` for more information on classifiers in static scopes. - delegate.processClassifiersByNameWithSubstitution(name, processor) + // We have to filter out classes from supertypes because the base scope might be a use-site scope that provides inner classes from + // supertypes. + delegate.processClassifiersByNameWithSubstitution(name) { classifier, substitutor -> + if (classifier is FirRegularClassSymbol && classifier.fir.isDeclared()) { + processor(classifier, substitutor) + } + } } override fun toString(): String = "Declared member scope for $delegate with owning class `${owner.classId}`" diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNonStaticMembersScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNonStaticMembersScope.kt index f195a105b7e..2b4c79a8e05 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNonStaticMembersScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNonStaticMembersScope.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isStatic 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.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol @@ -46,15 +47,15 @@ internal class FirNonStaticMembersScope( override fun getClassifierNames(): Set = delegate.getClassifierNames() override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { - processInnerClassesByName(name, processor) + delegate.processInnerClassesByName(name, processor) } +} - private fun processInnerClassesByName(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { - delegate.processClassifiersByNameWithSubstitution(name) { classifier, substitutor -> - val firDeclaration = classifier.fir - if (firDeclaration is FirMemberDeclaration && firDeclaration.isInner) { - processor(classifier, substitutor) - } +internal fun FirScope.processInnerClassesByName(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { + processClassifiersByNameWithSubstitution(name) { classifier, substitutor -> + val firDeclaration = classifier.fir + if (firDeclaration is FirMemberDeclaration && firDeclaration.isInner) { + processor(classifier, substitutor) } } }