From cf886c5975ffdc81bbfad9f1816ec456fc875881 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Tue, 9 Nov 2021 22:01:46 -0800 Subject: [PATCH] FIR LL: fix searching logic for enum entry KtEnumEntry, a subtype of KtClass, has been handled by findNonLocalClass. Since KtEnumEntry doesn't have class id, that util always throws an error while retrieving class id. Instead, we should use containing class (i.e., enum class) id. Also, once the enum class is resolved, we should search for matching enum entry inside the enum class. --- .../api/fir/FirModuleResolveStateImpl.kt | 1 + ...irDeclarationForCompiledElementSearcher.kt | 19 +++++++++++++++---- .../annotations/retentionValue.kt | 2 ++ .../annotations/retentionValue.txt | 5 +++++ .../api/fir/GetOrBuildFirTestGenerated.java | 6 ++++++ 5 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.kt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.txt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirModuleResolveStateImpl.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirModuleResolveStateImpl.kt index 7a0f7628c56..443c739e0b1 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirModuleResolveStateImpl.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirModuleResolveStateImpl.kt @@ -129,6 +129,7 @@ internal class FirModuleResolveStateImpl( val searcher = FirDeclarationForCompiledElementSearcher(rootModuleSession.symbolProvider) return when (ktDeclaration) { + is KtEnumEntry -> searcher.findNonLocalEnumEntry(ktDeclaration) is KtClassOrObject -> searcher.findNonLocalClass(ktDeclaration) is KtConstructor<*> -> searcher.findConstructorOfNonLocalClass(ktDeclaration) is KtNamedFunction -> searcher.findNonLocalFunction(ktDeclaration) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/FirDeclarationForCompiledElementSearcher.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/FirDeclarationForCompiledElementSearcher.kt index 62e3b960523..3234b9423e8 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/FirDeclarationForCompiledElementSearcher.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/FirDeclarationForCompiledElementSearcher.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.util import org.jetbrains.kotlin.analysis.low.level.api.fir.api.KtDeclarationAndFirDeclarationEqualityChecker -import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration -import org.jetbrains.kotlin.fir.declarations.FirConstructor -import org.jetbrains.kotlin.fir.declarations.FirFunction -import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredConstructors import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredFunctionSymbols @@ -24,6 +21,20 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject * Allows to search for FIR declarations by compiled [KtDeclaration]s. */ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvider: FirSymbolProvider) { + + fun findNonLocalEnumEntry(declaration: KtEnumEntry): FirEnumEntry { + require(!declaration.isLocal) + val classId = declaration.containingClassOrObject?.getClassId() + ?: error("Non-local class should have classId. The class is ${declaration.getElementTextInContext()}") + + val classCandidate = symbolProvider.getClassLikeSymbolByClassId(classId) + ?: error("We should be able to find a symbol for $classId") + + return (classCandidate.fir as? FirRegularClass)?.declarations?.first { + it is FirEnumEntry && it.name == declaration.nameAsName + } as FirEnumEntry + } + fun findNonLocalClass(declaration: KtClassOrObject): FirClassLikeDeclaration { require(!declaration.isLocal) val classId = declaration.getClassId() diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.kt b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.kt new file mode 100644 index 00000000000..33e3dc06964 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.kt @@ -0,0 +1,2 @@ +@Retention(AnnotationRetention.SOURCE) +annotation class Anno diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.txt new file mode 100644 index 00000000000..9e0a2ee5f71 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.txt @@ -0,0 +1,5 @@ +KT element: KtNameReferenceExpression +FIR element: FirResolvedNamedReferenceImpl + +FIR element rendered: +R|kotlin/annotation/AnnotationRetention.SOURCE| diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java index 79a042013e8..b089704eeef 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java @@ -68,6 +68,12 @@ public class GetOrBuildFirTestGenerated extends AbstractGetOrBuildFirTest { public void testFileAnnotation() throws Exception { runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/fileAnnotation.kt"); } + + @Test + @TestMetadata("retentionValue.kt") + public void testRetentionValue() throws Exception { + runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/retentionValue.kt"); + } } @Nested