private ConditionalState visitCondition(ExpressionTree tree, State newState) { State oldState = currentState; currentState = newState; ConditionalState result = visitCondition(tree); currentState = oldState; return result; }
private void visitorConditionalAnd(BinaryExpressionTree tree) { ConditionalState leftConditionalState = visitCondition(tree.leftOperand()); // in case of a conditional and, the current state for the right operand is the true state of the left one, // because the right operand is evaluated only if the left operand was true. ConditionalState rightConditionalState = visitCondition(tree.rightOperand(), leftConditionalState.trueState); if (currentConditionalState != null) { currentConditionalState.mergeConditionalAnd(leftConditionalState, rightConditionalState); } }
private void visitConditionalOr(BinaryExpressionTree tree) { ConditionalState leftConditionalState = visitCondition(tree.leftOperand()); // in case of a conditional or, the current state for the right operand is the false state of the left one, // because of the right operand is evaluated only if the left operand was false. ConditionalState rightConditionalState = visitCondition(tree.rightOperand(), leftConditionalState.falseState); if (currentConditionalState != null) { currentConditionalState.mergeConditionalOr(leftConditionalState, rightConditionalState); } }
@Override public void visitConditionalExpression(ConditionalExpressionTree tree) { ConditionalState conditionalState = visitCondition(tree.condition()); currentState = conditionalState.trueState; tree.trueExpression().accept(this); currentState = conditionalState.falseState; tree.falseExpression().accept(this); currentState = currentState.parentState.mergeValues(conditionalState.trueState, conditionalState.falseState); }
@Override public void visitIfStatement(IfStatementTree tree) { ConditionalState conditionalState = visitCondition(tree.condition()); currentState = conditionalState.trueState; tree.thenStatement().accept(this); if (tree.elseStatement() != null) { currentState = conditionalState.falseState; tree.elseStatement().accept(this); } currentState = currentState.parentState.mergeValues(conditionalState.trueState, conditionalState.falseState); }
@Override public void visitWhileStatement(WhileStatementTree tree) { ConditionalState conditionalState = visitCondition(tree.condition()); Set<VariableSymbol> assignedVariables = new AssignmentVisitor().findAssignedVariables(tree.statement()); currentState = conditionalState.trueState; currentState.invalidateVariables(assignedVariables); scan(tree.statement()); restorePreviousState(); currentState.invalidateVariables(assignedVariables); }
@Override public void visitForStatement(ForStatementTree tree) { scan(tree.initializer()); ConditionalState conditionalState = visitCondition(tree.condition()); Set<VariableSymbol> assignedVariables = new AssignmentVisitor().findAssignedVariables(tree.statement()); assignedVariables.addAll(new AssignmentVisitor().findAssignedVariables(tree.update())); currentState = conditionalState.trueState; currentState.invalidateVariables(assignedVariables); scan(tree.statement()); scan(tree.update()); restorePreviousState(); currentState.invalidateVariables(assignedVariables); }