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)));
}
}
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));
}
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;
}
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;
}
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();
}
Aggregations