KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > ext > jl > ast > For_c


1 package polyglot.ext.jl.ast;
2
3 import polyglot.ast.*;
4 import polyglot.types.*;
5 import polyglot.visit.*;
6 import polyglot.util.*;
7 import java.util.*;
8
9 /**
10  * An immutable representation of a Java language <code>for</code>
11  * statement. Contains a statement to be executed and an expression
12  * to be tested indicating whether to reexecute the statement.
13  */

14 public class For_c extends Loop_c implements For
15 {
16     protected List inits;
17     protected Expr cond;
18     protected List iters;
19     protected Stmt body;
20
21     public For_c(Position pos, List inits, Expr cond, List iters, Stmt body) {
22     super(pos);
23     this.inits = TypedList.copyAndCheck(inits, ForInit.class, true);
24     this.cond = cond;
25     this.iters = TypedList.copyAndCheck(iters, ForUpdate.class, true);
26     this.body = body;
27     }
28
29     /** List of initialization statements */
30     public List inits() {
31     return Collections.unmodifiableList(this.inits);
32     }
33
34     /** Set the inits of the statement. */
35     public For inits(List inits) {
36     For_c n = (For_c) copy();
37     n.inits = TypedList.copyAndCheck(inits, ForInit.class, true);
38     return n;
39     }
40
41     /** Loop condition */
42     public Expr cond() {
43     return this.cond;
44     }
45
46     /** Set the conditional of the statement. */
47     public For cond(Expr cond) {
48     For_c n = (For_c) copy();
49     n.cond = cond;
50     return n;
51     }
52
53     /** List of iterator expressions. */
54     public List iters() {
55     return Collections.unmodifiableList(this.iters);
56     }
57
58     /** Set the iterator expressions of the statement. */
59     public For iters(List iters) {
60     For_c n = (For_c) copy();
61     n.iters = TypedList.copyAndCheck(iters, ForUpdate.class, true);
62     return n;
63     }
64
65     /** Loop body */
66     public Stmt body() {
67     return this.body;
68     }
69
70     /** Set the body of the statement. */
71     public For body(Stmt body) {
72     For_c n = (For_c) copy();
73     n.body = body;
74     return n;
75     }
76
77     /** Reconstruct the statement. */
78     protected For_c reconstruct(List inits, Expr cond, List iters, Stmt body) {
79     if (! CollectionUtil.equals(inits, this.inits) || cond != this.cond || ! CollectionUtil.equals(iters, this.iters) || body != this.body) {
80         For_c n = (For_c) copy();
81         n.inits = TypedList.copyAndCheck(inits, ForInit.class, true);
82         n.cond = cond;
83         n.iters = TypedList.copyAndCheck(iters, ForUpdate.class, true);
84         n.body = body;
85         return n;
86     }
87
88     return this;
89     }
90
91     /** Visit the children of the statement. */
92     public Node visitChildren(NodeVisitor v) {
93     List inits = visitList(this.inits, v);
94     Expr cond = (Expr) visitChild(this.cond, v);
95     List iters = visitList(this.iters, v);
96     Stmt body = (Stmt) visitChild(this.body, v);
97     return reconstruct(inits, cond, iters, body);
98     }
99
100     public Context enterScope(Context c) {
101     return c.pushBlock();
102     }
103
104     /** Type check the statement. */
105     public Node typeCheck(TypeChecker tc) throws SemanticException {
106     TypeSystem ts = tc.typeSystem();
107
108         // Check that all initializers have the same type.
109
// This should be enforced by the parser, but check again here,
110
// just to be sure.
111
Type t = null;
112
113         for (Iterator i = inits.iterator(); i.hasNext(); ) {
114             ForInit s = (ForInit) i.next();
115
116             if (s instanceof LocalDecl) {
117                 LocalDecl d = (LocalDecl) s;
118                 Type dt = d.type().type();
119                 if (t == null) {
120                     t = dt;
121                 }
122                 else if (! t.equals(dt)) {
123                     throw new InternalCompilerError("Local variable " +
124                         "declarations in a for loop initializer must all " +
125                         "be the same type, in this case " + t + ", not " +
126                         dt + ".", d.position());
127                 }
128             }
129         }
130
131     if (cond != null &&
132         ! ts.isImplicitCastValid(cond.type(), ts.Boolean())) {
133         throw new SemanticException(
134         "The condition of a for statement must have boolean type.",
135         cond.position());
136     }
137
138     return this;
139     }
140
141     public Type childExpectedType(Expr child, AscriptionVisitor av) {
142         TypeSystem ts = av.typeSystem();
143
144         if (child == cond) {
145             return ts.Boolean();
146         }
147
148         return child.type();
149     }
150
151     /** Write the statement to an output file. */
152     public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
153     w.write("for (");
154     w.begin(0);
155
156     if (inits != null) {
157             boolean first = true;
158         for (Iterator i = inits.iterator(); i.hasNext(); ) {
159         ForInit s = (ForInit) i.next();
160             printForInit(s, w, tr, first);
161                 first = false;
162
163         if (i.hasNext()) {
164             w.write(",");
165             w.allowBreak(2, " ");
166         }
167         }
168     }
169
170     w.write(";");
171     w.allowBreak(0);
172
173     if (cond != null) {
174         printBlock(cond, w, tr);
175     }
176
177     w.write (";");
178     w.allowBreak(0);
179     
180     if (iters != null) {
181         for (Iterator i = iters.iterator(); i.hasNext();) {
182         ForUpdate s = (ForUpdate) i.next();
183         printForUpdate(s, w, tr);
184         
185         if (i.hasNext()) {
186             w.write(",");
187             w.allowBreak(2, " ");
188         }
189         }
190     }
191
192     w.end();
193     w.write(")");
194
195     printSubStmt(body, w, tr);
196     }
197
198     public String JavaDoc toString() {
199     return "for (...) ...";
200     }
201
202     private void printForInit(ForInit s, CodeWriter w, PrettyPrinter tr, boolean printType) {
203         boolean oldSemiColon = tr.appendSemicolon(false);
204         boolean oldPrintType = tr.printType(printType);
205         printBlock(s, w, tr);
206         tr.printType(oldPrintType);
207         tr.appendSemicolon(oldSemiColon);
208     }
209
210     private void printForUpdate(ForUpdate s, CodeWriter w, PrettyPrinter tr) {
211         boolean oldSemiColon = tr.appendSemicolon(false);
212         printBlock(s, w, tr);
213         tr.appendSemicolon(oldSemiColon);
214     }
215
216     public Term entry() {
217         return listEntry(inits, (cond != null ? cond.entry() : body.entry()));
218     }
219
220     public List acceptCFG(CFGBuilder v, List succs) {
221         v.visitCFGList(inits, (cond != null ? cond.entry() : body.entry()));
222
223         if (cond != null) {
224             if (condIsConstantTrue()) {
225                 v.visitCFG(cond, body.entry());
226             }
227             else {
228                 v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, body.entry(),
229                                  FlowGraph.EDGE_KEY_FALSE, this);
230             }
231         }
232
233         v.push(this).visitCFG(body, continueTarget());
234         v.visitCFGList(iters, (cond != null ? cond.entry() : body.entry()));
235
236         return succs;
237     }
238
239     public Term continueTarget() {
240         return listEntry(iters, (cond != null ? cond.entry() : body.entry()));
241     }
242 }
243
Popular Tags