KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > ext > jl > ast > Node_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
8 import java.util.*;
9
10 /**
11  * A <code>Node</code> represents an AST node. All AST nodes must implement
12  * this interface. Nodes should be immutable: methods which set fields
13  * of the node should copy the node, set the field in the copy, and then
14  * return the copy.
15  */

16 public abstract class Node_c implements Node
17 {
18     protected Position position;
19     protected JL del;
20     protected Ext ext;
21
22     public Node_c(Position pos) {
23         this.position = pos;
24     }
25
26     public void init(Node node) {
27         if (node != this) {
28             throw new InternalCompilerError("Cannot use a Node as a delegate or extension.");
29         }
30     }
31
32     public Node node() {
33         return this;
34     }
35
36     public JL del() {
37         return del != null ? del : this;
38     }
39
40     public Node del(JL del) {
41         if (this.del == del) {
42             return this;
43         }
44
45         JL old = this.del;
46         this.del = null;
47
48         Node_c n = (Node_c) copy();
49
50         n.del = del != this ? del : null;
51
52         if (n.del != null) {
53             n.del.init(n);
54         }
55
56         this.del = old;
57
58         return n;
59     }
60
61     public Ext ext(int n) {
62         if (n < 1) throw new InternalCompilerError("n must be >= 1");
63         if (n == 1) return ext();
64         return ext(n-1).ext();
65     }
66
67     public Node ext(int n, Ext ext) {
68         if (n < 1)
69             throw new InternalCompilerError("n must be >= 1");
70         if (n == 1)
71             return ext(ext);
72
73         Ext prev = this.ext(n-1);
74         if (prev == null)
75             throw new InternalCompilerError("cannot set the nth extension if there is no (n-1)st extension");
76         return this.ext(n-1, prev.ext(ext));
77     }
78
79     public Ext ext() {
80         return ext;
81     }
82
83     public Node ext(Ext ext) {
84         if (this.ext == ext) {
85             return this;
86         }
87
88         Ext old = this.ext;
89         this.ext = null;
90
91         Node_c n = (Node_c) copy();
92
93         n.ext = ext;
94
95         if (n.ext != null) {
96             n.ext.init(n);
97         }
98
99         this.ext = old;
100
101         return n;
102     }
103
104     public Object JavaDoc copy() {
105         try {
106             Node_c n = (Node_c) super.clone();
107
108             if (this.del != null) {
109                 n.del = (JL) this.del.copy();
110                 n.del.init(n);
111             }
112
113             if (this.ext != null) {
114                 n.ext = (Ext) this.ext.copy();
115                 n.ext.init(n);
116             }
117
118             return n;
119         }
120         catch (CloneNotSupportedException JavaDoc e) {
121             throw new InternalCompilerError("Java clone() weirdness.");
122         }
123     }
124
125     public Position position() {
126     return this.position;
127     }
128
129     public Node position(Position position) {
130     Node_c n = (Node_c) copy();
131     n.position = position;
132     return n;
133     }
134
135     public Node visitChild(Node n, NodeVisitor v) {
136     if (n == null) {
137         return null;
138     }
139
140     return v.visitEdge(this, n);
141     }
142
143     public Node visit(NodeVisitor v) {
144     return v.visitEdge(null, this);
145     }
146
147     public Node visitEdge(Node parent, NodeVisitor v) {
148     Node n = v.override(parent, this);
149
150     if (n == null) {
151         NodeVisitor v_ = v.enter(parent, this);
152
153         if (v_ == null) {
154         throw new InternalCompilerError(
155             "NodeVisitor.enter() returned null.");
156         }
157
158         n = this.del().visitChildren(v_);
159
160         if (n == null) {
161         throw new InternalCompilerError(
162             "Node_c.visitChildren() returned null.");
163         }
164
165         n = v.leave(parent, this, n, v_);
166
167         if (n == null) {
168         throw new InternalCompilerError(
169             "NodeVisitor.leave() returned null.");
170         }
171     }
172
173     return n;
174     }
175
176     /**
177      * Visit all the elements of a list.
178      * @param l The list to visit.
179      * @param v The visitor to use.
180      * @return A new list with each element from the old list
181      * replaced by the result of visiting that element.
182      * If <code>l</code> is a <code>TypedList</code>, the
183      * new list will also be typed with the same type as
184      * <code>l</code>. If <code>l</code> is <code>null</code>,
185      * <code>null</code> is returned.
186      */

187     public List visitList(List l, NodeVisitor v) {
188     if (l == null) {
189         return null;
190     }
191
192         List result = l;
193     List vl = new ArrayList(l.size());
194
195     for (Iterator i = l.iterator(); i.hasNext(); ) {
196         Node n = (Node) i.next();
197         Node m = visitChild(n, v);
198             if (n != m) {
199                 result = vl;
200             }
201         vl.add(m);
202     }
203
204     return result;
205     }
206
207     public Node visitChildren(NodeVisitor v) {
208     return this;
209     }
210
211     /**
212      * Push a new scope upon entering this node, and add any declarations to the
213      * context that should be in scope when visiting children of this node.
214      *
215      * @param c the current <code>Context</code>
216      * @return the <code>Context</code> to be used for visiting this node.
217      */

218     public Context enterScope(Context c) { return c; }
219
220     /**
221      * Push a new scope for visiting the child node <code>child</code>.
222      * The default behavior is to delegate the call to the child node, and let
223      * it add appropriate declarations that should be in scope. However,
224      * this method gives parent nodes have the ability to modify this behavior.
225      *
226      * @param child the child node about to be entered.
227      * @param c the current <code>Context</code>
228      * @return the <code>Context</code> to be used for visiting node
229      * <code>child</code>
230      */

231     public Context enterScope(Node child, Context c) {
232         return child.del().enterScope(c);
233     }
234
235     /**
236      * Add any declarations to the context that should be in scope when
237      * visiting later sibling nodes.
238      */

239     public void addDecls(Context c) { }
240
241     // These methods override the methods in Ext_c.
242
// These are the default implementation of these passes.
243

244     public Node buildTypesOverride(TypeBuilder tb) throws SemanticException {
245     return null;
246     }
247
248     public NodeVisitor buildTypesEnter(TypeBuilder tb) throws SemanticException {
249     return tb;
250     }
251
252     public Node buildTypes(TypeBuilder tb) throws SemanticException {
253     return this;
254     }
255
256     /** Remove any remaining ambiguities from the AST. */
257     public Node disambiguateOverride(AmbiguityRemover ar) throws SemanticException {
258     return null;
259     }
260
261     public NodeVisitor disambiguateEnter(AmbiguityRemover ar) throws SemanticException {
262     return ar;
263     }
264
265     public Node disambiguate(AmbiguityRemover ar) throws SemanticException {
266     return this;
267     }
268
269     /** Add members to a class. */
270     public Node addMembersOverride(AddMemberVisitor am) throws SemanticException {
271     return null;
272     }
273
274     public NodeVisitor addMembersEnter(AddMemberVisitor am) throws SemanticException {
275     return am;
276     }
277
278     public Node addMembers(AddMemberVisitor am) throws SemanticException {
279     return this;
280     }
281
282     /** Type check the AST. */
283     public Node typeCheckOverride(TypeChecker tc) throws SemanticException {
284     return null;
285     }
286
287     public NodeVisitor typeCheckEnter(TypeChecker tc) throws SemanticException {
288     return tc;
289     }
290
291     public Node typeCheck(TypeChecker tc) throws SemanticException {
292     return this;
293     }
294
295     public Type childExpectedType(Expr child, AscriptionVisitor av) {
296     return child.type();
297     }
298
299     /** Check that exceptions are properly propagated throughout the AST. */
300     public Node exceptionCheckOverride(ExceptionChecker ec) throws SemanticException {
301     return null;
302     }
303
304     public NodeVisitor exceptionCheckEnter(ExceptionChecker ec) throws SemanticException {
305     return ec;
306     }
307
308     public Node exceptionCheck(ExceptionChecker ec) throws SemanticException {
309         List l = this.del().throwTypes(ec.typeSystem());
310         for (Iterator i = l.iterator(); i.hasNext(); ) {
311             ec.throwsException((Type)i.next(), position());
312         }
313         return this;
314     }
315
316     public List throwTypes(TypeSystem ts) {
317        return Collections.EMPTY_LIST;
318     }
319
320     /** Pretty-print the AST using the given <code>CodeWriter</code>. */
321     public void prettyPrint(CodeWriter w, PrettyPrinter pp) { }
322
323     public void printBlock(Node n, CodeWriter w, PrettyPrinter pp) {
324         w.begin(0);
325         print(n, w, pp);
326         w.end();
327     }
328
329     public void printSubStmt(Stmt stmt, CodeWriter w, PrettyPrinter pp) {
330         if (stmt instanceof Block) {
331             w.write(" ");
332             print(stmt, w, pp);
333         }
334         else {
335             w.allowBreak(4, " ");
336             printBlock(stmt, w, pp);
337         }
338     }
339
340     public void print(Node child, CodeWriter w, PrettyPrinter pp) {
341         pp.print(this, child, w);
342     }
343
344     /** Translate the AST using the given <code>CodeWriter</code>. */
345     public void translate(CodeWriter w, Translator tr) {
346         // By default, just rely on the pretty printer.
347
this.del().prettyPrint(w, tr);
348     }
349
350     public void dump(CodeWriter w) {
351         w.write(StringUtil.getShortNameComponent(getClass().getName()));
352
353         w.allowBreak(4, " ");
354         w.begin(0);
355         w.write("(del " + del() + ")");
356         w.end();
357
358         w.allowBreak(4, " ");
359         w.begin(0);
360         w.write("(ext ");
361     if (ext() == null) w.write("null");
362     else ext().dump(w);
363     w.write(")");
364         w.end();
365
366         w.allowBreak(4, " ");
367         w.begin(0);
368         w.write("(position " + (position != null ? position.toString()
369                                                   : "UNKNOWN") + ")");
370         w.end();
371     }
372
373     public String JavaDoc toString() {
374           // This is really slow and so you are encouraged to override.
375
// return new StringPrettyPrinter(5).toString(this);
376

377           // Not slow anymore.
378
return getClass().getName();
379     }
380 }
381
Popular Tags