package polyglot.ext.jl.ast; import polyglot.ast.*; import polyglot.types.*; import polyglot.visit.*; import polyglot.util.*; import java.util.*; /** * 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 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); 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); Stmt consequent = (Stmt) visitChild(this.consequent, v); Stmt alternative = (Stmt) visitChild(this.alternative, v); return reconstruct(cond, consequent, alternative); } /** Type check the statement. */ public Node typeCheck(TypeChecker tc) throws SemanticException { TypeSystem ts = tc.typeSystem(); if (! ts.equals(cond.type(), ts.Boolean())) { throw new SemanticException( "Condition of if statement must have boolean type.", cond.position()); } return this; } public Type childExpectedType(Expr child, AscriptionVisitor av) { TypeSystem ts = av.typeSystem(); if (child == cond) { return ts.Boolean(); } return child.type(); } 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, " "); } w.write ("else"); printSubStmt(alternative, w, tr); } } public Term entry() { return cond.entry(); } public List acceptCFG(CFGBuilder v, List succs) { if (alternative == null) { v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, consequent.entry(), FlowGraph.EDGE_KEY_FALSE, this); v.visitCFG(consequent, this); } else { v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, consequent.entry(), FlowGraph.EDGE_KEY_FALSE, alternative.entry()); v.visitCFG(consequent, this); v.visitCFG(alternative, this); } return succs; } }