From 9e82411e78fa5cc9160a1ba3085dc70a88088890 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 29 Jun 2015 17:45:05 +0300 Subject: [PATCH] Change Signature: Do not process calls with unmatched arguments/parameters --- .../JetChangeSignatureUsageProcessor.java | 29 ++++++++++++------- .../JavaMethodKotlinUsageWithDelegate.kt | 2 +- .../usages/JetFunctionCallUsage.java | 22 ++++++++++++-- .../addConstructorParameter.kt.after | 2 +- .../addFunctionParameter.kt.after | 4 +-- ...ddFunctionParameterAndChangeTypes.kt.after | 6 ++-- .../removeConstructorParameter.kt.after | 2 +- .../removeFunctionFirstParameter.kt.after | 4 +-- .../removeFunctionSecondParameter1.kt.after | 2 +- .../removeFunctionSecondParameter2.kt.after | 4 +-- .../removeNamedParameter.kt.after | 2 +- 11 files changed, 51 insertions(+), 28 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java index 3294100a876..216aac90765 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java @@ -750,6 +750,20 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro if (changeSignatureData != originalJavaMethodDescriptor) { originalJavaMethodDescriptor = changeSignatureData; } + + // This change info is used as a placeholder before primary method update + // It gets replaced with real change info afterwards + JetChangeInfo dummyChangeInfo = + new JetChangeInfo(originalJavaMethodDescriptor, "", null, "", Visibilities.INTERNAL, Collections.emptyList(), null, changeInfo.getMethod()); + for (int i = 0; i < usages.length; i++) { + UsageInfo oldUsageInfo = usages[i]; + if (!isJavaMethodUsage(oldUsageInfo)) continue; + + UsageInfo newUsageInfo = createReplacementUsage(oldUsageInfo, dummyChangeInfo); + if (newUsageInfo != null) { + usages[i] = newUsageInfo; + } + } } return true; @@ -758,20 +772,13 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro PsiElement element = usageInfo.getElement(); if (element == null) return false; - if (isJavaMethodUsage && originalJavaMethodDescriptor != null) { + if (originalJavaMethodDescriptor != null) { JetChangeInfo javaMethodChangeInfo = ChangeSignaturePackage.toJetChangeInfo(changeInfo, originalJavaMethodDescriptor); originalJavaMethodDescriptor = null; - for (int i = 0; i < usages.length; i++) { - UsageInfo oldUsageInfo = usages[i]; - if (!isJavaMethodUsage(oldUsageInfo)) continue; - - UsageInfo newUsageInfo = createReplacementUsage(oldUsageInfo, javaMethodChangeInfo); - if (newUsageInfo != null) { - usages[i] = newUsageInfo; - if (oldUsageInfo == usageInfo) { - usageInfo = newUsageInfo; - } + for (UsageInfo info : usages) { + if (info instanceof JavaMethodKotlinUsageWithDelegate) { + ((JavaMethodKotlinUsageWithDelegate) info).setJavaMethodChangeInfo(javaMethodChangeInfo); } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JavaMethodKotlinUsageWithDelegate.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JavaMethodKotlinUsageWithDelegate.kt index 39b42d0a29f..2a319434b91 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JavaMethodKotlinUsageWithDelegate.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JavaMethodKotlinUsageWithDelegate.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor public abstract class JavaMethodKotlinUsageWithDelegate( val psiElement: T, - val javaMethodChangeInfo: JetChangeInfo): UsageInfo(psiElement) { + var javaMethodChangeInfo: JetChangeInfo): UsageInfo(psiElement) { protected abstract val delegateUsage: JetUsageInfo fun processUsage(): Boolean = delegateUsage.processUsage(javaMethodChangeInfo, psiElement) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java index 785ecd6cf3f..e5e155b094d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/usages/JetFunctionCallUsage.java @@ -45,9 +45,7 @@ import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage; -import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument; -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; -import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument; +import org.jetbrains.kotlin.resolve.calls.model.*; import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; @@ -92,6 +90,8 @@ public class JetFunctionCallUsage extends JetUsageInfo { @Override public boolean processUsage(JetChangeInfo changeInfo, JetCallElement element) { + if (shouldSkipUsage(element)) return true; + changeNameIfNeeded(changeInfo, element); if (element.getValueArgumentList() != null) { @@ -116,6 +116,22 @@ public class JetFunctionCallUsage extends JetUsageInfo { return true; } + private boolean shouldSkipUsage(JetCallElement element) { + // TODO: We probable need more clever processing of invalid calls, but for now default to Java-like behaviour + // TODO: Investigate why resolved call is not recorded for enum constructor call + if (resolvedCall == null && !(element instanceof JetDelegatorToSuperCall)) return true; + if (resolvedCall != null && !resolvedCall.getStatus().isSuccess()) { + for (ValueArgument valueArgument : resolvedCall.getCall().getValueArguments()) { + if (!(resolvedCall.getArgumentMapping(valueArgument) instanceof ArgumentMatch)) return true; + } + Map arguments = resolvedCall.getValueArguments(); + for (ValueParameterDescriptor valueParameter : resolvedCall.getResultingDescriptor().getValueParameters()) { + if (!arguments.containsKey(valueParameter)) return true; + } + } + return false; + } + private boolean isPropertyJavaUsage() { PsiElement calleeElement = this.callee.getElement(); return (calleeElement instanceof JetProperty || calleeElement instanceof JetParameter) diff --git a/idea/testData/quickfix/changeSignature/addConstructorParameter.kt.after b/idea/testData/quickfix/changeSignature/addConstructorParameter.kt.after index 46e025b3162..de8e0e17339 100644 --- a/idea/testData/quickfix/changeSignature/addConstructorParameter.kt.after +++ b/idea/testData/quickfix/changeSignature/addConstructorParameter.kt.after @@ -2,7 +2,7 @@ // DISABLE-ERRORS open class Base(var x: Int, d: Double) { - val y = Base(1, 2.5); + val y = Base(1, 2); fun f() { val base = Base(1, 2.5); diff --git a/idea/testData/quickfix/changeSignature/addFunctionParameter.kt.after b/idea/testData/quickfix/changeSignature/addFunctionParameter.kt.after index ea126c90485..43ecbb9773b 100644 --- a/idea/testData/quickfix/changeSignature/addFunctionParameter.kt.after +++ b/idea/testData/quickfix/changeSignature/addFunctionParameter.kt.after @@ -2,8 +2,8 @@ // DISABLE-ERRORS fun foo(x: Int, i: Int) { - foo(, 4); + foo(); foo(1, 4); foo(1, 4); - foo(2, 4); + foo(2, 3, sdsd); } \ No newline at end of file diff --git a/idea/testData/quickfix/changeSignature/addFunctionParameterAndChangeTypes.kt.after b/idea/testData/quickfix/changeSignature/addFunctionParameterAndChangeTypes.kt.after index 14629bbb076..3e2ef77d39f 100644 --- a/idea/testData/quickfix/changeSignature/addFunctionParameterAndChangeTypes.kt.after +++ b/idea/testData/quickfix/changeSignature/addFunctionParameterAndChangeTypes.kt.after @@ -2,9 +2,9 @@ // DISABLE-ERRORS fun foo(x: Double, i: Int, i1: Int, i2: Int) { - foo(,, 5, 6); - foo(1,, 5, 6); + foo(); + foo(1); foo(1, 2.5, 5, 6); foo(1.5, 4, 5, 6); - foo(2, 3, 5, 6); + foo(2, 3, sdsd); } \ No newline at end of file diff --git a/idea/testData/quickfix/changeSignature/removeConstructorParameter.kt.after b/idea/testData/quickfix/changeSignature/removeConstructorParameter.kt.after index 69b96d13914..6c40ec1d8dd 100644 --- a/idea/testData/quickfix/changeSignature/removeConstructorParameter.kt.after +++ b/idea/testData/quickfix/changeSignature/removeConstructorParameter.kt.after @@ -5,7 +5,7 @@ open class Base() { val y = Base(); fun f() { - val base = Base(); + val base = Base(1, 2); } } diff --git a/idea/testData/quickfix/changeSignature/removeFunctionFirstParameter.kt.after b/idea/testData/quickfix/changeSignature/removeFunctionFirstParameter.kt.after index b59b76f88e3..cf636f4f4ec 100644 --- a/idea/testData/quickfix/changeSignature/removeFunctionFirstParameter.kt.after +++ b/idea/testData/quickfix/changeSignature/removeFunctionFirstParameter.kt.after @@ -3,7 +3,7 @@ fun foo(y: Int) { foo(); - foo(); + foo(1); foo(2); - foo(3); + foo(2, 3, sdsd); } \ No newline at end of file diff --git a/idea/testData/quickfix/changeSignature/removeFunctionSecondParameter1.kt.after b/idea/testData/quickfix/changeSignature/removeFunctionSecondParameter1.kt.after index baa5fc9cdab..85ceb301e66 100644 --- a/idea/testData/quickfix/changeSignature/removeFunctionSecondParameter1.kt.after +++ b/idea/testData/quickfix/changeSignature/removeFunctionSecondParameter1.kt.after @@ -5,5 +5,5 @@ fun foo(x: Int) { foo(); foo(1); foo(1); - foo(2); + foo(2, 3, sdsd); } \ No newline at end of file diff --git a/idea/testData/quickfix/changeSignature/removeFunctionSecondParameter2.kt.after b/idea/testData/quickfix/changeSignature/removeFunctionSecondParameter2.kt.after index 75434347a0f..85ceb301e66 100644 --- a/idea/testData/quickfix/changeSignature/removeFunctionSecondParameter2.kt.after +++ b/idea/testData/quickfix/changeSignature/removeFunctionSecondParameter2.kt.after @@ -3,7 +3,7 @@ fun foo(x: Int) { foo(); - foo(1); foo(1); - foo(2); + foo(1); + foo(2, 3, sdsd); } \ No newline at end of file diff --git a/idea/testData/quickfix/changeSignature/removeNamedParameter.kt.after b/idea/testData/quickfix/changeSignature/removeNamedParameter.kt.after index a57cce2079b..52081e7d94a 100644 --- a/idea/testData/quickfix/changeSignature/removeNamedParameter.kt.after +++ b/idea/testData/quickfix/changeSignature/removeNamedParameter.kt.after @@ -5,5 +5,5 @@ fun foo(y: Int) { foo(); foo(y = 1); foo(2); - foo(3); + foo(2, 3, sdsd); } \ No newline at end of file