Search in sources :

Example 16 with MethodInvocationTree

use of com.sun.source.tree.MethodInvocationTree in project bazel by bazelbuild.

the class TreeUtils method containsThisConstructorInvocation.

/**
     * @return true if the first statement in the body is a self constructor
     *  invocation within a constructor
     */
public static final boolean containsThisConstructorInvocation(MethodTree node) {
    if (!TreeUtils.isConstructor(node) || node.getBody().getStatements().isEmpty())
        return false;
    StatementTree st = node.getBody().getStatements().get(0);
    if (!(st instanceof ExpressionStatementTree) || !(((ExpressionStatementTree) st).getExpression() instanceof MethodInvocationTree))
        return false;
    MethodInvocationTree invocation = (MethodInvocationTree) ((ExpressionStatementTree) st).getExpression();
    return "this".contentEquals(TreeUtils.methodName(invocation));
}
Also used : ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) StatementTree(com.sun.source.tree.StatementTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree)

Example 17 with MethodInvocationTree

use of com.sun.source.tree.MethodInvocationTree in project bazel by bazelbuild.

the class TreeUtils method isMethodInvocation.

/**
     * Returns true if the given element is an invocation of the method, or
     * of any method that overrides that one.
     */
public static boolean isMethodInvocation(Tree tree, ExecutableElement method, ProcessingEnvironment env) {
    if (!(tree instanceof MethodInvocationTree))
        return false;
    MethodInvocationTree methInvok = (MethodInvocationTree) tree;
    ExecutableElement invoked = TreeUtils.elementFromUse(methInvok);
    return isMethod(invoked, method, env);
}
Also used : MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ExecutableElement(javax.lang.model.element.ExecutableElement)

Example 18 with MethodInvocationTree

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

the class ChainingConstructorIgnoresParameter method evaluateCallers.

private Description evaluateCallers(MethodSymbol symbol) {
    List<VariableTree> paramTypes = paramTypesForMethod.get(symbol);
    if (paramTypes == null) {
        // We haven't seen the declaration yet. We'll evaluate the call when we do.
        return NO_MATCH;
    }
    for (Caller caller : callersToEvaluate.removeAll(symbol)) {
        VisitorState state = caller.state;
        MethodInvocationTree invocation = caller.tree;
        MethodTree callerConstructor = state.findEnclosing(MethodTree.class);
        if (callerConstructor == null) {
            // impossible, at least in compilable code?
            continue;
        }
        Map<String, Type> availableParams = indexTypeByName(callerConstructor.getParameters());
        /*
       * TODO(cpovirk): Better handling of varargs: If the last parameter type is varargs and it is
       * called as varargs (rather than by passing an array), then rewrite the parameter types to
       * (p0, p1, ..., p[n-2], p[n-1] = element type of varargs parameter if an argument is
       * supplied, p[n] = ditto, etc.). For now, we settle for not crashing in the face of a
       * mismatch between the number of parameters declared and the number supplied.
       *
       * (Use MethodSymbol.isVarArgs.)
       */
        for (int i = 0; i < paramTypes.size() && i < invocation.getArguments().size(); i++) {
            VariableTree formalParam = paramTypes.get(i);
            String formalParamName = formalParam.getName().toString();
            Type formalParamType = getType(formalParam.getType());
            Type availableParamType = availableParams.get(formalParamName);
            ExpressionTree actualParam = invocation.getArguments().get(i);
            if (/*
             * The caller has no param of this type. (Or if it did, we couldn't determine the type.
             * Does that ever happen?) If the param doesn't exist, the caller can't be failing to
             * pass it.
             */
            availableParamType == null || /*
             * We couldn't determine the type of the formal parameter. (Does this ever happen?)
             */
            formalParamType == null || /*
             * The caller is passing the expected parameter (or "ImmutableList.copyOf(parameter),"
             * "new File(parameter)," etc.).
             */
            referencesIdentifierWithName(formalParamName, actualParam, state)) {
                continue;
            }
            if (state.getTypes().isAssignable(availableParamType, formalParamType)) {
                reportMatch(invocation, state, actualParam, formalParamName);
            }
        /*
         * If formal parameter is of an incompatible type, the caller might in theory still intend
         * to pass a dervied expression. For example, "Foo(String file)" might intend to call
         * "Foo(File file)" by passing "new File(file)." If this comes up in practice, we could
         * provide the dummy suggested fix "someExpression(formalParamName)." However, my research
         * suggests that this will rarely if ever be what the user wants.
         */
        }
    }
    // All matches are reported through reportMatch calls instead of return values.
    return NO_MATCH;
}
Also used : ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) Type(com.sun.tools.javac.code.Type) VisitorState(com.google.errorprone.VisitorState) MethodTree(com.sun.source.tree.MethodTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) VariableTree(com.sun.source.tree.VariableTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 19 with MethodInvocationTree

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

the class FunctionalInterfaceMethodChanged method matchMethod.

@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(// TypeSymbol to single abstract method of the type
        types::findDescriptorSymbol).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 SimpleTreeVisitor<Boolean, VisitorState>(false) {

            @Override
            public Boolean visitMethod(MethodTree node, VisitorState state) {
                return node.getBody() != null && node.getBody().accept(this, state);
            }

            @Override
            public Boolean visitBlock(BlockTree node, VisitorState state) {
                return node.getStatements().size() == 1 && Iterables.getOnlyElement(node.getStatements()).accept(this, state);
            }

            @Override
            public Boolean visitExpressionStatement(ExpressionStatementTree node, VisitorState state) {
                return node.getExpression().accept(this, state);
            }

            @Override
            public Boolean visitReturn(ReturnTree node, VisitorState state) {
                return node.getExpression().accept(this, state);
            }

            @Override
            public Boolean visitMethodInvocation(MethodInvocationTree node, VisitorState state) {
                return ASTHelpers.getSymbol(node) == thisInterfaceSam;
            }
        };
        if (!Collections.disjoint(ASTHelpers.findSuperMethods(ASTHelpers.getSymbol(tree), types), functionalSuperInterfaceSams) && !tree.accept(behaviorPreserving, state)) {
            return describeMatch(tree);
        }
    }
    return Description.NO_MATCH;
}
Also used : Types(com.sun.tools.javac.code.Types) MethodTree(com.sun.source.tree.MethodTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) SimpleTreeVisitor(com.sun.source.util.SimpleTreeVisitor) ClassTree(com.sun.source.tree.ClassTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ReturnTree(com.sun.source.tree.ReturnTree) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) BlockTree(com.sun.source.tree.BlockTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol)

Example 20 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)

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