/** Allow mocking APIs that return obsolete types. */ private boolean mockingObsoleteMethod(MethodTree enclosingMethod, VisitorState state, Type type) { // mutable boolean to return result from visitor boolean[] found = {false}; enclosingMethod.accept( new TreeScanner<Void, Void>() { @Override public Void visitMethodInvocation(MethodInvocationTree node, Void unused) { if (found[0]) { return null; } if (MOCKITO_MATCHER.matches(node, state)) { Type stubber = ASTHelpers.getReturnType(node); if (!stubber.getTypeArguments().isEmpty() && ASTHelpers.isSameType( getOnlyElement(stubber.getTypeArguments()), type, state)) { found[0] = true; } } return super.visitMethodInvocation(node, null); } }, null); return found[0]; }
private static ImmutableSet<ClassType> getMethodReturnTypes(MethodTree methodTree) { ImmutableSet.Builder<ClassType> returnTypes = ImmutableSet.builder(); methodTree.accept( new TreeScanner<Void, Void>() { @Override public Void visitReturn(ReturnTree node, Void unused) { Type type = ASTHelpers.getType(node.getExpression()); if (type instanceof ClassType) { returnTypes.add((ClassType) type); } return null; } @Override public Void visitClass(ClassTree tree, Void unused) { // Don't continue into nested classes. return null; } @Override public Void visitLambdaExpression(LambdaExpressionTree tree, Void unused) { // Don't continue into nested lambdas. return null; } }, null /* unused */); return returnTypes.build(); }
private void refactorInternalApplyMethods( MethodTree tree, SuggestedFix.Builder fixBuilder, Tree param, String mappedFunction) { getMappingForApply(mappedFunction) .ifPresent( apply -> { tree.accept( new TreeScanner<Void, Void>() { @Override public Void visitMethodInvocation(MethodInvocationTree callTree, Void unused) { if (getSymbol(callTree).name.contentEquals("apply")) { Symbol receiverSym = getSymbol(getReceiver(callTree)); if (receiverSym != null && receiverSym.equals(ASTHelpers.getSymbol(param))) { fixBuilder.replace( callTree.getMethodSelect(), receiverSym.name + "." + apply); } } return super.visitMethodInvocation(callTree, unused); } }, null); }); }
private static FieldAccessFinder scanMethod( VisitorState state, ClassSymbol classSymbol, MethodTree methodTree, Map<MethodSymbol, ImmutableSet<Symbol>> knownMethods, Matcher<ExpressionTree> acceptableMethods) { FieldAccessFinder finder = new FieldAccessFinder(state, classSymbol, knownMethods, acceptableMethods); methodTree.accept(finder, null); return finder; }
@Override public Description matchMethod(MethodTree tree, VisitorState state) { for (MatchType matchType : MatchType.values()) { if (matchType.methodMatcher.matches(tree, state)) { return tree.accept(new LifecycleMethodVisitor(matchType, state), null); } } return Description.NO_MATCH; }
tree.accept( new TreeScanner<Boolean, Void>() { @Override
@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; }
if (isValidFragmentMethodTree.accept(ALWAYS_RETURNS_TRUE, null)) { return buildDescription(isValidFragmentMethodTree) .setMessage("isValidFragment unconditionally returns true.")
@Override public Set<Name> getOwnMethodInvocations(ExecutableElement method) { try { return ImmutableSet.copyOf(trees .getTree(method) .accept(OWN_METHOD_INVOCATIONS_FETCHER, null) .names); } catch (RuntimeException e) { // Fail gracefully return ImmutableSet.of(); } }
@Override public void visitAllOwnMethodInvocations( ExecutableElement method, OwnMethodInvocationVisitor visitor) { trees.getTree(method).accept(OWN_METHOD_INVOCATIONS_VISITOR, (tree, methodName) -> { visitor.visitInvocation(methodName, (kind, msg) -> { CompilationUnitTree compilationUnit = trees.getPath(method).getCompilationUnit(); trees.printMessage(kind, msg, tree, compilationUnit); }); }); }
/** Allow mocking APIs that return obsolete types. */ private boolean mockingObsoleteMethod(MethodTree enclosingMethod, VisitorState state, Type type) { // mutable boolean to return result from visitor boolean[] found = {false}; enclosingMethod.accept( new TreeScanner<Void, Void>() { @Override public Void visitMethodInvocation(MethodInvocationTree node, Void unused) { if (found[0]) { return null; } if (MOCKITO_MATCHER.matches(node, state)) { Type stubber = ASTHelpers.getReturnType(node); if (!stubber.getTypeArguments().isEmpty() && ASTHelpers.isSameType( getOnlyElement(stubber.getTypeArguments()), type, state)) { found[0] = true; } } return super.visitMethodInvocation(node, null); } }, null); return found[0]; }
private static ImmutableSet<ClassType> getMethodReturnTypes(MethodTree methodTree) { ImmutableSet.Builder<ClassType> returnTypes = ImmutableSet.builder(); methodTree.accept( new TreeScanner<Void, Void>() { @Override public Void visitReturn(ReturnTree node, Void unused) { Type type = ASTHelpers.getType(node.getExpression()); if (type instanceof ClassType) { returnTypes.add((ClassType) type); } return null; } }, null /* unused */); return returnTypes.build(); }
private void refactorInternalApplyMethods( MethodTree tree, SuggestedFix.Builder fixBuilder, Tree param, String mappedFunction) { getMappingForApply(mappedFunction) .ifPresent( apply -> { tree.accept( new TreeScanner<Void, Void>() { @Override public Void visitMethodInvocation(MethodInvocationTree callTree, Void unused) { if (getSymbol(callTree).name.contentEquals("apply")) { Symbol receiverSym = getSymbol(getReceiver(callTree)); if (receiverSym != null && receiverSym.equals(ASTHelpers.getSymbol(param))) { fixBuilder.replace( callTree.getMethodSelect(), receiverSym.name + "." + apply); } } return super.visitMethodInvocation(callTree, unused); } }, null); }); }
private static FieldAccessFinder scanMethod( VisitorState state, ClassSymbol classSymbol, MethodTree methodTree, Map<MethodSymbol, ImmutableSet<Symbol>> knownMethods, Matcher<ExpressionTree> acceptableMethods) { FieldAccessFinder finder = new FieldAccessFinder(state, classSymbol, knownMethods, acceptableMethods); methodTree.accept(finder, null); return finder; }
@Override public Set<Name> getOwnMethodInvocations(ExecutableElement method) { try { return ImmutableSet.copyOf(trees .getTree(method) .accept(OWN_METHOD_INVOCATIONS_FETCHER, null) .names); } catch (RuntimeException e) { // Fail gracefully return ImmutableSet.of(); } }
@Override public Description matchMethod(MethodTree tree, VisitorState state) { for (MatchType matchType : MatchType.values()) { if (matchType.methodMatcher.matches(tree, state)) { return tree.accept(new LifecycleMethodVisitor(matchType, state), null); } } return Description.NO_MATCH; }
tree.accept( new TreeScanner<Boolean, Void>() { @Override
@Override public void visitAllOwnMethodInvocations( ExecutableElement method, OwnMethodInvocationVisitor visitor) { trees.getTree(method).accept(OWN_METHOD_INVOCATIONS_VISITOR, (tree, methodName) -> { visitor.visitInvocation(methodName, (kind, msg) -> { CompilationUnitTree compilationUnit = trees.getPath(method).getCompilationUnit(); trees.printMessage(kind, msg, tree, compilationUnit); }); }); }
@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; }
if (isValidFragmentMethodTree.accept(ALWAYS_RETURNS_TRUE, null)) { return buildDescription(isValidFragmentMethodTree) .setMessage("isValidFragment unconditionally returns true.")