@Override public Void visitMethod(MethodTree tree, Void unused) { if (tree.getModifiers().getFlags().contains(Modifier.NATIVE)) { hasAnyNativeMethods.set(true); } return null; } }.scan(tree, null);
private static boolean isStatic(VariableTree varTree) { return varTree.getModifiers().getFlags().contains(Modifier.STATIC); }
private static boolean isValidParameterTree(VariableTree variableTree) { // A valid parameter has no initializer. if (variableTree.getInitializer() != null) { return false; } // A valid parameter either has no modifiers or has only `final` keyword. Set<Modifier> flags = variableTree.getModifiers().getFlags(); return flags.isEmpty() || (flags.size() == 1 && flags.contains(Modifier.FINAL)); }
@Override public Choice<Unifier> visitModifiers(ModifiersTree modifier, Unifier unifier) { return Choice.condition(getFlags().equals(modifier.getFlags()), unifier); }
@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()); } } });
@Override public boolean matches(ClassTree classTree, VisitorState state) { return classTree.getModifiers().getFlags().contains(ABSTRACT) || (ASTHelpers.getSymbol(classTree).flags() & Flags.INTERFACE) != 0; } };
@Override public boolean matches(MethodTree t, VisitorState state) { Set<Modifier> modifiers = t.getModifiers().getFlags(); if (visibility == Visibility.DEFAULT) { return !(modifiers.contains(Visibility.PUBLIC.toModifier()) || modifiers.contains(Visibility.PROTECTED.toModifier()) || modifiers.contains(Visibility.PRIVATE.toModifier())); } else { return modifiers.contains(visibility.toModifier()); } }
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; } }
@Override public boolean matches(T tree, VisitorState state) { SynchronizedTree synchronizedTree = ASTHelpers.findEnclosingNode(state.getPath(), SynchronizedTree.class); if (synchronizedTree != null) { return true; } MethodTree methodTree = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class); return methodTree != null && methodTree.getModifiers().getFlags().contains(Modifier.SYNCHRONIZED); } };
Set<Modifier> modifiers = modifiersTree.getFlags(); if (!modifiers.contains(Modifier.PROTECTED)) { fixes.add(
@Override public Description matchAnnotation(AnnotationTree tree, VisitorState state) { Set<Modifier> incompatibleModifiers = getIncompatibleModifiers(tree, state); if (incompatibleModifiers.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> incompatible = Sets.intersection(incompatibleModifiers, ((ModifiersTree) parent).getFlags()); if (incompatible.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, incompatible); return buildDescription(tree).setMessage(customMessage).build(); } }
@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); }
flags.addAll(classTree.getModifiers().getFlags()); boolean wasFinal = flags.remove(FINAL); boolean wasAbstract = !flags.add(ABSTRACT);
Set<Modifier> missing = Sets.difference(requiredModifiers, ((ModifiersTree) parent).getFlags());
@Override public Void visitMethod(MethodTree tree, HeldLockSet locks) { // Synchronized instance methods hold the 'this' lock; synchronized static methods // hold the Class lock for the enclosing class. Set<Modifier> mods = tree.getModifiers().getFlags(); if (mods.contains(Modifier.SYNCHRONIZED)) { Symbol owner = (((JCTree.JCMethodDecl) tree).sym.owner); GuardedByExpression lock = mods.contains(Modifier.STATIC) ? F.classLiteral(owner) : F.thisliteral(); locks = locks.plus(lock); } // @GuardedBy annotations on methods are trusted for declarations, and checked // for invocations. for (String guard : GuardedByUtils.getGuardValues(tree, visitorState)) { Optional<GuardedByExpression> bound = GuardedByBinder.bindString(guard, GuardedBySymbolResolver.from(tree, visitorState)); if (bound.isPresent()) { locks = locks.plus(bound.get()); } } return super.visitMethod(tree, locks); }
@Override public Description matchMethod(MethodTree tree, VisitorState state) { ClassTree enclosingClazz = ASTHelpers.findEnclosingNode(state.getPath(), ClassTree.class); if (tree.getModifiers().getFlags().contains(Modifier.DEFAULT) && IS_FUNCTIONAL_INTERFACE.matches(enclosingClazz, state)) { Types types = Types.instance(state.context); Set<Symbol> functionalSuperInterfaceSams = enclosingClazz.getImplementsClause().stream() .filter(t -> IS_FUNCTIONAL_INTERFACE.matches(t, state)) .map(ASTHelpers::getSymbol) .map(TypeSymbol.class::cast) .map(types::findDescriptorSymbol) // TypeSymbol to single abstract method of the type .collect(toImmutableSet()); // We designate an override of a superinterface SAM "behavior preserving" if it just // calls the SAM of this interface. Symbol thisInterfaceSam = types.findDescriptorSymbol(ASTHelpers.getSymbol(enclosingClazz)); // relatively crude: doesn't verify that the same args are passed in the same order // so it can get false positives for behavior-preservingness (false negatives for the check) TreeVisitor<Boolean, VisitorState> behaviorPreserving = new BehaviorPreservingChecker(thisInterfaceSam); if (!Collections.disjoint( ASTHelpers.findSuperMethods(ASTHelpers.getSymbol(tree), types), functionalSuperInterfaceSams) && !tree.accept(behaviorPreserving, state)) { return describeMatch(tree); } } return Description.NO_MATCH; }
@Override public Description matchVariable(VariableTree tree, VisitorState state) { ExpressionTree initializer = stripNullCheck(tree.getInitializer(), state); Tree parent = state.getPath().getParentPath().getLeaf(); // must be a static class variable with member select initializer if (initializer == null || initializer.getKind() != MEMBER_SELECT || parent.getKind() != CLASS || !tree.getModifiers().getFlags().contains(STATIC)) { return Description.NO_MATCH; } MemberSelectTree rhs = (MemberSelectTree) initializer; Symbol rhsClass = ASTHelpers.getSymbol(rhs.getExpression()); Symbol lhsClass = ASTHelpers.getSymbol(parent); if (rhsClass != null && lhsClass != null && rhsClass.equals(lhsClass) && rhs.getIdentifier().contentEquals(tree.getName())) { return describeForVarDecl(tree, state); } return Description.NO_MATCH; }
@Override public Description matchMethod(MethodTree method, VisitorState state) { if (!CAN_BE_A_BINDS_METHOD.matches(method, state)) { return NO_MATCH; } JCClassDecl enclosingClass = ASTHelpers.findEnclosingNode(state.getPath(), JCClassDecl.class); // Dagger 1 modules don't support @Binds. if (!IS_DAGGER_2_MODULE.matches(enclosingClass, state)) { return NO_MATCH; } if (enclosingClass.getExtendsClause() != null) { return fixByDelegating(); } for (Tree member : enclosingClass.getMembers()) { if (member.getKind().equals(Tree.Kind.METHOD) && !getSymbol(member).isConstructor()) { MethodTree siblingMethod = (MethodTree) member; Set<Modifier> siblingFlags = siblingMethod.getModifiers().getFlags(); if (!(siblingFlags.contains(Modifier.STATIC) || siblingFlags.contains(Modifier.ABSTRACT)) && !CAN_BE_A_BINDS_METHOD.matches(siblingMethod, state)) { return fixByDelegating(); } } } return fixByModifyingMethod(state, enclosingClass, method); }
if (classTree == null || classTree.getModifiers().getFlags().contains(Modifier.FINAL)) { return Description.NO_MATCH;