From c61a0360a734bdd229a0992b8dca0717210c59fd Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 9 Mar 2011 15:08:29 +0100 Subject: [PATCH] suppress possible heap pollution with unchecked id (IDEA-66066) --- ...ossibleHeapPollutionVarargsInspection.java | 80 ++++++++++++------- ...ntUncheckedSuppressWarningsInspection.java | 8 ++ .../redundantUncheckedVarargs/before10.java | 11 +++ ...moveRedundantUncheckedSuppressionTest.java | 2 + 4 files changed, 70 insertions(+), 31 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before10.java diff --git a/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java b/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java index 45cf2f5aba52..8cb271a89d80 100644 --- a/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java @@ -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) { + } + } } diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantUncheckedSuppressWarningsInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantUncheckedSuppressWarningsInspection.java index a63a9b6f99ca..e7656686ba0b 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantUncheckedSuppressWarningsInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantUncheckedSuppressWarningsInspection.java @@ -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); } }); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before10.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before10.java new file mode 100644 index 000000000000..6601055a862d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before10.java @@ -0,0 +1,11 @@ +// "Remove redundant "unchecked" suppression" "false" + +@SuppressWarnings({"unchecked", "bla-blah-toolid"}) +public enum Planet { + MERCURY(), + VENUS(); + + Planet(T... ts) { + } + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java index f2a7ca38b7e7..b3e6c908472e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.daemon.quickFix; import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.PossibleHeapPollutionVarargsInspection; import com.intellij.codeInspection.RedundantUncheckedSuppressWarningsInspection; @@ -24,6 +25,7 @@ public class RemoveRedundantUncheckedSuppressionTest extends LightQuickFixTestCa protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ new RedundantUncheckedSuppressWarningsInspection(), + new PossibleHeapPollutionVarargsInspection(), }; }