Change Signature: Do not process calls with unmatched arguments/parameters

This commit is contained in:
Alexey Sedunov
2015-06-29 17:45:05 +03:00
parent 4cc2a57aed
commit 9e82411e78
11 changed files with 51 additions and 28 deletions
@@ -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.<JetParameterInfo>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);
}
}
}
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
public abstract class JavaMethodKotlinUsageWithDelegate<T: PsiElement>(
val psiElement: T,
val javaMethodChangeInfo: JetChangeInfo): UsageInfo(psiElement) {
var javaMethodChangeInfo: JetChangeInfo): UsageInfo(psiElement) {
protected abstract val delegateUsage: JetUsageInfo<T>
fun processUsage(): Boolean = delegateUsage.processUsage(javaMethodChangeInfo, psiElement)
@@ -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<JetCallElement> {
@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<JetCallElement> {
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<ValueParameterDescriptor, ResolvedValueArgument> 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)
@@ -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);
@@ -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);
}
@@ -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);
}
@@ -5,7 +5,7 @@ open class Base() {
val y = Base();
fun f() {
val base = Base();
val base = Base(1, 2);
}
}
@@ -3,7 +3,7 @@
fun foo(y: Int) {
foo();
foo();
foo(1);
foo(2);
foo(3);
foo(2, 3, sdsd);
}
@@ -5,5 +5,5 @@ fun foo(x: Int) {
foo();
foo(1);
foo(1);
foo(2);
foo(2, 3, sdsd);
}
@@ -3,7 +3,7 @@
fun foo(x: Int) {
foo();
foo(1<caret>);
foo(1);
foo(2);
foo(1);
foo(2, 3, sdsd);
}
@@ -5,5 +5,5 @@ fun foo(y: Int) {
foo();
foo(y = 1<caret>);
foo(2);
foo(3);
foo(2, 3, sdsd);
}