/** Returns the modifiers tree of the given class, method, or variable declaration. */ @Nullable public static ModifiersTree getModifiers(Tree tree) { if (tree instanceof ClassTree) { return ((ClassTree) tree).getModifiers(); } else if (tree instanceof MethodTree) { return ((MethodTree) tree).getModifiers(); } else if (tree instanceof VariableTree) { return ((VariableTree) tree).getModifiers(); } else { return null; } }
@Override public Description matchClass(ClassTree tree, VisitorState state) { return handle(tree, tree.getSimpleName(), tree.getModifiers(), state); }
@Override public boolean matches(ClassTree classTree, VisitorState state) { return classTree.getModifiers().getFlags().contains(ABSTRACT) || (ASTHelpers.getSymbol(classTree).flags() & Flags.INTERFACE) != 0; } };
/** Returns the annotation on {@code classTree} whose type's FQCN is {@code annotationName}. */ static Optional<AnnotationTree> findAnnotation(String annotationName, ClassTree classTree) { for (AnnotationTree annotationTree : classTree.getModifiers().getAnnotations()) { ClassSymbol annotationClass = (ClassSymbol) getSymbol(annotationTree.getAnnotationType()); if (annotationClass.fullname.contentEquals(annotationName)) { return Optional.of(annotationTree); } } return Optional.absent(); }
flags.addAll(classTree.getModifiers().getFlags()); boolean wasFinal = flags.remove(FINAL); boolean wasAbstract = !flags.add(ABSTRACT); for (AnnotationTree annotation : classTree.getModifiers().getAnnotations()) { modifiers.add(state.getSourceForNode(annotation)); if (((JCModifiers) classTree.getModifiers()).pos == -1) { makeAbstract.prefixWith(classTree, Joiner.on(' ').join(modifiers.build())); } else { makeAbstract.replace(classTree.getModifiers(), Joiner.on(' ').join(modifiers.build()));
private static boolean isInPrivateScope(VisitorState state) { TreePath treePath = state.getPath(); do { Tree currentLeaf = treePath.getLeaf(); if (currentLeaf instanceof ClassTree) { ClassTree currentClassTree = (ClassTree) currentLeaf; if (currentClassTree.getModifiers().getFlags().contains(PRIVATE)) { return true; } } treePath = treePath.getParentPath(); } while (treePath != null); return false; } }
/** Detects if the class is annotated as @BTrace(trusted=true). */ private boolean hasTrustedAnnotation(ClassTree ct, Element topElement) { for (AnnotationTree at : ct.getModifiers().getAnnotations()) { String annFqn = ((JCTree)at.getAnnotationType()).type.tsym.getQualifiedName().toString(); if (!annFqn.equals(BTrace.class.getName())) { continue; } // now we have @BTrace, look for unsafe = xxx or trusted = xxx for (ExpressionTree ext : at.getArguments()) { if (!(ext instanceof JCAssign)) { continue; } JCAssign assign = (JCAssign) ext; String name = ((JCIdent)assign.lhs).name.toString(); if (!"unsafe".equals(name) && !"trusted".equals(name)) { continue; } // now rhs is the value of @BTrace.unsafe. // The value can be complex (!!true, 1 == 2, etc.) - we support only booleans String val = assign.rhs.toString(); if ("true".equals(val)) { return true; // bingo! } else if (!"false".equals(val)) { processingEnv.getMessager().printMessage(Kind.WARNING, Messages.get("no.complex.unsafe.value"), topElement); } } } return false; }
@Override protected void traverse(Tree tree, VisitorState state) { // If class is final, no method is overridable. ClassTree classTree = state.findEnclosing(ClassTree.class); if (classTree.getModifiers().getFlags().contains(Modifier.FINAL)) { return; } ClassSymbol classSym = ASTHelpers.getSymbol(classTree); tree.accept( new TreeScanner<Void, Void>() { @Override public Void visitMethodInvocation(MethodInvocationTree node, Void data) { MethodSymbol method = ASTHelpers.getSymbol(node); if (method != null && !method.isConstructor() && !method.isStatic() && !method.isPrivate() && !method.getModifiers().contains(Modifier.FINAL) && isOnThis(node) && method.isMemberOf(classSym, state.getTypes())) { state.reportMatch(describeMatch(node)); } return super.visitMethodInvocation(node, data); } }, null); }
@Override public boolean apply(Tree tree) { switch (tree.getKind()) { case CLASS: return ((ClassTree) tree).getModifiers().getFlags().contains(STATIC); case METHOD: return ((MethodTree) tree).getModifiers().getFlags().contains(STATIC); case VARIABLE: return ((VariableTree) tree).getModifiers().getFlags().contains(STATIC); case BLOCK: return ((BlockTree) tree).isStatic(); case ENUM: case ANNOTATION_TYPE: case INTERFACE: return true; default: throw new AssertionError("unknown member type:" + tree.getKind()); } } });
return Description.NO_MATCH; if (classMember.getModifiers().getFlags().contains(Modifier.PUBLIC)) {
@Override public Description matchClass(ClassTree classTree, VisitorState state) { if (!DaggerAnnotations.isAnyModule().matches(classTree, state)) { return Description.NO_MATCH; } List<SuggestedFix> fixes = new ArrayList<>(); for (AnnotationTree annotation : classTree.getModifiers().getAnnotations()) { Symbol annotationType = getSymbol(annotation.getAnnotationType()); if (hasAnnotation(annotationType, "javax.inject.Scope", state)) { fixes.add(SuggestedFix.delete(annotation)); } } if (fixes.isEmpty()) { return Description.NO_MATCH; } return buildDescription(classTree).addAllFixes(fixes).build(); } }
@Override protected Iterable<? extends AnnotationTree> getChildNodes(T tree, VisitorState state) { if (tree instanceof ClassTree) { return ((ClassTree) tree).getModifiers().getAnnotations(); } else if (tree instanceof VariableTree) { return ((VariableTree) tree).getModifiers().getAnnotations(); } else if (tree instanceof MethodTree) { return ((MethodTree) tree).getModifiers().getAnnotations(); } else if (tree instanceof CompilationUnitTree) { return ((CompilationUnitTree) tree).getPackageAnnotations(); } else if (tree instanceof AnnotatedTypeTree) { return ((AnnotatedTypeTree) tree).getAnnotations(); } else if (tree instanceof PackageTree) { return ((PackageTree) tree).getAnnotations(); } else { throw new IllegalArgumentException( "Cannot access annotations from tree of type " + tree.getClass()); } } }
if (classTree.getModifiers().getFlags().contains(ABSTRACT)) { return Description.NO_MATCH; if (!classTree.getModifiers().getFlags().contains(PUBLIC)) { return buildErrorMessage(classTree, "a fragment must be public");
for (AnnotationTree annotationTree : classTree.getModifiers().getAnnotations()) { JCIdent ident = (JCIdent) annotationTree.getAnnotationType(); String annotationClassName = ident.sym.getQualifiedName().toString();
} else if (state.getEndPosition(classTree.getModifiers()) == Position.NOPOS) { startTokenization = ((JCTree) classTree).getStartPosition(); } else { startTokenization = state.getEndPosition(classTree.getModifiers());
ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Immutable"); if (annotation != null) { state.reportMatch(
private Description describe( ClassTree classTree, VisitorState state, @Nullable Retention retention) { if (retention == null) { return describeMatch( classTree, SuggestedFix.builder() .addImport("java.lang.annotation.Retention") .addStaticImport("java.lang.annotation.RetentionPolicy.RUNTIME") .prefixWith(classTree, "@Retention(RUNTIME)\n") .build()); } AnnotationTree retentionNode = null; for (AnnotationTree annotation : classTree.getModifiers().getAnnotations()) { if (ASTHelpers.getSymbol(annotation) .equals(state.getSymbolFromString(RETENTION_ANNOTATION))) { retentionNode = annotation; } } return describeMatch( retentionNode, SuggestedFix.builder() .addImport("java.lang.annotation.Retention") .addStaticImport("java.lang.annotation.RetentionPolicy.RUNTIME") .replace(retentionNode, "@Retention(RUNTIME)") .build()); } }
@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) && !implementsImmutableInterface(symbol)) { 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(); }
if (classTree == null || classTree.getModifiers().getFlags().contains(Modifier.FINAL)) { return Description.NO_MATCH;
ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "BugPattern"); if (bugPatternAnnotation == null) { return NO_MATCH;