suppress possible heap pollution with unchecked id (IDEA-66066)

This commit is contained in:
anna
2011-03-09 20:53:20 +01:00
parent 3b8b505304
commit c61a0360a7
4 changed files with 70 additions and 31 deletions
@@ -58,41 +58,23 @@ public class PossibleHeapPollutionVarargsInspection extends BaseJavaLocalInspect
return "SafeVarargsDetector";
}
@NotNull
@Override
public String getID() {
return "unchecked";
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new JavaElementVisitor() {
return new HeapPollutionVisitor() {
@Override
public void visitMethod(PsiMethod method) {
super.visitMethod(method);
if (!PsiUtil.getLanguageLevel(method).isAtLeast(LanguageLevel.JDK_1_7)) return;
if (AnnotationUtil.isAnnotated(method, "java.lang.SafeVarargs", false)) return;
if (!method.isVarArgs()) return;
final PsiParameter psiParameter = method.getParameterList().getParameters()[method.getParameterList().getParametersCount() - 1];
final PsiType componentType = ((PsiEllipsisType)psiParameter.getType()).getComponentType();
if (GenericsHighlightUtil.isReifiableType(componentType)) {
return;
}
for (PsiReference reference : ReferencesSearch.search(psiParameter)) {
final PsiElement element = reference.getElement();
if (element instanceof PsiExpression && !PsiUtil.isAccessedForReading((PsiExpression)element)) {
return;
}
}
final PsiIdentifier nameIdentifier = method.getNameIdentifier();
if (nameIdentifier != null) {
//if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return;
//final PsiClass containingClass = method.getContainingClass();
//if (containingClass == null || containingClass.isInterface()) return; do not add
holder.registerProblem(nameIdentifier, "Possible heap pollution from parameterized vararg type #loc",
//todo check if can be final or static
method.hasModifierProperty(PsiModifier.FINAL) || method.hasModifierProperty(PsiModifier.STATIC) || method.isConstructor() ? new AnnotateAsSafeVarargsQuickFix() : null);
}
}
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
protected void registerProblem(PsiMethod method, PsiIdentifier nameIdentifier) {
holder.registerProblem(nameIdentifier, "Possible heap pollution from parameterized vararg type #loc",
//todo check if can be final or static
method.hasModifierProperty(PsiModifier.FINAL) ||
method.hasModifierProperty(PsiModifier.STATIC) ||
method.isConstructor() ? new AnnotateAsSafeVarargsQuickFix() : null);
}
};
}
@@ -119,4 +101,40 @@ public class PossibleHeapPollutionVarargsInspection extends BaseJavaLocalInspect
}
}
}
public static abstract class HeapPollutionVisitor extends JavaElementVisitor {
@Override
public void visitMethod(PsiMethod method) {
super.visitMethod(method);
if (!PsiUtil.getLanguageLevel(method).isAtLeast(LanguageLevel.JDK_1_7)) return;
if (AnnotationUtil.isAnnotated(method, "java.lang.SafeVarargs", false)) return;
if (!method.isVarArgs()) return;
final PsiParameter psiParameter = method.getParameterList().getParameters()[method.getParameterList().getParametersCount() - 1];
final PsiType componentType = ((PsiEllipsisType)psiParameter.getType()).getComponentType();
if (GenericsHighlightUtil.isReifiableType(componentType)) {
return;
}
for (PsiReference reference : ReferencesSearch.search(psiParameter)) {
final PsiElement element = reference.getElement();
if (element instanceof PsiExpression && !PsiUtil.isAccessedForReading((PsiExpression)element)) {
return;
}
}
final PsiIdentifier nameIdentifier = method.getNameIdentifier();
if (nameIdentifier != null) {
//if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return;
//final PsiClass containingClass = method.getContainingClass();
//if (containingClass == null || containingClass.isInterface()) return; do not add
registerProblem(method, nameIdentifier);
}
}
protected abstract void registerProblem(PsiMethod method, PsiIdentifier nameIdentifier);
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
}
}
}
@@ -125,11 +125,19 @@ public class RedundantUncheckedSuppressWarningsInspection extends BaseJavaLocalI
warningsElements.add(psiElement);
}
};
final PossibleHeapPollutionVarargsInspection.HeapPollutionVisitor hVisitor = new PossibleHeapPollutionVarargsInspection.HeapPollutionVisitor() {
@Override
protected void registerProblem(PsiMethod method, PsiIdentifier nameIdentifier) {
warningsElements.add(method);
}
};
place.accept(new JavaRecursiveElementVisitor(){
@Override
public void visitElement(PsiElement element) {
super.visitElement(element);
element.accept(visitor);
element.accept(hVisitor);
}
});
}