From 89ff1f0c0b69eaadce80c9af4c5d3829475b66c6 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Fri, 24 Jun 2022 13:53:01 +0200 Subject: [PATCH] [Analysis API FIR] fix member scope for enum entries without body --- .../api/fir/components/KtFirScopeProvider.kt | 4 +- ...oduleMemberScopeByFqNameTestGenerated.java | 12 + .../cases/scopes/AbstractMemberScopeTest.kt | 3 +- .../test/cases/symbols/AbstractSymbolTest.kt | 8 +- ...oduleMemberScopeByFqNameTestGenerated.java | 12 + .../emumEntryWithoutMembers.kt | 7 + .../emumEntryWithoutMembers.pretty.txt | 1 + .../emumEntryWithoutMembers.txt | 1 + .../scopes/memberScopeByFqName/enumEntry.kt | 10 + .../memberScopeByFqName/enumEntry.pretty.txt | 22 ++ .../scopes/memberScopeByFqName/enumEntry.txt | 300 ++++++++++++++++++ 11 files changed, 375 insertions(+), 5 deletions(-) create mode 100644 analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.kt create mode 100644 analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.pretty.txt create mode 100644 analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.txt create mode 100644 analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt create mode 100644 analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.pretty.txt create mode 100644 analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.txt 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 3143363cb8c..2ff975b37a4 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 @@ -71,8 +71,8 @@ internal class KtFirScopeProvider( } is KtFirEnumEntrySymbol -> { firSymbol.ensureResolved(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) - val initializer = firSymbol.fir.initializer - check(initializer is FirAnonymousObjectExpression) { "Unexpected enum entry initializer: ${initializer?.javaClass}" } + val initializer = firSymbol.fir.initializer ?: return null + check(initializer is FirAnonymousObjectExpression) { "Unexpected enum entry initializer: ${initializer.javaClass}" } body(initializer.anonymousObject) } else -> error { "Unknown KtSymbolWithDeclarations implementation ${this::class.qualifiedName}" } diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/scopes/FirIdeNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/scopes/FirIdeNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated.java index b0547c956d3..f686fda35f7 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/scopes/FirIdeNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/scopes/FirIdeNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated.java @@ -46,6 +46,18 @@ public class FirIdeNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated ex KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/scopes/memberScopeByFqName"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("emumEntryWithoutMembers.kt") + public void testEmumEntryWithoutMembers() throws Exception { + runTest("analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.kt"); + } + + @Test + @TestMetadata("enumEntry.kt") + public void testEnumEntry() throws Exception { + runTest("analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt"); + } + @Test @TestMetadata("Int.kt") public void testInt() throws Exception { diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/scopes/AbstractMemberScopeTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/scopes/AbstractMemberScopeTest.kt index 06e755d5318..58f085de2db 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/scopes/AbstractMemberScopeTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/scopes/AbstractMemberScopeTest.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.SymbolByFqName import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.AbstractSymbolByFqNameTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolsData import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.services.TestServices @@ -18,7 +19,7 @@ abstract class AbstractMemberScopeByFqNameTest : AbstractSymbolByFqNameTest() { override fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): SymbolsData { val symbolData = SymbolByFqName.getSymbolDataFromFile(testDataPath) val symbols = with(symbolData) { toSymbols() } - val classSymbol = symbols.singleOrNull() as? KtClassOrObjectSymbol + val classSymbol = symbols.singleOrNull() as? KtSymbolWithMembers ?: error("Should be a single class symbol, but $symbols found") return SymbolsData(classSymbol.getMemberScope().getAllSymbols().toList()) } 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 54ad6e729b1..56a2de96c10 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 @@ -90,13 +90,17 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() { data: SymbolPointersData, testServices: TestServices, ) { - val actual = data.pointers.joinToString(separator = "\n\n") { it.rendered } + val actual = data.pointers.renderDeclarations() testServices.assertions.assertEqualsToTestDataFileSibling(actual) - val actualPretty = data.pointersForPrettyRendering.joinToString(separator = "\n\n") { it.rendered } + val actualPretty = data.pointersForPrettyRendering.renderDeclarations() testServices.assertions.assertEqualsToTestDataFileSibling(actualPretty, extension = ".pretty.txt") } + private fun List.renderDeclarations(): String = + if (isEmpty()) "NO_SYMBOLS" + else joinToString(separator = "\n\n") { it.rendered } + private fun restoreSymbolsInOtherReadActionAndCompareResults( ktFile: KtFile, pointersWithRendered: List, diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/scopes/FirStandaloneNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/scopes/FirStandaloneNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated.java index f68519db226..125c0459171 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/scopes/FirStandaloneNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/scopes/FirStandaloneNormalAnalysisSourceModuleMemberScopeByFqNameTestGenerated.java @@ -46,6 +46,18 @@ public class FirStandaloneNormalAnalysisSourceModuleMemberScopeByFqNameTestGener KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/scopes/memberScopeByFqName"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("emumEntryWithoutMembers.kt") + public void testEmumEntryWithoutMembers() throws Exception { + runTest("analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.kt"); + } + + @Test + @TestMetadata("enumEntry.kt") + public void testEnumEntry() throws Exception { + runTest("analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt"); + } + @Test @TestMetadata("Int.kt") public void testInt() throws Exception { diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.kt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.kt new file mode 100644 index 00000000000..a0babb8af55 --- /dev/null +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.kt @@ -0,0 +1,7 @@ +package test + +enum class E { + A +} + +// callable: test/E.A diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.pretty.txt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.pretty.txt new file mode 100644 index 00000000000..e71fee3bda8 --- /dev/null +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.pretty.txt @@ -0,0 +1 @@ +NO_SYMBOLS diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.txt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.txt new file mode 100644 index 00000000000..63e2cb6e5c3 --- /dev/null +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/emumEntryWithoutMembers.txt @@ -0,0 +1 @@ +NO_SYMBOLS \ No newline at end of file diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt new file mode 100644 index 00000000000..27631dee541 --- /dev/null +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt @@ -0,0 +1,10 @@ +package test + +enum class E { + A { + val x: String = "" + } +} + +// callable: test/E.A +// DO_NOT_CHECK_SYMBOL_RESTORE diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.pretty.txt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.pretty.txt new file mode 100644 index 00000000000..cda719bff39 --- /dev/null +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.pretty.txt @@ -0,0 +1,22 @@ +val x: kotlin.String + +protected fun clone(): kotlin.Any + +operator fun compareTo(other: test.E): kotlin.Int + +operator fun equals(other: kotlin.Any?): kotlin.Boolean + +fun hashCode(): kotlin.Int + +open fun toString(): kotlin.String + +@kotlin.internal.IntrinsicConstEvaluation +val name: kotlin.String + +val ordinal: kotlin.Int + +fun getDeclaringClass(): java.lang.Class! + +companion object + +private constructor() diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.txt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.txt new file mode 100644 index 00000000000..9237c666941 --- /dev/null +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.txt @@ -0,0 +1,300 @@ +KtKotlinPropertySymbol: + annotationsList: [] + callableIdIfNonLocal: null + getter: KtPropertyGetterSymbol() + hasBackingField: true + hasGetter: true + hasSetter: false + initializer: KtConstantInitializerValue("") + isConst: false + isDelegatedProperty: false + isExtension: false + isFromPrimaryConstructor: false + isLateInit: false + isOverride: false + isStatic: false + isVal: true + modality: FINAL + name: x + origin: SOURCE + receiverType: null + returnType: kotlin/String + setter: null + symbolKind: CLASS_MEMBER + typeParameters: [] + visibility: Public + getDispatchReceiver(): + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + getterDeprecationStatus: null + javaGetterName: getX + javaSetterName: null + setterDeprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: kotlin/Enum.clone + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: clone + origin: LIBRARY + receiverType: null + returnType: kotlin/Any + symbolKind: CLASS_MEMBER + typeParameters: [] + valueParameters: [] + visibility: Protected + getDispatchReceiver(): kotlin/Enum + getContainingModule: KtLibraryModule "Library kotlin-stdlib" + deprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: test/E.compareTo + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: true + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: compareTo + origin: SUBSTITUTION_OVERRIDE + receiverType: null + returnType: kotlin/Int + symbolKind: CLASS_MEMBER + typeParameters: [] + valueParameters: [ + KtValueParameterSymbol(other) + ] + visibility: Public + getDispatchReceiver(): test/E + getContainingModule: KtSourceModule "Sources of main" + deprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: kotlin/Enum.equals + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: true + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: equals + origin: LIBRARY + receiverType: null + returnType: kotlin/Boolean + symbolKind: CLASS_MEMBER + typeParameters: [] + valueParameters: [ + KtValueParameterSymbol(other) + ] + visibility: Public + getDispatchReceiver(): kotlin/Enum + getContainingModule: KtLibraryModule "Library kotlin-stdlib" + deprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: kotlin/Enum.hashCode + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: hashCode + origin: LIBRARY + receiverType: null + returnType: kotlin/Int + symbolKind: CLASS_MEMBER + typeParameters: [] + valueParameters: [] + visibility: Public + getDispatchReceiver(): kotlin/Enum + getContainingModule: KtLibraryModule "Library kotlin-stdlib" + deprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: kotlin/Enum.toString + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: OPEN + name: toString + origin: LIBRARY + receiverType: null + returnType: kotlin/String + symbolKind: CLASS_MEMBER + typeParameters: [] + valueParameters: [] + visibility: Public + getDispatchReceiver(): kotlin/Enum + getContainingModule: KtLibraryModule "Library kotlin-stdlib" + deprecationStatus: null + +KtKotlinPropertySymbol: + annotationsList: [ + kotlin/internal/IntrinsicConstEvaluation() + psi: null + ] + callableIdIfNonLocal: kotlin/Enum.name + getter: KtPropertyGetterSymbol() + hasBackingField: true + hasGetter: true + hasSetter: false + initializer: null + isConst: false + isDelegatedProperty: false + isExtension: false + isFromPrimaryConstructor: false + isLateInit: false + isOverride: false + isStatic: false + isVal: true + modality: FINAL + name: name + origin: LIBRARY + receiverType: null + returnType: kotlin/String + setter: null + symbolKind: CLASS_MEMBER + typeParameters: [] + visibility: Public + getDispatchReceiver(): kotlin/Enum + getContainingModule: KtLibraryModule "Library kotlin-stdlib" + deprecationStatus: null + getterDeprecationStatus: null + javaGetterName: getName + javaSetterName: null + setterDeprecationStatus: null + +KtKotlinPropertySymbol: + annotationsList: [] + callableIdIfNonLocal: kotlin/Enum.ordinal + getter: KtPropertyGetterSymbol() + hasBackingField: true + hasGetter: true + hasSetter: false + initializer: null + isConst: false + isDelegatedProperty: false + isExtension: false + isFromPrimaryConstructor: false + isLateInit: false + isOverride: false + isStatic: false + isVal: true + modality: FINAL + name: ordinal + origin: LIBRARY + receiverType: null + returnType: kotlin/Int + setter: null + symbolKind: CLASS_MEMBER + typeParameters: [] + visibility: Public + getDispatchReceiver(): kotlin/Enum + getContainingModule: KtLibraryModule "Library kotlin-stdlib" + deprecationStatus: null + getterDeprecationStatus: null + javaGetterName: getOrdinal + javaSetterName: null + setterDeprecationStatus: null + +KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: test/E.getDeclaringClass + hasStableParameterNames: false + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: getDeclaringClass + origin: SUBSTITUTION_OVERRIDE + receiverType: null + returnType: ft>, java/lang/Class>?> + symbolKind: CLASS_MEMBER + typeParameters: [] + valueParameters: [] + 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