Simplify for intention: apply name validator to prevent conflicts
This commit is contained in:
@@ -25,6 +25,8 @@ import com.intellij.util.Query
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||||
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||||
|
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
|
||||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
@@ -34,7 +36,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import java.util.*
|
||||||
import kotlin.collections.forEach
|
import kotlin.collections.forEach
|
||||||
|
|
||||||
class SimplifyForInspection : IntentionBasedInspection<KtForExpression>(SimplifyForIntention())
|
class SimplifyForInspection : IntentionBasedInspection<KtForExpression>(SimplifyForIntention())
|
||||||
@@ -51,13 +53,18 @@ class SimplifyForIntention : SelfTargetingRangeIntention<KtForExpression>(
|
|||||||
val loopParameter = element.loopParameter ?: return
|
val loopParameter = element.loopParameter ?: return
|
||||||
|
|
||||||
val factory = KtPsiFactory(element)
|
val factory = KtPsiFactory(element)
|
||||||
loopParameter.replace(factory.createDestructuringDeclarationInFor("(${usagesToRemove.joinToString { it.name!! }})"))
|
val validator = NewDeclarationNameValidator(element.parent, element, NewDeclarationNameValidator.Target.VARIABLES,
|
||||||
|
usagesToRemove.map { it.properties }.flatten())
|
||||||
|
val names = ArrayList<String>()
|
||||||
usagesToRemove.forEach { p ->
|
usagesToRemove.forEach { p ->
|
||||||
|
val name = KotlinNameSuggester.suggestNameByName(p.name!!, validator)
|
||||||
p.properties.firstOrNull()?.delete()
|
p.properties.firstOrNull()?.delete()
|
||||||
p.usersToReplace.forEach {
|
p.usersToReplace.forEach {
|
||||||
it.replace(factory.createExpression(p.name!!))
|
it.replace(factory.createExpression(name))
|
||||||
}
|
}
|
||||||
|
names.add(name)
|
||||||
}
|
}
|
||||||
|
loopParameter.replace(factory.createDestructuringDeclarationInFor("(${names.joinToString()})"))
|
||||||
|
|
||||||
if (removeSelectorInLoopRange && loopRange is KtDotQualifiedExpression) {
|
if (removeSelectorInLoopRange && loopRange is KtDotQualifiedExpression) {
|
||||||
loopRange.replace(loopRange.receiverExpression)
|
loopRange.replace(loopRange.receiverExpression)
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
data class XY(val x: Int, val y: Int)
|
||||||
|
|
||||||
|
fun foo(list: List<XY>) {
|
||||||
|
val y = list.size
|
||||||
|
for (<caret>element in list) {
|
||||||
|
val x = element.x + element.y
|
||||||
|
println(x)
|
||||||
|
println(y)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
data class XY(val x: Int, val y: Int)
|
||||||
|
|
||||||
|
fun foo(list: List<XY>) {
|
||||||
|
val y = list.size
|
||||||
|
for ((x1, y1) in list) {
|
||||||
|
val x = x1 + y1
|
||||||
|
println(x)
|
||||||
|
println(y)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -167,4 +167,12 @@
|
|||||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' that can be simplified using destructing declaration</problem_class>
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' that can be simplified using destructing declaration</problem_class>
|
||||||
<description>Simplify 'for' using destructing declaration</description>
|
<description>Simplify 'for' using destructing declaration</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
<problem>
|
||||||
|
<file>DataClassNameConflict.kt</file>
|
||||||
|
<line>7</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="temp:///src/DataClassNameConflict.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' that can be simplified using destructing declaration</problem_class>
|
||||||
|
<description>Simplify 'for' using destructing declaration</description>
|
||||||
|
</problem>
|
||||||
</problems>
|
</problems>
|
||||||
@@ -6555,6 +6555,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("DataClassNameConflict.kt")
|
||||||
|
public void testDataClassNameConflict() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/iterationOverMap/DataClassNameConflict.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("DataClassNoVariablesInside.kt")
|
@TestMetadata("DataClassNoVariablesInside.kt")
|
||||||
public void testDataClassNoVariablesInside() throws Exception {
|
public void testDataClassNoVariablesInside() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/iterationOverMap/DataClassNoVariablesInside.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/iterationOverMap/DataClassNoVariablesInside.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user