diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspectionBase.java
index 65933ea5ef89..f2ad88f53f5f 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspectionBase.java
@@ -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)});
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedExtendedWarnings.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedExtendedWarnings.java
new file mode 100644
index 000000000000..ab6027311276
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedExtendedWarnings.java
@@ -0,0 +1,29 @@
+import java.util.Iterator;
+import java.util.List;
+
+class A<T> {
+ List getList() {
+ return null;
+ }
+}
+
+public class DefaultEventSource<T> extends A {
+ public Iterator getKeys(){
+ return null;
+ }
+
+ @Override
+ List getList() {
+ return super.getList();
+ }
+
+ void f(DefaultEventSource source){
+ final Iterator keys = source. getKeys();
+ final Iterator keys1 = (Iterator)source.getKeys();
+ final Iterator keys2;
+ keys2 = source.getKeys();
+
+ for (String o : super.getList()) {}
+ }
+}
+
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java
index 1c41cd93ea5d..5637abf7215e 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java
@@ -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);
+ }
}
diff --git a/resources-en/src/inspectionDescriptions/UNCHECKED_WARNING.html b/resources-en/src/inspectionDescriptions/UNCHECKED_WARNING.html
index cf5632c6e61d..77b9abea0900 100644
--- a/resources-en/src/inspectionDescriptions/UNCHECKED_WARNING.html
+++ b/resources-en/src/inspectionDescriptions/UNCHECKED_WARNING.html
@@ -8,5 +8,6 @@ by the compiler, for example:
}
+Hint: Pass -Xlint:unchecked to javac to get more details.