Join with assignment: fix false negative when local variable are used

#KT-34270 Fixed
This commit is contained in:
Toshiaki Kameyama
2019-12-02 14:49:06 +09:00
committed by Yan Zhulanow
parent b56272dc64
commit 5a3c6def8f
6 changed files with 47 additions and 4 deletions
@@ -57,7 +57,7 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingRangeIntention<KtProp
val assignment = findAssignment(element) ?: return null
if (assignment.right?.let {
hasNoLocalDependencies(it, element.parent) && assignment.analyze().let { context ->
hasNoLocalDependencies(it, element) && assignment.analyze().let { context ->
(element.isVar && !element.isLocal) ||
equalNullableTypes(it.getType(context), context[BindingContext.TYPE, element.typeReference])
}
@@ -155,10 +155,13 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingRangeIntention<KtProp
// a block that only contains comments is not empty
private fun KtBlockExpression.isEmpty() = contentRange().isEmpty
private fun hasNoLocalDependencies(element: KtElement, localContext: PsiElement): Boolean =
!element.anyDescendantOfType<PsiElement> { child ->
child.resolveAllReferences().any { it != null && PsiTreeUtil.isAncestor(localContext, it, false) }
private fun hasNoLocalDependencies(element: KtElement, property: KtProperty): Boolean {
val localContext = property.parent
val nextSiblings = property.siblings(forward = true, withItself = false)
return !element.anyDescendantOfType<PsiElement> { child ->
child.resolveAllReferences().any { it != null && PsiTreeUtil.isAncestor(localContext, it, false) && it in nextSiblings }
}
}
}
private fun PsiElement.resolveAllReferences(): Sequence<PsiElement?> =
@@ -0,0 +1,8 @@
class Test(height: Int, width: Int) {
private val size: Int = height * width
private val <caret>data: Int
init {
data = size
}
}
@@ -0,0 +1,5 @@
class Test(height: Int, width: Int) {
private val size: Int = height * width
private val data: Int = size
}
@@ -0,0 +1,10 @@
class Foo(size: Int)
class Test(height: Int, width: Int) {
private val size: Int = height * width
private val <caret>data: Foo
init {
data = Foo(size)
}
}
@@ -0,0 +1,7 @@
class Foo(size: Int)
class Test(height: Int, width: Int) {
private val size: Int = height * width
private val data: Foo = Foo(size)
}
@@ -10826,6 +10826,16 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
runTest("idea/testData/intentions/joinDeclarationAndAssignment/usedLocal2.kt");
}
@TestMetadata("usedLocal3.kt")
public void testUsedLocal3() throws Exception {
runTest("idea/testData/intentions/joinDeclarationAndAssignment/usedLocal3.kt");
}
@TestMetadata("usedLocal4.kt")
public void testUsedLocal4() throws Exception {
runTest("idea/testData/intentions/joinDeclarationAndAssignment/usedLocal4.kt");
}
@TestMetadata("varReassignment.kt")
public void testVarReassignment() throws Exception {
runTest("idea/testData/intentions/joinDeclarationAndAssignment/varReassignment.kt");