/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* This file was originally derived from the Polyglot extensible compiler framework.
*
* (C) Copyright 2000-2007 Polyglot project group, Cornell University
* (C) Copyright IBM Corporation 2007-2012.
*/
package polyglot.ast;
import java.util.List;
import polyglot.types.*;
import polyglot.util.CodeWriter;
import polyglot.util.Position;
import polyglot.visit.*;
/**
* An immutable representation of a Java language <code>if</code> statement.
* Contains an expression whose value is tested, a ``then'' statement
* (consequent), and optionally an ``else'' statement (alternate).
*/
public abstract class If_c extends Stmt_c implements If
{
protected Expr cond;
protected Stmt consequent;
protected Stmt alternative;
public If_c(Position pos, Expr cond, Stmt consequent, Stmt alternative) {
super(pos);
assert(cond != null && consequent != null); // alternative may be null;
this.cond = cond;
this.consequent = consequent;
this.alternative = alternative;
}
/** Get the conditional of the statement. */
public Expr cond() {
return this.cond;
}
/** Set the conditional of the statement. */
public If cond(Expr cond) {
If_c n = (If_c) copy();
n.cond = cond;
return n;
}
/** Get the consequent of the statement. */
public Stmt consequent() {
return this.consequent;
}
/** Set the consequent of the statement. */
public If consequent(Stmt consequent) {
If_c n = (If_c) copy();
n.consequent = consequent;
return n;
}
/** Get the alternative of the statement. */
public Stmt alternative() {
return this.alternative;
}
/** Set the alternative of the statement. */
public If alternative(Stmt alternative) {
If_c n = (If_c) copy();
n.alternative = alternative;
return n;
}
/** Reconstruct the statement. */
protected If_c reconstruct(Expr cond, Stmt consequent, Stmt alternative) {
if (cond != this.cond || consequent != this.consequent || alternative != this.alternative) {
If_c n = (If_c) copy();
n.cond = cond;
n.consequent = consequent;
n.alternative = alternative;
return n;
}
return this;
}
/** Visit the children of the statement. */
public Node visitChildren(NodeVisitor v) {
Expr cond = (Expr) visitChild(this.cond, v);
Node consequent = visitChild(this.consequent, v);
if (consequent instanceof NodeList)
consequent = ((NodeList) consequent).toBlock();
Node alternative = visitChild(this.alternative, v);
if (alternative instanceof NodeList)
alternative = ((NodeList) alternative).toBlock();
return reconstruct(cond, (Stmt) consequent, (Stmt) alternative);
}
/** Type check the statement. */
public abstract Node typeCheck(ContextVisitor tc);
public String toString() {
return "if (" + cond + ") " + consequent +
(alternative != null ? " else " + alternative : "");
}
/** Write the statement to an output file. */
public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
w.write("if (");
printBlock(cond, w, tr);
w.write(")");
printSubStmt(consequent, w, tr);
if (alternative != null) {
if (consequent instanceof Block) {
// allow the "} else {" formatting
w.write(" ");
} else {
w.allowBreak(0, " ");
}
if (alternative instanceof Block) {
w.write ("else ");
print(alternative, w, tr);
} else {
w.begin(4);
w.write("else");
printSubStmt(alternative, w, tr);
w.end();
}
}
}
public Term firstChild() {
return cond;
}
public <S> List<S> acceptCFG(CFGBuilder v, List<S> succs) {
if (alternative == null) {
v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, consequent,
ENTRY, FlowGraph.EDGE_KEY_FALSE, this, EXIT);
v.visitCFG(consequent, this, EXIT);
}
else {
v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, consequent,
ENTRY, FlowGraph.EDGE_KEY_FALSE, alternative, ENTRY);
v.visitCFG(consequent, this, EXIT);
v.visitCFG(alternative, this, EXIT);
}
return succs;
}
}