mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
unchecked warning explanation (IDEA-126457)
This commit is contained in:
+44
-16
@@ -27,9 +27,11 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.xml.util.XmlUtil;
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -135,7 +137,15 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
|
||||
return new UncheckedWarningsVisitor(isOnTheFly, languageLevel){
|
||||
@Override
|
||||
protected void registerProblem(@NotNull String message, @NotNull PsiElement psiElement, @NotNull LocalQuickFix[] quickFixes) {
|
||||
protected void registerProblem(@NotNull String message,
|
||||
@Nullable PsiElement callExpression,
|
||||
@NotNull PsiElement psiElement,
|
||||
@NotNull LocalQuickFix[] quickFixes) {
|
||||
final String rawExpression = isMethodCalledOnRawType(callExpression);
|
||||
if (rawExpression != null) {
|
||||
final String referenceName = ((PsiMethodCallExpression)callExpression).getMethodExpression().getReferenceName();
|
||||
message += ". Reason: '" + rawExpression + "' has raw type, so result of " + referenceName + " is erased";
|
||||
}
|
||||
holder.registerProblem(psiElement, message, quickFixes);
|
||||
}
|
||||
};
|
||||
@@ -145,6 +155,21 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String isMethodCalledOnRawType(PsiElement expression) {
|
||||
if (expression instanceof PsiMethodCallExpression) {
|
||||
final PsiExpression qualifierExpression = ((PsiMethodCallExpression)expression).getMethodExpression().getQualifierExpression();
|
||||
if (qualifierExpression != null) {
|
||||
final PsiClass qualifierClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType());
|
||||
if (qualifierClass != null) {
|
||||
if (PsiUtil.isRawSubstitutor(qualifierClass, ((PsiMethodCallExpression)expression).resolveMethodGenerics().getSubstitutor())) {
|
||||
return qualifierExpression.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private abstract class UncheckedWarningsVisitor extends JavaElementVisitor {
|
||||
private final boolean myOnTheFly;
|
||||
@NotNull private final LanguageLevel myLanguageLevel;
|
||||
@@ -156,7 +181,10 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
myGenerifyFixes = onTheFly ? createFixes() : LocalQuickFix.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
protected abstract void registerProblem(@NotNull String message, @NotNull PsiElement psiElement, @NotNull LocalQuickFix[] quickFixes);
|
||||
protected abstract void registerProblem(@NotNull String message,
|
||||
PsiElement callExpression,
|
||||
@NotNull PsiElement psiElement,
|
||||
@NotNull LocalQuickFix[] quickFixes);
|
||||
|
||||
|
||||
@Override
|
||||
@@ -164,7 +192,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
if (IGNORE_UNCHECKED_GENERICS_ARRAY_CREATION) return;
|
||||
final JavaResolveResult result = expression.advancedResolve(false);
|
||||
if (JavaGenericsUtil.isUncheckedWarning(expression, result, myLanguageLevel)) {
|
||||
registerProblem("Unchecked generics array creation for varargs parameter", expression, LocalQuickFix.EMPTY_ARRAY);
|
||||
registerProblem("Unchecked generics array creation for varargs parameter", null, expression, LocalQuickFix.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +202,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
if (IGNORE_UNCHECKED_GENERICS_ARRAY_CREATION) return;
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
if (classReference != null && JavaGenericsUtil.isUncheckedWarning(classReference, expression.resolveMethodGenerics(), myLanguageLevel)) {
|
||||
registerProblem("Unchecked generics array creation for varargs parameter", classReference, LocalQuickFix.EMPTY_ARRAY);
|
||||
registerProblem("Unchecked generics array creation for varargs parameter", expression, classReference, LocalQuickFix.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +222,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
final String description =
|
||||
JavaErrorMessages.message("generics.unchecked.cast", JavaHighlightUtil.formatType(exprType), JavaHighlightUtil
|
||||
.formatType(castType));
|
||||
registerProblem(description, expression, myGenerifyFixes);
|
||||
registerProblem(description, operand, expression, myGenerifyFixes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +234,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
final String description = getUncheckedCallDescription(result);
|
||||
if (description != null) {
|
||||
final PsiElement referenceNameElement = expression.getReferenceNameElement();
|
||||
registerProblem(description, referenceNameElement != null ? referenceNameElement : expression, myGenerifyFixes);
|
||||
registerProblem(description, expression, referenceNameElement != null ? referenceNameElement : expression, myGenerifyFixes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +248,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
final PsiExpression element = callExpression instanceof PsiMethodCallExpression
|
||||
? ((PsiMethodCallExpression)callExpression).getMethodExpression()
|
||||
: callExpression;
|
||||
registerProblem(description, element, myGenerifyFixes);
|
||||
registerProblem(description, callExpression, element, myGenerifyFixes);
|
||||
}
|
||||
else {
|
||||
if (IGNORE_UNCHECKED_ASSIGNMENT) return;
|
||||
@@ -238,7 +266,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
final PsiType parameterType = substitutor.substitute(parameter.getType());
|
||||
final PsiType expressionType = expression.getType();
|
||||
if (expressionType != null) {
|
||||
checkRawToGenericsAssignment(expression, parameterType, expressionType, true, myGenerifyFixes);
|
||||
checkRawToGenericsAssignment(expression, expression, parameterType, expressionType, true, myGenerifyFixes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,7 +282,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer == null || initializer instanceof PsiArrayInitializerExpression) return;
|
||||
final PsiType initializerType = initializer.getType();
|
||||
checkRawToGenericsAssignment(initializer, variable.getType(), initializerType, true,
|
||||
checkRawToGenericsAssignment(initializer, initializer, variable.getType(), initializerType, true,
|
||||
myOnTheFly ? getChangeVariableTypeFixes(variable, initializerType) : LocalQuickFix.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
@@ -267,7 +295,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
final PsiExpression iteratedValue = statement.getIteratedValue();
|
||||
if (iteratedValue == null) return;
|
||||
final PsiType itemType = JavaGenericsUtil.getCollectionItemType(iteratedValue);
|
||||
checkRawToGenericsAssignment(parameter, parameterType, itemType, true, myOnTheFly ? getChangeVariableTypeFixes(parameter, itemType) : LocalQuickFix.EMPTY_ARRAY);
|
||||
checkRawToGenericsAssignment(parameter, iteratedValue, parameterType, itemType, true, myOnTheFly ? getChangeVariableTypeFixes(parameter, itemType) : LocalQuickFix.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -288,7 +316,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
leftVar = (PsiVariable)element;
|
||||
}
|
||||
}
|
||||
checkRawToGenericsAssignment(rExpr, lType, rType, true, myOnTheFly && leftVar != null ? getChangeVariableTypeFixes(leftVar, rType) : LocalQuickFix.EMPTY_ARRAY);
|
||||
checkRawToGenericsAssignment(rExpr, rExpr, lType, rType, true, myOnTheFly && leftVar != null ? getChangeVariableTypeFixes(leftVar, rType) : LocalQuickFix.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -320,14 +348,14 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
}
|
||||
|
||||
if (fix != null) {
|
||||
registerProblem(description, expression, new LocalQuickFix[]{fix});
|
||||
registerProblem(description, null, expression, new LocalQuickFix[]{fix});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRawToGenericsAssignment(@NotNull PsiElement parameter,
|
||||
PsiType parameterType,
|
||||
PsiExpression expression, PsiType parameterType,
|
||||
PsiType itemType,
|
||||
boolean checkAssignability,
|
||||
@NotNull LocalQuickFix[] quickFixes) {
|
||||
@@ -337,7 +365,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
String description = JavaErrorMessages.message("generics.unchecked.assignment",
|
||||
JavaHighlightUtil.formatType(itemType),
|
||||
JavaHighlightUtil.formatType(parameterType));
|
||||
registerProblem(description, parameter, quickFixes);
|
||||
registerProblem(description, expression, parameter, quickFixes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +392,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
|
||||
final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
|
||||
LOG.assertTrue(returnTypeElement != null);
|
||||
registerProblem(message, returnTypeElement, LocalQuickFix.EMPTY_ARRAY);
|
||||
registerProblem(message, null, returnTypeElement, LocalQuickFix.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -384,7 +412,7 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
|
||||
if (returnValue != null) {
|
||||
final PsiType valueType = returnValue.getType();
|
||||
if (valueType != null) {
|
||||
checkRawToGenericsAssignment(returnValue, returnType, valueType,
|
||||
checkRawToGenericsAssignment(returnValue, returnValue, returnType, valueType,
|
||||
false,
|
||||
new LocalQuickFix[]{QuickFixFactory.getInstance().createMethodReturnFix(method, valueType, true)});
|
||||
}
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
class A<<warning descr="Type parameter 'T' is never used">T</warning>> {
|
||||
List<String> getList() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultEventSource<<warning descr="Type parameter 'T' is never used">T</warning>> extends A {
|
||||
public Iterator<String> getKeys(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<String> getList() {
|
||||
return <warning descr="Unchecked assignment: 'java.util.List' to 'java.util.List<java.lang.String>'. Reason: 'super' has raw type, so result of getList is erased">super.getList()</warning>;
|
||||
}
|
||||
|
||||
void f(DefaultEventSource source){
|
||||
final Iterator<String> <warning descr="Variable 'keys' is never used">keys</warning> = <warning descr="Unchecked assignment: 'java.util.Iterator' to 'java.util.Iterator<java.lang.String>'. Reason: 'source' has raw type, so result of getKeys is erased">source. getKeys()</warning>;
|
||||
final Iterator<String> <warning descr="Variable 'keys1' is never used">keys1</warning> = <warning descr="Unchecked cast: 'java.util.Iterator' to 'java.util.Iterator<java.lang.String>'. Reason: 'source' has raw type, so result of getKeys is erased">(Iterator<String>)source.getKeys()</warning>;
|
||||
final Iterator<String> <warning descr="Variable 'keys2' is assigned but never accessed">keys2</warning>;
|
||||
keys2 = <warning descr="Unchecked assignment: 'java.util.Iterator' to 'java.util.Iterator<java.lang.String>'. Reason: 'source' has raw type, so result of getKeys is erased">source.getKeys()</warning>;
|
||||
|
||||
for (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">String <warning descr="Parameter 'o' is never used">o</warning> : super.getList()</error>) {}
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -188,4 +188,8 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testIDEA111450() { doTest(true, false); }
|
||||
public void testExternalizable() { doTest(true, false); }
|
||||
public void testAccessToStaticMethodsFromInterfaces() { doTest(true, false); }
|
||||
|
||||
public void testUncheckedExtendedWarnings() throws Exception {
|
||||
doTest(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,5 +8,6 @@ by the compiler, for example:
|
||||
}
|
||||
</code>
|
||||
</pre>
|
||||
Hint: Pass -Xlint:unchecked to javac to get more details.
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user