From 186beddf5c60848ed80580e08a6f882ad41520d7 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Fri, 24 Jun 2022 14:11:37 +0200 Subject: [PATCH] [Analysis API FIR] fix member scope for enum entries --- .../api/fir/components/KtFirScopeProvider.kt | 46 +++++++++++++++++-- .../test/cases/symbols/AbstractSymbolTest.kt | 10 ++-- .../memberScopeByFqName/enumEntry.pretty.txt | 6 +-- .../scopes/memberScopeByFqName/enumEntry.txt | 41 +---------------- 4 files changed, 50 insertions(+), 53 deletions(-) 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 2ff975b37a4..8c4f80d50b9 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 @@ -24,24 +24,32 @@ import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtCompositeTypeScope import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtEmptyScope import org.jetbrains.kotlin.analysis.api.scopes.KtScope import org.jetbrains.kotlin.analysis.api.scopes.KtTypeScope +import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext -import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.utils.delegateFields +import org.jetbrains.kotlin.fir.declarations.utils.isCompanion import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope import org.jetbrains.kotlin.fir.resolve.scope -import org.jetbrains.kotlin.fir.scopes.* +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator +import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope +import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.* +import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.ensureResolved +import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.utils.addToStdlib.applyIf import java.util.* internal class KtFirScopeProvider( @@ -88,8 +96,8 @@ internal class KtFirScopeProvider( scopeSession, withForcedTypeCalculator = false ) - } ?: return@getOrPut getEmptyScope() - + }?.applyIf(classSymbol is KtEnumEntrySymbol, ::EnumEntryContainingNamesAwareScope) + ?: return@getOrPut getEmptyScope() KtFirDelegatingScope(firScope, builder, token) } } @@ -243,4 +251,34 @@ internal class KtFirScopeProvider( else -> TODO(firScope::class.toString()) } } +} + +private class EnumEntryContainingNamesAwareScope(private val originalScope: FirContainingNamesAwareScope) : FirContainingNamesAwareScope() { + override fun getCallableNames(): Set = originalScope.getCallableNames() + override fun getClassifierNames(): Set = originalScope.getClassifierNames() + override fun mayContainName(name: Name): Boolean = originalScope.mayContainName(name) + override val scopeOwnerLookupNames: List get() = super.scopeOwnerLookupNames + + override fun processClassifiersByNameWithSubstitution( + name: Name, + processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit + ) { + originalScope.processClassifiersByNameWithSubstitution(name) { classifier, substitutor -> + if ((classifier as? FirRegularClassSymbol)?.isCompanion != true) { + processor(classifier, substitutor) + } + } + } + + override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { + originalScope.processFunctionsByName(name, processor) + } + + override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { + originalScope.processPropertiesByName(name, processor) + } + + override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) { + // enum entries does not have constructors + } } \ No newline at end of file diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolTest.kt index 56a2de96c10..770f6dd398b 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/symbols/AbstractSymbolTest.kt @@ -7,13 +7,12 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner -import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest import org.jetbrains.kotlin.analysis.api.symbols.DebugSymbolRenderer import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint import org.jetbrains.kotlin.psi.KtFile @@ -98,8 +97,11 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() { } private fun List.renderDeclarations(): String = + map { it.rendered }.renderAsDeclarations() + + private fun List.renderAsDeclarations(): String = if (isEmpty()) "NO_SYMBOLS" - else joinToString(separator = "\n\n") { it.rendered } + else joinToString(separator = "\n\n") private fun restoreSymbolsInOtherReadActionAndCompareResults( ktFile: KtFile, @@ -114,7 +116,7 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() { renderSymbolForComparison(restored) } } - val actual = restored.joinToString(separator = "\n\n") + val actual = restored.renderAsDeclarations() testServices.assertions.assertEqualsToTestDataFileSibling(actual) } diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.pretty.txt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.pretty.txt index cda719bff39..9e4e3c80e02 100644 --- a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.pretty.txt +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.pretty.txt @@ -15,8 +15,4 @@ val name: kotlin.String val ordinal: kotlin.Int -fun getDeclaringClass(): java.lang.Class! - -companion object - -private constructor() +fun getDeclaringClass(): java.lang.Class! \ No newline at end of file diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.txt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.txt index 9237c666941..0f7e949b2aa 100644 --- a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.txt +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.txt @@ -258,43 +258,4 @@ KtFunctionSymbol: visibility: Public getDispatchReceiver(): test/E getContainingModule: KtSourceModule "Sources of main" - deprecationStatus: null - -KtNamedClassOrObjectSymbol: - annotationsList: [] - classIdIfNonLocal: kotlin/Enum.Companion - classKind: COMPANION_OBJECT - companionObject: null - isData: false - isExternal: false - isFun: false - isInline: false - isInner: false - modality: FINAL - name: Companion - origin: LIBRARY - superTypes: [ - kotlin/Any - ] - symbolKind: CLASS_MEMBER - typeParameters: [] - visibility: Public - getContainingModule: KtLibraryModule "Library kotlin-stdlib" - deprecationStatus: null - -KtConstructorSymbol: - annotationsList: [] - callableIdIfNonLocal: null - containingClassIdIfNonLocal: null - hasStableParameterNames: true - isExtension: false - isPrimary: true - origin: SOURCE_MEMBER_GENERATED - receiverType: null - returnType: - symbolKind: CLASS_MEMBER - typeParameters: [] - valueParameters: [] - visibility: Private - getContainingModule: KtSourceModule "Sources of main" - deprecationStatus: null + deprecationStatus: null \ No newline at end of file