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 BadImport method buildDescription.
private Description buildDescription(SuggestedFix.Builder builder, Set<Symbol> symbols, String enclosingReplacement, VisitorState state) {
CompilationUnitTree compilationUnit = state.getPath().getCompilationUnit();
TreePath path = TreePath.getPath(compilationUnit, compilationUnit);
IdentifierTree firstFound = new SuppressibleTreePathScanner<IdentifierTree, Void>() {
@Override
public IdentifierTree reduce(IdentifierTree r1, IdentifierTree r2) {
return (r2 != null) ? r2 : r1;
}
@Override
public IdentifierTree visitIdentifier(IdentifierTree node, Void unused) {
Symbol nodeSymbol = getSymbol(node);
if (symbols.contains(nodeSymbol) && !isSuppressed(node)) {
if (getCurrentPath().getParentPath().getLeaf().getKind() != Kind.CASE) {
builder.prefixWith(node, enclosingReplacement);
moveTypeAnnotations(node);
return node;
}
}
return super.visitIdentifier(node, unused);
}
// We need to move any type annotation inside the qualified usage to preserve semantics,
// e.g. @Nullable Builder -> SomeClass.@Nullable Builder.
private void moveTypeAnnotations(IdentifierTree node) {
Tree parent = getCurrentPath().getParentPath().getLeaf();
switch(parent.getKind()) {
case METHOD:
case VARIABLE:
case ANNOTATED_TYPE:
moveTypeAnnotations(node, parent, state, builder);
break;
case PARAMETERIZED_TYPE:
Tree grandParent = getCurrentPath().getParentPath().getParentPath().getLeaf();
if (grandParent.getKind() == Kind.VARIABLE || grandParent.getKind() == Kind.METHOD) {
moveTypeAnnotations(node, grandParent, state, builder);
}
break;
default:
}
}
private void moveTypeAnnotations(IdentifierTree node, Tree annotationHolder, VisitorState state, SuggestedFix.Builder builder) {
for (AnnotationTree annotation : HAS_TYPE_USE_ANNOTATION.multiMatchResult(annotationHolder, state).matchingNodes()) {
builder.delete(annotation);
builder.prefixWith(node, state.getSourceForNode(annotation) + " ");
}
}
}.scan(path, null);
if (firstFound == null) {
// import fix.
return Description.NO_MATCH;
}
return buildDescription(firstFound).setMessage(String.format("Importing nested classes/static methods/static fields with commonly-used names can" + " make code harder to read, because it may not be clear from the context" + " exactly which type is being referred to. Qualifying the name with that of" + " the containing class can make the code clearer. Here we recommend using" + " qualified class: %s", enclosingReplacement)).addFix(builder.build()).build();
}
use of com.sun.source.tree.AnnotationTree in project error-prone by google.
the class TestParametersNotInitialized method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
if (!JUNIT4_RUNNER.matches(tree, state)) {
return NO_MATCH;
}
if (TEST_PARAMETER_INJECTOR.matches(tree, state)) {
return NO_MATCH;
}
if (tree.getMembers().stream().noneMatch(m -> hasAnnotation(m, TEST_PARAMETER, state))) {
return NO_MATCH;
}
AnnotationTree annotation = getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "RunWith");
SuggestedFix.Builder fix = SuggestedFix.builder();
fix.replace(annotation, String.format("@RunWith(%s.class)", SuggestedFixes.qualifyType(state, fix, RUNNER)));
return describeMatch(tree, fix.build());
}
use of com.sun.source.tree.AnnotationTree in project error-prone by google.
the class NullablePrimitiveArray method check.
// other cases of `@Nullable int[]` are covered by the existing NullablePrimitive
private Description check(Tree typeTree, List<? extends AnnotationTree> annotations, VisitorState state) {
Type type = getType(typeTree);
if (type == null) {
return NO_MATCH;
}
if (!type.getKind().equals(TypeKind.ARRAY)) {
return NO_MATCH;
}
while (type.getKind().equals(TypeKind.ARRAY)) {
type = state.getTypes().elemtype(type);
}
if (!type.isPrimitive()) {
return NO_MATCH;
}
AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(annotations, "Nullable");
if (annotation == null) {
return NO_MATCH;
}
Attribute.Compound target = ASTHelpers.getSymbol(annotation).attribute(state.getSymtab().annotationTargetType.tsym);
if (!isTypeAnnotation(target)) {
return NO_MATCH;
}
Tree dims = typeTree;
while (dims instanceof ArrayTypeTree) {
dims = ((ArrayTypeTree) dims).getType();
}
SuggestedFix.Builder fix = SuggestedFix.builder().delete(annotation);
if (!(dims instanceof AnnotatedTypeTree) || getAnnotationsWithSimpleName(((AnnotatedTypeTree) dims).getAnnotations(), "Nullable") == null) {
fix.postfixWith(dims, " " + state.getSourceForNode(annotation) + " ");
}
return describeMatch(annotation, fix.build());
}
use of com.sun.source.tree.AnnotationTree in project error-prone by google.
the class ImmutableEnumChecker method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
ClassSymbol symbol = getSymbol(tree);
if (symbol == null || !symbol.isEnum()) {
return NO_MATCH;
}
if (ASTHelpers.hasAnnotation(symbol, Immutable.class, state) && !implementsExemptInterface(symbol, state)) {
AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Immutable");
if (annotation != null) {
state.reportMatch(buildDescription(annotation).setMessage(ANNOTATED_ENUM_MESSAGE).addFix(SuggestedFix.delete(annotation)).build());
} else {
state.reportMatch(buildDescription(tree).setMessage(ANNOTATED_ENUM_MESSAGE).build());
}
}
Violation info = new ImmutableAnalysis(this, state, wellKnownMutability, ImmutableSet.of(Immutable.class.getName())).checkForImmutability(Optional.of(tree), ImmutableSet.of(), getType(tree), this::describe);
if (!info.isPresent()) {
return NO_MATCH;
}
return describe(tree, info).build();
}
Aggregations