Search in sources :

Example 1 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.

the class GenericAnnotatedTypeFactory method analyze.

protected void analyze(Queue<ClassTree> queue, Queue<Pair<LambdaExpressionTree, Store>> lambdaQueue, UnderlyingAST ast, List<Pair<VariableElement, Value>> fieldValues, ClassTree currentClass, boolean isInitializationCode, boolean updateInitializationStore, boolean isStatic, Store lambdaStore) {
    CFGBuilder builder = new CFCFGBuilder(checker, this);
    ControlFlowGraph cfg = builder.run(root, processingEnv, ast);
    FlowAnalysis newAnalysis = createFlowAnalysis(fieldValues);
    TransferFunction transfer = newAnalysis.getTransferFunction();
    if (emptyStore == null) {
        emptyStore = newAnalysis.createEmptyStore(transfer.usesSequentialSemantics());
    }
    analyses.addFirst(newAnalysis);
    if (lambdaStore != null) {
        transfer.setFixedInitialStore(lambdaStore);
    } else {
        Store initStore = !isStatic ? initializationStore : initializationStaticStore;
        if (isInitializationCode) {
            if (initStore != null) {
                // we have already seen initialization code and analyzed it, and
                // the analysis ended with the store initStore.
                // use it to start the next analysis.
                transfer.setFixedInitialStore(initStore);
            }
        }
    }
    analyses.getFirst().performAnalysis(cfg);
    AnalysisResult<Value, Store> result = analyses.getFirst().getResult();
    // store result
    flowResult.combine(result);
    if (ast.getKind() == UnderlyingAST.Kind.METHOD) {
        // store exit store (for checking postconditions)
        CFGMethod mast = (CFGMethod) ast;
        MethodTree method = mast.getMethod();
        Store regularExitStore = analyses.getFirst().getRegularExitStore();
        if (regularExitStore != null) {
            regularExitStores.put(method, regularExitStore);
        }
        returnStatementStores.put(method, analyses.getFirst().getReturnStatementStores());
    } else if (ast.getKind() == UnderlyingAST.Kind.ARBITRARY_CODE) {
        CFGStatement block = (CFGStatement) ast;
        Store regularExitStore = analyses.getFirst().getRegularExitStore();
        if (regularExitStore != null) {
            regularExitStores.put(block.getCode(), regularExitStore);
        }
    } else if (ast.getKind() == UnderlyingAST.Kind.LAMBDA) {
        // TODO: Postconditions?
        CFGLambda block = (CFGLambda) ast;
        Store regularExitStore = analyses.getFirst().getRegularExitStore();
        if (regularExitStore != null) {
            regularExitStores.put(block.getCode(), regularExitStore);
        }
    }
    if (isInitializationCode && updateInitializationStore) {
        Store newInitStore = analyses.getFirst().getRegularExitStore();
        if (!isStatic) {
            initializationStore = newInitStore;
        } else {
            initializationStaticStore = newInitStore;
        }
    }
    if (checker.hasOption("flowdotdir") || checker.hasOption("cfgviz")) {
        handleCFGViz();
    }
    analyses.removeFirst();
    // add classes declared in method
    queue.addAll(builder.getDeclaredClasses());
    for (LambdaExpressionTree lambda : builder.getDeclaredLambdas()) {
        lambdaQueue.add(Pair.of(lambda, getStoreBefore(lambda)));
    }
}
Also used : CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) MethodTree(com.sun.source.tree.MethodTree) CFGStatement(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGStatement) CFCFGBuilder(org.checkerframework.framework.flow.CFCFGBuilder) CFGBuilder(org.checkerframework.dataflow.cfg.CFGBuilder) CFStore(org.checkerframework.framework.flow.CFStore) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) CFValue(org.checkerframework.framework.flow.CFValue) CFGLambda(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGLambda) CFCFGBuilder(org.checkerframework.framework.flow.CFCFGBuilder)

Example 2 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.

the class Analysis method init.

/**
 * Initialize the analysis with a new control flow graph.
 */
protected void init(ControlFlowGraph cfg) {
    this.cfg = cfg;
    thenStores = new IdentityHashMap<>();
    elseStores = new IdentityHashMap<>();
    blockCount = maxCountBeforeWidening == -1 ? null : new IdentityHashMap<>();
    inputs = new IdentityHashMap<>();
    storesAtReturnStatements = new IdentityHashMap<>();
    worklist = new Worklist(cfg);
    nodeValues = new IdentityHashMap<>();
    finalLocalValues = new HashMap<>();
    worklist.add(cfg.getEntryBlock());
    List<LocalVariableNode> parameters = null;
    UnderlyingAST underlyingAST = cfg.getUnderlyingAST();
    if (underlyingAST.getKind() == Kind.METHOD) {
        MethodTree tree = ((CFGMethod) underlyingAST).getMethod();
        parameters = new ArrayList<>();
        for (VariableTree p : tree.getParameters()) {
            LocalVariableNode var = new LocalVariableNode(p);
            parameters.add(var);
        // TODO: document that LocalVariableNode has no block that it
        // belongs to
        }
    } else if (underlyingAST.getKind() == Kind.LAMBDA) {
        LambdaExpressionTree lambda = ((CFGLambda) underlyingAST).getLambdaTree();
        parameters = new ArrayList<>();
        for (VariableTree p : lambda.getParameters()) {
            LocalVariableNode var = new LocalVariableNode(p);
            parameters.add(var);
        // TODO: document that LocalVariableNode has no block that it
        // belongs to
        }
    } else {
    // nothing to do
    }
    S initialStore = transferFunction.initialStore(underlyingAST, parameters);
    Block entry = cfg.getEntryBlock();
    thenStores.put(entry, initialStore);
    elseStores.put(entry, initialStore);
    inputs.put(entry, new TransferInput<>(null, this, initialStore));
}
Also used : MethodTree(com.sun.source.tree.MethodTree) CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) IdentityHashMap(java.util.IdentityHashMap) VariableTree(com.sun.source.tree.VariableTree) ArrayList(java.util.ArrayList) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST)

Example 3 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.

the class GuiEffectVisitor method visitReturn.

// Returning a lambda expression also triggers inference based on the method's return type.
@Override
public Void visitReturn(ReturnTree node, Void p) {
    Void result = super.visitReturn(node, p);
    if (node.getExpression() != null && node.getExpression().getKind() == Tree.Kind.LAMBDA_EXPRESSION) {
        // Unfortunatelly, need to duplicate a fair bit of BaseTypeVisitor.visitReturn after lambdas have been
        // inferred.
        Pair<Tree, AnnotatedTypeMirror> preAssCtxt = visitorState.getAssignmentContext();
        try {
            Tree enclosing = TreeUtils.enclosingMethodOrLambda(getCurrentPath());
            AnnotatedTypeMirror ret = null;
            if (enclosing.getKind() == Tree.Kind.METHOD) {
                MethodTree enclosingMethod = (MethodTree) enclosing;
                boolean valid = validateTypeOf(enclosing);
                if (valid) {
                    ret = atypeFactory.getMethodReturnType(enclosingMethod, node);
                }
            } else {
                ret = atypeFactory.getFnInterfaceFromTree((LambdaExpressionTree) enclosing).second.getReturnType();
            }
            if (ret != null) {
                visitorState.setAssignmentContext(Pair.of((Tree) node, ret));
                lambdaAssignmentCheck(ret, (LambdaExpressionTree) node.getExpression(), "return.type.incompatible");
            }
        } finally {
            visitorState.setAssignmentContext(preAssCtxt);
        }
    }
    return result;
}
Also used : LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) MethodTree(com.sun.source.tree.MethodTree) ReturnTree(com.sun.source.tree.ReturnTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 4 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree 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)

Example 5 with LambdaExpressionTree

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

the class WakelockReleasedDangerously method getFix.

private SuggestedFix getFix(Tree releaseStatement, Symbol wakelockSymbol, VisitorState state) {
    // Wrap the release call line in a try/catch(RuntimeException) block.
    String before = "\ntry {\n";
    String after = "\n} catch (RuntimeException unused) {\n" + "// Ignore: already released by timeout.\n" + "// TODO: Log this exception.\n" + "}\n";
    // only wrap body (not args) and convert to block lambda.
    if (releaseStatement.getKind() == Kind.LAMBDA_EXPRESSION) {
        LambdaExpressionTree enclosingLambda = (LambdaExpressionTree) releaseStatement;
        if (enclosingLambda.getBodyKind() == BodyKind.EXPRESSION) {
            releaseStatement = enclosingLambda.getBody();
            before = "{" + before;
            after = ";" + after + "}";
        }
    }
    // Remove `if (wakelock.isHeld())` check.
    // TODO(epmjohnston): can avoid this if no isHeld check in class (check call map).
    IfTree enclosingIfHeld = findEnclosingNode(state.getPath(), IfTree.class);
    if (enclosingIfHeld != null) {
        ExpressionTree condition = ASTHelpers.stripParentheses(enclosingIfHeld.getCondition());
        if (enclosingIfHeld.getElseStatement() == null && instanceMethod().onExactClass(WAKELOCK_CLASS_NAME).named("isHeld").matches(condition, state) && wakelockSymbol.equals(getSymbol(getReceiver(condition)))) {
            String ifBody = state.getSourceForNode(enclosingIfHeld.getThenStatement()).trim();
            // Remove leading and trailing `{}`
            ifBody = ifBody.startsWith("{") ? ifBody.substring(1) : ifBody;
            ifBody = ifBody.endsWith("}") ? ifBody.substring(0, ifBody.length() - 1) : ifBody;
            ifBody = ifBody.trim();
            String releaseStatementSource = state.getSourceForNode(releaseStatement);
            return SuggestedFix.replace(enclosingIfHeld, ifBody.replace(releaseStatementSource, before + releaseStatementSource + after));
        }
    }
    return SuggestedFix.builder().prefixWith(releaseStatement, before).postfixWith(releaseStatement, after).build();
}
Also used : LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) IfTree(com.sun.source.tree.IfTree)

Aggregations

LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)22 MethodTree (com.sun.source.tree.MethodTree)19 VariableTree (com.sun.source.tree.VariableTree)15 ExpressionTree (com.sun.source.tree.ExpressionTree)14 Tree (com.sun.source.tree.Tree)13 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)12 NewClassTree (com.sun.source.tree.NewClassTree)11 ClassTree (com.sun.source.tree.ClassTree)10 ReturnTree (com.sun.source.tree.ReturnTree)9 AssignmentTree (com.sun.source.tree.AssignmentTree)8 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)7 AnnotationTree (com.sun.source.tree.AnnotationTree)6 MemberReferenceTree (com.sun.source.tree.MemberReferenceTree)6 MemberSelectTree (com.sun.source.tree.MemberSelectTree)6 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)6 TreePath (com.sun.source.util.TreePath)5 CFGMethod (org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod)5 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)4 CompoundAssignmentTree (com.sun.source.tree.CompoundAssignmentTree)4 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)4