mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
erasure method call type if unchecked assignment was applied during applicability check (IDEA-67862)
(cherry picked from commit f106f813559768f90952caac6a2eec4cfeed7103)
This commit is contained in:
+23
-3
@@ -28,6 +28,7 @@ import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.tree.ChildRoleBase;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
@@ -197,7 +198,7 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
|
||||
ret = ((PsiClassType)ret).setLanguageLevel(languageLevel);
|
||||
}
|
||||
if (is15OrHigher) {
|
||||
return captureReturnType(call, method, ret, result.getSubstitutor());
|
||||
return captureReturnType(call, method, ret, result, languageLevel);
|
||||
}
|
||||
return TypeConversionUtil.erasure(ret);
|
||||
}
|
||||
@@ -206,15 +207,34 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
|
||||
public static PsiType captureReturnType(PsiMethodCallExpression call,
|
||||
PsiMethod method,
|
||||
PsiType ret,
|
||||
PsiSubstitutor substitutor) {
|
||||
JavaResolveResult result,
|
||||
LanguageLevel languageLevel) {
|
||||
PsiSubstitutor substitutor = result.getSubstitutor();
|
||||
PsiType substitutedReturnType = substitutor.substitute(ret);
|
||||
if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
|
||||
if (substitutedReturnType == null) {
|
||||
return TypeConversionUtil.erasure(ret);
|
||||
}
|
||||
|
||||
if (InferenceSession.wasUncheckedConversionPerformed(call)) {
|
||||
// 18.5.2
|
||||
// if unchecked conversion was necessary, then this substitution provides the parameter types of the invocation type,
|
||||
// while the return type and thrown types are given by the erasure of m's type (without applying θ').
|
||||
return TypeConversionUtil.erasure(substitutedReturnType);
|
||||
}
|
||||
|
||||
//15.12.2.6. Method Invocation Type
|
||||
// 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 (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);
|
||||
}
|
||||
}
|
||||
|
||||
if (PsiUtil.isRawSubstitutor(method, substitutor)) {
|
||||
final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
|
||||
if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
class Main1 {
|
||||
static <T> Collection<Collection<T>> foo(Collection<Collection<T>> x) { return x; }
|
||||
|
||||
public static void main(String[] args) {
|
||||
List x = null;
|
||||
foo(x).iterator().next().<error descr="Cannot resolve method 'iterator()'">iterator</error>();
|
||||
}
|
||||
}
|
||||
|
||||
class Main {
|
||||
static <T> List<String> foo(Collection<String> x) { return null; }
|
||||
|
||||
public static void main(String[] args) {
|
||||
List x = null;
|
||||
<error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">String s = foo(x).get(0);</error>
|
||||
foo(x).iterator().next().<error descr="Cannot resolve method 'toLowerCase()'">toLowerCase</error>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,6 +410,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
|
||||
}
|
||||
|
||||
public void testMethodCallTypeErasedWhenUncheckedConversionWasAppliedDuringApplicabilityCheck() {
|
||||
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
|
||||
}
|
||||
|
||||
public void testInferredParameterInBoundsInRecursiveGenerics() {
|
||||
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user