mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
unchecked warnings as fair inspection
This commit is contained in:
+5
-195
@@ -16,29 +16,18 @@
|
||||
package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.daemon.impl.JavaHightlightInfoTypes;
|
||||
import com.intellij.codeInsight.daemon.impl.actions.SuppressFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.*;
|
||||
import com.intellij.codeInsight.intention.EmptyIntentionAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.SuppressManager;
|
||||
import com.intellij.codeInspection.ex.InspectionManagerEx;
|
||||
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
@@ -48,7 +37,6 @@ import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
@@ -529,21 +517,7 @@ public class GenericsHighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
//precondition: TypeConversionUtil.isAssignable(lType, rType) || expressionAssignable
|
||||
public static HighlightInfo checkRawToGenericAssignment(PsiType lType, PsiType rType, @NotNull final PsiElement elementToHighlight) {
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(elementToHighlight)) return null;
|
||||
final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME);
|
||||
if (!InspectionProjectProfileManager.getInstance(elementToHighlight.getProject()).getInspectionProfile().isToolEnabled(key,
|
||||
elementToHighlight)) return null;
|
||||
if (!isRawToGeneric(lType, rType)) return null;
|
||||
String description = JavaErrorMessages.message("generics.unchecked.assignment",
|
||||
HighlightUtil.formatType(rType),
|
||||
HighlightUtil.formatType(lType));
|
||||
|
||||
return createUncheckedWarning(elementToHighlight, key, description, elementToHighlight);
|
||||
}
|
||||
|
||||
private static boolean isRawToGeneric(PsiType lType, PsiType rType) {
|
||||
public static boolean isRawToGeneric(PsiType lType, PsiType rType) {
|
||||
if (lType instanceof PsiPrimitiveType || rType instanceof PsiPrimitiveType) return false;
|
||||
if (lType.equals(rType)) return false;
|
||||
if (lType instanceof PsiArrayType && rType instanceof PsiArrayType) {
|
||||
@@ -628,27 +602,7 @@ public class GenericsHighlightUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static HighlightInfo checkUncheckedTypeCast(PsiTypeCastExpression typeCast) {
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(typeCast)) return null;
|
||||
final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME);
|
||||
if (!InspectionProjectProfileManager.getInstance(typeCast.getProject()).getInspectionProfile().isToolEnabled(key, typeCast)) return null;
|
||||
final PsiTypeElement typeElement = typeCast.getCastType();
|
||||
if (typeElement == null) return null;
|
||||
final PsiType castType = typeElement.getType();
|
||||
final PsiExpression expression = typeCast.getOperand();
|
||||
if (expression == null) return null;
|
||||
final PsiType exprType = expression.getType();
|
||||
if (exprType == null) return null;
|
||||
if (isUncheckedCast(castType, exprType)) {
|
||||
String description = JavaErrorMessages.message("generics.unchecked.cast",
|
||||
HighlightUtil.formatType(exprType),
|
||||
HighlightUtil.formatType(castType));
|
||||
return createUncheckedWarning(expression, key, description, typeCast);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isUncheckedCast(PsiType castType, PsiType operandType) {
|
||||
public static boolean isUncheckedCast(PsiType castType, PsiType operandType) {
|
||||
if (TypeConversionUtil.isAssignable(castType, operandType, false)) return false;
|
||||
|
||||
castType = castType.getDeepComponentType();
|
||||
@@ -727,74 +681,7 @@ public class GenericsHighlightUtil {
|
||||
((PsiClassType)rTypeArg).resolve() instanceof PsiTypeParameter;
|
||||
}
|
||||
|
||||
public static HighlightInfo checkUncheckedCall(JavaResolveResult resolveResult, PsiCall call) {
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(call)) return null;
|
||||
final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME);
|
||||
if (!InspectionProjectProfileManager.getInstance(call.getProject()).getInspectionProfile().isToolEnabled(key, call)) return null;
|
||||
|
||||
final PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
if (method == null) return null;
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
for (final PsiParameter parameter : parameters) {
|
||||
final PsiType parameterType = parameter.getType();
|
||||
if (parameterType.accept(new PsiTypeVisitor<Boolean>() {
|
||||
public Boolean visitPrimitiveType(PsiPrimitiveType primitiveType) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
public Boolean visitArrayType(PsiArrayType arrayType) {
|
||||
return arrayType.getComponentType().accept(this);
|
||||
}
|
||||
|
||||
public Boolean visitClassType(PsiClassType classType) {
|
||||
PsiClass psiClass = classType.resolve();
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
return substitutor.substitute((PsiTypeParameter)psiClass) == null ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
PsiType[] parameters = classType.getParameters();
|
||||
for (PsiType parameter : parameters) {
|
||||
if (parameter.accept(this).booleanValue()) return Boolean.TRUE;
|
||||
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
public Boolean visitWildcardType(PsiWildcardType wildcardType) {
|
||||
PsiType bound = wildcardType.getBound();
|
||||
if (bound != null) return bound.accept(this);
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
public Boolean visitEllipsisType(PsiEllipsisType ellipsisType) {
|
||||
return ellipsisType.getComponentType().accept(this);
|
||||
}
|
||||
}).booleanValue()) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
|
||||
PsiType type = elementFactory.createType(method.getContainingClass(), substitutor);
|
||||
String description = JavaErrorMessages.message("generics.unchecked.call.to.member.of.raw.type",
|
||||
HighlightUtil.formatMethod(method),
|
||||
HighlightUtil.formatType(type));
|
||||
PsiElement element = call instanceof PsiMethodCallExpression
|
||||
? ((PsiMethodCallExpression)call).getMethodExpression()
|
||||
: call;
|
||||
return createUncheckedWarning(call, key, description, element);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static HighlightInfo createUncheckedWarning(PsiElement context, HighlightDisplayKey key, String description, PsiElement elementToHighlight) {
|
||||
final InspectionProfile inspectionProfile =
|
||||
InspectionProjectProfileManager.getInstance(context.getProject()).getInspectionProfile();
|
||||
final LocalInspectionTool tool =
|
||||
((LocalInspectionToolWrapper)inspectionProfile.getInspectionTool(UncheckedWarningLocalInspection.SHORT_NAME, elementToHighlight)).getTool();
|
||||
if (InspectionManagerEx.inspectionResultSuppressed(context, tool)) return null;
|
||||
HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(JavaHightlightInfoTypes.UNCHECKED_WARNING, elementToHighlight, description);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new GenerifyFileFix(elementToHighlight.getContainingFile()), key);
|
||||
return highlightInfo;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkForeachLoopParameterType(PsiForeachStatement statement) {
|
||||
final PsiParameter parameter = statement.getIterationParameter();
|
||||
final PsiExpression expression = statement.getIteratedValue();
|
||||
@@ -811,14 +698,12 @@ public class GenericsHighlightUtil {
|
||||
HighlightInfo highlightInfo = HighlightUtil.checkAssignability(parameterType, itemType, null, new TextRange(start, end));
|
||||
if (highlightInfo != null) {
|
||||
HighlightUtil.registerChangeVariableTypeFixes(parameter, itemType, highlightInfo);
|
||||
} else {
|
||||
highlightInfo = checkRawToGenericAssignment(parameterType, itemType, statement.getIterationParameter());
|
||||
}
|
||||
return highlightInfo;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType getCollectionItemType(PsiExpression expression) {
|
||||
public static PsiType getCollectionItemType(PsiExpression expression) {
|
||||
final PsiType type = expression.getType();
|
||||
if (type == null) return null;
|
||||
if (type instanceof PsiArrayType) {
|
||||
@@ -1112,27 +997,11 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkUncheckedGenericsArrayCreation(PsiJavaCodeReferenceElement referenceExpression, PsiElement resolved){
|
||||
final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME);
|
||||
if (!InspectionProjectProfileManager.getInstance(referenceExpression.getProject()).getInspectionProfile().isToolEnabled(key, referenceExpression)) return null;
|
||||
if (isUncheckedWarning(referenceExpression, resolved, false)) {
|
||||
final HighlightInfo highlightInfo =
|
||||
HighlightInfo.createHighlightInfo(HighlightInfoType.WARNING, referenceExpression, "Unchecked generics array creation for varargs parameter");
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new SuppressFix("unchecked"));
|
||||
return highlightInfo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, PsiElement resolve, boolean ignoreSuppressed) {
|
||||
public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, PsiElement resolve) {
|
||||
if (resolve instanceof PsiMethod) {
|
||||
final PsiMethod psiMethod = (PsiMethod)resolve;
|
||||
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(expression);
|
||||
if (!ignoreSuppressed) {
|
||||
if (SuppressManager.getInstance().isSuppressedFor(expression, "unchecked")) return false;
|
||||
}
|
||||
|
||||
if (psiMethod.isVarArgs()) {
|
||||
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_7) || !AnnotationUtil.isAnnotated(psiMethod, "java.lang.SafeVarargs", false)) {
|
||||
@@ -1282,29 +1151,6 @@ public class GenericsHighlightUtil {
|
||||
return list;
|
||||
}
|
||||
|
||||
public static HighlightInfo checkGenericCallWithRawArguments(JavaResolveResult resolveResult, PsiCallExpression callExpression) {
|
||||
final PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
if (method == null) return null;
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
final PsiExpressionList argumentList = callExpression.getArgumentList();
|
||||
if (argumentList == null) return null;
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length != 0) {
|
||||
for (int i = 0; i < expressions.length; i++) {
|
||||
PsiParameter parameter = parameters[Math.min(i, parameters.length - 1)];
|
||||
final PsiExpression expression = expressions[i];
|
||||
final PsiType parameterType = substitutor.substitute(parameter.getType());
|
||||
final PsiType expressionType = substitutor.substitute(expression.getType());
|
||||
if (expressionType != null) {
|
||||
final HighlightInfo highlightInfo = checkRawToGenericAssignment(parameterType, expressionType, expression);
|
||||
if (highlightInfo != null) return highlightInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HighlightInfo checkParametersOnRaw(PsiReferenceParameterList refParamList) {
|
||||
if (refParamList.getTypeArguments().length == 0) return null;
|
||||
JavaResolveResult resolveResult = null;
|
||||
@@ -1363,42 +1209,6 @@ public class GenericsHighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HighlightInfo checkUncheckedOverriding (PsiMethod overrider, final List<HierarchicalMethodSignature> superMethodSignatures) {
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(overrider)) return null;
|
||||
final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME);
|
||||
final InspectionProfile inspectionProfile =
|
||||
InspectionProjectProfileManager.getInstance(overrider.getProject()).getInspectionProfile();
|
||||
if (!inspectionProfile.isToolEnabled(key, overrider)) return null;
|
||||
final LocalInspectionTool tool =
|
||||
((LocalInspectionToolWrapper)inspectionProfile.getInspectionTool(UncheckedWarningLocalInspection.SHORT_NAME, overrider)).getTool();
|
||||
if (InspectionManagerEx.inspectionResultSuppressed(overrider, tool)) return null;
|
||||
final MethodSignature signature = overrider.getSignature(PsiSubstitutor.EMPTY);
|
||||
for (MethodSignatureBackedByPsiMethod superSignature : superMethodSignatures) {
|
||||
PsiMethod baseMethod = superSignature.getMethod();
|
||||
PsiSubstitutor substitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(signature, superSignature);
|
||||
if (substitutor == null) substitutor = superSignature.getSubstitutor();
|
||||
if (PsiUtil.isRawSubstitutor(baseMethod, superSignature.getSubstitutor())) continue;
|
||||
final PsiType baseReturnType = substitutor.substitute(baseMethod.getReturnType());
|
||||
final PsiType overriderReturnType = overrider.getReturnType();
|
||||
if (baseReturnType == null || overriderReturnType == null) return null;
|
||||
if (isRawToGeneric(baseReturnType, overriderReturnType)) {
|
||||
final String message = JavaErrorMessages.message("unchecked.overriding.incompatible.return.type",
|
||||
HighlightUtil.formatType(overriderReturnType),
|
||||
HighlightUtil.formatType(baseReturnType));
|
||||
|
||||
final PsiTypeElement returnTypeElement = overrider.getReturnTypeElement();
|
||||
LOG.assertTrue(returnTypeElement != null);
|
||||
final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(JavaHightlightInfoTypes.UNCHECKED_WARNING, returnTypeElement, message);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo,
|
||||
new EmptyIntentionAction(JavaErrorMessages.message("unchecked.overriding")),
|
||||
key);
|
||||
|
||||
return highlightInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HighlightInfo checkEnumMustNotBeLocal(final PsiClass aClass) {
|
||||
if (!aClass.isEnum()) return null;
|
||||
PsiElement parent = aClass.getParent();
|
||||
|
||||
+2
-19
@@ -317,13 +317,6 @@ public class HighlightMethodUtil {
|
||||
if (element instanceof PsiMethod && resolveResult.isValidResult()) {
|
||||
TextRange fixRange = getFixRange(methodCall);
|
||||
highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange);
|
||||
|
||||
if (highlightInfo == null) {
|
||||
highlightInfo = GenericsHighlightUtil.checkUncheckedCall(resolveResult, methodCall);
|
||||
}
|
||||
if (highlightInfo == null) {
|
||||
highlightInfo = GenericsHighlightUtil.checkGenericCallWithRawArguments(resolveResult, methodCall);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiMethod resolvedMethod = null;
|
||||
@@ -1271,11 +1264,7 @@ public class HighlightMethodUtil {
|
||||
ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, info);
|
||||
}
|
||||
else {
|
||||
HighlightInfo highlightInfo = GenericsHighlightUtil.checkUncheckedCall(result, constructorCall);
|
||||
if (highlightInfo != null) {
|
||||
holder.add(highlightInfo);
|
||||
return;
|
||||
}
|
||||
HighlightInfo highlightInfo;
|
||||
if (constructorCall instanceof PsiNewExpression) {
|
||||
highlightInfo = GenericsHighlightUtil.checkReferenceTypeArgumentList(constructor,
|
||||
((PsiNewExpression)constructorCall).getTypeArgumentList(),
|
||||
@@ -1284,13 +1273,7 @@ public class HighlightMethodUtil {
|
||||
holder.add(highlightInfo);
|
||||
return;
|
||||
}
|
||||
highlightInfo = GenericsHighlightUtil.checkGenericCallWithRawArguments(result, (PsiCallExpression)constructorCall);
|
||||
if (highlightInfo != null) {
|
||||
holder.add(highlightInfo);
|
||||
}
|
||||
//if (PsiUtil.isLanguageLevel7OrHigher(constructorCall)) {
|
||||
// // todo[anna] check if not diamond - apply corresponding fix
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,8 +459,7 @@ public class HighlightUtil {
|
||||
if (rType == null || lType == null || TypeConversionUtil.isAssignable(lType, rType)) return null;
|
||||
}
|
||||
else if (TypeConversionUtil.areTypesAssignmentCompatible(lType, expression)) {
|
||||
if (lType == null || rType == null) return null;
|
||||
return GenericsHighlightUtil.checkRawToGenericAssignment(lType, rType, expression);
|
||||
return null;
|
||||
}
|
||||
if (rType == null) {
|
||||
rType = expression.getType();
|
||||
@@ -1131,7 +1130,7 @@ public class HighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiType sameType(PsiExpression[] expressions) {
|
||||
public static PsiType sameType(PsiExpression[] expressions) {
|
||||
PsiType type = null;
|
||||
for (PsiExpression expression : expressions) {
|
||||
final PsiType currentType;
|
||||
|
||||
-4
@@ -635,7 +635,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleThrows(methodSignature, superMethodSignatures, true, method.getContainingClass()));
|
||||
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodWeakerPrivileges(methodSignature, superMethodSignatures, true));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedOverriding(method, superMethodSignatures));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodOverridesFinal(methodSignature, superMethodSignatures));
|
||||
}
|
||||
}
|
||||
@@ -686,7 +685,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType()));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedGenericsArrayCreation(expression.getClassOrAnonymousClassReference(), expression.resolveConstructor()));
|
||||
if (!myHolder.hasErrorResults()) registerConstructorCall(expression);
|
||||
|
||||
if (!myHolder.hasErrorResults()) visitExpression(expression);
|
||||
@@ -837,7 +835,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallMustBeFirstStatement(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkAccessStaticFieldFromEnumConstructor(expression, result));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkClassReferenceAfterQualifier(expression, resolved));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedGenericsArrayCreation(expression, resolved));
|
||||
}
|
||||
|
||||
@Override public void visitReferenceList(PsiReferenceList list) {
|
||||
@@ -918,7 +915,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
@Override public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
|
||||
super.visitTypeCastExpression(typeCast);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedTypeCast(typeCast));
|
||||
}
|
||||
|
||||
@Override public void visitTypeParameterList(PsiTypeParameterList list) {
|
||||
|
||||
+23
-1
@@ -18,14 +18,19 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.refactoring.actions.TypeCookAction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class GenerifyFileFix implements IntentionAction {
|
||||
public class GenerifyFileFix implements IntentionAction, LocalQuickFix {
|
||||
private final PsiFile myFile;
|
||||
|
||||
public GenerifyFileFix(PsiFile file) {
|
||||
@@ -37,11 +42,28 @@ public class GenerifyFileFix implements IntentionAction {
|
||||
return QuickFixBundle.message("generify.text", myFile.getName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("generify.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
|
||||
if (isAvailable(project, null, null)) {
|
||||
new WriteCommandAction(project) {
|
||||
protected void run(Result result) throws Throwable {
|
||||
invoke(project, FileEditorManager.getInstance(project).getSelectedTextEditor(), descriptor.getPsiElement().getContainingFile());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return myFile.isValid() && PsiManager.getInstance(project).isInProject(myFile);
|
||||
}
|
||||
|
||||
+8
-3
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.IntentionAndQuickFixAction;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -29,7 +30,7 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class VariableArrayTypeFix implements IntentionAction {
|
||||
public class VariableArrayTypeFix extends IntentionAndQuickFixAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.VariableArrayTypeFix");
|
||||
|
||||
private final PsiVariable myVariable;
|
||||
@@ -93,12 +94,15 @@ public class VariableArrayTypeFix implements IntentionAction {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return myTargetType.equals(myVariable.getType()) && myNewExpression != null ?
|
||||
QuickFixBundle.message("change.new.operator.type.text", getNewText(), myTargetType.getCanonicalText(), "") :
|
||||
QuickFixBundle.message("fix.variable.type.text", myVariable.getName(), myTargetType.getCanonicalText());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return myTargetType.equals(myVariable.getType()) && myNewExpression != null ?
|
||||
@@ -113,7 +117,8 @@ public class VariableArrayTypeFix implements IntentionAction {
|
||||
&& myInitializer.isValid();
|
||||
}
|
||||
|
||||
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
|
||||
@Override
|
||||
public void applyFix(Project project, PsiFile file, @Nullable Editor editor) {
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(myVariable.getContainingFile())) return;
|
||||
try {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(file.getProject()).getElementFactory();
|
||||
|
||||
+8
-3
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.IntentionAndQuickFixAction;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -27,8 +28,9 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class VariableTypeFix implements IntentionAction {
|
||||
public class VariableTypeFix extends IntentionAndQuickFixAction {
|
||||
static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.VariableTypeFix");
|
||||
|
||||
private final PsiVariable myVariable;
|
||||
@@ -39,8 +41,10 @@ public class VariableTypeFix implements IntentionAction {
|
||||
myReturnType = toReturn != null ? GenericsUtil.getVariableTypeByExpressionType(toReturn) : null;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return QuickFixBundle.message("fix.variable.type.text",
|
||||
getVariable().getName(),
|
||||
getReturnType().getCanonicalText());
|
||||
@@ -61,7 +65,8 @@ public class VariableTypeFix implements IntentionAction {
|
||||
&& !TypeConversionUtil.isVoidType(getReturnType());
|
||||
}
|
||||
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
@Override
|
||||
public void applyFix(Project project, PsiFile file, @Nullable Editor editor) {
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(getVariable().getContainingFile())) return;
|
||||
try {
|
||||
getVariable().normalizeDeclaration();
|
||||
|
||||
+16
-9
@@ -17,7 +17,9 @@ package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -105,8 +107,8 @@ public class RedundantUncheckedSuppressWarningsInspection extends BaseJavaLocalI
|
||||
}
|
||||
|
||||
private static void checkIfSafeToRemoveWarning(PsiElement suppressElement, PsiElement placeToCheckWarningsIn, ProblemsHolder holder) {
|
||||
final HashSet<PsiReferenceExpression> warningsElements = new HashSet<PsiReferenceExpression>();
|
||||
collectUncheckedWarnings(placeToCheckWarningsIn, true, warningsElements);
|
||||
final HashSet<PsiElement> warningsElements = new HashSet<PsiElement>();
|
||||
collectUncheckedWarnings(placeToCheckWarningsIn, warningsElements);
|
||||
if (warningsElements.isEmpty()) {
|
||||
final int uncheckedIdx = suppressElement.getText().indexOf(RemoveUncheckedWarningFix.UNCHECKED);
|
||||
holder.registerProblem(suppressElement,
|
||||
@@ -115,14 +117,19 @@ public class RedundantUncheckedSuppressWarningsInspection extends BaseJavaLocalI
|
||||
}
|
||||
}
|
||||
|
||||
public static void collectUncheckedWarnings(final PsiElement place, final boolean ignoreSuppressed, final Collection<PsiReferenceExpression> warningsElements) {
|
||||
place.accept(new JavaRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
if (GenericsHighlightUtil.isUncheckedWarning(expression, expression.resolve(), ignoreSuppressed)) {
|
||||
warningsElements.add(expression);
|
||||
public static void collectUncheckedWarnings(final PsiElement place, final Collection<PsiElement> warningsElements) {
|
||||
final UncheckedWarningLocalInspection.UncheckedWarningsVisitor visitor =
|
||||
new UncheckedWarningLocalInspection.UncheckedWarningsVisitor(false) {
|
||||
@Override
|
||||
protected void registerProblem(String message, PsiElement psiElement, LocalQuickFix... quickFix) {
|
||||
warningsElements.add(psiElement);
|
||||
}
|
||||
};
|
||||
place.accept(new JavaRecursiveElementVisitor(){
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
super.visitElement(element);
|
||||
element.accept(visitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+320
-3
@@ -16,20 +16,38 @@
|
||||
|
||||
package com.intellij.codeInspection.uncheckedWarnings;
|
||||
|
||||
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.GenerifyFileFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.VariableArrayTypeFix;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.UnfairLocalInspectionTool;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.*;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 17-Feb-2006
|
||||
*/
|
||||
public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool implements UnfairLocalInspectionTool {
|
||||
public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool {
|
||||
@NonNls public static final String SHORT_NAME = "UNCHECKED_WARNING";
|
||||
public static final String DISPLAY_NAME = InspectionsBundle.message("unchecked.warning");
|
||||
@NonNls public static final String ID = "unchecked";
|
||||
private static final Logger LOG = Logger.getInstance("#" + UncheckedWarningLocalInspection.class);
|
||||
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
@@ -56,4 +74,303 @@ public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
|
||||
return new UncheckedWarningsVisitor(isOnTheFly){
|
||||
@Override
|
||||
protected void registerProblem(String message, PsiElement psiElement, LocalQuickFix... quickFix) {
|
||||
holder.registerProblem(psiElement, message, quickFix);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static abstract class UncheckedWarningsVisitor extends JavaElementVisitor {
|
||||
private final boolean myOnTheFly;
|
||||
|
||||
public UncheckedWarningsVisitor(boolean onTheFly) {
|
||||
myOnTheFly = onTheFly;
|
||||
}
|
||||
|
||||
protected abstract void registerProblem(String message, PsiElement psiElement, LocalQuickFix... quickFix);
|
||||
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return;
|
||||
if (GenericsHighlightUtil.isUncheckedWarning(expression, expression.resolve())) {
|
||||
registerProblem("Unchecked generics array creation for varargs parameter", expression, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
super.visitNewExpression(expression);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return;
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
if (GenericsHighlightUtil.isUncheckedWarning(classReference, expression.resolveConstructor())) {
|
||||
registerProblem("Unchecked generics array creation for varargs parameter", classReference, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeCastExpression(PsiTypeCastExpression expression) {
|
||||
super.visitTypeCastExpression(expression);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return;
|
||||
final PsiTypeElement typeElement = expression.getCastType();
|
||||
if (typeElement == null) return;
|
||||
final PsiType castType = typeElement.getType();
|
||||
final PsiExpression operand = expression.getOperand();
|
||||
if (operand == null) return;
|
||||
final PsiType exprType = operand.getType();
|
||||
if (exprType == null) return;
|
||||
if (!TypeConversionUtil.areTypesConvertible(exprType, castType)) return;
|
||||
if (GenericsHighlightUtil.isUncheckedCast(castType, exprType)) {
|
||||
final String description =
|
||||
JavaErrorMessages.message("generics.unchecked.cast", HighlightUtil.formatType(exprType), HighlightUtil.formatType(castType));
|
||||
registerProblem(description, expression, myOnTheFly ? new GenerifyFileFix(operand.getContainingFile()) : null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallExpression(PsiCallExpression callExpression) {
|
||||
super.visitCallExpression(callExpression);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(callExpression)) return;
|
||||
final JavaResolveResult result = callExpression.resolveMethodGenerics();
|
||||
final String description = getUncheckedCallDescription(result);
|
||||
if (description != null) {
|
||||
registerProblem(description, callExpression instanceof PsiMethodCallExpression
|
||||
? ((PsiMethodCallExpression)callExpression).getMethodExpression()
|
||||
: callExpression, myOnTheFly ? new GenerifyFileFix(callExpression.getContainingFile()) : null);
|
||||
}
|
||||
else {
|
||||
final PsiSubstitutor substitutor = result.getSubstitutor();
|
||||
final PsiExpressionList argumentList = callExpression.getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final PsiMethod method = (PsiMethod)result.getElement();
|
||||
if (method != null) {
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length != 0) {
|
||||
for (int i = 0; i < expressions.length; i++) {
|
||||
PsiParameter parameter = parameters[Math.min(i, parameters.length - 1)];
|
||||
final PsiExpression expression = expressions[i];
|
||||
final PsiType parameterType = substitutor.substitute(parameter.getType());
|
||||
final PsiType expressionType = substitutor.substitute(expression.getType());
|
||||
if (expressionType != null) {
|
||||
checkRawToGenericsAssignment(expression, parameterType, expressionType, true, myOnTheFly ? new GenerifyFileFix(expression.getContainingFile()) : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVariable(PsiVariable variable) {
|
||||
super.visitVariable(variable);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(variable)) return;
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer == null || initializer instanceof PsiArrayInitializerExpression) return;
|
||||
final PsiType initializerType = initializer.getType();
|
||||
checkRawToGenericsAssignment(initializer, variable.getType(), initializerType, true, myOnTheFly ? getChangeVariableTypeFixes(variable, initializerType) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitForeachStatement(PsiForeachStatement statement) {
|
||||
super.visitForeachStatement(statement);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(statement)) return;
|
||||
final PsiParameter parameter = statement.getIterationParameter();
|
||||
final PsiType parameterType = parameter.getType();
|
||||
final PsiType itemType = GenericsHighlightUtil.getCollectionItemType(statement.getIteratedValue());
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(statement)) return;
|
||||
checkRawToGenericsAssignment(parameter, parameterType, itemType, true, myOnTheFly ? getChangeVariableTypeFixes(parameter, itemType) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssignmentExpression(PsiAssignmentExpression expression) {
|
||||
super.visitAssignmentExpression(expression);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return;
|
||||
if (!"=".equals(expression.getOperationSign().getText())) return;
|
||||
PsiExpression lExpr = expression.getLExpression();
|
||||
PsiExpression rExpr = expression.getRExpression();
|
||||
if (rExpr == null) return;
|
||||
PsiType lType = lExpr.getType();
|
||||
PsiType rType = rExpr.getType();
|
||||
if (rType == null) return;
|
||||
PsiVariable leftVar = null;
|
||||
if (lExpr instanceof PsiReferenceExpression) {
|
||||
PsiElement element = ((PsiReferenceExpression)lExpr).resolve();
|
||||
if (element instanceof PsiVariable) {
|
||||
leftVar = (PsiVariable)element;
|
||||
}
|
||||
}
|
||||
checkRawToGenericsAssignment(rExpr, lType, rType, true, myOnTheFly && leftVar != null ? getChangeVariableTypeFixes(leftVar, rType) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArrayInitializerExpression(PsiArrayInitializerExpression arrayInitializer) {
|
||||
super.visitArrayInitializerExpression(arrayInitializer);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(arrayInitializer)) return;
|
||||
final PsiType type = arrayInitializer.getType();
|
||||
if (!(type instanceof PsiArrayType)) return;
|
||||
final PsiType componentType = ((PsiArrayType)type).getComponentType();
|
||||
|
||||
|
||||
boolean arrayTypeFixChecked = false;
|
||||
VariableArrayTypeFix fix = null;
|
||||
|
||||
final PsiExpression[] initializers = arrayInitializer.getInitializers();
|
||||
for (PsiExpression expression : initializers) {
|
||||
final PsiType itemType = expression.getType();
|
||||
|
||||
if (itemType == null) continue;
|
||||
if (!TypeConversionUtil.isAssignable(componentType, itemType)) continue;
|
||||
if (GenericsHighlightUtil.isRawToGeneric(componentType, itemType)) {
|
||||
String description = JavaErrorMessages.message("generics.unchecked.assignment",
|
||||
HighlightUtil.formatType(itemType),
|
||||
HighlightUtil.formatType(componentType));
|
||||
if (!arrayTypeFixChecked) {
|
||||
final PsiType checkResult = HighlightUtil.sameType(initializers);
|
||||
fix = checkResult != null ? new VariableArrayTypeFix(arrayInitializer, checkResult) : null;
|
||||
arrayTypeFixChecked = true;
|
||||
}
|
||||
|
||||
if (fix != null) {
|
||||
registerProblem(description, expression, (LocalQuickFix)fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRawToGenericsAssignment(PsiElement parameter,
|
||||
PsiType parameterType,
|
||||
PsiType itemType,
|
||||
boolean checkAssignability,
|
||||
final LocalQuickFix... quickFix) {
|
||||
if (parameterType == null || itemType == null) return;
|
||||
if (checkAssignability && !TypeConversionUtil.isAssignable(parameterType, itemType)) return;
|
||||
if (GenericsHighlightUtil.isRawToGeneric(parameterType, itemType)) {
|
||||
String description = JavaErrorMessages.message("generics.unchecked.assignment",
|
||||
HighlightUtil.formatType(itemType),
|
||||
HighlightUtil.formatType(parameterType));
|
||||
registerProblem(description, parameter, quickFix);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethod(PsiMethod method) {
|
||||
super.visitMethod(method);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(method)) return;
|
||||
if (!method.isConstructor()) {
|
||||
List<HierarchicalMethodSignature> superMethodSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
|
||||
if (!superMethodSignatures.isEmpty() && !method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY);
|
||||
for (MethodSignatureBackedByPsiMethod superSignature : superMethodSignatures) {
|
||||
PsiMethod baseMethod = superSignature.getMethod();
|
||||
PsiSubstitutor substitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(signature, superSignature);
|
||||
if (substitutor == null) substitutor = superSignature.getSubstitutor();
|
||||
if (PsiUtil.isRawSubstitutor(baseMethod, superSignature.getSubstitutor())) continue;
|
||||
final PsiType baseReturnType = substitutor.substitute(baseMethod.getReturnType());
|
||||
final PsiType overriderReturnType = method.getReturnType();
|
||||
if (baseReturnType == null || overriderReturnType == null) return;
|
||||
if (GenericsHighlightUtil.isRawToGeneric(baseReturnType, overriderReturnType)) {
|
||||
final String message = JavaErrorMessages.message("unchecked.overriding.incompatible.return.type",
|
||||
HighlightUtil.formatType(overriderReturnType),
|
||||
HighlightUtil.formatType(baseReturnType));
|
||||
|
||||
final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
|
||||
LOG.assertTrue(returnTypeElement != null);
|
||||
registerProblem(message, returnTypeElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReturnStatement(PsiReturnStatement statement) {
|
||||
super.visitReturnStatement(statement);
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(statement)) return;
|
||||
final PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
|
||||
if (method != null) {
|
||||
final PsiType returnType = method.getReturnType();
|
||||
if (returnType != null && returnType != PsiType.VOID) {
|
||||
final PsiExpression returnValue = statement.getReturnValue();
|
||||
if (returnValue != null) {
|
||||
final PsiType valueType = returnValue.getType();
|
||||
if (valueType != null) {
|
||||
checkRawToGenericsAssignment(returnValue, returnType, valueType,
|
||||
false,
|
||||
(LocalQuickFix)QuickFixFactory.getInstance().createMethodReturnFix(method, valueType, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static String getUncheckedCallDescription(JavaResolveResult resolveResult) {
|
||||
final PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
if (method == null) return null;
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
for (final PsiParameter parameter : parameters) {
|
||||
final PsiType parameterType = parameter.getType();
|
||||
if (parameterType.accept(new PsiTypeVisitor<Boolean>() {
|
||||
public Boolean visitPrimitiveType(PsiPrimitiveType primitiveType) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
public Boolean visitArrayType(PsiArrayType arrayType) {
|
||||
return arrayType.getComponentType().accept(this);
|
||||
}
|
||||
|
||||
public Boolean visitClassType(PsiClassType classType) {
|
||||
PsiClass psiClass = classType.resolve();
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
return substitutor.substitute((PsiTypeParameter)psiClass) == null ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
PsiType[] parameters = classType.getParameters();
|
||||
for (PsiType parameter : parameters) {
|
||||
if (parameter.accept(this).booleanValue()) return Boolean.TRUE;
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
public Boolean visitWildcardType(PsiWildcardType wildcardType) {
|
||||
PsiType bound = wildcardType.getBound();
|
||||
if (bound != null) return bound.accept(this);
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
public Boolean visitEllipsisType(PsiEllipsisType ellipsisType) {
|
||||
return ellipsisType.getComponentType().accept(this);
|
||||
}
|
||||
}).booleanValue()) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
|
||||
PsiType type = elementFactory.createType(method.getContainingClass(), substitutor);
|
||||
return JavaErrorMessages.message("generics.unchecked.call.to.member.of.raw.type",
|
||||
HighlightUtil.formatMethod(method),
|
||||
HighlightUtil.formatType(type));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalQuickFix[] getChangeVariableTypeFixes(PsiVariable parameter, PsiType itemType) {
|
||||
final List<LocalQuickFix> result = new ArrayList<LocalQuickFix>();
|
||||
for (ChangeVariableTypeQuickFixProvider fixProvider : Extensions.getExtensions(ChangeVariableTypeQuickFixProvider.EP_NAME)) {
|
||||
for (IntentionAction action : fixProvider.getFixes(parameter, itemType)) {
|
||||
if (action instanceof LocalQuickFix) {
|
||||
result.add((LocalQuickFix)action);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toArray(new LocalQuickFix[result.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -86,12 +86,12 @@ class SemKey<T extends String> {
|
||||
}
|
||||
|
||||
public static <T> T[] append(final T[] src, final T element) {
|
||||
return append(src, element, (Class<T>)src.getClass().getComponentType());
|
||||
return append(src, element, <warning descr="Unchecked cast: 'java.lang.Class<capture<?>>' to 'java.lang.Class<T>'">(Class<T>)src.getClass().getComponentType()</warning>);
|
||||
}
|
||||
|
||||
public static <T> T[] append(T[] src, final T element, Class<T> componentType) {
|
||||
int length = src.length;
|
||||
T[] result = (T[])java.lang.reflect.Array.newInstance(componentType, length + 1);
|
||||
T[] result = <warning descr="Unchecked cast: 'java.lang.Object' to 'T[]'">(T[])java.lang.reflect.Array.newInstance(componentType, length + 1)</warning>;
|
||||
System.arraycopy(src, 0, result, 0, length);
|
||||
result[length] = element;
|
||||
return result;
|
||||
@@ -118,4 +118,4 @@ class OCM<T> {
|
||||
OCM(T s, Condition<T>... c) {
|
||||
this(s, false, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ class Test {
|
||||
}
|
||||
|
||||
void foo() {
|
||||
<error descr="Incompatible types. Found: 'java.util.List<java.lang.Class<? extends java.io.Serializable & java.lang.Comparable<?>>>', required: 'java.util.List<java.lang.Class<? extends java.io.Serializable>>'">List<Class<? extends Serializable>> l = this.asList(String.class, Integer.class);</error>
|
||||
<error descr="Incompatible types. Found: 'java.util.List<java.lang.Class<? extends java.io.Serializable & java.lang.Comparable<?>>>', required: 'java.util.List<java.lang.Class<? extends java.io.Serializable>>'">List<Class<? extends Serializable>> l = <warning descr="Unchecked generics array creation for varargs parameter">this.asList</warning>(String.class, Integer.class);</error>
|
||||
l.size();
|
||||
List<? extends Object> objects = this.asList(new String(), new Integer(0));
|
||||
objects.size();
|
||||
@@ -131,7 +131,7 @@ class IDEADEV25515 {
|
||||
|
||||
public static final
|
||||
<error descr="Incompatible types. Found: 'java.util.List<java.lang.Class<? extends java.io.Serializable & java.lang.Comparable<?>>>', required: 'java.util.List<java.lang.Class<? extends java.io.Serializable>>'">List<Class<? extends Serializable>> SIMPLE_TYPES =
|
||||
asList(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/
|
||||
<warning descr="Unchecked generics array creation for varargs parameter">asList</warning>(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/
|
||||
Boolean.class, Boolean.TYPE /*,String[].class */ /*,BigDecimal.class*/);</error>
|
||||
|
||||
|
||||
@@ -162,4 +162,4 @@ public class MaximalType {
|
||||
}
|
||||
class M extends MaximalType implements L{}
|
||||
class M2 extends MaximalType implements L{}
|
||||
/////////////
|
||||
/////////////
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ public class Test {
|
||||
|
||||
void foo() {
|
||||
//noinspection unc<caret>hecked
|
||||
foo(new ArrayList<String>()).addAll(Arrays.asList(new ArrayList<String>);
|
||||
foo(new ArrayList<String>()).addAll(Arrays.asList(new ArrayList<String>()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@ import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
|
||||
import com.intellij.codeInspection.reference.EntryPoint;
|
||||
import com.intellij.codeInspection.reference.RefElement;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.extensions.ExtensionPoint;
|
||||
@@ -30,7 +31,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{new UnusedSymbolLocalInspection()};
|
||||
return new LocalInspectionTool[]{new UnusedSymbolLocalInspection(), new UncheckedWarningLocalInspection()};
|
||||
}
|
||||
|
||||
public void testDuplicateAnnotations() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user