Destructure intention: entries / entrySet are now removed only for kotlin.Map inheritors #KT-14244 Fixed
This commit is contained in:
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||
import java.util.*
|
||||
|
||||
@@ -161,10 +162,17 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
|
||||
// Note: list should contains properties in order to create destructuring declaration
|
||||
val usagesToRemove = mutableListOf<UsageData>()
|
||||
var noBadUsages = true
|
||||
val removeSelectorInLoopRange: Boolean
|
||||
var removeSelectorInLoopRange = false
|
||||
if (forLoop != null && DescriptorUtils.isSubclass(classDescriptor, mapEntryClassDescriptor)) {
|
||||
val loopRangeDescriptorName = forLoop.loopRange.getResolvedCall(context)?.resultingDescriptor?.name
|
||||
removeSelectorInLoopRange = loopRangeDescriptorName?.asString().let { it == "entries" || it == "entrySet" }
|
||||
val loopRangeDescriptor = forLoop.loopRange.getResolvedCall(context)?.resultingDescriptor
|
||||
if (loopRangeDescriptor != null) {
|
||||
val loopRangeDescriptorOwner = loopRangeDescriptor.containingDeclaration
|
||||
val mapClassDescriptor = classDescriptor.builtIns.map
|
||||
if (loopRangeDescriptorOwner is ClassDescriptor &&
|
||||
DescriptorUtils.isSubclass(loopRangeDescriptorOwner, mapClassDescriptor)) {
|
||||
removeSelectorInLoopRange = loopRangeDescriptor.name.asString().let { it == "entries" || it == "entrySet" }
|
||||
}
|
||||
}
|
||||
|
||||
listOf("key", "value").mapTo(usagesToRemove) {
|
||||
UsageData(mapEntryClassDescriptor.unsubstitutedMemberScope.getContributedVariables(
|
||||
@@ -178,7 +186,6 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
|
||||
)
|
||||
}
|
||||
else if (classDescriptor.isData) {
|
||||
removeSelectorInLoopRange = false
|
||||
|
||||
val valueParameters = classDescriptor.unsubstitutedPrimaryConstructor?.valueParameters ?: return null
|
||||
valueParameters.mapTo(usagesToRemove) { UsageData(it) }
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class MyMap {
|
||||
val entries = listOf<Map.Entry<Int, Int>>()
|
||||
}
|
||||
|
||||
fun foo(mm: MyMap) {
|
||||
for (entry<caret> in mm.entries) {
|
||||
val (key, value) = entry
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class MyMap {
|
||||
val entries = listOf<Map.Entry<Int, Int>>()
|
||||
}
|
||||
|
||||
fun foo(mm: MyMap) {
|
||||
for ((key, value) in mm.entries) {
|
||||
}
|
||||
}
|
||||
@@ -231,4 +231,12 @@
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Use destructuring declaration</problem_class>
|
||||
<description>Use destructuring declaration</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>FakeEntries.kt</file>
|
||||
<line>8</line>
|
||||
<module>light_idea_test_case</module>
|
||||
<entry_point TYPE="file" FQNAME="temp:///src/FakeEntries.kt" />
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Use destructuring declaration</problem_class>
|
||||
<description>Use destructuring declaration</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -7699,6 +7699,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FakeEntries.kt")
|
||||
public void testFakeEntries() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/iterationOverMap/FakeEntries.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Getters.kt")
|
||||
public void testGetters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/iterationOverMap/Getters.kt");
|
||||
|
||||
Reference in New Issue
Block a user