KickJava   Java API By Example, From Geeks To Geeks.

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


1 package polyglot.ext.jl.ast;
2
3 import java.util.*;
4
5 import polyglot.ast.*;
6 import polyglot.types.*;
7 import polyglot.util.CodeWriter;
8 import polyglot.util.CollectionUtil;
9 import polyglot.util.Position;
10 import polyglot.util.SubtypeSet;
11 import polyglot.util.TypedList;
12 import polyglot.visit.*;
13
14 /**
15  * A <code>ConstructorDecl</code> is an immutable representation of a
16  * constructor declaration as part of a class body.
17  */

18 public class ConstructorDecl_c extends Term_c implements ConstructorDecl
19 {
20     protected Flags flags;
21     protected String JavaDoc name;
22     protected List formals;
23     protected List throwTypes;
24     protected Block body;
25     protected ConstructorInstance ci;
26
27     public ConstructorDecl_c(Position pos, Flags flags, String JavaDoc name, List formals, List throwTypes, Block body) {
28     super(pos);
29     this.flags = flags;
30     this.name = name;
31     this.formals = TypedList.copyAndCheck(formals, Formal.class, true);
32     this.throwTypes = TypedList.copyAndCheck(throwTypes, TypeNode.class, true);
33     this.body = body;
34     }
35
36     /** Get the flags of the constructor. */
37     public Flags flags() {
38     return this.flags;
39     }
40
41     /** Set the flags of the constructor. */
42     public ConstructorDecl flags(Flags flags) {
43     ConstructorDecl_c n = (ConstructorDecl_c) copy();
44     n.flags = flags;
45     return n;
46     }
47
48     /** Get the name of the constructor. */
49     public String JavaDoc name() {
50     return this.name;
51     }
52
53     /** Set the name of the constructor. */
54     public ConstructorDecl name(String JavaDoc name) {
55     ConstructorDecl_c n = (ConstructorDecl_c) copy();
56     n.name = name;
57     return n;
58     }
59
60     /** Get the formals of the constructor. */
61     public List formals() {
62     return Collections.unmodifiableList(this.formals);
63     }
64
65     /** Set the formals of the constructor. */
66     public ConstructorDecl formals(List formals) {
67     ConstructorDecl_c n = (ConstructorDecl_c) copy();
68     n.formals = TypedList.copyAndCheck(formals, Formal.class, true);
69     return n;
70     }
71
72     /** Get the throwTypes of the constructor. */
73     public List throwTypes() {
74     return Collections.unmodifiableList(this.throwTypes);
75     }
76
77     /** Set the throwTypes of the constructor. */
78     public ConstructorDecl throwTypes(List throwTypes) {
79     ConstructorDecl_c n = (ConstructorDecl_c) copy();
80     n.throwTypes = TypedList.copyAndCheck(throwTypes, TypeNode.class, true);
81     return n;
82     }
83
84     /** Get the body of the constructor. */
85     public Block body() {
86     return this.body;
87     }
88
89     /** Set the body of the constructor. */
90     public CodeDecl body(Block body) {
91     ConstructorDecl_c n = (ConstructorDecl_c) copy();
92     n.body = body;
93     return n;
94     }
95
96     /** Get the constructorInstance of the constructor. */
97     public ConstructorInstance constructorInstance() {
98     return ci;
99     }
100
101
102     /** Get the procedureInstance of the constructor. */
103     public ProcedureInstance procedureInstance() {
104     return ci;
105     }
106
107     public CodeInstance codeInstance() {
108     return procedureInstance();
109     }
110     
111     /** Set the constructorInstance of the constructor. */
112     public ConstructorDecl constructorInstance(ConstructorInstance ci) {
113     ConstructorDecl_c n = (ConstructorDecl_c) copy();
114     n.ci = ci;
115     return n;
116     }
117
118     /** Reconstruct the constructor. */
119     protected ConstructorDecl_c reconstruct(List formals, List throwTypes, Block body) {
120     if (! CollectionUtil.equals(formals, this.formals) || ! CollectionUtil.equals(throwTypes, this.throwTypes) || body != this.body) {
121         ConstructorDecl_c n = (ConstructorDecl_c) copy();
122         n.formals = TypedList.copyAndCheck(formals, Formal.class, true);
123         n.throwTypes = TypedList.copyAndCheck(throwTypes, TypeNode.class, true);
124         n.body = body;
125         return n;
126     }
127
128     return this;
129     }
130
131     /** Visit the children of the constructor. */
132     public Node visitChildren(NodeVisitor v) {
133     List formals = visitList(this.formals, v);
134     List throwTypes = visitList(this.throwTypes, v);
135     Block body = (Block) visitChild(this.body, v);
136     return reconstruct(formals, throwTypes, body);
137     }
138
139     public NodeVisitor buildTypesEnter(TypeBuilder tb) throws SemanticException {
140         return tb.pushCode();
141     }
142
143     public Node buildTypes(TypeBuilder tb) throws SemanticException {
144         TypeSystem ts = tb.typeSystem();
145
146         List l = new ArrayList(formals.size());
147         for (int i = 0; i < formals.size(); i++) {
148             l.add(ts.unknownType(position()));
149         }
150
151         List m = new ArrayList(throwTypes().size());
152         for (int i = 0; i < throwTypes().size(); i++) {
153             m.add(ts.unknownType(position()));
154         }
155
156         ConstructorInstance ci = ts.constructorInstance(position(), ts.Object(),
157                                                         Flags.NONE, l, m);
158         return constructorInstance(ci);
159     }
160
161     public NodeVisitor disambiguateEnter(AmbiguityRemover ar) throws SemanticException {
162         if (ar.kind() == AmbiguityRemover.SUPER) {
163             return ar.bypassChildren(this);
164         }
165         else if (ar.kind() == AmbiguityRemover.SIGNATURES) {
166             if (body != null) {
167                 return ar.bypass(body);
168             }
169         }
170
171         return ar;
172     }
173
174     public Node disambiguate(AmbiguityRemover ar) throws SemanticException {
175         if (ar.kind() == AmbiguityRemover.SIGNATURES) {
176             Context c = ar.context();
177             TypeSystem ts = ar.typeSystem();
178
179             ParsedClassType ct = c.currentClassScope();
180
181             ConstructorInstance ci = makeConstructorInstance(ct, ts);
182
183             return constructorInstance(ci);
184         }
185
186         return this;
187     }
188
189     public NodeVisitor addMembersEnter(AddMemberVisitor am) {
190     ParsedClassType ct = am.context().currentClassScope();
191         ct.addConstructor(ci);
192         return am.bypassChildren(this);
193     }
194
195     public Context enterScope(Context c) {
196         return c.pushCode(ci);
197     }
198
199     /** Type check the constructor. */
200     public Node typeCheck(TypeChecker tc) throws SemanticException {
201         Context c = tc.context();
202         TypeSystem ts = tc.typeSystem();
203
204         ClassType ct = c.currentClass();
205
206     if (ct.flags().isInterface()) {
207         throw new SemanticException(
208         "Cannot declare a constructor inside an interface.",
209         position());
210     }
211
212         if (ct.isAnonymous()) {
213         throw new SemanticException(
214         "Cannot declare a constructor inside an anonymous class.",
215         position());
216         }
217
218         String JavaDoc ctName = ct.name();
219
220         if (! ctName.equals(name)) {
221         throw new SemanticException("Constructor name \"" + name +
222                 "\" does not match name of containing class \"" +
223                 ctName + "\".", position());
224         }
225
226     try {
227         ts.checkConstructorFlags(flags());
228     }
229     catch (SemanticException e) {
230         throw new SemanticException(e.getMessage(), position());
231     }
232
233     if (body == null && ! flags().isNative()) {
234         throw new SemanticException("Missing constructor body.",
235         position());
236     }
237
238     if (body != null && flags().isNative()) {
239         throw new SemanticException(
240         "A native constructor cannot have a body.", position());
241     }
242
243         for (Iterator i = throwTypes().iterator(); i.hasNext(); ) {
244             TypeNode tn = (TypeNode) i.next();
245             Type t = tn.type();
246             if (! t.isThrowable()) {
247                 throw new SemanticException("Type \"" + t +
248                     "\" is not a subclass of \"" + ts.Throwable() + "\".",
249                     tn.position());
250             }
251         }
252
253         return this;
254     }
255
256     /** Check exceptions thrown by the constructor. */
257     public Node exceptionCheck(ExceptionChecker ec) throws SemanticException {
258     TypeSystem ts = ec.typeSystem();
259
260     SubtypeSet s = (SubtypeSet) ec.throwsSet();
261
262     for (Iterator i = s.iterator(); i.hasNext(); ) {
263         Type t = (Type) i.next();
264
265         boolean throwDeclared = false;
266
267         if (! t.isUncheckedException()) {
268         for (Iterator j = throwTypes().iterator(); j.hasNext(); ) {
269             TypeNode tn = (TypeNode) j.next();
270             Type tj = tn.type();
271
272             if (ts.isSubtype(t, tj)) {
273             throwDeclared = true;
274             break;
275             }
276         }
277
278         if (! throwDeclared) {
279                     ec.throwsSet().clear();
280                     Position pos = ec.exceptionPosition(t);
281                     throw new SemanticException("The exception \"" + t +
282                         "\" must either be caught or declared to be thrown.",
283                         pos==null?position():pos);
284         }
285         }
286     }
287
288     ec.throwsSet().clear();
289
290     return super.exceptionCheck(ec);
291     }
292
293     public String JavaDoc toString() {
294     return flags.translate() + name + "(...)";
295     }
296
297     /** Write the constructor to an output file. */
298     public void prettyPrintHeader(CodeWriter w, PrettyPrinter tr) {
299     w.begin(0);
300     w.write(flags().translate());
301
302     w.write(name);
303     w.write("(");
304
305     w.begin(0);
306
307     for (Iterator i = formals.iterator(); i.hasNext(); ) {
308         Formal f = (Formal) i.next();
309         print(f, w, tr);
310
311         if (i.hasNext()) {
312         w.write(",");
313         w.allowBreak(0, " ");
314         }
315     }
316
317     w.end();
318     w.write(")");
319
320     if (! throwTypes().isEmpty()) {
321         w.allowBreak(6);
322         w.write("throws ");
323
324         for (Iterator i = throwTypes().iterator(); i.hasNext(); ) {
325             TypeNode tn = (TypeNode) i.next();
326         print(tn, w, tr);
327
328         if (i.hasNext()) {
329             w.write(",");
330             w.allowBreak(4, " ");
331         }
332         }
333     }
334
335     w.end();
336     }
337
338     public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
339         prettyPrintHeader(w, tr);
340
341     if (body != null) {
342         printSubStmt(body, w, tr);
343     }
344     else {
345         w.write(";");
346     }
347     }
348
349     public void dump(CodeWriter w) {
350     super.dump(w);
351
352     if (ci != null) {
353         w.allowBreak(4, " ");
354         w.begin(0);
355         w.write("(instance " + ci + ")");
356         w.end();
357     }
358     }
359
360     protected ConstructorInstance makeConstructorInstance(ClassType ct,
361     TypeSystem ts) throws SemanticException {
362
363     List argTypes = new LinkedList();
364     List excTypes = new LinkedList();
365
366     for (Iterator i = formals.iterator(); i.hasNext(); ) {
367         Formal f = (Formal) i.next();
368         argTypes.add(f.declType());
369     }
370
371     for (Iterator i = throwTypes().iterator(); i.hasNext(); ) {
372         TypeNode tn = (TypeNode) i.next();
373         excTypes.add(tn.type());
374     }
375
376     return ts.constructorInstance(position(), ct, flags,
377                               argTypes, excTypes);
378     }
379     
380     /**
381      * Return the first (sub)term performed when evaluating this
382      * term.
383      */

384     public Term entry() {
385         return listEntry(formals(), (body()==null? this : body().entry()));
386     }
387
388     /**
389      * Visit this term in evaluation order.
390      */

391     public List acceptCFG(CFGBuilder v, List succs) {
392         if (body() == null) {
393             v.visitCFGList(formals(), this);
394         }
395         else {
396             v.visitCFGList(formals(), body().entry());
397             v.visitCFG(body(), this);
398         }
399         return succs;
400     }
401     
402 }
403
Popular Tags