diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/DestructureIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/DestructureIntention.kt index dbb84538d46..b3f97bb04de 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/DestructureIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/DestructureIntention.kt @@ -59,9 +59,13 @@ class DestructureIntention : SelfTargetingRangeIntention( override fun applyTo(element: KtDeclaration, editor: Editor?) { val (usagesToRemove, removeSelectorInLoopRange) = collectUsagesToRemove(element) ?: return val factory = KtPsiFactory(element) + val parent = element.parent + val (container, anchor) = if (parent is KtParameterList) parent.parent to null else parent to element val validator = NewDeclarationNameValidator( - container = element.parent, anchor = element, target = NewDeclarationNameValidator.Target.VARIABLES, - excludedDeclarations = usagesToRemove.map { listOfNotNull(it.declarationToDrop) }.flatten() + container = container, anchor = anchor, target = NewDeclarationNameValidator.Target.VARIABLES, + excludedDeclarations = usagesToRemove.map { + (it.declarationToDrop as? KtDestructuringDeclaration)?.entries ?: listOfNotNull(it.declarationToDrop) + }.flatten() ) val names = ArrayList() @@ -76,7 +80,7 @@ class DestructureIntention : SelfTargetingRangeIntention( if (usagesToReplace.isEmpty() && variableToDrop == null && underscoreSupported && !allUnused) { "_" } else { - name ?: KotlinNameSuggester.suggestNameByName(descriptor.name.asString(), validator) + KotlinNameSuggester.suggestNameByName(name ?: descriptor.name.asString(), validator) } runWriteAction { diff --git a/idea/testData/intentions/destructuringInLambda/dependentLocal.kt.after b/idea/testData/intentions/destructuringInLambda/dependentLocal.kt.after index 9e130328c81..ab8120cdd76 100644 --- a/idea/testData/intentions/destructuringInLambda/dependentLocal.kt.after +++ b/idea/testData/intentions/destructuringInLambda/dependentLocal.kt.after @@ -2,9 +2,9 @@ data class XY(val x: Int, val y: Int) fun test(xys: Array) { - xys.forEach { (x, y) -> + xys.forEach { (x, y1) -> println(x) - val y = y + x + val y = y1 + x println(y) } } \ No newline at end of file diff --git a/idea/testData/intentions/destructuringInLambda/hasSameNameParameter.kt b/idea/testData/intentions/destructuringInLambda/hasSameNameParameter.kt new file mode 100644 index 00000000000..bbed1159363 --- /dev/null +++ b/idea/testData/intentions/destructuringInLambda/hasSameNameParameter.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +data class Event(val timestamp: Int, val otherVar: Int = 1, val otherVar2: String = "") + +val listA = listOf(Event(1), Event(2), Event(3)) +val listB = listOf(Event(1), Event(2), Event(3)) + +fun test2() { + listA.zip(listB) { (timestamp), it2 -> timestamp + it2.timestamp } +} \ No newline at end of file diff --git a/idea/testData/intentions/destructuringInLambda/hasSameNameParameter.kt.after b/idea/testData/intentions/destructuringInLambda/hasSameNameParameter.kt.after new file mode 100644 index 00000000000..d4741507521 --- /dev/null +++ b/idea/testData/intentions/destructuringInLambda/hasSameNameParameter.kt.after @@ -0,0 +1,9 @@ +// WITH_RUNTIME +data class Event(val timestamp: Int, val otherVar: Int = 1, val otherVar2: String = "") + +val listA = listOf(Event(1), Event(2), Event(3)) +val listB = listOf(Event(1), Event(2), Event(3)) + +fun test2() { + listA.zip(listB) { (timestamp), (timestamp1) -> timestamp + timestamp1 } +} \ No newline at end of file diff --git a/idea/testData/intentions/destructuringInLambda/hasShadowedVariable.kt b/idea/testData/intentions/destructuringInLambda/hasShadowedVariable.kt new file mode 100644 index 00000000000..2d1bd183694 --- /dev/null +++ b/idea/testData/intentions/destructuringInLambda/hasShadowedVariable.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME +data class A(var x: Int) + +fun convert(f: (A) -> Unit) {} + +fun test() { + convert { + val x = it.x + + run { + val x = 1 + val z = it.x + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/destructuringInLambda/hasShadowedVariable.kt.after b/idea/testData/intentions/destructuringInLambda/hasShadowedVariable.kt.after new file mode 100644 index 00000000000..06942ccb4a7 --- /dev/null +++ b/idea/testData/intentions/destructuringInLambda/hasShadowedVariable.kt.after @@ -0,0 +1,14 @@ +// WITH_RUNTIME +data class A(var x: Int) + +fun convert(f: (A) -> Unit) {} + +fun test() { + convert { (x1) -> + + run { + val x = 1 + val z = x1 + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/destructuringInLambda/hasShadowedVariable2.kt b/idea/testData/intentions/destructuringInLambda/hasShadowedVariable2.kt new file mode 100644 index 00000000000..aab2ca23c25 --- /dev/null +++ b/idea/testData/intentions/destructuringInLambda/hasShadowedVariable2.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME +data class A(var x: Int) + +fun convert(f: (A) -> Unit) {} + +fun test() { + convert { a -> + val x = a.x + + run { + val x = 1 + val z = a.x + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/destructuringInLambda/hasShadowedVariable2.kt.after b/idea/testData/intentions/destructuringInLambda/hasShadowedVariable2.kt.after new file mode 100644 index 00000000000..06942ccb4a7 --- /dev/null +++ b/idea/testData/intentions/destructuringInLambda/hasShadowedVariable2.kt.after @@ -0,0 +1,14 @@ +// WITH_RUNTIME +data class A(var x: Int) + +fun convert(f: (A) -> Unit) {} + +fun test() { + convert { (x1) -> + + run { + val x = 1 + val z = x1 + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/destructuringVariables/hasShadowedVariable.kt b/idea/testData/intentions/destructuringVariables/hasShadowedVariable.kt new file mode 100644 index 00000000000..efb9603174f --- /dev/null +++ b/idea/testData/intentions/destructuringVariables/hasShadowedVariable.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +fun main() { + data class A(var x: Int) + + val a = A(0) + val x = a.x + + run { + val x = 1 + val z = a.x + } +} \ No newline at end of file diff --git a/idea/testData/intentions/destructuringVariables/hasShadowedVariable.kt.after b/idea/testData/intentions/destructuringVariables/hasShadowedVariable.kt.after new file mode 100644 index 00000000000..9113f97555a --- /dev/null +++ b/idea/testData/intentions/destructuringVariables/hasShadowedVariable.kt.after @@ -0,0 +1,11 @@ +// WITH_RUNTIME +fun main() { + data class A(var x: Int) + + val (x1) = A(0) + + run { + val x = 1 + val z = x1 + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 36fc2095db6..04173288fd7 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -8757,6 +8757,21 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/destructuringInLambda/fold.kt"); } + @TestMetadata("hasSameNameParameter.kt") + public void testHasSameNameParameter() throws Exception { + runTest("idea/testData/intentions/destructuringInLambda/hasSameNameParameter.kt"); + } + + @TestMetadata("hasShadowedVariable.kt") + public void testHasShadowedVariable() throws Exception { + runTest("idea/testData/intentions/destructuringInLambda/hasShadowedVariable.kt"); + } + + @TestMetadata("hasShadowedVariable2.kt") + public void testHasShadowedVariable2() throws Exception { + runTest("idea/testData/intentions/destructuringInLambda/hasShadowedVariable2.kt"); + } + @TestMetadata("invisible.kt") public void testInvisible() throws Exception { runTest("idea/testData/intentions/destructuringInLambda/invisible.kt"); @@ -8868,6 +8883,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/destructuringVariables/classProperty.kt"); } + @TestMetadata("hasShadowedVariable.kt") + public void testHasShadowedVariable() throws Exception { + runTest("idea/testData/intentions/destructuringVariables/hasShadowedVariable.kt"); + } + @TestMetadata("noInitializer.kt") public void testNoInitializer() throws Exception { runTest("idea/testData/intentions/destructuringVariables/noInitializer.kt");