[LL API] Get designation correctly for enum value members (KTIJ-23458)
Although being a 'KtClass' in the PSI, 'KtEnumEntry' is a callable in Analysis API, and its direct members should also be treated as local.
This commit is contained in:
+10
-15
@@ -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<KtNamedDeclaration>()
|
||||
.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<KtNamedDeclaration>().firstOrNull { ktDeclaration ->
|
||||
ktDeclaration.canBeEnclosingDeclaration()
|
||||
}
|
||||
|
||||
private fun recordOriginalDeclaration(targetDeclaration: KtNamedDeclaration, originalDeclaration: KtNamedDeclaration) {
|
||||
require(originalDeclaration.containingKtFile !== targetDeclaration.containingKtFile)
|
||||
val originalDeclarationParents = originalDeclaration.parentsOfType<KtDeclaration>().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) {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
enum class Foo {
|
||||
VALUE {
|
||||
/*PLACE*/fun run() = 1
|
||||
}
|
||||
}
|
||||
|
||||
/*ONAIR*/fun box(): Int = 0
|
||||
@@ -0,0 +1,3 @@
|
||||
public final [BODY_RESOLVE] fun box(): R|kotlin/Int| {
|
||||
^box Int(0)
|
||||
}
|
||||
+6
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user