Search in sources :

Example 21 with ExpressionTree

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

the class ProtoFieldNullComparison method isGetMethodInvocation.

private static boolean isGetMethodInvocation(ExpressionTree tree, VisitorState state) {
    if (tree.getKind() == Tree.Kind.METHOD_INVOCATION) {
        MethodInvocationTree method = (MethodInvocationTree) tree;
        if (!method.getArguments().isEmpty()) {
            return false;
        }
        if (returnsListMatcher.matches(method, state)) {
            return false;
        }
        ExpressionTree expressionTree = method.getMethodSelect();
        if (expressionTree instanceof JCFieldAccess) {
            JCFieldAccess access = (JCFieldAccess) expressionTree;
            String methodName = access.sym.getQualifiedName().toString();
            return isFieldGetMethod(methodName);
        }
        return true;
    }
    return false;
}
Also used : JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 22 with ExpressionTree

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

the class RandomModInteger method matchBinary.

@Override
public Description matchBinary(BinaryTree tree, VisitorState state) {
    if (tree.getKind() == Kind.REMAINDER && tree.getLeftOperand() instanceof MethodInvocationTree && RANDOM_NEXT_INT.matches(tree.getLeftOperand(), state)) {
        ExpressionTree randomExpr = ASTHelpers.getReceiver(tree.getLeftOperand());
        ExpressionTree modulus = tree.getRightOperand();
        return describeMatch(tree, SuggestedFix.replace(tree, String.format("%s.nextInt(%s)", state.getSourceForNode(randomExpr), state.getSourceForNode(modulus))));
    }
    return Description.NO_MATCH;
}
Also used : MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 23 with ExpressionTree

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

the class RedundantThrows method matchMethod.

@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
    List<? extends ExpressionTree> thrown = tree.getThrows();
    if (thrown.isEmpty()) {
        return NO_MATCH;
    }
    SetMultimap<Symbol, ExpressionTree> exceptionsBySuper = LinkedHashMultimap.create();
    for (ExpressionTree exception : thrown) {
        Type type = getType(exception);
        do {
            type = state.getTypes().supertype(type);
            exceptionsBySuper.put(type.tsym, exception);
        } while (!state.getTypes().isSameType(type, state.getSymtab().objectType));
    }
    Set<ExpressionTree> toRemove = new HashSet<>();
    List<String> messages = new ArrayList<>();
    for (ExpressionTree exception : thrown) {
        Symbol sym = getSymbol(exception);
        if (exceptionsBySuper.containsKey(sym)) {
            Set<ExpressionTree> sub = exceptionsBySuper.get(sym);
            messages.add(String.format("%s %s of %s", oxfordJoin(", ", sub), sub.size() == 1 ? "is a subtype" : "are subtypes", sym.getSimpleName()));
            toRemove.addAll(sub);
        }
    }
    if (toRemove.isEmpty()) {
        return NO_MATCH;
    }
    // sort by order in input
    List<ExpressionTree> delete = ImmutableList.<ExpressionTree>copyOf(Iterables.filter(tree.getThrows(), Predicates.in(toRemove)));
    return buildDescription(delete.get(0)).setMessage("Redundant throws clause: " + oxfordJoin("; ", messages)).addFix(SuggestedFixes.deleteExceptions(tree, state, delete)).build();
}
Also used : ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) Type(com.sun.tools.javac.code.Type) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) ArrayList(java.util.ArrayList) ExpressionTree(com.sun.source.tree.ExpressionTree) HashSet(java.util.HashSet)

Example 24 with ExpressionTree

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

the class NullnessPropagationTransfer method fieldInitializerNullnessIfAvailable.

@Nullable
private Nullness fieldInitializerNullnessIfAvailable(ClassAndField accessed) {
    if (!traversed.add(accessed.symbol)) {
        // TODO(kmb): Try to recognize problems with initialization order
        return NULL;
    }
    try {
        JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
        TreePath fieldDeclPath = Trees.instance(javacEnv).getPath(accessed.symbol);
        // missing types.
        if (fieldDeclPath == null || fieldDeclPath.getCompilationUnit() != compilationUnit || !(fieldDeclPath.getLeaf() instanceof VariableTree)) {
            return null;
        }
        ExpressionTree initializer = ((VariableTree) fieldDeclPath.getLeaf()).getInitializer();
        if (initializer == null) {
            return null;
        }
        // Run flow analysis on field initializer.  This is inefficient compared to just walking
        // the initializer expression tree but it avoids duplicating the logic from this transfer
        // function into a method that operates on Javac Nodes.
        TreePath initializerPath = TreePath.getPath(fieldDeclPath, initializer);
        UnderlyingAST ast = new UnderlyingAST.CFGStatement(initializerPath.getLeaf());
        ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
        false, /* assumeAssertionsDisabled */
        false);
        Analysis<Nullness, LocalStore<Nullness>, NullnessPropagationTransfer> analysis = new Analysis<>(javacEnv, this);
        analysis.performAnalysis(cfg);
        return analysis.getValue(initializerPath.getLeaf());
    } finally {
        traversed.remove(accessed.symbol);
    }
}
Also used : TreePath(com.sun.source.util.TreePath) Analysis(org.checkerframework.dataflow.analysis.Analysis) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) VariableTree(com.sun.source.tree.VariableTree) ExpressionTree(com.sun.source.tree.ExpressionTree) LocalStore(com.google.errorprone.dataflow.LocalStore) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST) Nullable(javax.annotation.Nullable)

Example 25 with ExpressionTree

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

the class TrustingNullnessAnalysis method getFieldInitializerNullness.

/**
   * Returns {@link Nullness} of the initializer of the {@link VariableTree} at the leaf of the
   * given {@code fieldDeclPath}.  Returns {@link Nullness#NULL} should there be no initializer.
   */
// TODO(kmb): Fold this functionality into Dataflow.expressionDataflow
public Nullness getFieldInitializerNullness(TreePath fieldDeclPath, Context context) {
    Tree decl = fieldDeclPath.getLeaf();
    checkArgument(decl instanceof VariableTree && ((JCVariableDecl) decl).sym.getKind() == ElementKind.FIELD, "Leaf of fieldDeclPath must be a field declaration: %s", decl);
    ExpressionTree initializer = ((VariableTree) decl).getInitializer();
    if (initializer == null) {
        // An uninitialized field is null or 0 to start :)
        return ((JCVariableDecl) decl).type.isPrimitive() ? Nullness.NONNULL : Nullness.NULL;
    }
    TreePath initializerPath = TreePath.getPath(fieldDeclPath, initializer);
    JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
    UnderlyingAST ast = new UnderlyingAST.CFGStatement(decl);
    ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
    false, /* assumeAssertionsDisabled */
    false);
    Analysis<Nullness, LocalStore<Nullness>, TrustingNullnessPropagation> analysis = new Analysis<>(javacEnv, nullnessPropagation);
    analysis.performAnalysis(cfg);
    return analysis.getValue(initializer);
}
Also used : VariableTree(com.sun.source.tree.VariableTree) LocalStore(com.google.errorprone.dataflow.LocalStore) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) TreePath(com.sun.source.util.TreePath) Analysis(org.checkerframework.dataflow.analysis.Analysis) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) ExpressionTree(com.sun.source.tree.ExpressionTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST)

Aggregations

ExpressionTree (com.sun.source.tree.ExpressionTree)78 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)27 Tree (com.sun.source.tree.Tree)18 Type (com.sun.tools.javac.code.Type)18 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)16 Symbol (com.sun.tools.javac.code.Symbol)14 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)14 JCTree (com.sun.tools.javac.tree.JCTree)14 Fix (com.google.errorprone.fixes.Fix)13 VariableTree (com.sun.source.tree.VariableTree)13 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)13 IdentifierTree (com.sun.source.tree.IdentifierTree)12 MemberSelectTree (com.sun.source.tree.MemberSelectTree)12 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)11 VisitorState (com.google.errorprone.VisitorState)9 AssignmentTree (com.sun.source.tree.AssignmentTree)9 BinaryTree (com.sun.source.tree.BinaryTree)9 ExpressionStatementTree (com.sun.source.tree.ExpressionStatementTree)8 MethodTree (com.sun.source.tree.MethodTree)8 TreePath (com.sun.source.util.TreePath)8