From 8b24baade911a1f4dbc3049558db39c220e4d0c9 Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Thu, 14 Sep 2023 22:35:25 +0200 Subject: [PATCH] [AA] Refactoring: Simplify `JavaClassDeclaredMembersEnhancementScope` - `JavaClassDeclaredMembersEnhancementScope` actually had nothing to do with Java enhancement, so it is easily replaceable with a more general `FirDeclaredMembersOnlyScope`. ^KT-61800 --- .../api/fir/components/KtFirScopeProvider.kt | 2 +- .../fir/scopes/FirCallableFilteringScope.kt | 49 +++++++++++ .../fir/scopes/FirDeclaredMembersOnlyScope.kt | 41 ++++++++++ ...avaClassDeclaredMembersEnhancementScope.kt | 82 ------------------- 4 files changed, 91 insertions(+), 83 deletions(-) create mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirCallableFilteringScope.kt create mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirDeclaredMembersOnlyScope.kt delete mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/JavaClassDeclaredMembersEnhancementScope.kt 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 1e10b60e3f1..583f3fc9543 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 @@ -130,7 +130,7 @@ internal class KtFirScopeProvider( } return scopeSession.getOrBuild(firJavaClass.symbol, cacheKey) { - JavaClassDeclaredMembersEnhancementScope(analysisSession.useSiteSession, firJavaClass, firScope) + FirDeclaredMembersOnlyScope(firScope, firJavaClass) } } 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 new file mode 100644 index 00000000000..337786eef5f --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirCallableFilteringScope.kt @@ -0,0 +1,49 @@ +/* + * 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.scopes.FirContainingNamesAwareScope +import org.jetbrains.kotlin.fir.scopes.processAllCallables +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.name.Name + +internal abstract class FirCallableFilteringScope(private val baseScope: FirContainingNamesAwareScope) : FirContainingNamesAwareScope() { + protected abstract fun isTargetCallable(callable: FirCallableSymbol<*>): Boolean + + private val cachedCallableNames by lazy(LazyThreadSafetyMode.NONE) { + buildSet { + baseScope.processAllCallables { callable -> + if (isTargetCallable(callable)) { + add(callable.name) + } + } + } + } + + override fun getCallableNames(): Set = cachedCallableNames + + override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { + if (!cachedCallableNames.contains(name)) return + + baseScope.processFunctionsByName(name) { function -> + if (isTargetCallable(function)) { + processor(function) + } + } + } + + override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { + if (!cachedCallableNames.contains(name)) return + + baseScope.processPropertiesByName(name) { property -> + if (isTargetCallable(property)) { + processor(property) + } + } + } +} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirDeclaredMembersOnlyScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirDeclaredMembersOnlyScope.kt new file mode 100644 index 00000000000..0b9753571c4 --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/FirDeclaredMembersOnlyScope.kt @@ -0,0 +1,41 @@ +/* + * 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.* +import org.jetbrains.kotlin.fir.declarations.utils.classId +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.scopes.* +import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.SpecialNames + +internal class FirDeclaredMembersOnlyScope( + private val delegate: FirContainingNamesAwareScope, + private val owner: FirClass, +) : FirCallableFilteringScope(delegate) { + private fun FirCallableDeclaration.isDeclared(): Boolean = + symbol.callableId.classId == owner.classId + && origin !is FirDeclarationOrigin.SubstitutionOverride + && origin != FirDeclarationOrigin.IntersectionOverride + + override fun isTargetCallable(callable: FirCallableSymbol<*>): Boolean = + callable.callableId.callableName != SpecialNames.INIT && callable.fir.isDeclared() + + override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) { + delegate.processDeclaredConstructors(processor) + } + + 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) + } + + 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/JavaClassDeclaredMembersEnhancementScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/JavaClassDeclaredMembersEnhancementScope.kt deleted file mode 100644 index 862817768e0..00000000000 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/JavaClassDeclaredMembersEnhancementScope.kt +++ /dev/null @@ -1,82 +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.analysis.api.fir.scopes - -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.classId -import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass -import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.scopes.* -import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope -import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.SpecialNames - -internal class JavaClassDeclaredMembersEnhancementScope( - private val useSiteSession: FirSession, - private val owner: FirJavaClass, - private val useSiteMemberEnhancementScope: FirContainingNamesAwareScope -) : FirContainingNamesAwareScope() { - private fun FirCallableDeclaration.isDeclared(): Boolean { - return symbol.callableId.classId == owner.classId - && origin !is FirDeclarationOrigin.SubstitutionOverride - && origin != FirDeclarationOrigin.IntersectionOverride - } - - private val callableNames = run { - (useSiteMemberEnhancementScope.collectAllProperties() + useSiteMemberEnhancementScope.collectAllFunctions()).filter { - it.fir.isDeclared() - }.map { - it.name - }.toSet() - } - - private val nestedClassifierScope: FirContainingNamesAwareScope? = - useSiteSession.nestedClassifierScope(owner) - - override fun getCallableNames(): Set { - return callableNames - } - - override fun getClassifierNames(): Set { - return nestedClassifierScope?.getClassifierNames().orEmpty() - } - - override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { - if (name == SpecialNames.INIT) return - useSiteMemberEnhancementScope.processFunctionsByName(name) { symbol -> - if (symbol.fir.isDeclared()) { - processor(symbol) - } - } - } - - override fun processClassifiersByNameWithSubstitution( - name: Name, - processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit - ) { - nestedClassifierScope?.processClassifiersByNameWithSubstitution(name, processor) - } - - override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) { - useSiteMemberEnhancementScope.processDeclaredConstructors { symbol -> - processor(symbol) - } - } - - override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { - useSiteMemberEnhancementScope.processPropertiesByName(name) { symbol -> - if (symbol.fir.isDeclared()) { - processor(symbol) - } - } - } - - override fun toString(): String { - return "Java enhancement declared member scope for ${owner.classId}" - } -}