use of com.sun.source.tree.AnnotationTree in project error-prone by google.
the class ImmutableAnnotationChecker method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
ClassSymbol symbol = getSymbol(tree);
if (symbol == null || symbol.isAnnotationType() || !WellKnownMutability.isAnnotation(state, symbol.type)) {
return NO_MATCH;
}
if (ASTHelpers.hasAnnotation(symbol, Immutable.class, state)) {
AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Immutable");
if (annotation != null) {
state.reportMatch(buildDescription(annotation).setMessage(ANNOTATED_ANNOTATION_MESSAGE).addFix(SuggestedFix.delete(annotation)).build());
} else {
state.reportMatch(buildDescription(tree).setMessage(ANNOTATED_ANNOTATION_MESSAGE).build());
}
}
Violation info = new ImmutableAnalysis(this, state, "annotations should be immutable, and cannot have non-final fields", "annotations should be immutable").checkForImmutability(Optional.of(tree), ImmutableSet.of(), getType(tree));
if (!info.isPresent()) {
return NO_MATCH;
}
String message = "annotations should be immutable: " + info.message();
return buildDescription(tree).setMessage(message).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;
}
use of com.sun.source.tree.AnnotationTree in project error-prone by google.
the class AutoFactoryAtInject method matchAnnotation.
@Override
public final Description matchAnnotation(AnnotationTree annotationTree, VisitorState state) {
if (!IS_APPLICATION_OF_AT_INJECT.matches(annotationTree, state)) {
return Description.NO_MATCH;
}
Tree annotatedTree = getCurrentlyAnnotatedNode(state);
if (!annotatedTree.getKind().equals(METHOD) || !methodIsConstructor().matches((MethodTree) annotatedTree, state)) {
return Description.NO_MATCH;
}
ClassTree classTree = findEnclosingNode(state.getPath(), ClassTree.class);
ImmutableList<Tree> potentiallyAnnotatedTrees = new ImmutableList.Builder<Tree>().add(classTree).addAll(getConstructors(classTree)).build();
for (Tree potentiallyAnnotatedTree : potentiallyAnnotatedTrees) {
if (HAS_AUTO_FACTORY_ANNOTATION.matches(potentiallyAnnotatedTree, state)) {
return describeMatch(annotationTree, SuggestedFix.delete(annotationTree));
}
}
return Description.NO_MATCH;
}
Aggregations