Search in sources :

Example 6 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project error-prone by google.

the class ASTHelpers method hasSimpleName.

private static boolean hasSimpleName(AnnotationTree annotation, String name) {
    Tree annotationType = annotation.getAnnotationType();
    javax.lang.model.element.Name simpleName;
    if (annotationType instanceof IdentifierTree) {
        simpleName = ((IdentifierTree) annotationType).getName();
    } else if (annotationType instanceof MemberSelectTree) {
        simpleName = ((MemberSelectTree) annotationType).getIdentifier();
    } else {
        return false;
    }
    return simpleName.contentEquals(name);
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) PackageTree(com.sun.source.tree.PackageTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree) IdentifierTree(com.sun.source.tree.IdentifierTree)

Example 7 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project error-prone by google.

the class AbstractJUnit4InitMethodNotRun method matchMethod.

/**
   * Matches if all of the following conditions are true:
   * 1) The method matches {@link #methodMatcher()}, (looks like setUp() or tearDown(),
   *    and none of the overrides in the hierarchy of the method have the appropriate @Before
   *    or @After annotations)
   * 2) The method is not annotated with @Test
   * 3) The enclosing class has an @RunWith annotation and does not extend TestCase. This marks
   *    that the test is intended to run with JUnit 4.
   */
@Override
public Description matchMethod(MethodTree methodTree, VisitorState state) {
    boolean matches = allOf(methodMatcher(), not(hasAnnotationOnAnyOverriddenMethod(JUNIT_TEST)), enclosingClass(isJUnit4TestClass)).matches(methodTree, state);
    if (!matches) {
        return Description.NO_MATCH;
    }
    // For each annotationReplacement, replace the first annotation that matches. If any of them
    // matches, don't try and do the rest of the work.
    Description description;
    for (AnnotationReplacements replacement : annotationReplacements()) {
        description = tryToReplaceAnnotation(methodTree, state, replacement.badAnnotation, replacement.goodAnnotation);
        if (description != null) {
            return description;
        }
    }
    // Search for another @Before annotation on the method and replace the import
    // if we find one
    String correctAnnotation = correctAnnotation();
    String unqualifiedClassName = getUnqualifiedClassName(correctAnnotation);
    for (AnnotationTree annotationNode : methodTree.getModifiers().getAnnotations()) {
        String annotationClassName = ASTHelpers.getSymbol(annotationNode).getQualifiedName().toString();
        if (annotationClassName.endsWith("." + unqualifiedClassName)) {
            SuggestedFix.Builder suggestedFix = SuggestedFix.builder().removeImport(annotationClassName).addImport(correctAnnotation);
            if (makeProtectedPublic(methodTree, state, unqualifiedClassName, suggestedFix, false) == null) {
                // No source position available, don't suggest a fix
                return describeMatch(annotationNode);
            }
            suggestedFix.replace(annotationNode, "@" + unqualifiedClassName);
            return describeMatch(annotationNode, suggestedFix.build());
        }
    }
    // Add correctAnnotation() to the unannotated method
    // (and convert protected to public if it is)
    SuggestedFix.Builder suggestedFix = SuggestedFix.builder().addImport(correctAnnotation);
    // The makeProtectedPublic will take care of adding the annotation for us
    Boolean annotationAdded = makeProtectedPublic(methodTree, state, unqualifiedClassName, suggestedFix, true);
    //
    if (annotationAdded == null) {
        // No source position available, don't suggest a fix
        return describeMatch(methodTree);
    }
    if (!annotationAdded) {
        suggestedFix.prefixWith(methodTree, "@" + unqualifiedClassName + "\n");
    }
    return describeMatch(methodTree, suggestedFix.build());
}
Also used : Description(com.google.errorprone.matchers.Description) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) AnnotationTree(com.sun.source.tree.AnnotationTree)

Example 8 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project error-prone by google.

the class SuggestedFixes method addSuppressWarnings.

/**
   * Modifies {@code fixBuilder} to either create a new {@code @SuppressWarnings} element on the
   * closest suppressible node, or add {@code warningToSuppress} to that node if there's already a
   * {@code SuppressWarnings} annotation there.
   *
   * @see #addSuppressWarnings(VisitorState, String)
   */
public static void addSuppressWarnings(Builder fixBuilder, VisitorState state, String warningToSuppress) {
    // Find the nearest tree to add @SuppressWarnings to.
    Tree suppressibleNode = suppressibleNode(state.getPath());
    if (suppressibleNode == null) {
        return;
    }
    SuppressWarnings existingAnnotation = getAnnotation(suppressibleNode, SuppressWarnings.class);
    // If we have an existing @SuppressWarnings on the element, extend its value
    if (existingAnnotation != null) {
        // Add warning to the existing annotation
        String[] values = existingAnnotation.value();
        if (Arrays.asList(values).contains(warningToSuppress)) {
            // The nearest suppress warnings already contains this thing, so we can't add another thing
            return;
        }
        AnnotationTree suppressAnnotationTree = getAnnotationWithSimpleName(findAnnotationsTree(suppressibleNode), SuppressWarnings.class.getSimpleName());
        if (suppressAnnotationTree == null) {
            // This is weird, bail out
            return;
        }
        fixBuilder.merge(addValuesToAnnotationArgument(suppressAnnotationTree, "value", ImmutableList.of(state.getTreeMaker().Literal(CLASS, warningToSuppress).toString()), state));
    } else {
        // Otherwise, add a suppress annotation to the element
        fixBuilder.prefixWith(suppressibleNode, "@SuppressWarnings(\"" + warningToSuppress + "\")\n");
    }
}
Also used : AssignmentTree(com.sun.source.tree.AssignmentTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) DCTree(com.sun.tools.javac.tree.DCTree) JCTree(com.sun.tools.javac.tree.JCTree) DocTree(com.sun.source.doctree.DocTree) AnnotationTree(com.sun.source.tree.AnnotationTree)

Example 9 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project error-prone by google.

the class RequiredModifiersChecker method matchAnnotation.

@Override
public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
    RequiredModifiers annotation = ASTHelpers.getAnnotation(tree, RequiredModifiers.class);
    if (annotation == null) {
        return Description.NO_MATCH;
    }
    Set<Modifier> requiredModifiers = ImmutableSet.copyOf(annotation.value());
    if (requiredModifiers.isEmpty()) {
        return Description.NO_MATCH;
    }
    Tree parent = state.getPath().getParentPath().getLeaf();
    if (!(parent instanceof ModifiersTree)) {
        // e.g. An annotated package name
        return Description.NO_MATCH;
    }
    Set<Modifier> missing = Sets.difference(requiredModifiers, ((ModifiersTree) parent).getFlags());
    if (missing.isEmpty()) {
        return Description.NO_MATCH;
    }
    String annotationName = ASTHelpers.getAnnotationName(tree);
    String nameString = annotationName != null ? String.format("The annotation '@%s'", annotationName) : "This annotation";
    String customMessage = String.format(MESSAGE_TEMPLATE, nameString, missing.toString());
    return buildDescription(tree).setMessage(customMessage).build();
}
Also used : ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotationTree(com.sun.source.tree.AnnotationTree) ModifiersTree(com.sun.source.tree.ModifiersTree) Tree(com.sun.source.tree.Tree) Modifier(javax.lang.model.element.Modifier) RequiredModifiers(com.google.errorprone.annotations.RequiredModifiers)

Example 10 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project error-prone by google.

the class Util method makeConcreteClassAbstract.

/**
   * Returns a fix that changes a concrete class to an abstract class.
   *
   * <ul>
   * <li>Removes {@code final} if it was there.
   * <li>Adds {@code abstract} if it wasn't there.
   * <li>Adds a private empty constructor if the class was {@code final} and had only a default
   *     constructor.
   * </ul>
   */
static SuggestedFix.Builder makeConcreteClassAbstract(ClassTree classTree, VisitorState state) {
    Set<Modifier> flags = EnumSet.noneOf(Modifier.class);
    flags.addAll(classTree.getModifiers().getFlags());
    boolean wasFinal = flags.remove(FINAL);
    boolean wasAbstract = !flags.add(ABSTRACT);
    if (classTree.getKind().equals(INTERFACE) || (!wasFinal && wasAbstract)) {
        // no-op
        return SuggestedFix.builder();
    }
    ImmutableList.Builder<Object> modifiers = ImmutableList.builder();
    for (AnnotationTree annotation : classTree.getModifiers().getAnnotations()) {
        modifiers.add(state.getSourceForNode(annotation));
    }
    modifiers.addAll(flags);
    SuggestedFix.Builder makeAbstract = SuggestedFix.builder();
    if (((JCModifiers) classTree.getModifiers()).pos == -1) {
        makeAbstract.prefixWith(classTree, Joiner.on(' ').join(modifiers.build()));
    } else {
        makeAbstract.replace(classTree.getModifiers(), Joiner.on(' ').join(modifiers.build()));
    }
    if (wasFinal && HAS_GENERATED_CONSTRUCTOR.matches(classTree, state)) {
        makeAbstract.merge(addPrivateConstructor(classTree));
    }
    return makeAbstract;
}
Also used : SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ImmutableList(com.google.common.collect.ImmutableList) AnnotationTree(com.sun.source.tree.AnnotationTree) Modifier(javax.lang.model.element.Modifier) Matchers.hasModifier(com.google.errorprone.matchers.Matchers.hasModifier)

Aggregations

AnnotationTree (com.sun.source.tree.AnnotationTree)17 Tree (com.sun.source.tree.Tree)6 ModifiersTree (com.sun.source.tree.ModifiersTree)4 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)3 ClassTree (com.sun.source.tree.ClassTree)3 MethodTree (com.sun.source.tree.MethodTree)3 Modifier (javax.lang.model.element.Modifier)3 ImmutableList (com.google.common.collect.ImmutableList)2 Violation (com.google.errorprone.bugpatterns.threadsafety.ImmutableAnalysis.Violation)2 ExpressionTree (com.sun.source.tree.ExpressionTree)2 VariableTree (com.sun.source.tree.VariableTree)2 TreePath (com.sun.source.util.TreePath)2 Symbol (com.sun.tools.javac.code.Symbol)2 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)2 JCTree (com.sun.tools.javac.tree.JCTree)2 Target (java.lang.annotation.Target)2 VisitorState (com.google.errorprone.VisitorState)1 Immutable (com.google.errorprone.annotations.Immutable)1 RequiredModifiers (com.google.errorprone.annotations.RequiredModifiers)1 Nullness (com.google.errorprone.dataflow.nullnesspropagation.Nullness)1