diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt index a6b0f16917f..438fddd359d 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacadeForResolveOnAir.kt @@ -37,26 +37,21 @@ import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment import org.jetbrains.kotlin.analysis.utils.errors.* +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject +import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf object LowLevelFirApiFacadeForResolveOnAir { - - private fun KtDeclaration.canBeEnclosingDeclaration(): Boolean = when (this) { - is KtNamedFunction -> isTopLevel || containingClassOrObject?.isLocal == false - is KtProperty -> isTopLevel || containingClassOrObject?.isLocal == false - is KtClassOrObject -> !isLocal - is KtTypeAlias -> isTopLevel() || containingClassOrObject?.isLocal == false - else -> false + private fun findNonLocalParentMaybeSelf(position: KtElement): KtNamedDeclaration? { + return position.parentsWithSelf + .filterIsInstance() + .filter { it is KtNamedFunction || it is KtProperty || (it is KtClassOrObject && it !is KtEnumEntry) || it is KtTypeAlias } + .filter { !KtPsiUtil.isLocal(it) && it.containingClassOrObject !is KtEnumEntry } + .firstOrNull() } - private fun findEnclosingNonLocalDeclaration(position: KtElement): KtNamedDeclaration? = - position.parentsOfType().firstOrNull { ktDeclaration -> - ktDeclaration.canBeEnclosingDeclaration() - } - private fun recordOriginalDeclaration(targetDeclaration: KtNamedDeclaration, originalDeclaration: KtNamedDeclaration) { require(originalDeclaration.containingKtFile !== targetDeclaration.containingKtFile) val originalDeclarationParents = originalDeclaration.parentsOfType().toList() @@ -150,7 +145,7 @@ object LowLevelFirApiFacadeForResolveOnAir { require(originalFirResolveSession is LLFirResolvableResolveSession) require(elementToAnalyze !is KtFile) { "KtFile for dependency element not supported" } - val dependencyNonLocalDeclaration = findEnclosingNonLocalDeclaration(elementToAnalyze) + val dependencyNonLocalDeclaration = findNonLocalParentMaybeSelf(elementToAnalyze) ?: return LLFirResolveSessionDepended( originalFirResolveSession, FileTowerProvider(elementToAnalyze.containingKtFile, onAirGetTowerContextForFile(originalFirResolveSession, originalKtFile)), @@ -216,7 +211,7 @@ object LowLevelFirApiFacadeForResolveOnAir { onAirCreatedDeclaration: Boolean, collector: FirTowerDataContextCollector? = null, ): FirElement { - val nonLocalDeclaration = findEnclosingNonLocalDeclaration(replacement.from) + val nonLocalDeclaration = findNonLocalParentMaybeSelf(replacement.from) val originalFirFile = firResolveSession.getOrBuildFirFile(replacement.from.containingKtFile) if (nonLocalDeclaration == null) { diff --git a/analysis/low-level-api-fir/testdata/onAirResolve/enumValueMember.kt b/analysis/low-level-api-fir/testdata/onAirResolve/enumValueMember.kt new file mode 100644 index 00000000000..69f6d2e8a00 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/onAirResolve/enumValueMember.kt @@ -0,0 +1,7 @@ +enum class Foo { + VALUE { + /*PLACE*/fun run() = 1 + } +} + +/*ONAIR*/fun box(): Int = 0 \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/onAirResolve/enumValueMember.txt b/analysis/low-level-api-fir/testdata/onAirResolve/enumValueMember.txt new file mode 100644 index 00000000000..ff0cf4ba00c --- /dev/null +++ b/analysis/low-level-api-fir/testdata/onAirResolve/enumValueMember.txt @@ -0,0 +1,3 @@ +public final [BODY_RESOLVE] fun box(): R|kotlin/Int| { + ^box Int(0) +} diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOnAirResolveTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOnAirResolveTestGenerated.java index c294da30f8e..f8e350cd29e 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOnAirResolveTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOnAirResolveTestGenerated.java @@ -30,6 +30,12 @@ public class FirOnAirResolveTestGenerated extends AbstractFirOnAirResolveTest { runTest("analysis/low-level-api-fir/testdata/onAirResolve/classInClass.kt"); } + @Test + @TestMetadata("enumValueMember.kt") + public void testEnumValueMember() throws Exception { + runTest("analysis/low-level-api-fir/testdata/onAirResolve/enumValueMember.kt"); + } + @Test @TestMetadata("fileAnnotation.kt") public void testFileAnnotation() throws Exception {