"Use destructuring declaration": fix it works correctly if variable name is shadowed
#KT-30601 Fixed #KT-20570 Fixed
This commit is contained in:
committed by
Yan Zhulanow
parent
f4b9c4777f
commit
d61158a176
@@ -59,9 +59,13 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
|
||||
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<String>()
|
||||
@@ -76,7 +80,7 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
|
||||
if (usagesToReplace.isEmpty() && variableToDrop == null && underscoreSupported && !allUnused) {
|
||||
"_"
|
||||
} else {
|
||||
name ?: KotlinNameSuggester.suggestNameByName(descriptor.name.asString(), validator)
|
||||
KotlinNameSuggester.suggestNameByName(name ?: descriptor.name.asString(), validator)
|
||||
}
|
||||
|
||||
runWriteAction {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
data class XY(val x: Int, val y: Int)
|
||||
fun test(xys: Array<XY>) {
|
||||
xys.forEach { (x, y) ->
|
||||
xys.forEach { (x, y1) ->
|
||||
println(x)
|
||||
val y = y + x
|
||||
val y = y1 + x
|
||||
println(y)
|
||||
}
|
||||
}
|
||||
@@ -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), <caret>it2 -> timestamp + it2.timestamp }
|
||||
}
|
||||
@@ -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 }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// WITH_RUNTIME
|
||||
data class A(var x: Int)
|
||||
|
||||
fun convert(f: (A) -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
convert <caret>{
|
||||
val x = it.x
|
||||
|
||||
run {
|
||||
val x = 1
|
||||
val z = it.x
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// WITH_RUNTIME
|
||||
data class A(var x: Int)
|
||||
|
||||
fun convert(f: (A) -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
convert { <caret>a ->
|
||||
val x = a.x
|
||||
|
||||
run {
|
||||
val x = 1
|
||||
val z = a.x
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// WITH_RUNTIME
|
||||
fun main() {
|
||||
data class A(var x: Int)
|
||||
|
||||
val <caret>a = A(0)
|
||||
val x = a.x
|
||||
|
||||
run {
|
||||
val x = 1
|
||||
val z = a.x
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user