Make property initializer modification is OutOfBlock change
Fixed #KT-38762
This commit is contained in:
+18
-22
@@ -29,6 +29,7 @@ import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
|
||||
@@ -220,32 +221,27 @@ abstract class KotlinCodeBlockModificationListenerCompat(protected val project:
|
||||
// return BlockModificationScopeElement(it, it)
|
||||
// }
|
||||
// }
|
||||
|
||||
if (blockDeclaration.typeReference != null) {
|
||||
val accessors =
|
||||
blockDeclaration.accessors.map { it.initializer ?: it.bodyExpression }
|
||||
|
||||
val accessorList = if (blockDeclaration.initializer.isAncestor(element) &&
|
||||
// call expression changes in property initializer are OCB, see KT-38443
|
||||
KtPsiUtil.getTopmostParentOfTypes(element, KtCallExpression::class.java) == null
|
||||
) {
|
||||
accessors + blockDeclaration.initializer
|
||||
} else {
|
||||
accessors
|
||||
}
|
||||
// adding annotations to accessor is the same as change contract of property
|
||||
if (element !is KtAnnotated || element.annotationEntries.isEmpty()) {
|
||||
|
||||
for (accessor in accessorList) {
|
||||
accessor?.takeIf {
|
||||
it.isAncestor(element) &&
|
||||
// adding annotations to accessor is the same as change contract of property
|
||||
(element !is KtAnnotated || element.annotationEntries.isEmpty())
|
||||
}
|
||||
?.let { expression ->
|
||||
val declaration =
|
||||
KtPsiUtil.getTopmostParentOfTypes(blockDeclaration, KtClassOrObject::class.java) as? KtElement ?:
|
||||
// ktFile to check top level property declarations
|
||||
return null
|
||||
return BlockModificationScopeElement(declaration, expression)
|
||||
val properExpression = blockDeclaration.accessors
|
||||
.firstOrNull { (it.initializer ?: it.bodyExpression).isAncestor(element) }
|
||||
?: blockDeclaration.initializer?.takeIf {
|
||||
// name references changes in property initializer are OCB, see KT-38443, KT-38762
|
||||
it.isAncestor(element) && !it.anyDescendantOfType<KtNameReferenceExpression>()
|
||||
}
|
||||
|
||||
if (properExpression != null) {
|
||||
val declaration =
|
||||
KtPsiUtil.getTopmostParentOfTypes(blockDeclaration, KtClassOrObject::class.java) as? KtElement
|
||||
|
||||
if (declaration != null) {
|
||||
return BlockModificationScopeElement(declaration, properExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// OUT_OF_CODE_BLOCK: TRUE
|
||||
// TYPE: 'A'
|
||||
// SKIP_ANALYZE_CHECK
|
||||
|
||||
class SomeClass(val paramA: Int) {
|
||||
val someProperty: Int = param<caret>
|
||||
}
|
||||
|
||||
// TODO: it has to be non OCB !
|
||||
@@ -1,5 +1,6 @@
|
||||
// OUT_OF_CODE_BLOCK: FALSE
|
||||
// OUT_OF_CODE_BLOCK: TRUE
|
||||
// ERROR: Unresolved reference: apri
|
||||
// SKIP_ANALYZE_CHECK
|
||||
|
||||
class Test {
|
||||
val a : () -> Int = { <caret>pri }
|
||||
|
||||
+5
@@ -118,6 +118,11 @@ public class OutOfBlockModificationTestGenerated extends AbstractOutOfBlockModif
|
||||
runTest("idea/testData/codeInsight/outOfBlock/InClassPropertyInitializer.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("InClassPropertyInitializer2.kt")
|
||||
public void testInClassPropertyInitializer2() throws Exception {
|
||||
runTest("idea/testData/codeInsight/outOfBlock/InClassPropertyInitializer2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("InClassPropertyInitializerWithoutInference.kt")
|
||||
public void testInClassPropertyInitializerWithoutInference() throws Exception {
|
||||
runTest("idea/testData/codeInsight/outOfBlock/InClassPropertyInitializerWithoutInference.kt");
|
||||
|
||||
Reference in New Issue
Block a user