diff --git a/check_api/src/main/java/com/google/errorprone/util/AnnotationNames.java b/check_api/src/main/java/com/google/errorprone/util/AnnotationNames.java new file mode 100644 index 00000000000..a11be602ee9 --- /dev/null +++ b/check_api/src/main/java/com/google/errorprone/util/AnnotationNames.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 The Error Prone Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.errorprone.util; + +/** Fully qualified names of common annotations used in ErrorProne checks. */ +public final class AnnotationNames { + + // keep-sorted start + + public static final String AFTER_TEMPLATE_ANNOTATION = + "com.google.errorprone.refaster.annotation.AfterTemplate"; + public static final String BEFORE_TEMPLATE_ANNOTATION = + "com.google.errorprone.refaster.annotation.BeforeTemplate"; + public static final String BUG_PATTERN_ANNOTATION = "com.google.errorprone.BugPattern"; + public static final String CAN_IGNORE_RETURN_VALUE_ANNOTATION = + "com.google.errorprone.annotations.CanIgnoreReturnValue"; + public static final String COMPATIBLE_WITH_ANNOTATION = + "com.google.errorprone.annotations.CompatibleWith"; + public static final String DO_NOT_CALL_ANNOTATION = "com.google.errorprone.annotations.DoNotCall"; + public static final String FORMAT_METHOD_ANNOTATION = + "com.google.errorprone.annotations.FormatMethod"; + public static final String FORMAT_STRING_ANNOTATION = + "com.google.errorprone.annotations.FormatString"; + public static final String IMMUTABLE_ANNOTATION = "com.google.errorprone.annotations.Immutable"; + public static final String LAZY_INIT_ANNOTATION = + "com.google.errorprone.annotations.concurrent.LazyInit"; + public static final String MUST_BE_CLOSED_ANNOTATION = + "com.google.errorprone.annotations.MustBeClosed"; + public static final String REPEATED_ANNOTATION = + "com.google.errorprone.refaster.annotation.Repeated"; + public static final String RESTRICTED_API_ANNOTATION = + "com.google.errorprone.annotations.RestrictedApi"; + public static final String THREAD_SAFE_ANNOTATION = + "com.google.errorprone.annotations.ThreadSafe"; + public static final String VAR_ANNOTATION = "com.google.errorprone.annotations.Var"; + + // keep-sorted end + + private AnnotationNames() {} +} diff --git a/check_api/src/test/java/com/google/errorprone/util/ASTHelpersTest.java b/check_api/src/test/java/com/google/errorprone/util/ASTHelpersTest.java index 699c56524f3..cbd5030b4c9 100644 --- a/check_api/src/test/java/com/google/errorprone/util/ASTHelpersTest.java +++ b/check_api/src/test/java/com/google/errorprone/util/ASTHelpersTest.java @@ -22,6 +22,7 @@ import static com.google.errorprone.BugPattern.SeverityLevel.ERROR; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.util.ASTHelpers.getStartPosition; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.LOCAL_VARIABLE; import static java.lang.annotation.ElementType.METHOD; @@ -312,7 +313,8 @@ public Void visitClass(ClassTree tree, VisitorState state) { new Matcher() { @Override public boolean matches(ClassTree t, VisitorState state) { - return ASTHelpers.hasAnnotation(t, InheritedAnnotation.class, state); + return hasAnnotation( + t, "com.google.errorprone.util.InheritedAnnotation", state); } }); setAssertionsComplete(); @@ -333,9 +335,7 @@ public void annotationHelpersWrongValueCached() { @Override public Void visitClass(ClassTree tree, VisitorState state) { if (tree.getSimpleName().contentEquals("D")) { - assertThat( - ASTHelpers.hasAnnotation( - tree, "TestAnnotation", state.withPath(getCurrentPath()))) + assertThat(hasAnnotation(tree, "TestAnnotation", state.withPath(getCurrentPath()))) .isFalse(); setAssertionsComplete(); } @@ -371,7 +371,7 @@ public Void visitClass(ClassTree tree, VisitorState state) { new Matcher() { @Override public boolean matches(ClassTree t, VisitorState state) { - return ASTHelpers.hasAnnotation(t, "TestAnnotation", state); + return hasAnnotation(t, "TestAnnotation", state); } }); setAssertionsComplete(); @@ -413,7 +413,7 @@ public Void visitMethod(MethodTree tree, VisitorState state) { tree, state, (MethodTree t, VisitorState s) -> - ASTHelpers.hasAnnotation(t, InheritedAnnotation.class, s)); + hasAnnotation(t, "com.google.errorprone.util.InheritedAnnotation", s)); setAssertionsComplete(); } return super.visitMethod(tree, state); @@ -454,8 +454,7 @@ public Void visitClass(ClassTree tree, VisitorState state) { new Matcher() { @Override public boolean matches(ClassTree t, VisitorState state) { - return ASTHelpers.hasAnnotation( - ASTHelpers.getSymbol(t), "test.Lib$MyAnnotation", state); + return hasAnnotation(ASTHelpers.getSymbol(t), "test.Lib$MyAnnotation", state); } }); setAssertionsComplete(); @@ -911,7 +910,7 @@ public class A { public Void visitMethodInvocation(MethodInvocationTree tree, VisitorState state) { if (ASTHelpers.getSymbol(tree).toString().equals("doIt()")) { setAssertionsComplete(); - assertThat(ASTHelpers.hasAnnotation(tree, Deprecated.class, state)).isFalse(); + assertThat(hasAnnotation(tree, Deprecated.class.getName(), state)).isFalse(); } return super.visitMethodInvocation(tree, state); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/AnnotateFormatMethod.java b/core/src/main/java/com/google/errorprone/bugpatterns/AnnotateFormatMethod.java index 518a69c4543..d7486f7cfa1 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/AnnotateFormatMethod.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/AnnotateFormatMethod.java @@ -23,10 +23,11 @@ import static com.google.errorprone.matchers.method.MethodMatchers.instanceMethod; import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod; import static com.google.errorprone.util.ASTHelpers.getReceiver; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.FORMAT_METHOD_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.FormatMethod; import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.matchers.Matcher; @@ -43,7 +44,7 @@ /** * Detects occurrences of pairs of parameters being passed straight through to {@link String#format} - * from a method not annotated with {@link FormatMethod}. + * from a method not annotated with {@link com.google.errorprone.annotations.FormatMethod}. * * @author ghm@google.com (Graeme Morgan) */ @@ -90,7 +91,7 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState MethodTree enclosingMethod = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class); if (enclosingMethod == null || !ASTHelpers.getSymbol(enclosingMethod).isVarArgs() - || ASTHelpers.hasAnnotation(enclosingMethod, FormatMethod.class, state)) { + || hasAnnotation(enclosingMethod, FORMAT_METHOD_ANNOTATION, state)) { return Description.NO_MATCH; } List enclosingParameters = enclosingMethod.getParameters(); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DeprecatedVariable.java b/core/src/main/java/com/google/errorprone/bugpatterns/DeprecatedVariable.java index 9268a2b92fa..35d4516c51c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DeprecatedVariable.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DeprecatedVariable.java @@ -19,6 +19,7 @@ import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.matchers.Description.NO_MATCH; import static com.google.errorprone.util.ASTHelpers.getAnnotationWithSimpleName; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; @@ -38,7 +39,7 @@ public class DeprecatedVariable extends BugChecker implements VariableTreeMatche @Override public Description matchVariable(VariableTree tree, VisitorState state) { Symbol.VarSymbol sym = ASTHelpers.getSymbol(tree); - if (!ASTHelpers.hasAnnotation(sym, Deprecated.class, state)) { + if (!hasAnnotation(sym, Deprecated.class.getName(), state)) { return NO_MATCH; } switch (sym.getKind()) { diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/FutureReturnValueIgnored.java b/core/src/main/java/com/google/errorprone/bugpatterns/FutureReturnValueIgnored.java index 42c607550be..e2b15766643 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/FutureReturnValueIgnored.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/FutureReturnValueIgnored.java @@ -20,11 +20,11 @@ import static com.google.errorprone.matchers.Matchers.anyOf; import static com.google.errorprone.matchers.method.MethodMatchers.instanceMethod; import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.CAN_IGNORE_RETURN_VALUE_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.BugPattern.StandardTags; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.bugpatterns.BugChecker.ReturnTreeMatcher; import com.google.errorprone.bugpatterns.threadsafety.ConstantExpressions; import com.google.errorprone.matchers.Matcher; @@ -104,14 +104,14 @@ public boolean matches(ExpressionTree tree, VisitorState state) { ASTHelpers.getUpperBound(resultType, state.getTypes()), futureType, state); } MethodSymbol sym = (MethodSymbol) untypedSymbol; - if (hasAnnotation(sym, CanIgnoreReturnValue.class, state)) { + if (hasAnnotation(sym, CAN_IGNORE_RETURN_VALUE_ANNOTATION, state)) { return false; } for (MethodSymbol superSym : ASTHelpers.findSuperMethods(sym, state.getTypes())) { // There are interfaces annotated with @CanIgnoreReturnValue (like Guava's Function) // whose return value really shouldn't be ignored - as a heuristic, check if the super's // method is returning a future subtype. - if (hasAnnotation(superSym, CanIgnoreReturnValue.class, state) + if (hasAnnotation(superSym, CAN_IGNORE_RETURN_VALUE_ANNOTATION, state) && ASTHelpers.isSubtype( ASTHelpers.getUpperBound(superSym.getReturnType(), state.getTypes()), futureType, 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 3c28aea1744..b5aa7e18c9b 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableMemberCollection.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/ImmutableMemberCollection.java @@ -16,7 +16,6 @@ package com.google.errorprone.bugpatterns; import static com.google.common.collect.ImmutableMap.toImmutableMap; -import static com.google.common.collect.Streams.stream; import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION; import static com.google.errorprone.matchers.Matchers.allOf; import static com.google.errorprone.matchers.Matchers.anyOf; @@ -128,7 +127,7 @@ public Description matchClass(ClassTree classTree, VisitorState state) { .filter(member -> !EXCLUSIONS.matches(member, state)) .filter(member -> !isSuppressed(member, state)) .map(VariableTree.class::cast) - .flatMap(varTree -> stream(isReplaceable(varTree, state))) + .flatMap(varTree -> isReplaceable(varTree, state).stream()) .collect(toImmutableMap(ReplaceableVar::symbol, var -> var)); if (replaceableVars.isEmpty()) { return Description.NO_MATCH; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/InjectOnBugCheckers.java b/core/src/main/java/com/google/errorprone/bugpatterns/InjectOnBugCheckers.java index f5cb7a386cb..9b95abbcaef 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/InjectOnBugCheckers.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/InjectOnBugCheckers.java @@ -25,6 +25,7 @@ import static com.google.errorprone.util.ASTHelpers.hasDirectAnnotationWithSimpleName; import static com.google.errorprone.util.ASTHelpers.isGeneratedConstructor; import static com.google.errorprone.util.ASTHelpers.isSubtype; +import static com.google.errorprone.util.AnnotationNames.BUG_PATTERN_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.ErrorProneFlags; @@ -51,7 +52,7 @@ public Description matchMethod(MethodTree tree, VisitorState state) { } if (!isSubtype( symbol.owner.type, state.getTypeFromString(BugChecker.class.getCanonicalName()), state) - || !hasAnnotation(symbol.owner, BugPattern.class, state)) { + || !hasAnnotation(symbol.owner, BUG_PATTERN_ANNOTATION, state)) { return NO_MATCH; } if (tree.getParameters().isEmpty() diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MissingOverride.java b/core/src/main/java/com/google/errorprone/bugpatterns/MissingOverride.java index 1b7a853166a..c4a1b76e857 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MissingOverride.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MissingOverride.java @@ -60,7 +60,7 @@ public Description matchMethod(MethodTree tree, VisitorState state) { if (sym.isStatic()) { return NO_MATCH; } - if (hasAnnotation(sym, Override.class, state)) { + if (hasAnnotation(sym, Override.class.getName(), state)) { return NO_MATCH; } if (ignoreInterfaceOverrides && sym.enclClass().isInterface()) { @@ -91,7 +91,7 @@ public Description matchMethod(MethodTree tree, VisitorState state) { .filter(unused -> ASTHelpers.getGeneratedBy(state).isEmpty()) // to allow deprecated methods to be removed non-atomically, we permit overrides of // @Deprecated to skip the annotation - .filter(override -> !hasAnnotation(override, Deprecated.class, state)) + .filter(override -> !hasAnnotation(override, Deprecated.class.getName(), state)) .map( override -> buildDescription(tree) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/MustBeClosedChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/MustBeClosedChecker.java index a4323fcbcd6..18713bc152a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/MustBeClosedChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/MustBeClosedChecker.java @@ -24,10 +24,11 @@ import static com.google.errorprone.matchers.Matchers.methodIsConstructor; import static com.google.errorprone.matchers.Matchers.methodReturns; import static com.google.errorprone.matchers.Matchers.not; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.MUST_BE_CLOSED_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.MustBeClosed; import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher; import com.google.errorprone.fixes.SuggestedFix; @@ -68,7 +69,7 @@ public class MustBeClosedChecker extends AbstractMustBeClosedChecker allOf(methodIsConstructor(), enclosingClass(isSubtypeOf(AutoCloseable.class))); /** - * Check that the {@link MustBeClosed} annotation is only used for constructors of AutoCloseables + * Check that the {@code MustBeClosed} annotation is only used for constructors of AutoCloseables * and methods that return an AutoCloseable. */ @Override @@ -125,7 +126,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { MethodTree methodTree = (MethodTree) member; if (!ASTHelpers.getSymbol(methodTree).isConstructor() - || ASTHelpers.hasAnnotation(methodTree, MustBeClosed.class, state) + || hasAnnotation(methodTree, MUST_BE_CLOSED_ANNOTATION, state) || !invokedConstructorMustBeClosed(state, methodTree)) { continue; } @@ -141,7 +142,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { SuggestedFix.Builder builder = SuggestedFix.builder(); String suggestedFixName = SuggestedFixes.qualifyType( - state, builder, state.getTypeFromString(MustBeClosed.class.getCanonicalName())); + state, builder, state.getTypeFromString(MUST_BE_CLOSED_ANNOTATION)); SuggestedFix fix = builder.prefixWith(methodTree, "@" + suggestedFixName + " ").build(); state.reportMatch( @@ -167,6 +168,6 @@ private static boolean invokedConstructorMustBeClosed(VisitorState state, Method ExpressionStatementTree est = (ExpressionStatementTree) statements.get(0); MethodInvocationTree mit = (MethodInvocationTree) est.getExpression(); MethodSymbol invokedConstructorSymbol = ASTHelpers.getSymbol(mit); - return ASTHelpers.hasAnnotation(invokedConstructorSymbol, MustBeClosed.class, state); + return hasAnnotation(invokedConstructorSymbol, MUST_BE_CLOSED_ANNOTATION, state); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/OrphanedFormatString.java b/core/src/main/java/com/google/errorprone/bugpatterns/OrphanedFormatString.java index c67726b2511..a62a43119f5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/OrphanedFormatString.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/OrphanedFormatString.java @@ -28,11 +28,11 @@ import static com.google.errorprone.util.ASTHelpers.getReceiverType; import static com.google.errorprone.util.ASTHelpers.getSymbol; import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.FORMAT_METHOD_ANNOTATION; +import static com.google.errorprone.util.AnnotationNames.FORMAT_STRING_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.FormatMethod; -import com.google.errorprone.annotations.FormatString; import com.google.errorprone.bugpatterns.BugChecker.LiteralTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.matchers.Matcher; @@ -89,9 +89,10 @@ public class OrphanedFormatString extends BugChecker implements LiteralTreeMatch && !findMatchingMethods( getSymbol(t).name, ms -> - hasAnnotation(ms, FormatMethod.class, s) + hasAnnotation(ms, FORMAT_METHOD_ANNOTATION, s) || ms.getParameters().stream() - .anyMatch(vs -> hasAnnotation(vs, FormatString.class, s)), + .anyMatch( + vs -> hasAnnotation(vs, FORMAT_STRING_ANNOTATION, s)), getReceiverType(t), s.getTypes()) .isEmpty())); @@ -123,7 +124,7 @@ && literalIsFormatMethodArg(tree, (MethodInvocationTree) methodInvocation, state private static boolean literalIsFormatMethodArg( LiteralTree tree, MethodInvocationTree methodInvocationTree, VisitorState state) { MethodSymbol symbol = getSymbol(methodInvocationTree); - if (hasAnnotation(symbol, FormatMethod.class, state)) { + if (hasAnnotation(symbol, FORMAT_METHOD_ANNOTATION, state)) { int indexOfParam = findIndexOfFormatStringParameter(state, symbol); if (indexOfParam != -1) { List args = methodInvocationTree.getArguments(); @@ -142,7 +143,7 @@ private static int findIndexOfFormatStringParameter(VisitorState state, MethodSy List params = symbol.params(); for (int i = 0; i < params.size(); i++) { VarSymbol varSymbol = params.get(i); - if (hasAnnotation(varSymbol, FormatString.class, state)) { + if (hasAnnotation(varSymbol, FORMAT_STRING_ANNOTATION, state)) { return i; } if (indexOfFirstString == -1 diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/PackageLocation.java b/core/src/main/java/com/google/errorprone/bugpatterns/PackageLocation.java index aa421840f62..a50984d358f 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/PackageLocation.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/PackageLocation.java @@ -17,6 +17,7 @@ package com.google.errorprone.bugpatterns; import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static java.lang.Math.max; import com.google.common.base.Joiner; @@ -54,7 +55,8 @@ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState s // package-info annotations are special // TODO(cushon): fix the core suppression logic to handle this - if (ASTHelpers.hasAnnotation(tree.getPackage(), SuppressPackageLocation.class, state)) { + if (hasAnnotation( + tree.getPackage(), "com.google.errorprone.annotations.SuppressPackageLocation", state)) { return Description.NO_MATCH; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/RestrictedApiChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/RestrictedApiChecker.java index 3490497d2dd..67aef99644a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/RestrictedApiChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/RestrictedApiChecker.java @@ -21,7 +21,9 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.errorprone.matchers.Description.NO_MATCH; import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.streamSuperMethods; +import static com.google.errorprone.util.AnnotationNames.RESTRICTED_API_ANNOTATION; import com.google.common.collect.ImmutableSet; import com.google.errorprone.BugPattern; @@ -80,7 +82,7 @@ public class RestrictedApiChecker extends BugChecker @Override public Description matchAnnotation(AnnotationTree tree, VisitorState state) { // TODO(bangert): Validate all the fields - if (!getSymbol(tree).getQualifiedName().contentEquals(RestrictedApi.class.getName())) { + if (!getSymbol(tree).getQualifiedName().contentEquals(RESTRICTED_API_ANNOTATION)) { return NO_MATCH; } // TODO(bangert): make a more elegant API to get the annotation within an annotation tree. @@ -185,7 +187,7 @@ private Description checkMethodUse( // Try each super method for @RestrictedApi return streamSuperMethods(method, state.getTypes()) - .filter((t) -> ASTHelpers.hasAnnotation(t, RestrictedApi.class, state)) + .filter((t) -> hasAnnotation(t, RESTRICTED_API_ANNOTATION, state)) .findFirst() .map( superWithRestrictedApi -> @@ -199,7 +201,7 @@ private Description checkMethodUse( if (sym == null) { return null; } - return sym.attribute(state.getSymbolFromString(RestrictedApi.class.getName())); + return sym.attribute(state.getSymbolFromString(RESTRICTED_API_ANNOTATION)); } private Description checkRestriction( diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/RxReturnValueIgnored.java b/core/src/main/java/com/google/errorprone/bugpatterns/RxReturnValueIgnored.java index 62d552bb54c..8d021e3de90 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/RxReturnValueIgnored.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/RxReturnValueIgnored.java @@ -23,10 +23,10 @@ import static com.google.errorprone.util.ASTHelpers.getSymbol; import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.streamSuperMethods; +import static com.google.errorprone.util.AnnotationNames.CAN_IGNORE_RETURN_VALUE_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.bugpatterns.threadsafety.ConstantExpressions; import com.google.errorprone.matchers.Description; import com.google.errorprone.matchers.Matcher; @@ -53,6 +53,7 @@ + "observables may never execute. It also means the error case is not being handled", severity = WARNING) public final class RxReturnValueIgnored extends AbstractReturnValueIgnored { + private static boolean hasCirvAnnotation(ExpressionTree tree, VisitorState state) { Symbol untypedSymbol = getSymbol(tree); if (!(untypedSymbol instanceof MethodSymbol)) { @@ -61,7 +62,7 @@ private static boolean hasCirvAnnotation(ExpressionTree tree, VisitorState state MethodSymbol sym = (MethodSymbol) untypedSymbol; // Directly has @CanIgnoreReturnValue - if (ASTHelpers.hasAnnotation(sym, CanIgnoreReturnValue.class, state)) { + if (hasAnnotation(sym, CAN_IGNORE_RETURN_VALUE_ANNOTATION, state)) { return true; } @@ -72,7 +73,7 @@ private static boolean hasCirvAnnotation(ExpressionTree tree, VisitorState state return streamSuperMethods(sym, state.getTypes()) .anyMatch( superSym -> - hasAnnotation(superSym, CanIgnoreReturnValue.class, state) + hasAnnotation(superSym, CAN_IGNORE_RETURN_VALUE_ANNOTATION, state) && superSym.getReturnType().tsym.equals(sym.getReturnType().tsym)); } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java index 1d8d5321ded..d543c420f2c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java @@ -18,11 +18,12 @@ import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.util.ASTHelpers.getAnnotationWithSimpleName; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.isConsideredFinal; +import static com.google.errorprone.util.AnnotationNames.VAR_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.Var; import com.google.errorprone.bugpatterns.BugChecker.VariableTreeMatcher; import com.google.errorprone.fixes.Fix; import com.google.errorprone.fixes.SuggestedFix; @@ -55,7 +56,7 @@ public class VarChecker extends BugChecker implements VariableTreeMatcher { @Override public Description matchVariable(VariableTree tree, VisitorState state) { Symbol sym = ASTHelpers.getSymbol(tree); - if (ASTHelpers.hasAnnotation(sym, Var.class, state)) { + if (hasAnnotation(sym, VAR_ANNOTATION, state)) { if ((sym.flags() & Flags.EFFECTIVELY_FINAL) != 0) { return buildDescription(tree) .setMessage("@Var variable is never modified") @@ -118,6 +119,6 @@ private Description handleLocalOrParam(VariableTree tree, VisitorState state, Sy } private static Fix addVarAnnotation(VariableTree tree) { - return SuggestedFix.builder().prefixWith(tree, "@Var ").addImport(Var.class.getName()).build(); + return SuggestedFix.builder().prefixWith(tree, "@Var ").addImport(VAR_ANNOTATION).build(); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiffChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiffChecker.java index e8e484fd6a7..94d22cabf18 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiffChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/ApiDiffChecker.java @@ -17,6 +17,7 @@ package com.google.errorprone.bugpatterns.apidiff; import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import com.google.errorprone.VisitorState; import com.google.errorprone.bugpatterns.BugChecker; @@ -117,7 +118,7 @@ private boolean classOrEnclosingClassIsForbiddenByAnnotation(Symbol clazz, Visit private boolean hasAnnotationForbiddingUse(Symbol sym, VisitorState state) { return alsoForbidApisAnnotated.isPresent() - && ASTHelpers.hasAnnotation(sym, alsoForbidApisAnnotated.get(), state); + && hasAnnotation(sym, alsoForbidApisAnnotated.get().getName(), state); } /** diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CompatibleWithMisuse.java b/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CompatibleWithMisuse.java index c72fb33eebe..901b90bf57a 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CompatibleWithMisuse.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/collectionincompatibletype/CompatibleWithMisuse.java @@ -19,13 +19,14 @@ import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.errorprone.BugPattern.SeverityLevel.ERROR; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.COMPATIBLE_WITH_ANNOTATION; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.CompatibleWith; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.AnnotationTreeMatcher; import com.google.errorprone.matchers.Description; @@ -56,7 +57,7 @@ public class CompatibleWithMisuse extends BugChecker implements AnnotationTreeMatcher { private static final Matcher IS_COMPATIBLE_WITH_ANNOTATION = - Matchers.isType(CompatibleWith.class.getCanonicalName()); + Matchers.isType(COMPATIBLE_WITH_ANNOTATION); @Override public Description matchAnnotation(AnnotationTree annoTree, VisitorState state) { @@ -75,7 +76,7 @@ public Description matchAnnotation(AnnotationTree annoTree, VisitorState state) for (MethodSymbol methodSymbol : ASTHelpers.findSuperMethods(declaredMethod, state.getTypes())) { if (methodSymbol.params().stream() - .anyMatch(p -> ASTHelpers.hasAnnotation(p, CompatibleWith.class, state))) { + .anyMatch(p -> hasAnnotation(p, COMPATIBLE_WITH_ANNOTATION, state))) { return describeWithMessage( annoTree, String.format( diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/FormatStringAnnotationChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/FormatStringAnnotationChecker.java index a6ef4360e80..77ec6c72f91 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/FormatStringAnnotationChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/FormatStringAnnotationChecker.java @@ -18,17 +18,19 @@ import static com.google.errorprone.BugPattern.SeverityLevel.ERROR; import static com.google.errorprone.matchers.Description.NO_MATCH; +import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.ASTHelpers.isSameType; +import static com.google.errorprone.util.AnnotationNames.FORMAT_METHOD_ANNOTATION; +import static com.google.errorprone.util.AnnotationNames.FORMAT_STRING_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.FormatMethod; -import com.google.errorprone.annotations.FormatString; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher; import com.google.errorprone.matchers.Description; -import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.MethodTree; @@ -56,7 +58,7 @@ private Description matchInvocation( MethodSymbol symbol, List args, VisitorState state) { - if (!ASTHelpers.hasAnnotation(symbol, FormatMethod.class, state)) { + if (!hasAnnotation(symbol, FORMAT_METHOD_ANNOTATION, state)) { return Description.NO_MATCH; } @@ -83,10 +85,10 @@ private static int formatStringIndex(MethodSymbol symbol, VisitorState state) { int firstStringIndex = -1; for (int i = 0; i < params.size(); i++) { VarSymbol param = params.get(i); - if (ASTHelpers.hasAnnotation(param, FormatString.class, state)) { + if (hasAnnotation(param, FORMAT_STRING_ANNOTATION, state)) { return i; } - if (firstStringIndex < 0 && ASTHelpers.isSameType(param.type, stringType, state)) { + if (firstStringIndex < 0 && isSameType(param.type, stringType, state)) { firstStringIndex = i; } } @@ -95,31 +97,30 @@ private static int formatStringIndex(MethodSymbol symbol, VisitorState state) { @Override public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { - return matchInvocation(tree, ASTHelpers.getSymbol(tree), tree.getArguments(), state); + return matchInvocation(tree, getSymbol(tree), tree.getArguments(), state); } @Override public Description matchNewClass(NewClassTree tree, VisitorState state) { - return matchInvocation(tree, ASTHelpers.getSymbol(tree), tree.getArguments(), state); + return matchInvocation(tree, getSymbol(tree), tree.getArguments(), state); } @Override public Description matchMethod(MethodTree tree, VisitorState state) { Type stringType = state.getSymtab().stringType; - boolean isFormatMethod = - ASTHelpers.hasAnnotation(ASTHelpers.getSymbol(tree), FormatMethod.class, state); + boolean isFormatMethod = hasAnnotation(getSymbol(tree), FORMAT_METHOD_ANNOTATION, state); boolean foundFormatString = false; boolean foundString = false; for (VariableTree param : tree.getParameters()) { - VarSymbol paramSymbol = ASTHelpers.getSymbol(param); - boolean isStringParam = ASTHelpers.isSameType(paramSymbol.type, stringType, state); + VarSymbol paramSymbol = getSymbol(param); + boolean isStringParam = isSameType(paramSymbol.type, stringType, state); if (isStringParam) { foundString = true; } - if (ASTHelpers.hasAnnotation(paramSymbol, FormatString.class, state)) { + if (hasAnnotation(paramSymbol, FORMAT_STRING_ANNOTATION, state)) { if (!isFormatMethod) { return buildDescription(tree) .setMessage( 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 c55baa519b6..9b2be17de84 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 @@ -22,15 +22,16 @@ import static com.google.errorprone.matchers.Matchers.anyOf; import static com.google.errorprone.matchers.Matchers.staticMethod; import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.isSubtype; +import static com.google.errorprone.util.AnnotationNames.FORMAT_METHOD_ANNOTATION; +import static com.google.errorprone.util.AnnotationNames.FORMAT_STRING_ANNOTATION; import com.google.common.collect.ImmutableList; import com.google.common.collect.MultimapBuilder; import com.google.common.collect.SetMultimap; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.FormatMethod; -import com.google.errorprone.annotations.FormatString; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.CompilationUnitTreeMatcher; import com.google.errorprone.fixes.SuggestedFix; @@ -96,7 +97,7 @@ private static boolean secondParameterIsString(ExpressionTree tree, VisitorState private static @Nullable ExpressionTree formatMethodAnnotationArguments( MethodInvocationTree tree, VisitorState state) { MethodSymbol sym = getSymbol(tree); - if (!ASTHelpers.hasAnnotation(sym, FormatMethod.class, state)) { + if (!hasAnnotation(sym, FORMAT_METHOD_ANNOTATION, state)) { return null; } return tree.getArguments().get(formatStringIndex(state, sym)); @@ -106,7 +107,7 @@ private static int formatStringIndex(VisitorState state, MethodSymbol sym) { int idx = 0; List parameters = sym.getParameters(); for (VarSymbol p : parameters) { - if (ASTHelpers.hasAnnotation(p, FormatString.class, state)) { + if (hasAnnotation(p, FORMAT_STRING_ANNOTATION, state)) { return idx; } idx++; diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/StrictFormatStringValidation.java b/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/StrictFormatStringValidation.java index 692d3aa0c1f..ad5ae3dcf84 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/StrictFormatStringValidation.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/formatstring/StrictFormatStringValidation.java @@ -17,16 +17,20 @@ package com.google.errorprone.bugpatterns.formatstring; import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod; +import static com.google.errorprone.util.ASTHelpers.constValue; +import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.getType; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.isConsideredFinal; +import static com.google.errorprone.util.ASTHelpers.isSameType; +import static com.google.errorprone.util.AnnotationNames.FORMAT_METHOD_ANNOTATION; +import static com.google.errorprone.util.AnnotationNames.FORMAT_STRING_ANNOTATION; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.FormatMethod; -import com.google.errorprone.annotations.FormatString; import com.google.errorprone.bugpatterns.formatstring.FormatStringValidation.ValidationResult; import com.google.errorprone.matchers.Matcher; -import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; @@ -72,7 +76,7 @@ public class StrictFormatStringValidation { // The format string is not a compile time constant. Check if it is an @FormatString method // parameter or is in an @FormatMethod method. - Symbol formatStringSymbol = ASTHelpers.getSymbol(formatStringTree); + Symbol formatStringSymbol = getSymbol(formatStringTree); if (!(formatStringSymbol instanceof VarSymbol)) { return ValidationResult.create( String.format( @@ -124,7 +128,7 @@ public class StrictFormatStringValidation { Types types = state.getTypes(); ImmutableList.Builder calleeFormatArgTypesBuilder = ImmutableList.builder(); for (ExpressionTree formatArgExpression : args) { - calleeFormatArgTypesBuilder.add(types.erasure(ASTHelpers.getType(formatArgExpression))); + calleeFormatArgTypesBuilder.add(types.erasure(getType(formatArgExpression))); } ImmutableList calleeFormatArgTypes = calleeFormatArgTypesBuilder.build(); @@ -138,8 +142,7 @@ public class StrictFormatStringValidation { calleeFormatArgTypes.size(), ownerFormatArgTypes.size())); } else { for (int i = 0; i < calleeFormatArgTypes.size(); i++) { - if (!ASTHelpers.isSameType( - ownerFormatArgTypes.get(i), calleeFormatArgTypes.get(i), state)) { + if (!isSameType(ownerFormatArgTypes.get(i), calleeFormatArgTypes.get(i), state)) { return ValidationResult.create( String.format( "The format argument types passed " @@ -178,7 +181,7 @@ private static ValidationResult validateFormatStringVariable( // that case. Symbol owner = formatStringSymbol.owner; TreePath path = TreePath.getPath(state.getPath(), formatStringTree); - while (path != null && ASTHelpers.getSymbol(path.getLeaf()) != owner) { + while (path != null && getSymbol(path.getLeaf()) != owner) { path = path.getParentPath(); } @@ -199,7 +202,7 @@ private static ValidationResult validateFormatStringVariable( new TreeScanner() { @Override public ValidationResult visitVariable(VariableTree node, Void unused) { - if (ASTHelpers.getSymbol(node) == formatStringSymbol) { + if (getSymbol(node) == formatStringSymbol) { if (node.getInitializer() == null) { return ValidationResult.create( String.format( @@ -231,7 +234,7 @@ private static ValidationResult validateStringFromAssignment( ExpressionTree formatStringRhs, List args, VisitorState state) { - String value = ASTHelpers.constValue(formatStringRhs, String.class); + String value = constValue(formatStringRhs, String.class); if (value == null) { return ValidationResult.create( String.format( @@ -261,14 +264,14 @@ private static boolean isFormatStringParameter(Symbol formatString, VisitorState Type stringType = state.getSymtab().stringType; // The input symbol must be a String and a parameter of a @FormatMethod to be a @FormatString. - if (!ASTHelpers.isSameType(formatString.type, stringType, state) + if (!isSameType(formatString.type, stringType, state) || !(formatString.owner instanceof MethodSymbol) - || !ASTHelpers.hasAnnotation(formatString.owner, FormatMethod.class, state)) { + || !hasAnnotation(formatString.owner, FORMAT_METHOD_ANNOTATION, state)) { return false; } // If the format string is annotated @FormatString in a @FormatMethod, it is a format string. - if (ASTHelpers.hasAnnotation(formatString, FormatString.class, state)) { + if (hasAnnotation(formatString, FORMAT_STRING_ANNOTATION, state)) { return true; } @@ -280,12 +283,12 @@ private static boolean isFormatStringParameter(Symbol formatString, VisitorState formatStringFound = true; } - if (ASTHelpers.isSameType(param.type, stringType, state)) { + if (isSameType(param.type, stringType, state)) { // If this is a String parameter before the input Symbol, then the input symbol can't be the // format string since it wasn't annotated @FormatString. if (!formatStringFound) { return false; - } else if (ASTHelpers.hasAnnotation(param, FormatString.class, state)) { + } else if (hasAnnotation(param, FORMAT_STRING_ANNOTATION, state)) { return false; } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/Suggester.java b/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/Suggester.java index 4b4b703d74a..e65b0f81a2d 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/Suggester.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/inlineme/Suggester.java @@ -21,10 +21,10 @@ import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.hasDirectAnnotationWithSimpleName; import static com.google.errorprone.util.ASTHelpers.shouldKeep; +import static com.google.errorprone.util.AnnotationNames.DO_NOT_CALL_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.DoNotCall; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher; import com.google.errorprone.bugpatterns.inlineme.InlinabilityResult.InlineValidationErrorReason; @@ -52,7 +52,7 @@ public final class Suggester extends BugChecker implements MethodTreeMatcher { @Override public Description matchMethod(MethodTree tree, VisitorState state) { // only suggest @InlineMe on @Deprecated APIs - if (!hasAnnotation(tree, Deprecated.class, state)) { + if (!hasAnnotation(tree, Deprecated.class.getName(), state)) { return Description.NO_MATCH; } @@ -62,7 +62,7 @@ public Description matchMethod(MethodTree tree, VisitorState state) { } // if the API is already annotated with @DoNotCall, then return no match - if (hasAnnotation(tree, DoNotCall.class, state)) { + if (hasAnnotation(tree, DO_NOT_CALL_ANNOTATION, state)) { return Description.NO_MATCH; } @@ -71,7 +71,7 @@ public Description matchMethod(MethodTree tree, VisitorState state) { return Description.NO_MATCH; } - // if the body is not inlineable, then return no match + // if the body is not inlinable, then return no match InlinabilityResult inlinabilityResult = InlinabilityResult.forMethod(tree, state); if (!inlinabilityResult.isValidForSuggester()) { return Description.NO_MATCH; 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 fbfb7c3813e..072791d007b 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 @@ -16,14 +16,15 @@ package com.google.errorprone.bugpatterns.threadsafety; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.isStatic; +import static com.google.errorprone.util.AnnotationNames.LAZY_INIT_ANNOTATION; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.errorprone.VisitorState; import com.google.errorprone.annotations.CheckReturnValue; import com.google.errorprone.annotations.ImmutableTypeParameter; -import com.google.errorprone.annotations.concurrent.LazyInit; import com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Purpose; import com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation; import com.google.errorprone.fixes.SuggestedFix; @@ -255,7 +256,7 @@ Violation isFieldImmutable( return Violation.absent(); } if (!var.getModifiers().contains(Modifier.FINAL) - && !ASTHelpers.hasAnnotation(var, LazyInit.class, state)) { + && !hasAnnotation(var, LAZY_INIT_ANNOTATION, state)) { Violation info = Violation.of( diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableAnnotationChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableAnnotationChecker.java index 8c6213dd5cd..ef32cbac8fa 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableAnnotationChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableAnnotationChecker.java @@ -21,12 +21,13 @@ import static com.google.errorprone.util.ASTHelpers.getGeneratedBy; import static com.google.errorprone.util.ASTHelpers.getSymbol; import static com.google.errorprone.util.ASTHelpers.getType; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.IMMUTABLE_ANNOTATION; import com.google.common.collect.ImmutableSet; import com.google.errorprone.BugPattern; import com.google.errorprone.BugPattern.StandardTags; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.Immutable; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher; import com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation; @@ -74,7 +75,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { return NO_MATCH; } - if (ASTHelpers.hasAnnotation(symbol, Immutable.class, state)) { + if (hasAnnotation(symbol, IMMUTABLE_ANNOTATION, state)) { AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Immutable"); if (annotation != null) { @@ -93,7 +94,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { this::isSuppressed, state, wellKnownMutability, - ImmutableSet.of(Immutable.class.getName())) + ImmutableSet.of(IMMUTABLE_ANNOTATION)) .checkForImmutability( Optional.of(tree), ImmutableSet.of(), getType(tree), this::describeClass); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableEnumChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableEnumChecker.java index 12a5965c6eb..27be68437d5 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableEnumChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ImmutableEnumChecker.java @@ -20,12 +20,13 @@ import static com.google.errorprone.matchers.Description.NO_MATCH; import static com.google.errorprone.util.ASTHelpers.getSymbol; import static com.google.errorprone.util.ASTHelpers.getType; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.IMMUTABLE_ANNOTATION; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Streams; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.Immutable; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher; import com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation; @@ -67,7 +68,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { return NO_MATCH; } - if (ASTHelpers.hasAnnotation(symbol, Immutable.class, state) + if (hasAnnotation(symbol, IMMUTABLE_ANNOTATION, state) && !implementsExemptInterface(symbol, state)) { AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Immutable"); @@ -87,7 +88,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { this::isSuppressed, state, wellKnownMutability, - ImmutableSet.of(Immutable.class.getName())) + ImmutableSet.of(IMMUTABLE_ANNOTATION)) .checkForImmutability( Optional.of(tree), ImmutableSet.of(), getType(tree), this::describe); @@ -109,10 +110,10 @@ private static boolean implementsExemptInterface(ClassSymbol symbol, VisitorStat } private static final ImmutableSet EXEMPT_ANNOTATIONS = - ImmutableSet.of("com.google.errorprone.annotations.Immutable"); + ImmutableSet.of(IMMUTABLE_ANNOTATION); private static boolean hasExemptAnnotation(Symbol symbol, VisitorState state) { return EXEMPT_ANNOTATIONS.stream() - .anyMatch(annotation -> ASTHelpers.hasAnnotation(symbol, annotation, state)); + .anyMatch(annotation -> hasAnnotation(symbol, annotation, state)); } } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/SynchronizeOnNonFinalField.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/SynchronizeOnNonFinalField.java index 65cd7728d81..4ba1485a680 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/SynchronizeOnNonFinalField.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/SynchronizeOnNonFinalField.java @@ -18,12 +18,13 @@ import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.matchers.Description.NO_MATCH; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.stripParentheses; +import static com.google.errorprone.util.AnnotationNames.LAZY_INIT_ANNOTATION; import com.google.errorprone.BugPattern; import com.google.errorprone.BugPattern.StandardTags; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.concurrent.LazyInit; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.matchers.Description; import com.google.errorprone.util.ASTHelpers; @@ -60,7 +61,7 @@ public Description matchSynchronized(SynchronizedTree tree, VisitorState state) || (varSymbol.flags() & Flags.FINAL) != 0) { return NO_MATCH; } - if (ASTHelpers.hasAnnotation(varSymbol, LazyInit.class, state)) { + if (hasAnnotation(varSymbol, LAZY_INIT_ANNOTATION, state)) { return NO_MATCH; } diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeAnalysis.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeAnalysis.java index 9a91ca78cf9..959e1b16caa 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeAnalysis.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeAnalysis.java @@ -16,10 +16,12 @@ package com.google.errorprone.bugpatterns.threadsafety; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.LAZY_INIT_ANNOTATION; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.concurrent.LazyInit; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation; import com.google.errorprone.fixes.SuggestedFixes; @@ -213,7 +215,7 @@ private Violation isFieldThreadSafe( VarSymbol var) { if (bugChecker.isSuppressed(var) || bugChecker.customSuppressionAnnotations().stream() - .map(a -> ASTHelpers.hasAnnotation(var, a, state)) + .map(a -> hasAnnotation(var, a.getName(), state)) .anyMatch(v -> v)) { return Violation.absent(); } @@ -225,7 +227,7 @@ private Violation isFieldThreadSafe( } if (!var.getModifiers().contains(Modifier.FINAL) - && !ASTHelpers.hasAnnotation(var, LazyInit.class, state)) { + && !hasAnnotation(var, LAZY_INIT_ANNOTATION, state)) { return processModifier(tree, classSym, var, Modifier.FINAL, "'%s' has non-final field '%s'"); } Type varType = state.getTypes().memberType(classType, var); diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeChecker.java index 3df20109a25..fd6475cdc51 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/threadsafety/ThreadSafeChecker.java @@ -19,6 +19,10 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.errorprone.BugPattern.SeverityLevel.ERROR; import static com.google.errorprone.matchers.Description.NO_MATCH; +import static com.google.errorprone.util.ASTHelpers.getSymbol; +import static com.google.errorprone.util.ASTHelpers.getType; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.THREAD_SAFE_ANNOTATION; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; @@ -26,8 +30,6 @@ import com.google.common.collect.Sets.SetView; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; -import com.google.errorprone.annotations.Immutable; -import com.google.errorprone.annotations.ThreadSafe; import com.google.errorprone.bugpatterns.BugChecker; import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher; import com.google.errorprone.bugpatterns.BugChecker.MemberReferenceTreeMatcher; @@ -38,7 +40,6 @@ import com.google.errorprone.fixes.SuggestedFix; import com.google.errorprone.fixes.SuggestedFixes; import com.google.errorprone.matchers.Description; -import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ClassTree; import com.sun.source.tree.MemberReferenceTree; import com.sun.source.tree.MethodInvocationTree; @@ -84,16 +85,14 @@ public class ThreadSafeChecker extends BugChecker // check instantiations of `@ThreadSafe`s in method references @Override public Description matchMemberReference(MemberReferenceTree tree, VisitorState state) { - checkInvocation( - tree, ((JCMemberReference) tree).referentType, state, ASTHelpers.getSymbol(tree)); + checkInvocation(tree, ((JCMemberReference) tree).referentType, state, getSymbol(tree)); return NO_MATCH; } // check instantiations of `@ThreadSafe`s in method invocations @Override public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { - checkInvocation( - tree, ASTHelpers.getType(tree.getMethodSelect()), state, ASTHelpers.getSymbol(tree)); + checkInvocation(tree, getType(tree.getMethodSelect()), state, getSymbol(tree)); return NO_MATCH; } @@ -106,8 +105,7 @@ public Description matchNewClass(NewClassTree tree, VisitorState state) { ThreadSafeAnalysis analysis = new ThreadSafeAnalysis(this, state, wellKnownThreadSafety); Violation info = analysis.checkInstantiation( - ASTHelpers.getSymbol(tree.getIdentifier()).getTypeParameters(), - ASTHelpers.getType(tree).getTypeArguments()); + getSymbol(tree.getIdentifier()).getTypeParameters(), getType(tree).getTypeArguments()); if (info.isPresent()) { state.reportMatch(buildDescription(tree).setMessage(info.message()).build()); } @@ -124,7 +122,7 @@ private void checkInvocation(Tree tree, Type methodType, VisitorState state, Sym @Override public Description matchTypeParameter(TypeParameterTree tree, VisitorState state) { - Symbol sym = ASTHelpers.getSymbol(tree); + Symbol sym = getSymbol(tree); if (sym == null) { return NO_MATCH; } @@ -177,8 +175,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { // Check that the types in containerOf actually exist Map typarams = new HashMap<>(); for (TypeParameterTree typaram : tree.getTypeParameters()) { - typarams.put( - typaram.getName().toString(), (TypeVariableSymbol) ASTHelpers.getSymbol(typaram)); + typarams.put(typaram.getName().toString(), (TypeVariableSymbol) getSymbol(typaram)); } SetView difference = Sets.difference(annotation.containerOf(), typarams.keySet()); if (!difference.isEmpty()) { @@ -214,8 +211,8 @@ public Description matchClass(ClassTree tree, VisitorState state) { Violation info = analysis.checkForThreadSafety( Optional.of(tree), - analysis.threadSafeTypeParametersInScope(ASTHelpers.getSymbol(tree)), - ASTHelpers.getType(tree)); + analysis.threadSafeTypeParametersInScope(getSymbol(tree)), + getType(tree)); if (!info.isPresent()) { return NO_MATCH; @@ -231,7 +228,7 @@ public Description matchClass(ClassTree tree, VisitorState state) { /** Check anonymous implementations of {@code @ThreadSafe} types. */ private Description handleAnonymousClass( ClassTree tree, VisitorState state, ThreadSafeAnalysis analysis) { - ClassSymbol sym = ASTHelpers.getSymbol(tree); + ClassSymbol sym = getSymbol(tree); if (sym == null) { return NO_MATCH; } @@ -244,8 +241,7 @@ private Description handleAnonymousClass( // the type arguments will be validated at any type use site where we care about // the instance's threadsafety. ImmutableSet typarams = analysis.threadSafeTypeParametersInScope(sym); - Violation info = - analysis.areFieldsThreadSafe(Optional.of(tree), typarams, ASTHelpers.getType(tree)); + Violation info = analysis.areFieldsThreadSafe(Optional.of(tree), typarams, getType(tree)); if (!info.isPresent()) { return NO_MATCH; } @@ -260,7 +256,7 @@ private Description handleAnonymousClass( /** Check for classes without {@code @ThreadSafe} that have threadsafe supertypes. */ private Description checkSubtype(ClassTree tree, VisitorState state) { - ClassSymbol sym = ASTHelpers.getSymbol(tree); + ClassSymbol sym = getSymbol(tree); if (sym == null) { return NO_MATCH; } @@ -268,7 +264,7 @@ private Description checkSubtype(ClassTree tree, VisitorState state) { if (superType == null) { return NO_MATCH; } - if (ASTHelpers.hasAnnotation(sym, Immutable.class, state)) { + if (hasAnnotation(sym, "com.google.errorprone.annotations.Immutable", state)) { // If the superclass is @ThreadSafe and the subclass is @Immutable, then the subclass is // effectively also @ThreadSafe, and we defer to the @Immutable plugin. return NO_MATCH; @@ -277,7 +273,7 @@ private Description checkSubtype(ClassTree tree, VisitorState state) { String.format( "Class extends @ThreadSafe type %s, but is not annotated as threadsafe", superType); SuggestedFix.Builder fix = SuggestedFix.builder(); - String typeName = SuggestedFixes.qualifyType(state, fix, ThreadSafe.class.getName()); + String typeName = SuggestedFixes.qualifyType(state, fix, THREAD_SAFE_ANNOTATION); fix.prefixWith(tree, "@" + typeName + " "); return buildDescription(tree).setMessage(message).addFix(fix.build()).build(); } @@ -293,7 +289,7 @@ private Description checkSubtype(ClassTree tree, VisitorState state) { } // Don't use getThreadSafeAnnotation here: subtypes of trusted types are // also trusted, only check for explicitly annotated supertypes. - if (ASTHelpers.hasAnnotation(superType.tsym, ThreadSafe.class, state)) { + if (hasAnnotation(superType.tsym, THREAD_SAFE_ANNOTATION, state)) { return superType; } // We currently trust that @interface annotations are threadsafe, but don't enforce that diff --git a/core/src/main/java/com/google/errorprone/refaster/RefasterRuleBuilderScanner.java b/core/src/main/java/com/google/errorprone/refaster/RefasterRuleBuilderScanner.java index 6a939a73307..eb0a4aac774 100644 --- a/core/src/main/java/com/google/errorprone/refaster/RefasterRuleBuilderScanner.java +++ b/core/src/main/java/com/google/errorprone/refaster/RefasterRuleBuilderScanner.java @@ -18,6 +18,9 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; +import static com.google.errorprone.util.AnnotationNames.AFTER_TEMPLATE_ANNOTATION; +import static com.google.errorprone.util.AnnotationNames.BEFORE_TEMPLATE_ANNOTATION; import static java.util.logging.Level.FINE; import com.google.common.collect.ImmutableClassToInstanceMap; @@ -28,11 +31,8 @@ import com.google.errorprone.CodeTransformer; import com.google.errorprone.SubContext; import com.google.errorprone.VisitorState; -import com.google.errorprone.refaster.annotation.AfterTemplate; import com.google.errorprone.refaster.annotation.AllowCodeBetweenLines; import com.google.errorprone.refaster.annotation.AlsoNegation; -import com.google.errorprone.refaster.annotation.BeforeTemplate; -import com.google.errorprone.refaster.annotation.Placeholder; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ClassTree; import com.sun.source.tree.MethodTree; @@ -110,7 +110,7 @@ public Void visitMethod(MethodTree tree, Void v) { try { VisitorState state = new VisitorState(context); logger.log(FINE, "Discovered method with name {0}", tree.getName()); - if (ASTHelpers.hasAnnotation(tree, Placeholder.class, state)) { + if (hasAnnotation(tree, "com.google.errorprone.refaster.annotation.Placeholder", state)) { checkArgument( tree.getModifiers().getFlags().contains(Modifier.ABSTRACT), "@Placeholder methods are expected to be abstract"); @@ -130,14 +130,14 @@ public Void visitMethod(MethodTree tree, Void v) { templater.template(sym.getReturnType()), params.buildOrThrow(), UTemplater.annotationMap(sym))); - } else if (ASTHelpers.hasAnnotation(tree, BeforeTemplate.class, state)) { + } else if (hasAnnotation(tree, BEFORE_TEMPLATE_ANNOTATION, state)) { checkState(afterTemplates.isEmpty(), "BeforeTemplate must come before AfterTemplate"); Template template = UTemplater.createTemplate(context, tree); beforeTemplates.add(template); if (template instanceof BlockTemplate) { context.put(UTemplater.REQUIRE_BLOCK_KEY, /* data= */ true); } - } else if (ASTHelpers.hasAnnotation(tree, AfterTemplate.class, state)) { + } else if (hasAnnotation(tree, AFTER_TEMPLATE_ANNOTATION, state)) { afterTemplates.add(UTemplater.createTemplate(context, tree)); } else if (tree.getModifiers().getFlags().contains(Modifier.ABSTRACT)) { throw new IllegalArgumentException( diff --git a/core/src/main/java/com/google/errorprone/refaster/UTemplater.java b/core/src/main/java/com/google/errorprone/refaster/UTemplater.java index 72fba3491b0..a81a816f002 100644 --- a/core/src/main/java/com/google/errorprone/refaster/UTemplater.java +++ b/core/src/main/java/com/google/errorprone/refaster/UTemplater.java @@ -18,7 +18,9 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; +import static com.google.errorprone.util.ASTHelpers.hasAnnotation; import static com.google.errorprone.util.ASTHelpers.isStatic; +import static com.google.errorprone.util.AnnotationNames.REPEATED_ANNOTATION; import com.google.common.collect.ImmutableClassToInstanceMap; import com.google.common.collect.ImmutableList; @@ -115,7 +117,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; @@ -457,8 +458,7 @@ public UExpression visitMethodInvocation(MethodInvocationTree tree, Void v) { } else if (anyMatch(AS_VARARGS, tree.getMethodSelect(), new Unifier(context))) { ExpressionTree arg = Iterables.getOnlyElement(tree.getArguments()); checkArgument( - ASTHelpers.hasAnnotation( - ASTHelpers.getSymbol(arg), Repeated.class, new VisitorState(context))); + hasAnnotation(ASTHelpers.getSymbol(arg), REPEATED_ANNOTATION, new VisitorState(context))); return template(arg); } Map placeholderMethods =