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.descriptors.CallableDescriptor
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.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
@@ -211,15 +212,13 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
else -> Name.identifier("it")
} ?: return null
val descriptorToIndex = mutableMapOf<CallableDescriptor, Int>()
for (valueParameter in valueParameters) {
val propertyDescriptor = context.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter) ?: continue
descriptorToIndex[propertyDescriptor] = valueParameter.index
}
val constructorParameterNameMap = mutableMapOf<Name, ValueParameterDescriptor>()
valueParameters.forEach { constructorParameterNameMap[it.name] = it }
usageScopeElement.iterateOverDataClassPropertiesUsagesWithIndex(
context,
nameToSearch,
descriptorToIndex,
constructorParameterNameMap,
{ index, usageData -> noBadUsages = usagesToRemove[index].add(usageData, index) && noBadUsages },
{ noBadUsages = false }
)
@@ -268,7 +267,7 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
private fun PsiElement.iterateOverDataClassPropertiesUsagesWithIndex(
context: BindingContext,
parameterName: Name,
descriptorToIndex: Map<CallableDescriptor, Int>,
constructorParameterNameMap: Map<Name, ValueParameterDescriptor>,
process: (Int, SingleUsageData) -> Unit,
cancel: () -> Unit
) {
@@ -279,14 +278,14 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
if (applicableUsage != null) {
val usageDescriptor = applicableUsage.descriptor
if (usageDescriptor == null) {
for (index in descriptorToIndex.values) {
process(index, applicableUsage)
for (parameter in constructorParameterNameMap.values) {
process(parameter.index, applicableUsage)
}
return@anyDescendantOfType false
}
val index = descriptorToIndex[usageDescriptor]
if (index != null) {
process(index, applicableUsage)
val parameter = constructorParameterNameMap[usageDescriptor.name]
if (parameter != null) {
process(parameter.index, applicableUsage)
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);
}
@TestMetadata("pair.kt")
public void testPair() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/destructuringInLambda/pair.kt");
doTest(fileName);
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/destructuringInLambda/simple.kt");