use of org.checkerframework.dataflow.cfg.node.VariableDeclarationNode in project checker-framework by typetools.
the class CFGTranslationPhaseOne method visitUnary.
@Override
public Node visitUnary(UnaryTree tree, Void p) {
Node result = null;
Tree.Kind kind = tree.getKind();
switch(kind) {
case BITWISE_COMPLEMENT:
case UNARY_MINUS:
case UNARY_PLUS:
{
// see JLS 15.14 and 15.15
Node expr = scan(tree.getExpression(), p);
expr = unaryNumericPromotion(expr);
switch(kind) {
case BITWISE_COMPLEMENT:
result = new BitwiseComplementNode(tree, expr);
break;
case UNARY_MINUS:
result = new NumericalMinusNode(tree, expr);
break;
case UNARY_PLUS:
result = new NumericalPlusNode(tree, expr);
break;
default:
throw new BugInCF("Unexpected kind: " + kind);
}
extendWithNode(result);
break;
}
case LOGICAL_COMPLEMENT:
{
// see JLS 15.15.6
Node expr = scan(tree.getExpression(), p);
result = new ConditionalNotNode(tree, unbox(expr));
extendWithNode(result);
break;
}
case POSTFIX_DECREMENT:
case POSTFIX_INCREMENT:
case PREFIX_DECREMENT:
case PREFIX_INCREMENT:
{
ExpressionTree exprTree = tree.getExpression();
Node expr = scan(exprTree, p);
boolean isIncrement = kind == Tree.Kind.POSTFIX_INCREMENT || kind == Tree.Kind.PREFIX_INCREMENT;
boolean isPostfix = kind == Tree.Kind.POSTFIX_INCREMENT || kind == Tree.Kind.POSTFIX_DECREMENT;
AssignmentNode unaryAssign = createIncrementOrDecrementAssign(isPostfix ? null : tree, expr, isIncrement);
addToUnaryAssignLookupMap(tree, unaryAssign);
if (isPostfix) {
TypeMirror exprType = TreeUtils.typeOf(exprTree);
VariableTree tempVarDecl = treeBuilder.buildVariableDecl(exprType, uniqueName("tempPostfix"), findOwner(), tree.getExpression());
handleArtificialTree(tempVarDecl);
VariableDeclarationNode tempVarDeclNode = new VariableDeclarationNode(tempVarDecl);
tempVarDeclNode.setInSource(false);
extendWithNode(tempVarDeclNode);
Tree tempVar = treeBuilder.buildVariableUse(tempVarDecl);
handleArtificialTree(tempVar);
Node tempVarNode = new LocalVariableNode(tempVar);
tempVarNode.setInSource(false);
extendWithNode(tempVarNode);
AssignmentNode tempAssignNode = new AssignmentNode(tree, tempVarNode, expr);
tempAssignNode.setInSource(false);
extendWithNode(tempAssignNode);
Tree resultExpr = treeBuilder.buildVariableUse(tempVarDecl);
handleArtificialTree(resultExpr);
result = new LocalVariableNode(resultExpr);
result.setInSource(false);
extendWithNode(result);
} else {
result = unaryAssign;
}
break;
}
case OTHER:
default:
// special node NLLCHK
if (tree.toString().startsWith("<*nullchk*>")) {
Node expr = scan(tree.getExpression(), p);
result = new NullChkNode(tree, expr);
extendWithNode(result);
break;
}
throw new BugInCF("Unknown kind (" + kind + ") of unary expression: " + tree);
}
return result;
}
use of org.checkerframework.dataflow.cfg.node.VariableDeclarationNode 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 org.checkerframework.dataflow.cfg.node.VariableDeclarationNode in project checker-framework by typetools.
the class CFGTranslationPhaseOne method visitVariable.
@Override
public Node visitVariable(VariableTree tree, Void p) {
// see JLS 14.4
boolean isField = false;
if (getCurrentPath().getParentPath() != null) {
Tree.Kind kind = TreeUtils.getKindRecordAsClass(getCurrentPath().getParentPath().getLeaf());
// CLASS includes records.
if (kind == Tree.Kind.CLASS || kind == Tree.Kind.INTERFACE || kind == Tree.Kind.ENUM) {
isField = true;
}
}
Node node = null;
ClassTree enclosingClass = TreePathUtil.enclosingClass(getCurrentPath());
TypeElement classElem = TreeUtils.elementFromDeclaration(enclosingClass);
Node receiver = new ImplicitThisNode(classElem.asType());
if (isField) {
ExpressionTree initializer = tree.getInitializer();
assert initializer != null;
node = translateAssignment(tree, new FieldAccessNode(tree, TreeUtils.elementFromDeclaration(tree), receiver), initializer);
} else {
// local variable definition
VariableDeclarationNode decl = new VariableDeclarationNode(tree);
extendWithNode(decl);
// initializer
ExpressionTree initializer = tree.getInitializer();
if (initializer != null) {
node = translateAssignment(tree, new LocalVariableNode(tree, receiver), initializer);
}
}
return node;
}
use of org.checkerframework.dataflow.cfg.node.VariableDeclarationNode in project checker-framework by typetools.
the class CFGTranslationPhaseOne method visitConditionalExpression.
@Override
public Node visitConditionalExpression(ConditionalExpressionTree tree, Void p) {
// see JLS 15.25
TypeMirror exprType = TreeUtils.typeOf(tree);
Label trueStart = new Label();
Label falseStart = new Label();
Label merge = new Label();
// create a synthetic variable for the value of the conditional expression
VariableTree condExprVarTree = treeBuilder.buildVariableDecl(exprType, uniqueName("condExpr"), findOwner(), null);
VariableDeclarationNode condExprVarNode = new VariableDeclarationNode(condExprVarTree);
condExprVarNode.setInSource(false);
extendWithNode(condExprVarNode);
Node condition = unbox(scan(tree.getCondition(), p));
ConditionalJump cjump = new ConditionalJump(trueStart, falseStart);
extendWithExtendedNode(cjump);
addLabelForNextNode(trueStart);
ExpressionTree trueExprTree = tree.getTrueExpression();
Node trueExprNode = scan(trueExprTree, p);
trueExprNode = conditionalExprPromotion(trueExprNode, exprType);
extendWithAssignmentForConditionalExpr(condExprVarTree, trueExprTree, trueExprNode);
extendWithExtendedNode(new UnconditionalJump(merge, FlowRule.BOTH_TO_THEN));
addLabelForNextNode(falseStart);
ExpressionTree falseExprTree = tree.getFalseExpression();
Node falseExprNode = scan(falseExprTree, p);
falseExprNode = conditionalExprPromotion(falseExprNode, exprType);
extendWithAssignmentForConditionalExpr(condExprVarTree, falseExprTree, falseExprNode);
extendWithExtendedNode(new UnconditionalJump(merge, FlowRule.BOTH_TO_ELSE));
addLabelForNextNode(merge);
Pair<IdentifierTree, LocalVariableNode> treeAndLocalVarNode = extendWithVarUseNode(condExprVarTree);
Node node = new TernaryExpressionNode(tree, condition, trueExprNode, falseExprNode, treeAndLocalVarNode.second);
extendWithNode(node);
return node;
}
Aggregations