unchecked warnings: check inferred type against bounds for java > 1.8 (IDEA-147529)

This commit is contained in:
Anna Kozlova
2015-11-10 17:45:15 +01:00
parent c686f3ba5a
commit a45937536a
4 changed files with 39 additions and 4 deletions

View File

@@ -25,6 +25,8 @@ import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider;
import com.intellij.codeInspection.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.util.Pass;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.pom.java.LanguageLevel;
@@ -229,7 +231,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
super.visitMethodReferenceExpression(expression);
if (IGNORE_UNCHECKED_CALL) return;
final JavaResolveResult result = expression.advancedResolve(false);
final String description = getUncheckedCallDescription(result);
final String description = getUncheckedCallDescription(expression, result);
if (description != null) {
final PsiElement referenceNameElement = expression.getReferenceNameElement();
registerProblem(description, expression, referenceNameElement != null ? referenceNameElement : expression, myGenerifyFixes);
@@ -240,7 +242,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
public void visitCallExpression(PsiCallExpression callExpression) {
super.visitCallExpression(callExpression);
final JavaResolveResult result = callExpression.resolveMethodGenerics();
final String description = getUncheckedCallDescription(result);
final String description = getUncheckedCallDescription(callExpression, result);
if (description != null) {
if (IGNORE_UNCHECKED_CALL) return;
final PsiExpression element = callExpression instanceof PsiMethodCallExpression
@@ -421,12 +423,27 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
@Nullable
private String getUncheckedCallDescription(JavaResolveResult resolveResult) {
private String getUncheckedCallDescription(PsiElement place, JavaResolveResult resolveResult) {
final PsiElement element = resolveResult.getElement();
if (!(element instanceof PsiMethod)) return null;
final PsiMethod method = (PsiMethod)element;
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
if (!PsiUtil.isRawSubstitutor(method, substitutor)) return null;
if (!PsiUtil.isRawSubstitutor(method, substitutor)) {
if (JavaVersionService.getInstance().isAtLeast(place, JavaSdkVersion.JDK_1_8)) {
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(method)) {
final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes();
if (extendsListTypes.length > 0) {
final PsiType subst = substitutor.substitute(parameter);
for (PsiClassType classType : extendsListTypes) {
if (JavaGenericsUtil.isRawToGeneric(substitutor.substitute(classType), subst)) {
return JavaErrorMessages.message("generics.unchecked.call", JavaHighlightUtil.formatMethod(method));
}
}
}
}
}
return null;
}
final PsiParameter[] parameters = method.getParameterList().getParameters();
for (final PsiParameter parameter : parameters) {
final PsiType parameterType = parameter.getType();

View File

@@ -82,6 +82,7 @@ generics.type.argument.cannot.be.of.primitive.type=Type argument cannot be of pr
generics.unchecked.assignment=Unchecked assignment: ''{0}'' to ''{1}''
generics.unchecked.cast=Unchecked cast: ''{0}'' to ''{1}''
generics.unchecked.call.to.member.of.raw.type=Unchecked call to ''{0}'' as a member of raw type ''{1}''
generics.unchecked.call=Unchecked method ''{0}'' invocation
generics.diamond.not.applicable=Diamond operator is not applicable for non-parameterized types
generics.reference.parameters.not.allowed=Reference parameters are not allowed here
foreach.not.applicable=foreach not applicable to type ''{0}''

View File

@@ -0,0 +1,13 @@
import java.util.ArrayList;
class Test {
static <T extends ArrayList<String>> T foo() {return null;}
static class Raw extends ArrayList {}
public static void main(String[] args) {
Raw r = <warning descr="Unchecked method 'foo()' invocation">foo</warning>();
System.out.println(r);
}
}

View File

@@ -873,4 +873,8 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
public void testExceptionCollectionWithLambda() throws Exception {
doTest();
}
public void testUncheckedWarningsWhenInferredTypeLeadsToRawRoGenericAssignment() throws Exception {
doTest(true);
}
}