Simplify for: take into account two or more possible local variables for the same loop parameter property
This commit is contained in:
@@ -50,7 +50,7 @@ class SimplifyForIntention : SelfTargetingRangeIntention<KtForExpression>(
|
|||||||
val factory = KtPsiFactory(element)
|
val factory = KtPsiFactory(element)
|
||||||
loopParameter.replace(factory.createDestructuringDeclarationInFor("(${usagesToRemove.joinToString { it.name!! }})"))
|
loopParameter.replace(factory.createDestructuringDeclarationInFor("(${usagesToRemove.joinToString { it.name!! }})"))
|
||||||
usagesToRemove.forEach { p ->
|
usagesToRemove.forEach { p ->
|
||||||
p.property?.delete()
|
p.properties.firstOrNull()?.delete()
|
||||||
p.usersToReplace.forEach {
|
p.usersToReplace.forEach {
|
||||||
it.replace(factory.createExpression(p.name!!))
|
it.replace(factory.createExpression(p.name!!))
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ class SimplifyForIntention : SelfTargetingRangeIntention<KtForExpression>(
|
|||||||
{ otherUsages = true }
|
{ otherUsages = true }
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!otherUsages && usagesToRemove.all { it != null && it.name != null}) {
|
if (!otherUsages && usagesToRemove.all { it != null && it.name != null && it.properties.size <= 1 }) {
|
||||||
return usagesToRemove.mapNotNull { it } to removeSelectorInLoopRange
|
return usagesToRemove.mapNotNull { it } to removeSelectorInLoopRange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ class SimplifyForIntention : SelfTargetingRangeIntention<KtForExpression>(
|
|||||||
|
|
||||||
val notNullUsages = usagesToRemove.filterNotNull().filter { it.name != null }
|
val notNullUsages = usagesToRemove.filterNotNull().filter { it.name != null }
|
||||||
val droppedLastUnused = usagesToRemove.dropLastWhile { it == null }
|
val droppedLastUnused = usagesToRemove.dropLastWhile { it == null }
|
||||||
if (droppedLastUnused.size == notNullUsages.size) {
|
if (droppedLastUnused.size == notNullUsages.size && droppedLastUnused.all { it != null && it.properties.size <= 1 } ) {
|
||||||
return notNullUsages to false
|
return notNullUsages to false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,13 +192,13 @@ class SimplifyForIntention : SelfTargetingRangeIntention<KtForExpression>(
|
|||||||
return UsageData(property, parentCall, descriptor)
|
return UsageData(property, parentCall, descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class UsageData(val property: KtProperty?,
|
private data class UsageData(val properties: List<KtProperty>,
|
||||||
val usersToReplace: List<KtExpression>,
|
val usersToReplace: List<KtExpression>,
|
||||||
val descriptor: CallableDescriptor,
|
val descriptor: CallableDescriptor,
|
||||||
val name: String? = property?.name
|
val name: String? = properties.firstOrNull()?.name
|
||||||
) {
|
) {
|
||||||
constructor(property: KtProperty?, user: KtExpression, descriptor: CallableDescriptor):
|
constructor(property: KtProperty?, user: KtExpression, descriptor: CallableDescriptor):
|
||||||
this(property, if (property != null) emptyList() else listOf(user), descriptor)
|
this(listOfNotNull(property), if (property != null) emptyList() else listOf(user), descriptor)
|
||||||
|
|
||||||
fun named(suggested: String) = if (name != null) this else copy(name = suggested)
|
fun named(suggested: String) = if (name != null) this else copy(name = suggested)
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,8 @@ class SimplifyForIntention : SelfTargetingRangeIntention<KtForExpression>(
|
|||||||
private operator fun UsageData?.plus(newData: UsageData): UsageData {
|
private operator fun UsageData?.plus(newData: UsageData): UsageData {
|
||||||
if (this == null) return newData
|
if (this == null) return newData
|
||||||
val allUsersToReplace = usersToReplace + newData.usersToReplace
|
val allUsersToReplace = usersToReplace + newData.usersToReplace
|
||||||
if (property != null) return copy(usersToReplace = allUsersToReplace)
|
val allProperties = properties + newData.properties
|
||||||
else return newData.copy(usersToReplace = allUsersToReplace)
|
if (properties.isNotEmpty()) return copy(properties = allProperties, usersToReplace = allUsersToReplace)
|
||||||
|
else return newData.copy(properties = allProperties, usersToReplace = allUsersToReplace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
data class XY(val x: String, val y: Int)
|
||||||
|
fun test(xys: Array<XY>) {
|
||||||
|
for (<caret>xy in xys) {
|
||||||
|
val x = xy.x
|
||||||
|
println(x)
|
||||||
|
val xx = xy.x
|
||||||
|
println(xx)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6579,6 +6579,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("DataClassTwoDifferentLocals.kt")
|
||||||
|
public void testDataClassTwoDifferentLocals() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/iterationOverMap/DataClassTwoDifferentLocals.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("DataClassUnused.kt")
|
@TestMetadata("DataClassUnused.kt")
|
||||||
public void testDataClassUnused() throws Exception {
|
public void testDataClassUnused() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/iterationOverMap/DataClassUnused.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/iterationOverMap/DataClassUnused.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user