Search in sources :

Example 31 with MethodInvocationTree

use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.

the class InfiniteRecursion method matchMethod.

@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
    if (tree.getBody() == null || tree.getBody().getStatements().size() != 1) {
        return NO_MATCH;
    }
    Tree statement = TreeInfo.skipParens((JCTree) Iterables.getOnlyElement(tree.getBody().getStatements()));
    ExpressionTree expr = statement.accept(new SimpleTreeVisitor<ExpressionTree, Void>() {

        @Override
        public ExpressionTree visitExpressionStatement(ExpressionStatementTree tree, Void unused) {
            return tree.getExpression();
        }

        @Override
        public ExpressionTree visitReturn(ReturnTree tree, Void unused) {
            return tree.getExpression();
        }
    }, null);
    if (!(expr instanceof MethodInvocationTree)) {
        return NO_MATCH;
    }
    ExpressionTree select = ((MethodInvocationTree) expr).getMethodSelect();
    switch(select.getKind()) {
        case IDENTIFIER:
            break;
        case MEMBER_SELECT:
            ExpressionTree receiver = ((MemberSelectTree) select).getExpression();
            if (receiver.getKind() != Kind.IDENTIFIER) {
                return NO_MATCH;
            }
            if (!((IdentifierTree) receiver).getName().contentEquals("this")) {
                return NO_MATCH;
            }
            break;
        default:
            return NO_MATCH;
    }
    MethodSymbol sym = ASTHelpers.getSymbol(tree);
    if (sym == null || !sym.equals(ASTHelpers.getSymbol(expr))) {
        return NO_MATCH;
    }
    return describeMatch(statement);
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ReturnTree(com.sun.source.tree.ReturnTree) MethodTree(com.sun.source.tree.MethodTree) ExpressionTree(com.sun.source.tree.ExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) JCTree(com.sun.tools.javac.tree.JCTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ReturnTree(com.sun.source.tree.ReturnTree)

Example 32 with MethodInvocationTree

use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.

the class MockitoUsage method buildFix.

/**
   * Create fixes for invalid assertions.
   *
   * <ul>
   * <li>Rewrite `verify(mock.bar())` to `verify(mock).bar()`
   * <li>Rewrite `verify(mock.bar(), times(N))` to `verify(mock, times(N)).bar()`
   * <li>Rewrite `verify(mock, never())` to `verifyZeroInteractions(mock)`
   * <li>Finally, offer to delete the mock statement.
   * </ul>
   */
private void buildFix(Description.Builder builder, MethodInvocationTree tree, VisitorState state) {
    MethodInvocationTree mockitoCall = tree;
    List<? extends ExpressionTree> args = mockitoCall.getArguments();
    Tree mock = mockitoCall.getArguments().get(0);
    boolean isVerify = ASTHelpers.getSymbol(tree).getSimpleName().contentEquals("verify");
    if (isVerify && mock.getKind() == Kind.METHOD_INVOCATION) {
        MethodInvocationTree invocation = (MethodInvocationTree) mock;
        String verify = state.getSourceForNode(mockitoCall.getMethodSelect());
        String receiver = state.getSourceForNode(ASTHelpers.getReceiver(invocation));
        String mode = args.size() > 1 ? ", " + state.getSourceForNode(args.get(1)) : "";
        String call = state.getSourceForNode(invocation).substring(receiver.length());
        builder.addFix(SuggestedFix.replace(tree, String.format("%s(%s%s)%s", verify, receiver, mode, call)));
    }
    if (isVerify && args.size() > 1 && NEVER_METHOD.matches(args.get(1), state)) {
        // TODO(cushon): handle times(0) the same as never()
        builder.addFix(SuggestedFix.builder().addStaticImport("org.mockito.Mockito.verifyZeroInteractions").replace(tree, String.format("verifyZeroInteractions(%s)", mock)).build());
    }
    // Always suggest the naive semantics-preserving option, which is just to
    // delete the assertion:
    Tree parent = state.getPath().getParentPath().getLeaf();
    if (parent.getKind() == Kind.EXPRESSION_STATEMENT) {
        // delete entire expression statement
        builder.addFix(SuggestedFix.delete(parent));
    } else {
        builder.addFix(SuggestedFix.delete(tree));
    }
}
Also used : MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ExpressionTree(com.sun.source.tree.ExpressionTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Tree(com.sun.source.tree.Tree)

Example 33 with MethodInvocationTree

use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.

the class PreconditionsCheckNotNullPrimitive method describe.

/**
   * If the call to Preconditions.checkNotNull is part of an expression (assignment, return, etc.),
   * we substitute the argument for the method call. E.g.:
   * {@code bar = Preconditions.checkNotNull(foo); ==> bar = foo;}
   *
   * <p>If the argument to Preconditions.checkNotNull is a comparison using == or != and one of the
   * operands is null, we call checkNotNull on the non-null operand. E.g.:
   * {@code checkNotNull(a == null); ==> checkNotNull(a);}
   *
   * <p>If the argument is a method call or binary tree and its return type is boolean, change it to a
   * checkArgument/checkState. E.g.:
   * {@code Preconditions.checkNotNull(foo.hasFoo()) ==> Preconditions.checkArgument(foo.hasFoo())}
   *
   * <p>Otherwise, delete the checkNotNull call. E.g.:
   * {@code Preconditions.checkNotNull(foo); ==> [delete the line]}
   */
public Description describe(MethodInvocationTree methodInvocationTree, VisitorState state) {
    ExpressionTree arg1 = methodInvocationTree.getArguments().get(0);
    Tree parent = state.getPath().getParentPath().getLeaf();
    // Assignment, return, etc.
    if (parent.getKind() != Kind.EXPRESSION_STATEMENT) {
        return describeMatch(arg1, SuggestedFix.replace(methodInvocationTree, arg1.toString()));
    }
    // Comparison to null
    if (arg1.getKind() == Kind.EQUAL_TO || arg1.getKind() == Kind.NOT_EQUAL_TO) {
        BinaryTree binaryExpr = (BinaryTree) arg1;
        if (binaryExpr.getLeftOperand().getKind() == Kind.NULL_LITERAL) {
            return describeMatch(arg1, SuggestedFix.replace(arg1, binaryExpr.getRightOperand().toString()));
        }
        if (binaryExpr.getRightOperand().getKind() == Kind.NULL_LITERAL) {
            return describeMatch(arg1, SuggestedFix.replace(arg1, binaryExpr.getLeftOperand().toString()));
        }
    }
    if ((arg1 instanceof BinaryTree || arg1.getKind() == Kind.METHOD_INVOCATION || arg1.getKind() == Kind.LOGICAL_COMPLEMENT) && ((JCExpression) arg1).type == state.getSymtab().booleanType) {
        return describeMatch(arg1, createCheckArgumentOrStateCall(methodInvocationTree, state, arg1));
    }
    return describeMatch(arg1, SuggestedFix.delete(parent));
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) BinaryTree(com.sun.source.tree.BinaryTree) ExpressionTree(com.sun.source.tree.ExpressionTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 34 with MethodInvocationTree

use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.

the class ElementsCountedInLoop method matchWhileLoop.

@Override
public Description matchWhileLoop(WhileLoopTree tree, VisitorState state) {
    JCWhileLoop whileLoop = (JCWhileLoop) tree;
    JCExpression whileExpression = ((JCParens) whileLoop.getCondition()).getExpression();
    if (whileExpression instanceof MethodInvocationTree) {
        MethodInvocationTree methodInvocation = (MethodInvocationTree) whileExpression;
        if (instanceMethod().onDescendantOf("java.util.Iterator").withSignature("hasNext()").matches(methodInvocation, state)) {
            IdentifierTree identifier = getIncrementedIdentifer(extractSingleStatement(whileLoop.body));
            if (identifier != null) {
                return describeMatch(tree);
            }
        }
    }
    return Description.NO_MATCH;
}
Also used : JCWhileLoop(com.sun.tools.javac.tree.JCTree.JCWhileLoop) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) JCParens(com.sun.tools.javac.tree.JCTree.JCParens)

Example 35 with MethodInvocationTree

use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.

the class MyCustomCheck method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!PRINT_METHOD.matches(tree, state)) {
        return NO_MATCH;
    }
    Symbol base = tree.getMethodSelect().accept(new TreeScanner<Symbol, Void>() {

        @Override
        public Symbol visitIdentifier(IdentifierTree node, Void unused) {
            return ASTHelpers.getSymbol(node);
        }

        @Override
        public Symbol visitMemberSelect(MemberSelectTree node, Void unused) {
            return super.visitMemberSelect(node, null);
        }
    }, null);
    if (!Objects.equals(base, state.getSymtab().systemType.tsym)) {
        return NO_MATCH;
    }
    ExpressionTree arg = Iterables.getOnlyElement(tree.getArguments());
    if (!STRING_FORMAT.matches(arg, state)) {
        return NO_MATCH;
    }
    List<? extends ExpressionTree> formatArgs = ((MethodInvocationTree) arg).getArguments();
    return describeMatch(tree, SuggestedFix.builder().replace(((JCTree) tree).getStartPosition(), ((JCTree) formatArgs.get(0)).getStartPosition(), "System.err.printf(").replace(state.getEndPosition((JCTree) getLast(formatArgs)), state.getEndPosition((JCTree) tree), ")").build());
}
Also used : Symbol(com.sun.tools.javac.code.Symbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree)

Aggregations

MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)35 ExpressionTree (com.sun.source.tree.ExpressionTree)24 Tree (com.sun.source.tree.Tree)13 IdentifierTree (com.sun.source.tree.IdentifierTree)10 MemberSelectTree (com.sun.source.tree.MemberSelectTree)9 VariableTree (com.sun.source.tree.VariableTree)9 JCTree (com.sun.tools.javac.tree.JCTree)9 ExpressionStatementTree (com.sun.source.tree.ExpressionStatementTree)8 MethodTree (com.sun.source.tree.MethodTree)8 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)8 VisitorState (com.google.errorprone.VisitorState)7 StatementTree (com.sun.source.tree.StatementTree)7 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)7 BinaryTree (com.sun.source.tree.BinaryTree)5 BlockTree (com.sun.source.tree.BlockTree)5 NewClassTree (com.sun.source.tree.NewClassTree)5 ReturnTree (com.sun.source.tree.ReturnTree)5 AssignmentTree (com.sun.source.tree.AssignmentTree)4 ClassTree (com.sun.source.tree.ClassTree)4 Description (com.google.errorprone.matchers.Description)3