From 79edaf45af79f9340b5ed6ba20aaee6c8d30f527 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 14 Jun 2016 11:10:00 +0300 Subject: [PATCH] erasure of method call expression type if method is not generics but unchecked conversion was needed to check the applicability (IDEA-157223) --- .../impl/analysis/JavaGenericsUtil.java | 0 .../java/PsiMethodCallExpressionImpl.java | 17 +++++++++++------ ...ErasureOfReturnTypeOfNonGenericMethod.java | 19 +++++++++++++++++++ .../lambda/GenericsHighlighting8Test.java | 4 ++++ 4 files changed, 34 insertions(+), 6 deletions(-) rename java/{java-analysis-impl => java-psi-api}/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java (100%) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureOfReturnTypeOfNonGenericMethod.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java similarity index 100% rename from java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java rename to java/java-psi-api/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java index 9c8d851c6147..18ed26bd5e43 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.impl.source.tree.java; +import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.projectRoots.JavaSdkVersion; @@ -254,14 +255,18 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements // If unchecked conversion was necessary for the method to be applicable, // the parameter types of the invocation type are the parameter types of the method's type, // and the return type and thrown types are given by the erasures of the return type and thrown types of the method's type. - if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && - (method.hasTypeParameters() || JavaVersionService.getInstance().isAtLeast(call, JavaSdkVersion.JDK_1_8)) && + if ((!languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && method.hasTypeParameters() || + !method.hasTypeParameters() && JavaVersionService.getInstance().isAtLeast(call, JavaSdkVersion.JDK_1_8)) && result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isApplicable()) { final PsiType[] args = call.getArgumentList().getExpressionTypes(); - final boolean allowUncheckedConversion = false; - final int applicabilityLevel = PsiUtil.getApplicabilityLevel(method, substitutor, args, languageLevel, allowUncheckedConversion, true); - if (applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE) { - return TypeConversionUtil.erasure(substitutedReturnType); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final boolean varargs = ((MethodCandidateInfo)result).getApplicabilityLevel() == MethodCandidateInfo.ApplicabilityLevel.VARARGS; + for (int i = 0; i < args.length; i++) { + final PsiType parameterType = substitutor.substitute(PsiTypesUtil.getParameterType(parameters, i, varargs)); + final PsiType expressionType = args[i]; + if (expressionType != null && parameterType != null && JavaGenericsUtil.isRawToGeneric(parameterType, expressionType)) { + return TypeConversionUtil.erasure(substitutedReturnType); + } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureOfReturnTypeOfNonGenericMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureOfReturnTypeOfNonGenericMethod.java new file mode 100644 index 000000000000..e760794e35be --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ErasureOfReturnTypeOfNonGenericMethod.java @@ -0,0 +1,19 @@ +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +class Test { + public static List sort(Comparator comp, Stream stream) { + return stream.sorted(comp).collect(Collectors.toList()); + } + + //accept unbounded wildcards + List get(List lists) { + return null; + } + + void foo(List l) { + String p = get(l).get(0); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java index cc65c975318e..0c929899f9bc 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java @@ -994,4 +994,8 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { public void testNestedCaptures() throws Exception { doTest(); } + + public void testErasureOfReturnTypeOfNonGenericMethod() throws Exception { + doTest(); + } }