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);
}
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());
}
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");
}
}
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();
}
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;
}
Aggregations