use of com.sun.source.tree.LambdaExpressionTree in project error-prone by google.
the class JdkObsolete method getTargetType.
static Type getTargetType(VisitorState state) {
Tree parent = state.getPath().getParentPath().getLeaf();
Type type;
if (parent instanceof VariableTree || parent instanceof AssignmentTree) {
type = ASTHelpers.getType(parent);
} else if (parent instanceof ReturnTree || parent instanceof LambdaExpressionTree) {
type = getMethodOrLambdaReturnType(state);
} else if (parent instanceof MethodInvocationTree) {
MethodInvocationTree tree = (MethodInvocationTree) parent;
int idx = tree.getArguments().indexOf(state.getPath().getLeaf());
if (idx == -1) {
return null;
}
Type methodType = ASTHelpers.getType(tree.getMethodSelect());
if (idx >= methodType.getParameterTypes().size()) {
return null;
}
return methodType.getParameterTypes().get(idx);
} else {
return null;
}
Tree tree = state.getPath().getLeaf();
if (tree instanceof MemberReferenceTree) {
type = state.getTypes().findDescriptorType(ASTHelpers.getType(tree)).getReturnType();
}
return type;
}
use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.
the class CFGTranslationPhaseOne method process.
/**
* Performs the actual work of phase one.
*
* @param bodyPath path to the body of the underlying AST's method
* @param underlyingAST the AST for which the CFG is to be built
* @return the result of phase one
*/
public PhaseOneResult process(TreePath bodyPath, UnderlyingAST underlyingAST) {
// traverse AST of the method body
this.path = bodyPath;
try {
// "finally" clause is "this.path = null"
Node finalNode = scan(path.getLeaf(), null);
// add an extra node for the result of that lambda
if (underlyingAST.getKind() == UnderlyingAST.Kind.LAMBDA) {
LambdaExpressionTree lambdaTree = ((UnderlyingAST.CFGLambda) underlyingAST).getLambdaTree();
if (lambdaTree.getBodyKind() == LambdaExpressionTree.BodyKind.EXPRESSION) {
Node resultNode = new LambdaResultExpressionNode((ExpressionTree) lambdaTree.getBody(), finalNode);
extendWithNode(resultNode);
}
}
// Add marker to indicate that the next block will be the exit block.
// Note: if there is a return statement earlier in the method (which is always the case for
// non-void methods), then this is not strictly necessary. However, it is also not a problem,
// as it will just generate a degenerate control graph case that will be removed in a later
// phase.
nodeList.add(new UnconditionalJump(regularExitLabel));
return new PhaseOneResult(underlyingAST, treeLookupMap, convertedTreeLookupMap, unaryAssignNodeLookupMap, nodeList, bindings, leaders, returnNodes, regularExitLabel, exceptionalExitLabel, declaredClasses, declaredLambdas);
} finally {
this.path = null;
}
}
use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.
the class CFGTranslationPhaseOne method findOwner.
/**
* Find nearest owner element (Method or Class) which holds current tree.
*
* @return nearest owner element of current tree
*/
private Element findOwner() {
Tree enclosingMethodOrLambda = TreePathUtil.enclosingMethodOrLambda(getCurrentPath());
if (enclosingMethodOrLambda != null) {
if (enclosingMethodOrLambda.getKind() == Kind.METHOD) {
return TreeUtils.elementFromDeclaration((MethodTree) enclosingMethodOrLambda);
} else {
// The current path is in a lambda tree. In this case the owner is either a method or
// an initializer block.
LambdaExpressionTree lambdaTree = (LambdaExpressionTree) enclosingMethodOrLambda;
if (!lambdaTree.getParameters().isEmpty()) {
// If there is a lambda parameter, use the same owner.
return TreeUtils.elementFromDeclaration(lambdaTree.getParameters().get(0)).getEnclosingElement();
}
// If there are no lambda parameters then if the lambda is enclosed in a method, that's the
// owner.
MethodTree enclosingMethod = TreePathUtil.enclosingMethod(getCurrentPath());
if (enclosingMethod != null) {
return TreeUtils.elementFromDeclaration(enclosingMethod);
}
// If the lambda is not enclosed in a method, then the owner should be a constructor. javac
// seems to use the last constructor in the list. (If the lambda is in an initializer of a
// static field then the owner should be a static initializer block, but there doesn't seem
// to be a way to get a reference to the static initializer element.)
ClassTree enclosingClass = TreePathUtil.enclosingClass(getCurrentPath());
TypeElement typeElement = TreeUtils.elementFromDeclaration(enclosingClass);
ExecutableElement constructor = null;
for (Element enclosing : typeElement.getEnclosedElements()) {
if (enclosing.getKind() == ElementKind.CONSTRUCTOR) {
constructor = (ExecutableElement) enclosing;
}
}
return constructor;
}
} else {
ClassTree enclosingClass = TreePathUtil.enclosingClass(getCurrentPath());
return TreeUtils.elementFromDeclaration(enclosingClass);
}
}
use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.
the class BaseTypeVisitor method visitReturn.
/**
* Checks that the type of the return expression is a subtype of the enclosing method required
* return type. If not, it issues a "return" error.
*/
@Override
public Void visitReturn(ReturnTree node, Void p) {
// Don't try to check return expressions for void methods.
if (node.getExpression() == null) {
return super.visitReturn(node, p);
}
Tree enclosing = TreePathUtil.enclosingOfKind(getCurrentPath(), new HashSet<>(Arrays.asList(Tree.Kind.METHOD, Tree.Kind.LAMBDA_EXPRESSION)));
AnnotatedTypeMirror ret = null;
if (enclosing.getKind() == Tree.Kind.METHOD) {
MethodTree enclosingMethod = TreePathUtil.enclosingMethod(getCurrentPath());
boolean valid = validateTypeOf(enclosing);
if (valid) {
ret = atypeFactory.getMethodReturnType(enclosingMethod, node);
}
} else {
AnnotatedExecutableType result = atypeFactory.getFunctionTypeFromTree((LambdaExpressionTree) enclosing);
ret = result.getReturnType();
}
if (ret != null) {
commonAssignmentCheck(ret, node.getExpression(), "return");
}
return super.visitReturn(node, p);
}
use of com.sun.source.tree.LambdaExpressionTree in project bazel by bazelbuild.
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<>();
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));
}
Aggregations