diff --git a/check_api/src/main/java/com/google/errorprone/VisitorState.java b/check_api/src/main/java/com/google/errorprone/VisitorState.java index 81d707c91d4..c4312004526 100644 --- a/check_api/src/main/java/com/google/errorprone/VisitorState.java +++ b/check_api/src/main/java/com/google/errorprone/VisitorState.java @@ -262,6 +262,10 @@ public ErrorProneOptions errorProneOptions() { return sharedState.errorProneOptions; } + public Map severityMap() { + return sharedState.severityMap; + } + public void reportMatch(Description description) { checkNotNull(description, "Use Description.NO_MATCH to denote an absent finding."); if (description == Description.NO_MATCH) { diff --git a/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java b/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java index d785545c431..6aa078935a0 100644 --- a/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java +++ b/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java @@ -19,12 +19,15 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.errorprone.util.ASTHelpers.getModifiers; import static com.google.errorprone.util.ASTHelpers.getStartPosition; +import static com.google.errorprone.util.ASTHelpers.getSymbol; import com.google.common.collect.ImmutableRangeSet; import com.google.common.collect.Iterables; import com.google.common.collect.Range; import com.google.errorprone.BugCheckerInfo; import com.google.errorprone.BugPattern.SeverityLevel; +import com.google.errorprone.ErrorProneOptions; +import com.google.errorprone.SuppressionInfo; import com.google.errorprone.VisitorState; import com.google.errorprone.annotations.CheckReturnValue; import com.google.errorprone.fixes.Fix; @@ -248,17 +251,17 @@ public boolean suppressedByAnyOf(Set annotations, VisitorState s) { } /** - * Returns true if the given tree is annotated with a {@code @SuppressWarnings} that disables this - * bug checker. + * @deprecated use {@link #isSuppressed(Tree, VisitorState)} instead */ + @Deprecated public boolean isSuppressed(Tree tree) { return isSuppressed(ASTHelpers.getAnnotation(tree, SuppressWarnings.class)); } /** - * Returns true if the given symbol is annotated with a {@code @SuppressWarnings} that disables - * this bug checker. + * @deprecated use {@link #isSuppressed(Symbol, VisitorState)} instead */ + @Deprecated public boolean isSuppressed(Symbol symbol) { return isSuppressed(ASTHelpers.getAnnotation(symbol, SuppressWarnings.class)); } @@ -268,13 +271,45 @@ private boolean isSuppressed(SuppressWarnings suppression) { && !Collections.disjoint(Arrays.asList(suppression.value()), allNames()); } + /** + * Returns true if the given tree is annotated with a {@code @SuppressWarnings} that disables this + * bug checker. + */ + public boolean isSuppressed(Tree tree, VisitorState state) { + Symbol sym = getSymbol(tree); + return sym != null && isSuppressed(sym, state); + } + + /** + * Returns true if the given symbol is annotated with a {@code @SuppressWarnings} or other + * annotation that disables this bug checker. + */ + public boolean isSuppressed(Symbol sym, VisitorState state) { + ErrorProneOptions errorProneOptions = state.errorProneOptions(); + boolean suppressedInGeneratedCode = + errorProneOptions.disableWarningsInGeneratedCode() + && state.severityMap().get(canonicalName()) != SeverityLevel.ERROR; + SuppressionInfo.SuppressedState suppressedState = + SuppressionInfo.EMPTY + .withExtendedSuppressions(sym, state, customSuppressionAnnotationNames.get(state)) + .suppressedState(BugChecker.this, suppressedInGeneratedCode, state); + return suppressedState == SuppressionInfo.SuppressedState.SUPPRESSED; + } + + private final Supplier> customSuppressionAnnotationNames = + VisitorState.memoize( + state -> + customSuppressionAnnotations().stream() + .map(a -> state.getName(a.getName())) + .collect(toImmutableSet())); + /** Computes a RangeSet of code regions which are suppressed by this bug checker. */ public ImmutableRangeSet suppressedRegions(VisitorState state) { ImmutableRangeSet.Builder suppressedRegions = ImmutableRangeSet.builder(); new TreeScanner() { @Override public Void scan(Tree tree, Void unused) { - if (getModifiers(tree) != null && isSuppressed(tree)) { + if (getModifiers(tree) != null && isSuppressed(tree, state)) { suppressedRegions.add(Range.closed(getStartPosition(tree), state.getEndPosition(tree))); } else { super.scan(tree, null); @@ -517,11 +552,34 @@ public int hashCode() { /** A {@link TreePathScanner} which skips trees which are suppressed for this check. */ protected class SuppressibleTreePathScanner extends TreePathScanner { + + // TODO(cushon): make this protected once it is required; currently it would shadow + // other variables named state and break checks that pass the deprecated constructor + private final VisitorState state; + + public SuppressibleTreePathScanner(VisitorState state) { + this.state = state; + } + + /** + * @deprecated use {@link #SuppressibleTreePathScanner(VisitorState)} instead + */ + @Deprecated + public SuppressibleTreePathScanner() { + this(null); + } + @Override public A scan(Tree tree, B b) { boolean isSuppressible = tree instanceof ClassTree || tree instanceof MethodTree || tree instanceof VariableTree; - return isSuppressible && isSuppressed(tree) ? null : super.scan(tree, b); + if (isSuppressible) { + boolean suppressed = state != null ? isSuppressed(tree, state) : isSuppressed(tree); + if (suppressed) { + return null; + } + } + return super.scan(tree, b); } } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AlreadyChecked.java b/core/src/main/java/com/google/errorprone/bugpatterns/AlreadyChecked.java index dbd90c34094..8c8955082c8 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AlreadyChecked.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AlreadyChecked.java @@ -80,6 +80,7 @@ private final class IfScanner extends SuppressibleTreePathScanner { private final VisitorState state; private IfScanner(VisitorState state) { + super(state); this.state = state; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AmbiguousMethodReference.java b/core/src/main/java/com/google/errorprone/bugpatterns/AmbiguousMethodReference.java index c23ab415eba..3cfe0d67fd5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AmbiguousMethodReference.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AmbiguousMethodReference.java @@ -67,7 +67,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { continue; } MethodSymbol msym = getSymbol((MethodTree) member); - if (isSuppressed(msym)) { + if (isSuppressed(msym, state)) { continue; } List clash = methods.remove(methodReferenceDescriptor(types, msym)); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueImmutableFields.java b/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueImmutableFields.java index c895267309a..8ba9ad3bc4f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueImmutableFields.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueImmutableFields.java @@ -131,7 +131,7 @@ private static Matcher returning(String type) { public Description matchClass(ClassTree tree, VisitorState state) { if (ASTHelpers.hasAnnotation(tree, "com.google.auto.value.AutoValue", state)) { for (Tree memberTree : tree.getMembers()) { - if (memberTree instanceof MethodTree && !isSuppressed(memberTree)) { + if (memberTree instanceof MethodTree && !isSuppressed(memberTree, state)) { MethodTree methodTree = (MethodTree) memberTree; if (ABSTRACT_MATCHER.matches(methodTree, state)) { for (Map.Entry> entry : REPLACEMENT_TO_MATCHERS.entries()) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueSubclassLeaked.java b/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueSubclassLeaked.java index 7f92d371dd8..60ecfe2b9f4 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueSubclassLeaked.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AutoValueSubclassLeaked.java @@ -66,7 +66,7 @@ private void scanAndReportAutoValueReferences( CompilationUnitTree tree, ImmutableSet autoValueClassesFromThisFile, VisitorState state) { - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitClass(ClassTree classTree, Void unused) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/BadImport.java b/core/src/main/java/com/google/errorprone/bugpatterns/BadImport.java index f2454d225c1..667d79065a4 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/BadImport.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/BadImport.java @@ -171,7 +171,7 @@ private Description buildDescription( CompilationUnitTree compilationUnit = state.getPath().getCompilationUnit(); TreePath path = TreePath.getPath(compilationUnit, compilationUnit); IdentifierTree firstFound = - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public IdentifierTree reduce(IdentifierTree r1, IdentifierTree r2) { return (r2 != null) ? r2 : r1; @@ -180,7 +180,7 @@ public IdentifierTree reduce(IdentifierTree r1, IdentifierTree r2) { @Override public IdentifierTree visitIdentifier(IdentifierTree node, Void unused) { Symbol nodeSymbol = getSymbol(node); - if (symbols.contains(nodeSymbol) && !isSuppressed(node)) { + if (symbols.contains(nodeSymbol) && !isSuppressed(node, state)) { if (getCurrentPath().getParentPath().getLeaf().getKind() != Kind.CASE) { builder.prefixWith(node, enclosingReplacement); moveTypeAnnotations(node); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ClassName.java b/core/src/main/java/com/google/errorprone/bugpatterns/ClassName.java index fdd0e52ec42..c232bd0873f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ClassName.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ClassName.java @@ -52,7 +52,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s for (Tree member : tree.getTypeDecls()) { if (member instanceof ClassTree) { ClassTree classMember = (ClassTree) member; - if (isSuppressed(classMember)) { + if (isSuppressed(classMember, state)) { // If any top-level classes have @SuppressWarnings("ClassName"), ignore // this compilation unit. We can't rely on the normal suppression // mechanism because the only enclosing element is the package declaration, diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DefaultPackage.java b/core/src/main/java/com/google/errorprone/bugpatterns/DefaultPackage.java index e8350e70dd1..8d4d09290ba 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DefaultPackage.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DefaultPackage.java @@ -39,7 +39,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s if (state.errorProneOptions().isTestOnlyTarget()) { return Description.NO_MATCH; } - if (tree.getTypeDecls().stream().anyMatch(s -> isSuppressed(s))) { + if (tree.getTypeDecls().stream().anyMatch(s -> isSuppressed(s, state))) { return Description.NO_MATCH; } if (tree.getTypeDecls().stream() diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DoNotCallChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/DoNotCallChecker.java index 6d488fda57a..a92c06de47b 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DoNotCallChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DoNotCallChecker.java @@ -185,7 +185,7 @@ public Description matchMethod(MethodTree tree, VisitorState state) { public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) { ImmutableListMultimap assignedTypes = getAssignedTypes(state); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitMethodInvocation(MethodInvocationTree tree, Void unused) { handleTree(tree, getSymbol(tree)); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/EqualsHashCode.java b/core/src/main/java/com/google/errorprone/bugpatterns/EqualsHashCode.java index b217cf485be..2ea8536edfc 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/EqualsHashCode.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/EqualsHashCode.java @@ -59,7 +59,7 @@ public class EqualsHashCode extends BugChecker implements ClassTreeMatcher { @Override public Description matchClass(ClassTree classTree, VisitorState state) { MethodTree methodTree = checkMethodPresence(classTree, state/* expectedNoArgMethod= */ ); - if (methodTree == null || isSuppressed(methodTree)) { + if (methodTree == null || isSuppressed(methodTree, state)) { return NO_MATCH; } return describeMatch(methodTree); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/FieldCanBeFinal.java b/core/src/main/java/com/google/errorprone/bugpatterns/FieldCanBeFinal.java index c1ac860298e..457dd65ede0 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/FieldCanBeFinal.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/FieldCanBeFinal.java @@ -257,7 +257,7 @@ private FinalScanner(VariableAssignmentRecords writes, VisitorState compilationS @Override public Void visitVariable(VariableTree node, InitializationContext init) { VarSymbol sym = ASTHelpers.getSymbol(node); - if (sym.getKind() == ElementKind.FIELD && !isSuppressed(node)) { + if (sym.getKind() == ElementKind.FIELD && !isSuppressed(node, compilationState)) { writes.recordDeclaration(sym, node); } return super.visitVariable(node, InitializationContext.NONE); @@ -317,7 +317,7 @@ private boolean isThisAccess(Tree tree) { public Void visitClass(ClassTree node, InitializationContext init) { VisitorState state = compilationState.withPath(getCurrentPath()); - if (isSuppressed(node)) { + if (isSuppressed(node, state)) { return null; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/FieldCanBeLocal.java b/core/src/main/java/com/google/errorprone/bugpatterns/FieldCanBeLocal.java index 57fbcd51763..239ce875fa4 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/FieldCanBeLocal.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/FieldCanBeLocal.java @@ -79,7 +79,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s SetMultimap uses = MultimapBuilder.linkedHashKeys().linkedHashSetValues().build(); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitVariable(VariableTree variableTree, Void unused) { VarSymbol symbol = getSymbol(variableTree); @@ -118,7 +118,7 @@ private boolean canBeUsedOnLocalVariable(AnnotationTree annotationTree) { @Override public Void visitClass(ClassTree classTree, Void unused) { - if (isSuppressed(classTree)) { + if (isSuppressed(classTree, state)) { return null; } inMethod = false; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/FunctionalInterfaceClash.java b/core/src/main/java/com/google/errorprone/bugpatterns/FunctionalInterfaceClash.java index 0d1b62ad4ea..c753a02932e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/FunctionalInterfaceClash.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/FunctionalInterfaceClash.java @@ -112,7 +112,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { continue; } - if (isSuppressed(member)) { + if (isSuppressed(member, state)) { continue; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/HidingField.java b/core/src/main/java/com/google/errorprone/bugpatterns/HidingField.java index a1600d15970..31709559cb3 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/HidingField.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/HidingField.java @@ -58,7 +58,11 @@ public Description matchClass(ClassTree classTree, VisitorState visitorState) { classTree.getMembers().stream() .filter(mem -> mem instanceof VariableTree) .map(mem -> (VariableTree) mem) - .filter(mem -> !isSuppressed(getSymbol(mem)) && !isIgnoredType(mem) && !isStatic(mem)) + .filter( + mem -> + !isSuppressed(getSymbol(mem), visitorState) + && !isIgnoredType(mem) + && !isStatic(mem)) .collect(toCollection(ArrayList::new)); ClassSymbol classSymbol = getSymbol(classTree); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableMemberCollection.java b/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableMemberCollection.java index bc336a76b10..3c28aea1744 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableMemberCollection.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableMemberCollection.java @@ -126,7 +126,7 @@ public Description matchClass(ClassTree classTree, VisitorState state) { classTree.getMembers().stream() .filter(member -> PRIVATE_FINAL_VAR_MATCHER.matches(member, state)) .filter(member -> !EXCLUSIONS.matches(member, state)) - .filter(member -> !isSuppressed(member)) + .filter(member -> !isSuppressed(member, state)) .map(VariableTree.class::cast) .flatMap(varTree -> stream(isReplaceable(varTree, state))) .collect(toImmutableMap(ReplaceableVar::symbol, var -> var)); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableSetForContains.java b/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableSetForContains.java index 41dd47a27d9..b4430a2751a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableSetForContains.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableSetForContains.java @@ -119,7 +119,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { SuggestedFix.Builder fix = SuggestedFix.builder(); Optional firstReplacement = Optional.empty(); for (VariableTree var : immutableListVar) { - if (isSuppressed(var)) { + if (isSuppressed(var, state)) { continue; } if (!usageScanner.disallowedVarUsages.get(getSymbol(var))) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/InterruptedExceptionSwallowed.java b/core/src/main/java/com/google/errorprone/bugpatterns/InterruptedExceptionSwallowed.java index fe9836146fb..07b7ebaa946 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/InterruptedExceptionSwallowed.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/InterruptedExceptionSwallowed.java @@ -165,7 +165,7 @@ public Description matchTry(TryTree tree, VisitorState state) { && !blockChecksForInterruptedException(catchTree.getBlock(), state) && !(exceptionIsRethrown(catchTree, catchTree.getParameter(), state) && methodDeclaresInterruptedException(state.findEnclosing(MethodTree.class), state)) - && !isSuppressed(catchTree.getParameter())) { + && !isSuppressed(catchTree.getParameter(), state)) { return describeMatch(catchTree, createFix(catchTree)); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/JUnit3TestNotRun.java b/core/src/main/java/com/google/errorprone/bugpatterns/JUnit3TestNotRun.java index 549db11fe09..42edb2687b2 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/JUnit3TestNotRun.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/JUnit3TestNotRun.java @@ -93,7 +93,7 @@ public final class JUnit3TestNotRun extends BugChecker implements CompilationUni @Override public Description matchCompilationUnit(CompilationUnitTree unused, VisitorState state) { ImmutableSet calledMethods = calledMethods(state); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitMethod(MethodTree tree, Void unused) { checkMethod(tree, calledMethods, state.withPath(getCurrentPath())) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/JUnit4TestNotRun.java b/core/src/main/java/com/google/errorprone/bugpatterns/JUnit4TestNotRun.java index 2a07a2b3a49..ae9d6b14637 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/JUnit4TestNotRun.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/JUnit4TestNotRun.java @@ -103,11 +103,11 @@ public Description matchClass(ClassTree tree, VisitorState state) { } Map suspiciousMethods = new HashMap<>(); for (Tree member : tree.getMembers()) { - if (!(member instanceof MethodTree) || isSuppressed(member)) { + if (!(member instanceof MethodTree) || isSuppressed(member, state)) { continue; } MethodTree methodTree = (MethodTree) member; - if (possibleTestMethod.matches(methodTree, state) && !isSuppressed(tree)) { + if (possibleTestMethod.matches(methodTree, state) && !isSuppressed(tree, state)) { suspiciousMethods.put(getSymbol(methodTree), methodTree); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MethodCanBeStatic.java b/core/src/main/java/com/google/errorprone/bugpatterns/MethodCanBeStatic.java index dd26b72b8cc..db42998f2da 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MethodCanBeStatic.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MethodCanBeStatic.java @@ -77,7 +77,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s @Override public Void visitClass(ClassTree classTree, Void unused) { - if (isSuppressed(classTree)) { + if (isSuppressed(classTree, state)) { suppressions++; super.visitClass(classTree, null); suppressions--; @@ -89,7 +89,7 @@ public Void visitClass(ClassTree classTree, Void unused) { @Override public Void visitMethod(MethodTree tree, Void unused) { - if (isSuppressed(tree)) { + if (isSuppressed(tree, state)) { suppressions++; matchMethod(tree); super.visitMethod(tree, null); @@ -103,7 +103,7 @@ public Void visitMethod(MethodTree tree, Void unused) { @Override public Void visitVariable(VariableTree variableTree, Void unused) { - if (isSuppressed(variableTree)) { + if (isSuppressed(variableTree, state)) { suppressions++; super.visitVariable(variableTree, null); suppressions--; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnType.java b/core/src/main/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnType.java index 8baad4234a7..5ef34d412ea 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MixedMutabilityReturnType.java @@ -193,6 +193,7 @@ private final class ReturnTypesScanner extends SuppressibleTreePathScanner immutable, Set mutable) { + super(state); this.state = state; this.immutable = immutable; this.mutable = mutable; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MultipleTopLevelClasses.java b/core/src/main/java/com/google/errorprone/bugpatterns/MultipleTopLevelClasses.java index ec5dbd26b7c..9c558eb6eb5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MultipleTopLevelClasses.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MultipleTopLevelClasses.java @@ -60,7 +60,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s case INTERFACE: case ANNOTATION_TYPE: case ENUM: - if (isSuppressed(classMember)) { + if (isSuppressed(classMember, state)) { // If any top-level classes have @SuppressWarnings("TopLevel"), ignore // this compilation unit. We can't rely on the normal suppression // mechanism because the only enclosing element is the package declaration, diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/OptionalNotPresent.java b/core/src/main/java/com/google/errorprone/bugpatterns/OptionalNotPresent.java index bdd88070378..e625a66892d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/OptionalNotPresent.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/OptionalNotPresent.java @@ -77,6 +77,7 @@ private final class IfScanner extends SuppressibleTreePathScanner { private final VisitorState state; private IfScanner(VisitorState state) { + super(state); this.state = state; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/PreferredInterfaceType.java b/core/src/main/java/com/google/errorprone/bugpatterns/PreferredInterfaceType.java index a305f0381e1..ba99856149a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/PreferredInterfaceType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/PreferredInterfaceType.java @@ -181,7 +181,7 @@ public Void visitLambdaExpression(LambdaExpressionTree node, Void unused) { private ImmutableMap getFixableTypes(VisitorState state) { ImmutableMap.Builder fixableTypes = ImmutableMap.builder(); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitVariable(VariableTree tree, Void unused) { VarSymbol symbol = getSymbol(tree); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ProtectedMembersInFinalClass.java b/core/src/main/java/com/google/errorprone/bugpatterns/ProtectedMembersInFinalClass.java index d5254a51c75..fc01b489c32 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ProtectedMembersInFinalClass.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ProtectedMembersInFinalClass.java @@ -70,7 +70,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { .filter(m -> HAS_PROTECTED.matches(m, state)) .filter( m -> !(m instanceof MethodTree) || methodHasNoParentMethod((MethodTree) m, state)) - .filter(m -> !isSuppressed(m)) + .filter(m -> !isSuppressed(m, state)) .collect(toImmutableList()); if (relevantMembers.isEmpty()) { return NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/ProtoFieldNullComparison.java b/core/src/main/java/com/google/errorprone/bugpatterns/ProtoFieldNullComparison.java index 5299fe98b25..2e6c07d122e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ProtoFieldNullComparison.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ProtoFieldNullComparison.java @@ -160,12 +160,12 @@ private ProtoNullComparisonScanner(VisitorState state) { @Override public Void visitMethod(MethodTree method, Void unused) { - return isSuppressed(method) ? null : super.visitMethod(method, unused); + return isSuppressed(method, state) ? null : super.visitMethod(method, unused); } @Override public Void visitClass(ClassTree clazz, Void unused) { - return isSuppressed(clazz) ? null : super.visitClass(clazz, unused); + return isSuppressed(clazz, state) ? null : super.visitClass(clazz, unused); } @Override @@ -175,7 +175,7 @@ public Void visitVariable(VariableTree variable, Void unused) { getInitializer(variable.getInitializer()) .ifPresent(e -> effectivelyFinalValues.put(symbol, e)); } - return isSuppressed(variable) ? null : super.visitVariable(variable, null); + return isSuppressed(variable, state) ? null : super.visitVariable(variable, null); } private Optional getInitializer(ExpressionTree tree) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SameNameButDifferent.java b/core/src/main/java/com/google/errorprone/bugpatterns/SameNameButDifferent.java index 0ff0364fc03..5ccba6f30ec 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/SameNameButDifferent.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SameNameButDifferent.java @@ -57,7 +57,7 @@ public final class SameNameButDifferent extends BugChecker implements Compilatio @Override public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) { Table> table = HashBasedTable.create(); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitMemberSelect(MemberSelectTree memberSelectTree, Void unused) { if (!shouldIgnore()) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/StronglyType.java b/core/src/main/java/com/google/errorprone/bugpatterns/StronglyType.java index e55a4acea35..ec9e6063a27 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/StronglyType.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/StronglyType.java @@ -217,7 +217,7 @@ private static String getMethodSelectOrNewClass(ExpressionTree tree, VisitorStat private ImmutableMap findPathToPotentialFields( VisitorState state, Set potentialTypes) { ImmutableMap.Builder fields = ImmutableMap.builder(); - bugChecker().new SuppressibleTreePathScanner() { + bugChecker().new SuppressibleTreePathScanner(state) { @Override public Void visitVariable(VariableTree variableTree, Void unused) { VarSymbol symbol = getSymbol(variableTree); @@ -228,7 +228,7 @@ && isConsideredFinal(symbol) && variableTree.getInitializer() != null && potentialTypes.stream() .anyMatch(potentialType -> isSameType(type, potentialType, state)) - && !bugChecker().isSuppressed(variableTree)) { + && !bugChecker().isSuppressed(variableTree, state)) { fields.put(symbol, getCurrentPath()); } return super.visitVariable(variableTree, null); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SuppressWarningsWithoutExplanation.java b/core/src/main/java/com/google/errorprone/bugpatterns/SuppressWarningsWithoutExplanation.java index a9eb02e1dbf..1c121c27c6c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/SuppressWarningsWithoutExplanation.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SuppressWarningsWithoutExplanation.java @@ -82,7 +82,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s return NO_MATCH; } ImmutableRangeSet linesWithComments = linesWithComments(state); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitAnnotation(AnnotationTree annotationTree, Void unused) { if (!SUPPRESS_WARNINGS.matches(annotationTree, state)) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UngroupedOverloads.java b/core/src/main/java/com/google/errorprone/bugpatterns/UngroupedOverloads.java index 0a4b4bb8027..4da4012597c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UngroupedOverloads.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UngroupedOverloads.java @@ -137,7 +137,7 @@ private Stream checkOverloads( if (group == 0) { return Stream.empty(); } - if (overloads.stream().anyMatch(m -> isSuppressed(m.tree()))) { + if (overloads.stream().anyMatch(m -> isSuppressed(m.tree(), state))) { return Stream.empty(); } // build a fix that replaces the first overload with all the overloads grouped together diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessarilyFullyQualified.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessarilyFullyQualified.java index 2ca3f8142bf..7202ebbf7b0 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessarilyFullyQualified.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessarilyFullyQualified.java @@ -80,7 +80,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s } Table> table = HashBasedTable.create(); SetMultimap identifiersSeen = HashMultimap.create(); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitImport(ImportTree importTree, Void unused) { return null; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedVariable.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedVariable.java index 015d35dc03e..25b8b9a986e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedVariable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnnecessaryBoxedVariable.java @@ -85,7 +85,7 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s FindBoxedUsagesScanner usages = new FindBoxedUsagesScanner(state); usages.scan(tree, null); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitVariable(VariableTree tree, Void unused) { VisitorState innerState = state.withPath(getCurrentPath()); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedException.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedException.java index 68cb618bb11..5fd27beec03 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedException.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedException.java @@ -74,7 +74,7 @@ public final class UnusedException extends BugChecker implements CatchTreeMatche @Override public Description matchCatch(CatchTree tree, VisitorState state) { - if (isSuppressed(tree.getParameter()) || isSuppressedViaName(tree.getParameter())) { + if (isSuppressed(tree.getParameter(), state) || isSuppressedViaName(tree.getParameter())) { return Description.NO_MATCH; } VarSymbol exceptionSymbol = ASTHelpers.getSymbol(tree.getParameter()); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedMethod.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedMethod.java index d945edffbed..48a3aef518d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedMethod.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedMethod.java @@ -132,6 +132,10 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s AtomicBoolean ignoreUnusedMethods = new AtomicBoolean(false); class MethodFinder extends SuppressibleTreePathScanner { + MethodFinder(VisitorState state) { + super(state); + } + @Override public Void visitClass(ClassTree tree, Void unused) { if (exemptedBySuperType(getType(tree), state)) { @@ -232,7 +236,7 @@ private boolean isExemptedConstructor(MethodSymbol methodSymbol, VisitorState st return false; } } - new MethodFinder().scan(state.getPath(), null); + new MethodFinder(state).scan(state.getPath(), null); class FilterUsedMethods extends TreePathScanner { @Override diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedNestedClass.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedNestedClass.java index d7435349fa9..2981f111f92 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedNestedClass.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedNestedClass.java @@ -53,7 +53,7 @@ public final class UnusedNestedClass extends BugChecker implements CompilationUn @Override public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) { - PrivateNestedClassScanner privateNestedClassScanner = new PrivateNestedClassScanner(); + PrivateNestedClassScanner privateNestedClassScanner = new PrivateNestedClassScanner(state); privateNestedClassScanner.scan(state.getPath(), null); Map privateNestedClasses = privateNestedClassScanner.classes; @@ -71,11 +71,15 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s private final class PrivateNestedClassScanner extends TreePathScanner { private final Map classes = new HashMap<>(); - private PrivateNestedClassScanner() {} + private final VisitorState state; + + private PrivateNestedClassScanner(VisitorState state) { + this.state = state; + } @Override public Void visitClass(ClassTree classTree, Void unused) { - if (ignoreUnusedClass(classTree)) { + if (ignoreUnusedClass(classTree, state)) { return null; } ClassSymbol symbol = getSymbol(classTree); @@ -86,8 +90,8 @@ public Void visitClass(ClassTree classTree, Void unused) { return super.visitClass(classTree, null); } - private boolean ignoreUnusedClass(ClassTree classTree) { - return isSuppressed(classTree) || shouldKeep(classTree); + private boolean ignoreUnusedClass(ClassTree classTree, VisitorState state) { + return isSuppressed(classTree, state) || shouldKeep(classTree); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java index 9aa155bcea4..79174cfbd0d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/UnusedVariable.java @@ -567,7 +567,7 @@ public Void visitVariable(VariableTree variableTree, Void unused) { if (exemptedByName(variableTree.getName())) { return null; } - if (isSuppressed(variableTree)) { + if (isSuppressed(variableTree, state)) { return null; } VarSymbol symbol = getSymbol(variableTree); @@ -658,7 +658,7 @@ public Void visitTry(TryTree node, Void unused) { @Override public Void visitClass(ClassTree tree, Void unused) { - if (isSuppressed(tree)) { + if (isSuppressed(tree, state)) { return null; } if (EXEMPTING_SUPER_TYPES.stream() @@ -679,7 +679,7 @@ public Void visitMethod(MethodTree tree, Void unused) { if (SERIALIZATION_METHODS.matches(tree, state)) { return scan(tree.getBody(), null); } - return isSuppressed(tree) ? null : super.visitMethod(tree, unused); + return isSuppressed(tree, state) ? null : super.visitMethod(tree, unused); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/WrongOneof.java b/core/src/main/java/com/google/errorprone/bugpatterns/WrongOneof.java index 7131f8b0b58..b56ec6e8ea8 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/WrongOneof.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/WrongOneof.java @@ -159,7 +159,7 @@ private void scanForInvalidGetters( CaseTree caseTree, ImmutableList receiverSymbolChain, VisitorState state) { - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitMethodInvocation(MethodInvocationTree methodInvocationTree, Void unused) { ExpressionTree receiver = getReceiver(methodInvocationTree); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerLogWithCause.java b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerLogWithCause.java index b1e690c86da..a4410fb9e4a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerLogWithCause.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerLogWithCause.java @@ -64,7 +64,7 @@ public final class FloggerLogWithCause extends BugChecker implements CatchTreeMa @Override public Description matchCatch(CatchTree tree, VisitorState state) { - if (isSuppressed(tree.getParameter())) { + if (isSuppressed(tree.getParameter(), state)) { return Description.NO_MATCH; } List statements = tree.getBlock().getStatements(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerPassedAround.java b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerPassedAround.java index 158762d0788..8361de2a9a1 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerPassedAround.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/flogger/FloggerPassedAround.java @@ -52,7 +52,7 @@ public final class FloggerPassedAround extends BugChecker implements MethodTreeM public Description matchMethod(MethodTree tree, VisitorState state) { for (Tree parameter : tree.getParameters()) { Type type = getType(parameter); - if (type != null && LOGGER_TYPE.apply(type, state) && !isSuppressed(parameter)) { + if (type != null && LOGGER_TYPE.apply(type, state) && !isSuppressed(parameter, state)) { state.reportMatch(describeMatch(parameter)); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/InlineFormatString.java b/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/InlineFormatString.java index 2d76aacf41e..4df787d5fdc 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/InlineFormatString.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/InlineFormatString.java @@ -172,7 +172,7 @@ private void handle(Tree tree) { }, null); // find the field declarations - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitVariable(VariableTree tree, Void unused) { VarSymbol sym = getSymbol(tree); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/AlmostJavadoc.java b/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/AlmostJavadoc.java index aea5a552d03..e876968388f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/AlmostJavadoc.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/javadoc/AlmostJavadoc.java @@ -123,7 +123,7 @@ private static Optional generateFix(Comment comment) { private ImmutableMap getJavadocableTrees( CompilationUnitTree tree, VisitorState state) { Map javadoccablePositions = new HashMap<>(); - new SuppressibleTreePathScanner() { + new SuppressibleTreePathScanner(state) { @Override public Void visitClass(ClassTree classTree, Void unused) { if (!shouldMatch()) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ReturnMissingNullable.java b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ReturnMissingNullable.java index ee876be351f..111e9981faa 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ReturnMissingNullable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/nullness/ReturnMissingNullable.java @@ -372,7 +372,7 @@ && methodCanBeOverridden(method)) { @Override public Void scan(Tree tree, Void unused) { - if (isSuppressed(tree)) { + if (isSuppressed(tree, stateForCompilationUnit)) { return null; } return super.scan(tree, unused); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/overloading/InconsistentOverloads.java b/core/src/main/java/com/google/errorprone/bugpatterns/overloading/InconsistentOverloads.java index 658a6172e8c..66d9072741e 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/overloading/InconsistentOverloads.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/overloading/InconsistentOverloads.java @@ -68,7 +68,7 @@ public final class InconsistentOverloads extends BugChecker implements ClassTree @Override public Description matchClass(ClassTree classTree, VisitorState state) { - processClassMethods(getClassTreeMethods(classTree), state); + processClassMethods(getClassTreeMethods(classTree, state), state); /* * We want to report inconsistencies per method group. There is no "method group" unit in the @@ -142,12 +142,12 @@ private static Collection> getMethodGroups(List cla *

Only method trees that belong to the {@code classTree} are returned, so methods declared in * nested classes are not going to be considered. */ - private ImmutableList getClassTreeMethods(ClassTree classTree) { + private ImmutableList getClassTreeMethods(ClassTree classTree, VisitorState state) { List members = classTree.getMembers(); return members.stream() .filter(MethodTree.class::isInstance) .map(MethodTree.class::cast) - .filter(m -> !isSuppressed(m)) + .filter(m -> !isSuppressed(m, state)) .collect(toImmutableList()); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByChecker.java index 1e00315c028..cbed17f6986 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/GuardedByChecker.java @@ -85,7 +85,7 @@ private void analyze(VisitorState state) { state, (ExpressionTree tree, GuardedByExpression guard, HeldLockSet live) -> report(GuardedByChecker.this.checkGuardedAccess(tree, guard, live, state), state), - this::isSuppressed, + tree1 -> isSuppressed(tree1, state), flags, reportMissingGuards); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableAnalysis.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableAnalysis.java index 9357562fef1..9a3557a5252 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableAnalysis.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableAnalysis.java @@ -264,7 +264,7 @@ private Violation isFieldImmutable( ClassType classType, VarSymbol var, ViolationReporter reporter) { - if (bugChecker.isSuppressed(var)) { + if (bugChecker.isSuppressed(var, state)) { return Violation.absent(); } if (!var.getModifiers().contains(Modifier.FINAL)