From 8a071c3f74b4d98585620972b401c95db4768874 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 20 Aug 2015 09:44:25 +0200 Subject: [PATCH] fix method return type for vararg calls (EA-71978 - IAE: PsiOldInferenceHelper.inferTypeArguments) --- .../impl/analysis/HighlightMethodUtil.java | 32 +++++++++++++------ .../methodReturn/afterInferFromVarArgs.java | 12 +++++++ .../methodReturn/afterInferFromVarArgs1.java | 12 +++++++ .../methodReturn/afterInferFromVarArgs3.java | 12 +++++++ .../methodReturn/beforeInferFromVarArgs.java | 10 ++++++ .../methodReturn/beforeInferFromVarArgs1.java | 10 ++++++ .../methodReturn/beforeInferFromVarArgs2.java | 10 ++++++ .../methodReturn/beforeInferFromVarArgs3.java | 10 ++++++ 8 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs1.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs3.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs1.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs2.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs3.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index cfd36c80aef7..54169ad9dd8f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -446,16 +446,30 @@ public class HighlightMethodUtil { final PsiMethod containerMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class, true, PsiLambdaExpression.class); if (containerMethod != null) { final PsiMethod method = candidate.getElement(); - final List list = ContainerUtil.map(method.getParameterList().getParameters(), - new Function() { - @Override - public PsiType fun(PsiParameter parameter) { - return parameter.getType(); - } - }); - PsiType[] leftTypes = list.toArray(new PsiType[list.size()]); + final PsiType[] expressionTypes = methodCall.getArgumentList().getExpressionTypes(); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final int max = Math.max(parameters.length, expressionTypes.length); + PsiType[] leftTypes = PsiType.createArray(max); + PsiType[] rightTypes = PsiType.createArray(max); + for (int i = 0; i < max; i++) { + if (i < parameters.length) { + leftTypes[i] = parameters[i].getType(); + rightTypes[i] = i < expressionTypes.length ? expressionTypes[i] : null; + + if (leftTypes[i] instanceof PsiEllipsisType && + !(max == expressionTypes.length && + expressionTypes[i] instanceof PsiArrayType && + expressionTypes[i].getArrayDimensions() == leftTypes[i].getArrayDimensions())) { + leftTypes[i] = ((PsiEllipsisType)leftTypes[i]).getComponentType(); + } + } + else { + leftTypes[i] = null; + rightTypes[i] = i < expressionTypes.length ? expressionTypes[i] : null; + } + } final PsiSubstitutor substitutor = resolveHelper - .inferTypeArguments(method.getTypeParameters(), leftTypes, methodCall.getArgumentList().getExpressionTypes(), + .inferTypeArguments(method.getTypeParameters(), leftTypes, rightTypes, PsiUtil.getLanguageLevel(methodCall)); PsiType methodCallTypeByArgs = substitutor.substitute(methodCall.getType()); //ensure type params are not included diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs.java new file mode 100644 index 000000000000..fedbe414d43a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs.java @@ -0,0 +1,12 @@ +import java.util.List; + +// "Make 'bar' return 'java.util.List'" "true" +public class Foo { + java.util.List foo(T... t) { + return null; + } + + List bar() { + return foo(""); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs1.java new file mode 100644 index 000000000000..43848f655b0b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs1.java @@ -0,0 +1,12 @@ +import java.util.List; + +// "Make 'bar' return 'java.util.List'" "true" +public class Foo { + java.util.List foo(T... t) { + return null; + } + + List bar() { + return foo("", ""); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs3.java new file mode 100644 index 000000000000..d8e56632af9b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/afterInferFromVarArgs3.java @@ -0,0 +1,12 @@ +import java.util.List; + +// "Make 'bar' return 'java.util.List'" "true" +public class Foo { + java.util.List foo(T... t) { + return null; + } + + List bar() { + return foo(new String[] {""}); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs.java new file mode 100644 index 000000000000..3a17d7bd3871 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs.java @@ -0,0 +1,10 @@ +// "Make 'bar' return 'java.util.List'" "true" +public class Foo { + java.util.List foo(T... t) { + return null; + } + + String bar() { + return foo(""); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs1.java new file mode 100644 index 000000000000..5be82cc25526 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs1.java @@ -0,0 +1,10 @@ +// "Make 'bar' return 'java.util.List'" "true" +public class Foo { + java.util.List foo(T... t) { + return null; + } + + String bar() { + return foo("", ""); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs2.java new file mode 100644 index 000000000000..4af0bec75f4f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs2.java @@ -0,0 +1,10 @@ +// "Make 'bar' return 'java.util.List'" "false" +public class Foo { + java.util.List foo(T... t) { + return null; + } + + String bar() { + return foo(); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs3.java new file mode 100644 index 000000000000..f79212693801 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/methodReturn/beforeInferFromVarArgs3.java @@ -0,0 +1,10 @@ +// "Make 'bar' return 'java.util.List'" "true" +public class Foo { + java.util.List foo(T... t) { + return null; + } + + String bar() { + return foo(new String[] {""}); + } +}