[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
This commit is contained in:
Marco Pennekamp
2023-09-22 16:11:15 +02:00
committed by Space Team
parent 17e181885f
commit 17b8d59e4b
4 changed files with 24 additions and 14 deletions
@@ -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,
@@ -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<Name> = emptySet()
internal class FirExcludingNonInnerClassesScope(
private val delegate: FirContainingNamesAwareScope,
) : FirDelegatingContainingNamesAwareScope(delegate) {
override fun getClassifierNames(): Set<Name> = delegate.getClassifierNames()
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
delegate.processInnerClassesByName(name, processor)
}
}
@@ -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<Name> = 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}`"
@@ -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<Name> = 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)
}
}
}