Make destructure intention work on library data classes

So #KT-16468 Fixed
So #KT-14402 Fixed
This commit is contained in:
mglukhikh
2017-03-31 13:53:25 +03:00
committed by Mikhail Glukhikh
parent 8a02ce3dc2
commit f13997750f
4 changed files with 33 additions and 12 deletions
@@ -26,6 +26,7 @@ import com.intellij.util.Query
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
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.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
@@ -211,15 +212,13 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
else -> Name.identifier("it") else -> Name.identifier("it")
} ?: return null } ?: return null
val descriptorToIndex = mutableMapOf<CallableDescriptor, Int>() val constructorParameterNameMap = mutableMapOf<Name, ValueParameterDescriptor>()
for (valueParameter in valueParameters) { valueParameters.forEach { constructorParameterNameMap[it.name] = it }
val propertyDescriptor = context.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter) ?: continue
descriptorToIndex[propertyDescriptor] = valueParameter.index
}
usageScopeElement.iterateOverDataClassPropertiesUsagesWithIndex( usageScopeElement.iterateOverDataClassPropertiesUsagesWithIndex(
context, context,
nameToSearch, nameToSearch,
descriptorToIndex, constructorParameterNameMap,
{ index, usageData -> noBadUsages = usagesToRemove[index].add(usageData, index) && noBadUsages }, { index, usageData -> noBadUsages = usagesToRemove[index].add(usageData, index) && noBadUsages },
{ noBadUsages = false } { noBadUsages = false }
) )
@@ -268,7 +267,7 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
private fun PsiElement.iterateOverDataClassPropertiesUsagesWithIndex( private fun PsiElement.iterateOverDataClassPropertiesUsagesWithIndex(
context: BindingContext, context: BindingContext,
parameterName: Name, parameterName: Name,
descriptorToIndex: Map<CallableDescriptor, Int>, constructorParameterNameMap: Map<Name, ValueParameterDescriptor>,
process: (Int, SingleUsageData) -> Unit, process: (Int, SingleUsageData) -> Unit,
cancel: () -> Unit cancel: () -> Unit
) { ) {
@@ -279,14 +278,14 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
if (applicableUsage != null) { if (applicableUsage != null) {
val usageDescriptor = applicableUsage.descriptor val usageDescriptor = applicableUsage.descriptor
if (usageDescriptor == null) { if (usageDescriptor == null) {
for (index in descriptorToIndex.values) { for (parameter in constructorParameterNameMap.values) {
process(index, applicableUsage) process(parameter.index, applicableUsage)
} }
return@anyDescendantOfType false return@anyDescendantOfType false
} }
val index = descriptorToIndex[usageDescriptor] val parameter = constructorParameterNameMap[usageDescriptor.name]
if (index != null) { if (parameter != null) {
process(index, applicableUsage) process(parameter.index, applicableUsage)
return@anyDescendantOfType false return@anyDescendantOfType false
} }
} }
@@ -0,0 +1,8 @@
// WITH_RUNTIME
fun foo() = 0 to 10
fun bar(): Int {
val <caret>b = foo()
return b.first + b.second
}
@@ -0,0 +1,8 @@
// WITH_RUNTIME
fun foo() = 0 to 10
fun bar(): Int {
val (first, second) = foo()
return first + second
}
@@ -7675,6 +7675,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("pair.kt")
public void testPair() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/destructuringInLambda/pair.kt");
doTest(fileName);
}
@TestMetadata("simple.kt") @TestMetadata("simple.kt")
public void testSimple() throws Exception { public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/destructuringInLambda/simple.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/destructuringInLambda/simple.kt");