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 583f3fc9543..06a47d03363 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 @@ -105,7 +105,7 @@ internal class KtFirScopeProvider( ): FirContainingNamesAwareScope { val combinedScope = getCombinedFirKotlinDeclaredMemberScope(classSymbol) return when (kind) { - DeclaredMemberScopeKind.NON_STATIC -> FirNonStaticCallablesScope(combinedScope) + DeclaredMemberScopeKind.NON_STATIC -> FirNonStaticCallablesOnlyScope(combinedScope) DeclaredMemberScopeKind.STATIC -> FirStaticScope(combinedScope) } } @@ -115,11 +115,14 @@ internal class KtFirScopeProvider( val scopeSession = getScopeSession() val firScope = when (kind) { - DeclaredMemberScopeKind.NON_STATIC -> JavaScopeProvider.getUseSiteMemberScope( - firJavaClass, - useSiteSession, - scopeSession, - memberRequiredPhase = FirResolvePhase.TYPES, + // `FirNoClassifiersScope` is a workaround for non-static member scopes containing classifiers (see KT-61900). + DeclaredMemberScopeKind.NON_STATIC -> FirNoClassifiersScope( + JavaScopeProvider.getUseSiteMemberScope( + firJavaClass, + useSiteSession, + scopeSession, + memberRequiredPhase = FirResolvePhase.TYPES, + ) ) DeclaredMemberScopeKind.STATIC -> JavaScopeProvider.getStaticScope(firJavaClass, useSiteSession, scopeSession) ?: return null } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirCallableFilteringScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirCallableFilteringScope.kt index 337786eef5f..aa678b8d767 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirCallableFilteringScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirCallableFilteringScope.kt @@ -12,6 +12,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.name.Name +/** + * A base implementation for [FirNonStaticCallablesOnlyScope] and [FirDeclaredMembersOnlyScope], which both filter callables based on some + * condition. + */ internal abstract class FirCallableFilteringScope(private val baseScope: FirContainingNamesAwareScope) : FirContainingNamesAwareScope() { protected abstract fun isTargetCallable(callable: FirCallableSymbol<*>): Boolean 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/FirNoClassifiersScope.kt new file mode 100644 index 00000000000..0bf67e20954 --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNoClassifiersScope.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2023 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.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope +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() + + override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { + } +} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNonStaticCallablesOnlyScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNonStaticCallablesOnlyScope.kt new file mode 100644 index 00000000000..ab542600535 --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirNonStaticCallablesOnlyScope.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2023 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.fir.declarations.utils.isStatic +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol +import org.jetbrains.kotlin.name.Name + +/** + * Excludes static callables and all classifiers. + */ +internal class FirNonStaticCallablesOnlyScope( + private val delegate: FirContainingNamesAwareScope, +) : FirCallableFilteringScope(delegate) { + override fun isTargetCallable(callable: FirCallableSymbol<*>): Boolean = !callable.fir.isStatic + + override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) { + delegate.processDeclaredConstructors(processor) + } + + override fun getClassifierNames(): Set = emptySet() + + override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtScopeProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtScopeProvider.kt index 7493e47d4a3..4f2f42f8b10 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtScopeProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtScopeProvider.kt @@ -157,7 +157,11 @@ public interface KtScopeProviderMixIn : KtAnalysisSessionMixIn { withValidityAssertion { analysisSession.scopeProvider.getCombinedMemberScope(this) } /** - * Returns a [KtScope] containing the *non-static* callables and all classifiers explicitly declared in the given [KtSymbolWithMembers]. + * Returns a [KtScope] containing the *non-static* callables (functions, properties, and constructors) explicitly declared in the given + * [KtSymbolWithMembers]. + * + * The declared member scope does not contain classifiers (including the companion object). To retrieve the classifiers declared in this + * [KtSymbolWithMembers], please use the *static* declared member scope provided by [getStaticDeclaredMemberScope]. * * @see getStaticDeclaredMemberScope */ @@ -165,7 +169,8 @@ public interface KtScopeProviderMixIn : KtAnalysisSessionMixIn { withValidityAssertion { analysisSession.scopeProvider.getDeclaredMemberScope(this) } /** - * Returns a [KtScope] containing the *static* members explicitly declared in the given [KtSymbolWithMembers]. + * Returns a [KtScope] containing the *static* callables (functions and properties) and all classifiers (classes and objects) explicitly + * declared in the given [KtSymbolWithMembers]. * * It is worth noting that, while Java classes may contain declarations of static callables freely, in Kotlin only enum classes define * static callables. Hence, for non-enum Kotlin classes, it is not expected that the static declared member scope will contain any diff --git a/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/class.pretty.txt b/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/class.pretty.txt index 15b582ff63a..aa6a096e49a 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/class.pretty.txt +++ b/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/class.pretty.txt @@ -2,10 +2,4 @@ fun foo(): kotlin.Int val bar: kotlin.String -class C2 - -object O2 - -companion object - constructor() diff --git a/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/class.txt b/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/class.txt index 8c1dfdd9151..25928126b05 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/class.txt +++ b/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/class.txt @@ -119,93 +119,6 @@ KtKotlinPropertySymbol: javaSetterName: null setterDeprecationStatus: null -KtNamedClassOrObjectSymbol: - annotationsList: [] - classIdIfNonLocal: test/C.C2 - classKind: CLASS - companionObject: null - contextReceivers: [] - isActual: false - isData: false - isExpect: false - isExternal: false - isFun: false - isInline: false - isInner: false - modality: FINAL - name: C2 - origin: SOURCE - superTypes: [ - KtUsualClassType: - annotationsList: [] - ownTypeArguments: [] - type: kotlin/Any - ] - symbolKind: CLASS_MEMBER - typeParameters: [] - visibility: Public - getContainingModule: KtSourceModule "Sources of main" - annotationApplicableTargets: null - deprecationStatus: null - -KtNamedClassOrObjectSymbol: - annotationsList: [] - classIdIfNonLocal: test/C.O2 - classKind: OBJECT - companionObject: null - contextReceivers: [] - isActual: false - isData: false - isExpect: false - isExternal: false - isFun: false - isInline: false - isInner: false - modality: FINAL - name: O2 - origin: SOURCE - superTypes: [ - KtUsualClassType: - annotationsList: [] - ownTypeArguments: [] - type: kotlin/Any - ] - symbolKind: CLASS_MEMBER - typeParameters: [] - visibility: Public - getContainingModule: KtSourceModule "Sources of main" - annotationApplicableTargets: null - deprecationStatus: null - -KtNamedClassOrObjectSymbol: - annotationsList: [] - classIdIfNonLocal: test/C.Companion - classKind: COMPANION_OBJECT - companionObject: null - contextReceivers: [] - isActual: false - isData: false - isExpect: false - isExternal: false - isFun: false - isInline: false - isInner: false - modality: FINAL - name: Companion - origin: SOURCE - superTypes: [ - KtUsualClassType: - annotationsList: [] - ownTypeArguments: [] - type: kotlin/Any - ] - symbolKind: CLASS_MEMBER - typeParameters: [] - visibility: Public - getContainingModule: KtSourceModule "Sources of main" - annotationApplicableTargets: null - deprecationStatus: null - KtConstructorSymbol: annotationsList: [] callableIdIfNonLocal: null diff --git a/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/javaClass.kt b/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/javaClass.kt index 3e7577c221b..bfceda40fd6 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/javaClass.kt +++ b/analysis/analysis-api/testData/components/scopeProvider/declaredMemberScope/javaClass.kt @@ -12,6 +12,8 @@ public interface SuperInterface { // FILE: SuperClass.java public abstract class SuperClass implements SuperInterface { + public static class NestedSuperClass { } + @Override public int getActualRandomNumber() { return getRandomNumber(); @@ -26,6 +28,8 @@ public abstract class SuperClass implements SuperInterface { // FILE: JavaClass.java public class JavaClass extends SuperClass { + public static class NestedClass { } + public static int foo = 1; public static String bar() { diff --git a/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.kt b/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.kt index 3e7577c221b..bfceda40fd6 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.kt +++ b/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.kt @@ -12,6 +12,8 @@ public interface SuperInterface { // FILE: SuperClass.java public abstract class SuperClass implements SuperInterface { + public static class NestedSuperClass { } + @Override public int getActualRandomNumber() { return getRandomNumber(); @@ -26,6 +28,8 @@ public abstract class SuperClass implements SuperInterface { // FILE: JavaClass.java public class JavaClass extends SuperClass { + public static class NestedClass { } + public static int foo = 1; public static String bar() { diff --git a/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.pretty.txt b/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.pretty.txt index 3184c7af4e7..c4aa2a0eef3 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.pretty.txt +++ b/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.pretty.txt @@ -9,4 +9,8 @@ open fun hashCode(): kotlin.Int open fun toString(): kotlin.String +open class NestedClass + +open class NestedSuperClass + constructor() diff --git a/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.txt b/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.txt index 20fea1af90c..c7f5535949e 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.txt +++ b/analysis/analysis-api/testData/components/scopeProvider/memberScope/javaClass.txt @@ -204,6 +204,64 @@ KtFunctionSymbol: getContainingModule: KtBinaryModule "Builtins for JVM (1.8)" deprecationStatus: null +KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: JavaClass.NestedClass + classKind: CLASS + companionObject: null + contextReceivers: [] + isActual: false + isData: false + isExpect: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: OPEN + name: NestedClass + origin: JAVA + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + ] + symbolKind: CLASS_MEMBER + typeParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + annotationApplicableTargets: null + deprecationStatus: null + +KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: SuperClass.NestedSuperClass + classKind: CLASS + companionObject: null + contextReceivers: [] + isActual: false + isData: false + isExpect: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: OPEN + name: NestedSuperClass + origin: JAVA + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + ] + symbolKind: CLASS_MEMBER + typeParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + annotationApplicableTargets: null + deprecationStatus: null + KtConstructorSymbol: annotationsList: [] callableIdIfNonLocal: null diff --git a/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/classWithJavaSuperclass.kt b/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/classWithJavaSuperclass.kt index aafd74379b4..ab423329f25 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/classWithJavaSuperclass.kt +++ b/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/classWithJavaSuperclass.kt @@ -13,7 +13,7 @@ public abstract class JavaClass { public static int y = 1; - public class C1 { + public static class C1 { } } diff --git a/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.kt b/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.kt index 3e7577c221b..bfceda40fd6 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.kt +++ b/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.kt @@ -12,6 +12,8 @@ public interface SuperInterface { // FILE: SuperClass.java public abstract class SuperClass implements SuperInterface { + public static class NestedSuperClass { } + @Override public int getActualRandomNumber() { return getRandomNumber(); @@ -26,6 +28,8 @@ public abstract class SuperClass implements SuperInterface { // FILE: JavaClass.java public class JavaClass extends SuperClass { + public static class NestedClass { } + public static int foo = 1; public static String bar() { diff --git a/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.pretty.txt b/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.pretty.txt index f93ecd8f1c1..656f2493fc3 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.pretty.txt +++ b/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.pretty.txt @@ -1,3 +1,5 @@ +open fun bar(): kotlin.String! + open var foo: kotlin.Int -open fun bar(): kotlin.String! \ No newline at end of file +open class NestedClass \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.txt b/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.txt index 953ab3728aa..8a18222e4e3 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.txt +++ b/analysis/analysis-api/testData/components/scopeProvider/staticDeclaredMemberScope/javaClass.txt @@ -1,24 +1,3 @@ -KtJavaFieldSymbol: - annotationsList: [] - callableIdIfNonLocal: /JavaClass.foo - contextReceivers: [] - isExtension: false - isStatic: true - isVal: false - modality: OPEN - name: foo - origin: JAVA - receiverParameter: null - returnType: KtUsualClassType: - annotationsList: [] - ownTypeArguments: [] - type: kotlin/Int - symbolKind: CLASS_MEMBER - typeParameters: [] - visibility: Public - getContainingModule: KtSourceModule "Sources of main" - deprecationStatus: null - KtFunctionSymbol: annotationsList: [] callableIdIfNonLocal: /JavaClass.bar @@ -48,4 +27,54 @@ KtFunctionSymbol: valueParameters: [] visibility: Public getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtJavaFieldSymbol: + annotationsList: [] + callableIdIfNonLocal: /JavaClass.foo + contextReceivers: [] + isExtension: false + isStatic: true + isVal: false + modality: OPEN + name: foo + origin: JAVA + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Int + symbolKind: CLASS_MEMBER + typeParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: JavaClass.NestedClass + classKind: CLASS + companionObject: null + contextReceivers: [] + isActual: false + isData: false + isExpect: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: OPEN + name: NestedClass + origin: JAVA + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + ] + symbolKind: CLASS_MEMBER + typeParameters: [] + visibility: Public + getContainingModule: KtSourceModule "Sources of main" + annotationApplicableTargets: null deprecationStatus: null \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/scopeProvider/staticMemberScope/classWithJavaSuperclass.kt b/analysis/analysis-api/testData/components/scopeProvider/staticMemberScope/classWithJavaSuperclass.kt index 2d55a6ff29f..ed5fab311f5 100644 --- a/analysis/analysis-api/testData/components/scopeProvider/staticMemberScope/classWithJavaSuperclass.kt +++ b/analysis/analysis-api/testData/components/scopeProvider/staticMemberScope/classWithJavaSuperclass.kt @@ -13,7 +13,7 @@ public abstract class JavaClass { public static int y = 1; - public class C1 { + public static class C1 { } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirNonStaticCallablesScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirNonStaticCallablesScope.kt deleted file mode 100644 index c44463d81b7..00000000000 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirNonStaticCallablesScope.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2010-2023 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.impl - -import org.jetbrains.kotlin.fir.declarations.utils.isStatic -import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope -import org.jetbrains.kotlin.fir.scopes.FirDelegatingContainingNamesAwareScope -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol -import org.jetbrains.kotlin.name.Name - -/** - * A counterpart to [FirStaticScope] that contains only the *non-static* callables and all classifiers of the [delegate] scope. - */ -class FirNonStaticCallablesScope(private val delegate: FirContainingNamesAwareScope) : FirDelegatingContainingNamesAwareScope(delegate) { - override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { - delegate.processFunctionsByName(name) { - if (!it.fir.isStatic) { - processor(it) - } - } - } - - override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { - delegate.processPropertiesByName(name) { - if (!it.fir.isStatic) { - processor(it) - } - } - } -}