FIR IDE: Search for the first non-local declaration in EnclosingDeclarationContext::detect

Local declarations do not have a stable `ClassId`, which is used in
`declarationUtils.collectDesignation`. Local classes will always have
`outerClassId.isLocal = true`, even when it is not true (see
`org.jetbrains.kotlin.fir.builder.Context.currentClassId` for why this
happens)
This commit is contained in:
Roman Golyshev
2021-03-26 18:51:25 +03:00
committed by Space
parent 0d2158325a
commit 28d8d2d903
7 changed files with 79 additions and 2 deletions
@@ -1,3 +1,4 @@
// FIR_COMPARISON
class A(private val xxx1: Int, val xxx2: Int) {
private val xxx3: Int = 0
@@ -0,0 +1,20 @@
package test
class T
fun topLevelFun(param: T) {
val firstVariable = T()
class LocalClass(constructorParam: T) {
val localClassField = constructorParam
init {
<caret>
}
}
val secondVariable = T()
}
// EXIST: firstVariable, param, constructorParam, localClassField
// ABSENT: secondVariable
@@ -0,0 +1,20 @@
package test
class T
fun topLevelFun(param: T) {
val firstVariable = T()
class LocalClass(constructorParam: T) {
val localClassField = constructorParam
fun localClassMethod(localParam: T) {
<caret>
}
}
val secondVariable = T()
}
// EXIST: firstVariable, param, constructorParam, localClassField, localParam
// ABSENT: secondVariable
@@ -2328,6 +2328,16 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/insideFunctionWithParameters.kt");
}
@TestMetadata("localClassConstructor.kt")
public void testLocalClassConstructor() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localClassConstructor.kt");
}
@TestMetadata("localClassMember.kt")
public void testLocalClassMember() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localClassMember.kt");
}
@TestMetadata("localVariablesAndFunctions.kt")
public void testLocalVariablesAndFunctions() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localVariablesAndFunctions.kt");
@@ -2328,6 +2328,16 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/insideFunctionWithParameters.kt");
}
@TestMetadata("localClassConstructor.kt")
public void testLocalClassConstructor() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localClassConstructor.kt");
}
@TestMetadata("localClassMember.kt")
public void testLocalClassMember() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localClassMember.kt");
}
@TestMetadata("localVariablesAndFunctions.kt")
public void testLocalVariablesAndFunctions() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localVariablesAndFunctions.kt");
@@ -2328,6 +2328,16 @@ public class HighLevelJvmBasicCompletionTestGenerated extends AbstractHighLevelJ
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/insideFunctionWithParameters.kt");
}
@TestMetadata("localClassConstructor.kt")
public void testLocalClassConstructor() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localClassConstructor.kt");
}
@TestMetadata("localClassMember.kt")
public void testLocalClassMember() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localClassMember.kt");
}
@TestMetadata("localVariablesAndFunctions.kt")
public void testLocalVariablesAndFunctions() throws Exception {
runTest("idea/idea-completion/testData/basic/common/primitiveCompletion/localVariablesAndFunctions.kt");
@@ -12,12 +12,15 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.api.LowLevelFirApiFacadeForCo
import org.jetbrains.kotlin.idea.fir.low.level.api.util.originalDeclaration
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
internal sealed class EnclosingDeclarationContext {
companion object {
fun detect(originalFile: KtFile, positionInFakeFile: KtElement): EnclosingDeclarationContext {
val fakeFunction = positionInFakeFile.parentsOfType<KtNamedFunction>().firstOrNull { !it.isLocal }
val fakeFunction = positionInFakeFile.parentsOfType<KtNamedFunction>().firstOrNull {
it.isTopLevel || it.containingClassOrObject?.isLocal == false
}
if (fakeFunction != null) {
val originalFunction = originalFile.findDeclarationOfTypeAt<KtNamedFunction>(fakeFunction.textOffset)
?: error("Cannot find original function matching to ${fakeFunction.getElementTextInContext()} in $originalFile")
@@ -25,7 +28,10 @@ internal sealed class EnclosingDeclarationContext {
return FunctionContext(fakeFunction, originalFunction)
}
val fakeProperty = positionInFakeFile.parentsOfType<KtProperty>().firstOrNull { !it.isLocal }
val fakeProperty = positionInFakeFile.parentsOfType<KtProperty>().firstOrNull {
it.isTopLevel || it.containingClassOrObject?.isLocal == false
}
if (fakeProperty != null) {
val originalProperty = originalFile.findDeclarationOfTypeAt<KtProperty>(fakeProperty.textOffset)
?: error("Cannot find original property matching to ${fakeProperty.getElementTextInContext()} in $originalFile")