[LL FIR] KTIJ-24574 Fix containing declaration finder for init blocks

- KTIJ-24574 occurred because a local destructuring declaration was
  erroneously returned as the non-local containing declaration of an
  element by `getNonLocalContainingOrThisDeclaration`. This occurred in
  `init` blocks.

KTIJ-24574 fixed
This commit is contained in:
Marco Pennekamp
2023-02-09 15:18:29 +01:00
committed by Space Team
parent 769fb835f9
commit fb43e53ca3
9 changed files with 62 additions and 14 deletions
@@ -166,6 +166,12 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
runTest("analysis/analysis-api/testData/referenceResolve/Deprecated.kt");
}
@Test
@TestMetadata("DestructuringDeclarationInInit.kt")
public void testDestructuringDeclarationInInit() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/DestructuringDeclarationInInit.kt");
}
@Test
@TestMetadata("EnumValues.kt")
public void testEnumValues() throws Exception {
@@ -166,6 +166,12 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
runTest("analysis/analysis-api/testData/referenceResolve/Deprecated.kt");
}
@Test
@TestMetadata("DestructuringDeclarationInInit.kt")
public void testDestructuringDeclarationInInit() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/DestructuringDeclarationInInit.kt");
}
@Test
@TestMetadata("EnumValues.kt")
public void testEnumValues() throws Exception {
@@ -166,6 +166,12 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
runTest("analysis/analysis-api/testData/referenceResolve/Deprecated.kt");
}
@Test
@TestMetadata("DestructuringDeclarationInInit.kt")
public void testDestructuringDeclarationInInit() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/DestructuringDeclarationInInit.kt");
}
@Test
@TestMetadata("EnumValues.kt")
public void testEnumValues() throws Exception {
@@ -166,6 +166,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
runTest("analysis/analysis-api/testData/referenceResolve/Deprecated.kt");
}
@Test
@TestMetadata("DestructuringDeclarationInInit.kt")
public void testDestructuringDeclarationInInit() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/DestructuringDeclarationInInit.kt");
}
@Test
@TestMetadata("EnumValues.kt")
public void testEnumValues() throws Exception {
@@ -166,6 +166,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
runTest("analysis/analysis-api/testData/referenceResolve/Deprecated.kt");
}
@Test
@TestMetadata("DestructuringDeclarationInInit.kt")
public void testDestructuringDeclarationInInit() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/DestructuringDeclarationInInit.kt");
}
@Test
@TestMetadata("EnumValues.kt")
public void testEnumValues() throws Exception {
@@ -0,0 +1,11 @@
var x: Any = 2
class Test {
init {
val (type, entityName) = when {
x is Int -> Int::class.java to "Int"
<caret>x is String -> String::class.java to "String"
else -> null to null
}
}
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in ROOT) var x: kotlin.Any
@@ -18,7 +18,9 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi2ir.deparenthesize
@@ -107,24 +109,27 @@ internal fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate: (KtDec
for (parent in parentsWithSelf) {
if (candidate != null) {
if (parent is KtEnumEntry || parent is KtCallableDeclaration) {
// Candidate turned to be local. Let's find another one
if (parent is KtEnumEntry || parent is KtCallableDeclaration || parent is KtClassInitializer) {
// Candidate turned out to be local. Let's find another one.
candidate = null
}
}
when (parent) {
is KtScript -> propose(parent)
is KtDestructuringDeclaration -> propose(parent)
is KtNamedDeclaration -> {
val isKindApplicable = when (parent) {
is KtClassOrObject -> !parent.isObjectLiteral()
is KtDeclarationWithBody, is KtProperty, is KtTypeAlias -> true
else -> false
}
// A new candidate only needs to be proposed when `candidate` is null.
if (candidate == null) {
when (parent) {
is KtScript -> propose(parent)
is KtDestructuringDeclaration -> propose(parent)
is KtNamedDeclaration -> {
val isKindApplicable = when (parent) {
is KtClassOrObject -> !parent.isObjectLiteral()
is KtDeclarationWithBody, is KtProperty, is KtTypeAlias -> true
else -> false
}
if (isKindApplicable && declarationCanBeLazilyResolved(parent) && predicate(parent)) {
propose(parent)
if (isKindApplicable && declarationCanBeLazilyResolved(parent) && predicate(parent)) {
propose(parent)
}
}
}
}