use of com.sun.source.tree.IdentifierTree in project checker-framework by typetools.
the class CFGTranslationPhaseOne method visitEnhancedForLoop.
@Override
public Node visitEnhancedForLoop(EnhancedForLoopTree tree, Void p) {
// see JLS 14.14.2
Name parentLabel = getLabel(getCurrentPath());
Label conditionStart = new Label();
Label loopEntry = new Label();
Label loopExit = new Label();
// If the loop is a labeled statement, then its continue target is identical for continues with
// no label and continues with the loop's label.
Label updateStart;
if (parentLabel != null) {
updateStart = continueLabels.get(parentLabel);
} else {
updateStart = new Label();
}
TryFinallyScopeCell oldBreakTargetL = breakTargetL;
breakTargetL = new TryFinallyScopeCell(loopExit);
TryFinallyScopeCell oldContinueTargetL = continueTargetL;
continueTargetL = new TryFinallyScopeCell(updateStart);
// Distinguish loops over Iterables from loops over arrays.
VariableTree variable = tree.getVariable();
VariableElement variableElement = TreeUtils.elementFromDeclaration(variable);
ExpressionTree expression = tree.getExpression();
StatementTree statement = tree.getStatement();
TypeMirror exprType = TreeUtils.typeOf(expression);
if (types.isSubtype(exprType, iterableType)) {
// Take the upper bound of a type variable or wildcard
exprType = TypesUtils.upperBound(exprType);
assert (exprType instanceof DeclaredType) : "an Iterable must be a DeclaredType";
DeclaredType declaredExprType = (DeclaredType) exprType;
declaredExprType.getTypeArguments();
MemberSelectTree iteratorSelect = treeBuilder.buildIteratorMethodAccess(expression);
handleArtificialTree(iteratorSelect);
MethodInvocationTree iteratorCall = treeBuilder.buildMethodInvocation(iteratorSelect);
handleArtificialTree(iteratorCall);
VariableTree iteratorVariable = createEnhancedForLoopIteratorVariable(iteratorCall, variableElement);
handleArtificialTree(iteratorVariable);
VariableDeclarationNode iteratorVariableDecl = new VariableDeclarationNode(iteratorVariable);
iteratorVariableDecl.setInSource(false);
extendWithNode(iteratorVariableDecl);
Node expressionNode = scan(expression, p);
MethodAccessNode iteratorAccessNode = new MethodAccessNode(iteratorSelect, expressionNode);
iteratorAccessNode.setInSource(false);
extendWithNode(iteratorAccessNode);
MethodInvocationNode iteratorCallNode = new MethodInvocationNode(iteratorCall, iteratorAccessNode, Collections.emptyList(), getCurrentPath());
iteratorCallNode.setInSource(false);
extendWithNode(iteratorCallNode);
translateAssignment(iteratorVariable, new LocalVariableNode(iteratorVariable), iteratorCallNode);
// Test the loop ending condition
addLabelForNextNode(conditionStart);
IdentifierTree iteratorUse1 = treeBuilder.buildVariableUse(iteratorVariable);
handleArtificialTree(iteratorUse1);
LocalVariableNode iteratorReceiverNode = new LocalVariableNode(iteratorUse1);
iteratorReceiverNode.setInSource(false);
extendWithNode(iteratorReceiverNode);
MemberSelectTree hasNextSelect = treeBuilder.buildHasNextMethodAccess(iteratorUse1);
handleArtificialTree(hasNextSelect);
MethodAccessNode hasNextAccessNode = new MethodAccessNode(hasNextSelect, iteratorReceiverNode);
hasNextAccessNode.setInSource(false);
extendWithNode(hasNextAccessNode);
MethodInvocationTree hasNextCall = treeBuilder.buildMethodInvocation(hasNextSelect);
handleArtificialTree(hasNextCall);
MethodInvocationNode hasNextCallNode = new MethodInvocationNode(hasNextCall, hasNextAccessNode, Collections.emptyList(), getCurrentPath());
hasNextCallNode.setInSource(false);
extendWithNode(hasNextCallNode);
extendWithExtendedNode(new ConditionalJump(loopEntry, loopExit));
// Loop body, starting with declaration of the loop iteration variable
addLabelForNextNode(loopEntry);
extendWithNode(new VariableDeclarationNode(variable));
IdentifierTree iteratorUse2 = treeBuilder.buildVariableUse(iteratorVariable);
handleArtificialTree(iteratorUse2);
LocalVariableNode iteratorReceiverNode2 = new LocalVariableNode(iteratorUse2);
iteratorReceiverNode2.setInSource(false);
extendWithNode(iteratorReceiverNode2);
MemberSelectTree nextSelect = treeBuilder.buildNextMethodAccess(iteratorUse2);
handleArtificialTree(nextSelect);
MethodAccessNode nextAccessNode = new MethodAccessNode(nextSelect, iteratorReceiverNode2);
nextAccessNode.setInSource(false);
extendWithNode(nextAccessNode);
MethodInvocationTree nextCall = treeBuilder.buildMethodInvocation(nextSelect);
handleArtificialTree(nextCall);
MethodInvocationNode nextCallNode = new MethodInvocationNode(nextCall, nextAccessNode, Collections.emptyList(), getCurrentPath());
// If the type of iteratorVariable is a capture, its type tree may be missing annotations, so
// save the expression in the node so that the full type can be found later.
nextCallNode.setIterableExpression(expression);
nextCallNode.setInSource(false);
extendWithNode(nextCallNode);
AssignmentNode assignNode = translateAssignment(variable, new LocalVariableNode(variable), nextCall);
// translateAssignment() scans variable and creates new nodes, so set the expression
// there, too.
((MethodInvocationNode) assignNode.getExpression()).setIterableExpression(expression);
assert statement != null;
scan(statement, p);
// Loop back edge
addLabelForNextNode(updateStart);
extendWithExtendedNode(new UnconditionalJump(conditionStart));
} else {
// TODO: Shift any labels after the initialization of the
// temporary array variable.
VariableTree arrayVariable = createEnhancedForLoopArrayVariable(expression, variableElement);
handleArtificialTree(arrayVariable);
VariableDeclarationNode arrayVariableNode = new VariableDeclarationNode(arrayVariable);
arrayVariableNode.setInSource(false);
extendWithNode(arrayVariableNode);
Node expressionNode = scan(expression, p);
translateAssignment(arrayVariable, new LocalVariableNode(arrayVariable), expressionNode);
// Declare and initialize the loop index variable
TypeMirror intType = types.getPrimitiveType(TypeKind.INT);
LiteralTree zero = treeBuilder.buildLiteral(Integer.valueOf(0));
handleArtificialTree(zero);
VariableTree indexVariable = treeBuilder.buildVariableDecl(intType, uniqueName("index"), variableElement.getEnclosingElement(), zero);
handleArtificialTree(indexVariable);
VariableDeclarationNode indexVariableNode = new VariableDeclarationNode(indexVariable);
indexVariableNode.setInSource(false);
extendWithNode(indexVariableNode);
IntegerLiteralNode zeroNode = new IntegerLiteralNode(zero);
extendWithNode(zeroNode);
translateAssignment(indexVariable, new LocalVariableNode(indexVariable), zeroNode);
// Compare index to array length
addLabelForNextNode(conditionStart);
IdentifierTree indexUse1 = treeBuilder.buildVariableUse(indexVariable);
handleArtificialTree(indexUse1);
LocalVariableNode indexNode1 = new LocalVariableNode(indexUse1);
indexNode1.setInSource(false);
extendWithNode(indexNode1);
IdentifierTree arrayUse1 = treeBuilder.buildVariableUse(arrayVariable);
handleArtificialTree(arrayUse1);
LocalVariableNode arrayNode1 = new LocalVariableNode(arrayUse1);
extendWithNode(arrayNode1);
MemberSelectTree lengthSelect = treeBuilder.buildArrayLengthAccess(arrayUse1);
handleArtificialTree(lengthSelect);
FieldAccessNode lengthAccessNode = new FieldAccessNode(lengthSelect, arrayNode1);
lengthAccessNode.setInSource(false);
extendWithNode(lengthAccessNode);
BinaryTree lessThan = treeBuilder.buildLessThan(indexUse1, lengthSelect);
handleArtificialTree(lessThan);
LessThanNode lessThanNode = new LessThanNode(lessThan, indexNode1, lengthAccessNode);
lessThanNode.setInSource(false);
extendWithNode(lessThanNode);
extendWithExtendedNode(new ConditionalJump(loopEntry, loopExit));
// Loop body, starting with declaration of the loop iteration variable
addLabelForNextNode(loopEntry);
extendWithNode(new VariableDeclarationNode(variable));
IdentifierTree arrayUse2 = treeBuilder.buildVariableUse(arrayVariable);
handleArtificialTree(arrayUse2);
LocalVariableNode arrayNode2 = new LocalVariableNode(arrayUse2);
arrayNode2.setInSource(false);
extendWithNode(arrayNode2);
IdentifierTree indexUse2 = treeBuilder.buildVariableUse(indexVariable);
handleArtificialTree(indexUse2);
LocalVariableNode indexNode2 = new LocalVariableNode(indexUse2);
indexNode2.setInSource(false);
extendWithNode(indexNode2);
ArrayAccessTree arrayAccess = treeBuilder.buildArrayAccess(arrayUse2, indexUse2);
handleArtificialTree(arrayAccess);
ArrayAccessNode arrayAccessNode = new ArrayAccessNode(arrayAccess, arrayNode2, indexNode2);
arrayAccessNode.setArrayExpression(expression);
arrayAccessNode.setInSource(false);
extendWithNode(arrayAccessNode);
AssignmentNode arrayAccessAssignNode = translateAssignment(variable, new LocalVariableNode(variable), arrayAccessNode);
extendWithNodeWithException(arrayAccessNode, nullPointerExceptionType);
// translateAssignment() scans variable and creates new nodes, so set the expression
// there, too.
Node arrayAccessAssignNodeExpr = arrayAccessAssignNode.getExpression();
if (arrayAccessAssignNodeExpr instanceof ArrayAccessNode) {
((ArrayAccessNode) arrayAccessAssignNodeExpr).setArrayExpression(expression);
} else if (arrayAccessAssignNodeExpr instanceof MethodInvocationNode) {
// If the array component type is a primitive, there may be a boxing or unboxing
// conversion. Treat that as an iterator.
MethodInvocationNode boxingNode = (MethodInvocationNode) arrayAccessAssignNodeExpr;
boxingNode.setIterableExpression(expression);
}
assert statement != null;
scan(statement, p);
// Loop back edge
addLabelForNextNode(updateStart);
IdentifierTree indexUse3 = treeBuilder.buildVariableUse(indexVariable);
handleArtificialTree(indexUse3);
LocalVariableNode indexNode3 = new LocalVariableNode(indexUse3);
indexNode3.setInSource(false);
extendWithNode(indexNode3);
LiteralTree oneTree = treeBuilder.buildLiteral(Integer.valueOf(1));
handleArtificialTree(oneTree);
Node one = new IntegerLiteralNode(oneTree);
one.setInSource(false);
extendWithNode(one);
BinaryTree addOneTree = treeBuilder.buildBinary(intType, Tree.Kind.PLUS, indexUse3, oneTree);
handleArtificialTree(addOneTree);
Node addOneNode = new NumericalAdditionNode(addOneTree, indexNode3, one);
addOneNode.setInSource(false);
extendWithNode(addOneNode);
AssignmentTree assignTree = treeBuilder.buildAssignment(indexUse3, addOneTree);
handleArtificialTree(assignTree);
Node assignNode = new AssignmentNode(assignTree, indexNode3, addOneNode);
assignNode.setInSource(false);
extendWithNode(assignNode);
extendWithExtendedNode(new UnconditionalJump(conditionStart));
}
// Loop exit
addLabelForNextNode(loopExit);
breakTargetL = oldBreakTargetL;
continueTargetL = oldContinueTargetL;
return null;
}
use of com.sun.source.tree.IdentifierTree in project checker-framework by typetools.
the class TreeUtils method isSpecificFieldAccess.
/**
* Returns true if and only if the given {@code tree} represents a field access of the given
* {@link VariableElement}.
*/
public static boolean isSpecificFieldAccess(Tree tree, VariableElement var) {
if (tree instanceof MemberSelectTree) {
MemberSelectTree memSel = (MemberSelectTree) tree;
assert isUseOfElement(memSel) : "@AssumeAssertion(nullness): tree kind";
Element field = TreeUtils.elementFromUse(memSel);
return field.equals(var);
} else if (tree instanceof IdentifierTree) {
IdentifierTree idTree = (IdentifierTree) tree;
assert isUseOfElement(idTree) : "@AssumeAssertion(nullness): tree kind";
Element field = TreeUtils.elementFromUse(idTree);
return field.equals(var);
} else {
return false;
}
}
use of com.sun.source.tree.IdentifierTree in project checker-framework by typetools.
the class TreeUtils method isFieldAccess.
/**
* Determine whether {@code tree} is a field access expression, such as
*
* <pre>
* <em>f</em>
* <em>obj</em> . <em>f</em>
* </pre>
*
* This method currently also returns true for class literals and qualified this.
*
* @param tree a tree that might be a field access
* @return true iff if tree is a field access expression (implicit or explicit)
*/
public static boolean isFieldAccess(Tree tree) {
if (tree.getKind() == Tree.Kind.MEMBER_SELECT) {
// explicit member access (or a class literal or a qualified this)
MemberSelectTree memberSelect = (MemberSelectTree) tree;
assert isUseOfElement(memberSelect) : "@AssumeAssertion(nullness): tree kind";
Element el = TreeUtils.elementFromUse(memberSelect);
return el.getKind().isField();
} else if (tree.getKind() == Tree.Kind.IDENTIFIER) {
// implicit field access
IdentifierTree ident = (IdentifierTree) tree;
assert isUseOfElement(ident) : "@AssumeAssertion(nullness): tree kind";
Element el = TreeUtils.elementFromUse(ident);
return el.getKind().isField() && !ident.getName().contentEquals("this") && !ident.getName().contentEquals("super");
}
return false;
}
use of com.sun.source.tree.IdentifierTree in project checker-framework by typetools.
the class TreeUtils method isSelfAccess.
/**
* Returns true if the tree is a tree that 'looks like' either an access of a field or an
* invocation of a method that are owned by the same accessing instance.
*
* <p>It would only return true if the access tree is of the form:
*
* <pre>
* field
* this.field
*
* method()
* this.method()
* </pre>
*
* It does not perform any semantical check to differentiate between fields and local variables;
* local methods or imported static methods.
*
* @param tree expression tree representing an access to object member
* @return {@code true} iff the member is a member of {@code this} instance
*/
public static boolean isSelfAccess(final ExpressionTree tree) {
ExpressionTree tr = TreeUtils.withoutParens(tree);
// If method invocation check the method select
if (tr.getKind() == Tree.Kind.ARRAY_ACCESS) {
return false;
}
if (tree.getKind() == Tree.Kind.METHOD_INVOCATION) {
tr = ((MethodInvocationTree) tree).getMethodSelect();
}
tr = TreeUtils.withoutParens(tr);
if (tr.getKind() == Tree.Kind.TYPE_CAST) {
tr = ((TypeCastTree) tr).getExpression();
}
tr = TreeUtils.withoutParens(tr);
if (tr.getKind() == Tree.Kind.IDENTIFIER) {
return true;
}
if (tr.getKind() == Tree.Kind.MEMBER_SELECT) {
tr = ((MemberSelectTree) tr).getExpression();
if (tr.getKind() == Tree.Kind.IDENTIFIER) {
Name ident = ((IdentifierTree) tr).getName();
return ident.contentEquals("this") || ident.contentEquals("super");
}
}
return false;
}
use of com.sun.source.tree.IdentifierTree in project bazel by bazelbuild.
the class TreeUtils method isSpecificFieldAccess.
/**
* Returns true if and only if the given {@code tree} represents a field
* access of the given {@link VariableElement}.
*/
public static boolean isSpecificFieldAccess(Tree tree, VariableElement var) {
if (tree instanceof MemberSelectTree) {
MemberSelectTree memSel = (MemberSelectTree) tree;
Element field = TreeUtils.elementFromUse(memSel);
return field.equals(var);
} else if (tree instanceof IdentifierTree) {
IdentifierTree idTree = (IdentifierTree) tree;
Element field = TreeUtils.elementFromUse(idTree);
return field.equals(var);
} else {
return false;
}
}
Aggregations