[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.types.FirResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.*
|
import org.jetbrains.kotlin.analysis.utils.errors.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||||
|
|
||||||
object LowLevelFirApiFacadeForResolveOnAir {
|
object LowLevelFirApiFacadeForResolveOnAir {
|
||||||
|
private fun findNonLocalParentMaybeSelf(position: KtElement): KtNamedDeclaration? {
|
||||||
private fun KtDeclaration.canBeEnclosingDeclaration(): Boolean = when (this) {
|
return position.parentsWithSelf
|
||||||
is KtNamedFunction -> isTopLevel || containingClassOrObject?.isLocal == false
|
.filterIsInstance<KtNamedDeclaration>()
|
||||||
is KtProperty -> isTopLevel || containingClassOrObject?.isLocal == false
|
.filter { it is KtNamedFunction || it is KtProperty || (it is KtClassOrObject && it !is KtEnumEntry) || it is KtTypeAlias }
|
||||||
is KtClassOrObject -> !isLocal
|
.filter { !KtPsiUtil.isLocal(it) && it.containingClassOrObject !is KtEnumEntry }
|
||||||
is KtTypeAlias -> isTopLevel() || containingClassOrObject?.isLocal == false
|
.firstOrNull()
|
||||||
else -> false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findEnclosingNonLocalDeclaration(position: KtElement): KtNamedDeclaration? =
|
|
||||||
position.parentsOfType<KtNamedDeclaration>().firstOrNull { ktDeclaration ->
|
|
||||||
ktDeclaration.canBeEnclosingDeclaration()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun recordOriginalDeclaration(targetDeclaration: KtNamedDeclaration, originalDeclaration: KtNamedDeclaration) {
|
private fun recordOriginalDeclaration(targetDeclaration: KtNamedDeclaration, originalDeclaration: KtNamedDeclaration) {
|
||||||
require(originalDeclaration.containingKtFile !== targetDeclaration.containingKtFile)
|
require(originalDeclaration.containingKtFile !== targetDeclaration.containingKtFile)
|
||||||
val originalDeclarationParents = originalDeclaration.parentsOfType<KtDeclaration>().toList()
|
val originalDeclarationParents = originalDeclaration.parentsOfType<KtDeclaration>().toList()
|
||||||
@@ -150,7 +145,7 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
|||||||
require(originalFirResolveSession is LLFirResolvableResolveSession)
|
require(originalFirResolveSession is LLFirResolvableResolveSession)
|
||||||
require(elementToAnalyze !is KtFile) { "KtFile for dependency element not supported" }
|
require(elementToAnalyze !is KtFile) { "KtFile for dependency element not supported" }
|
||||||
|
|
||||||
val dependencyNonLocalDeclaration = findEnclosingNonLocalDeclaration(elementToAnalyze)
|
val dependencyNonLocalDeclaration = findNonLocalParentMaybeSelf(elementToAnalyze)
|
||||||
?: return LLFirResolveSessionDepended(
|
?: return LLFirResolveSessionDepended(
|
||||||
originalFirResolveSession,
|
originalFirResolveSession,
|
||||||
FileTowerProvider(elementToAnalyze.containingKtFile, onAirGetTowerContextForFile(originalFirResolveSession, originalKtFile)),
|
FileTowerProvider(elementToAnalyze.containingKtFile, onAirGetTowerContextForFile(originalFirResolveSession, originalKtFile)),
|
||||||
@@ -216,7 +211,7 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
|||||||
onAirCreatedDeclaration: Boolean,
|
onAirCreatedDeclaration: Boolean,
|
||||||
collector: FirTowerDataContextCollector? = null,
|
collector: FirTowerDataContextCollector? = null,
|
||||||
): FirElement {
|
): FirElement {
|
||||||
val nonLocalDeclaration = findEnclosingNonLocalDeclaration(replacement.from)
|
val nonLocalDeclaration = findNonLocalParentMaybeSelf(replacement.from)
|
||||||
val originalFirFile = firResolveSession.getOrBuildFirFile(replacement.from.containingKtFile)
|
val originalFirFile = firResolveSession.getOrBuildFirFile(replacement.from.containingKtFile)
|
||||||
|
|
||||||
if (nonLocalDeclaration == null) {
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("fileAnnotation.kt")
|
@TestMetadata("fileAnnotation.kt")
|
||||||
public void testFileAnnotation() throws Exception {
|
public void testFileAnnotation() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user