Search in sources :

Example 31 with VariableTree

use of com.sun.source.tree.VariableTree in project tutorials by eugenp.

the class SampleJavacPlugin method init.

@Override
public void init(JavacTask task, String... args) {
    Context context = ((BasicJavacTask) task).getContext();
    task.addTaskListener(new TaskListener() {

        @Override
        public void started(TaskEvent e) {
        }

        @Override
        public void finished(TaskEvent e) {
            if (e.getKind() != TaskEvent.Kind.PARSE) {
                return;
            }
            e.getCompilationUnit().accept(new TreeScanner<Void, Void>() {

                @Override
                public Void visitMethod(MethodTree method, Void v) {
                    List<VariableTree> parametersToInstrument = method.getParameters().stream().filter(SampleJavacPlugin.this::shouldInstrument).collect(Collectors.toList());
                    if (!parametersToInstrument.isEmpty()) {
                        // There is a possible case that more than one argument is marked by @Positive,
                        // as the checks are added to the method's body beginning, we process parameters RTL
                        // to ensure correct order.
                        Collections.reverse(parametersToInstrument);
                        parametersToInstrument.forEach(p -> addCheck(method, p, context));
                    }
                    // hence, we want to proceed with method body AST as well.
                    return super.visitMethod(method, v);
                }
            }, null);
        }
    });
}
Also used : Context(com.sun.tools.javac.util.Context) MethodTree(com.sun.source.tree.MethodTree) BasicJavacTask(com.sun.tools.javac.api.BasicJavacTask) VariableTree(com.sun.source.tree.VariableTree)

Example 32 with VariableTree

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

the class FindIdentifiers method inStaticContext.

/**
 * Returns true iff the leaf node of the {@code path} occurs in a JLS 8.3.1 static context.
 */
private static boolean inStaticContext(TreePath path) {
    Tree prev = path.getLeaf();
    path = path.getParentPath();
    ClassSymbol enclosingClass = ASTHelpers.getSymbol(ASTHelpers.findEnclosingNode(path, ClassTree.class));
    ClassSymbol directSuperClass = (ClassSymbol) enclosingClass.getSuperclass().tsym;
    for (Tree tree : path) {
        switch(tree.getKind()) {
            case METHOD:
                return ASTHelpers.getSymbol(tree).isStatic();
            case // static initializer
            BLOCK:
                if (((BlockTree) tree).isStatic()) {
                    return true;
                }
                break;
            case // variable initializer of static variable
            VARIABLE:
                VariableTree variableTree = (VariableTree) tree;
                VarSymbol variableSym = ASTHelpers.getSymbol(variableTree);
                if (variableSym.getKind() == ElementKind.FIELD) {
                    return Objects.equals(variableTree.getInitializer(), prev) && variableSym.isStatic();
                }
                break;
            case // JLS 8.8.7.1 explicit constructor invocation
            METHOD_INVOCATION:
                MethodSymbol methodSym = ASTHelpers.getSymbol((MethodInvocationTree) tree);
                if (methodSym == null) {
                    // visibility)
                    return true;
                }
                if (methodSym.isConstructor() && (Objects.equals(methodSym.owner, enclosingClass) || Objects.equals(methodSym.owner, directSuperClass))) {
                    return true;
                }
                break;
            default:
                break;
        }
        prev = tree;
    }
    return false;
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) ForLoopTree(com.sun.source.tree.ForLoopTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) TryTree(com.sun.source.tree.TryTree) BlockTree(com.sun.source.tree.BlockTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Example 33 with VariableTree

use of com.sun.source.tree.VariableTree 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;
        }
        ClassTree classTree = (ClassTree) fieldDeclPath.getParentPath().getLeaf();
        // 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(), classTree);
        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 : VariableTree(com.sun.source.tree.VariableTree) ClassTree(com.sun.source.tree.ClassTree) LocalStore(com.google.errorprone.dataflow.LocalStore) 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) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST) Nullable(javax.annotation.Nullable)

Example 34 with VariableTree

use of com.sun.source.tree.VariableTree 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);
    ClassTree classTree = (ClassTree) fieldDeclPath.getParentPath().getLeaf();
    JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
    UnderlyingAST ast = new UnderlyingAST.CFGStatement(decl, classTree);
    ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
    false, /* assumeAssertionsDisabled */
    false);
    try {
        nullnessPropagation.setContext(context).setCompilationUnit(fieldDeclPath.getCompilationUnit());
        Analysis<Nullness, LocalStore<Nullness>, TrustingNullnessPropagation> analysis = new Analysis<>(javacEnv, nullnessPropagation);
        analysis.performAnalysis(cfg);
        return analysis.getValue(initializer);
    } finally {
        nullnessPropagation.setContext(null).setCompilationUnit(null);
    }
}
Also used : VariableTree(com.sun.source.tree.VariableTree) ClassTree(com.sun.source.tree.ClassTree) 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) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST)

Example 35 with VariableTree

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

the class DataFlow method findEnclosingMethodOrLambdaOrInitializer.

// TODO(user), remove once we merge jdk8 specific's with core
private static <T> TreePath findEnclosingMethodOrLambdaOrInitializer(TreePath path) {
    while (path != null) {
        if (path.getLeaf() instanceof MethodTree) {
            return path;
        }
        TreePath parent = path.getParentPath();
        if (parent != null) {
            if (parent.getLeaf() instanceof ClassTree) {
                if (path.getLeaf() instanceof BlockTree) {
                    // this is a class or instance initializer block
                    return path;
                }
                if (path.getLeaf() instanceof VariableTree && ((VariableTree) path.getLeaf()).getInitializer() != null) {
                    // this is a field with an inline initializer
                    return path;
                }
            }
            if (parent.getLeaf() instanceof LambdaExpressionTree) {
                return parent;
            }
        }
        path = parent;
    }
    return null;
}
Also used : LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) VariableTree(com.sun.source.tree.VariableTree) BlockTree(com.sun.source.tree.BlockTree)

Aggregations

VariableTree (com.sun.source.tree.VariableTree)86 Tree (com.sun.source.tree.Tree)43 ClassTree (com.sun.source.tree.ClassTree)37 MethodTree (com.sun.source.tree.MethodTree)37 ExpressionTree (com.sun.source.tree.ExpressionTree)34 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)25 NewClassTree (com.sun.source.tree.NewClassTree)23 TreePath (com.sun.source.util.TreePath)23 IdentifierTree (com.sun.source.tree.IdentifierTree)22 JCTree (com.sun.tools.javac.tree.JCTree)21 MemberSelectTree (com.sun.source.tree.MemberSelectTree)19 AssignmentTree (com.sun.source.tree.AssignmentTree)17 ArrayList (java.util.ArrayList)17 BlockTree (com.sun.source.tree.BlockTree)16 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)13 Type (com.sun.tools.javac.code.Type)13 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)12 ReturnTree (com.sun.source.tree.ReturnTree)12 StatementTree (com.sun.source.tree.StatementTree)12 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)12