KickJava   Java API By Example, From Geeks To Geeks.

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


1 package polyglot.ext.jl.ast;
2
3 import java.util.*;
4
5 import polyglot.ast.*;
6 import polyglot.main.Report;
7 import polyglot.types.*;
8 import polyglot.util.*;
9 import polyglot.visit.*;
10
11 /**
12  * A <code>FieldDecl</code> is an immutable representation of the declaration
13  * of a field of a class.
14  */

15 public class FieldDecl_c extends Term_c implements FieldDecl {
16     Flags flags;
17     TypeNode type;
18     String JavaDoc name;
19     Expr init;
20     FieldInstance fi;
21     InitializerInstance ii;
22
23     public FieldDecl_c(Position pos, Flags flags, TypeNode type,
24                        String JavaDoc name, Expr init)
25     {
26         super(pos);
27         this.flags = flags;
28         this.type = type;
29         this.name = name;
30         this.init = init;
31     }
32
33     /** Get the initializer instance of the initializer. */
34     public InitializerInstance initializerInstance() {
35         return ii;
36     }
37
38     /** Set the initializer instance of the initializer. */
39     public FieldDecl initializerInstance(InitializerInstance ii) {
40         FieldDecl_c n = (FieldDecl_c) copy();
41         n.ii = ii;
42         return n;
43     }
44
45     /** Get the type of the declaration. */
46     public Type declType() {
47         return type.type();
48     }
49
50     /** Get the flags of the declaration. */
51     public Flags flags() {
52         return flags;
53     }
54
55     /** Set the flags of the declaration. */
56     public FieldDecl flags(Flags flags) {
57         FieldDecl_c n = (FieldDecl_c) copy();
58         n.flags = flags;
59         return n;
60     }
61
62     /** Get the type node of the declaration. */
63     public TypeNode type() {
64         return type;
65     }
66
67     /** Set the type of the declaration. */
68     public FieldDecl type(TypeNode type) {
69         FieldDecl_c n = (FieldDecl_c) copy();
70         n.type = type;
71         return n;
72     }
73
74     /** Get the name of the declaration. */
75     public String JavaDoc name() {
76         return name;
77     }
78
79     /** Set the name of the declaration. */
80     public FieldDecl name(String JavaDoc name) {
81         FieldDecl_c n = (FieldDecl_c) copy();
82         n.name = name;
83         return n;
84     }
85
86     /** Get the initializer of the declaration. */
87     public Expr init() {
88         return init;
89     }
90
91     /** Set the initializer of the declaration. */
92     public FieldDecl init(Expr init) {
93         FieldDecl_c n = (FieldDecl_c) copy();
94         n.init = init;
95         return n;
96     }
97
98     /** Set the field instance of the declaration. */
99     public FieldDecl fieldInstance(FieldInstance fi) {
100         FieldDecl_c n = (FieldDecl_c) copy();
101         n.fi = fi;
102         return n;
103     }
104
105     /** Get the field instance of the declaration. */
106     public FieldInstance fieldInstance() {
107         return fi;
108     }
109
110     /** Reconstruct the declaration. */
111     protected FieldDecl_c reconstruct(TypeNode type, Expr init) {
112         if (this.type != type || this.init != init) {
113             FieldDecl_c n = (FieldDecl_c) copy();
114             n.type = type;
115             n.init = init;
116             return n;
117         }
118
119         return this;
120     }
121
122     /** Visit the children of the declaration. */
123     public Node visitChildren(NodeVisitor v) {
124         TypeNode type = (TypeNode) visitChild(this.type, v);
125         Expr init = (Expr) visitChild(this.init, v);
126         return reconstruct(type, init);
127     }
128
129     public NodeVisitor buildTypesEnter(TypeBuilder tb) throws SemanticException {
130         return tb.pushCode();
131     }
132
133     public Node buildTypes(TypeBuilder tb) throws SemanticException {
134         TypeSystem ts = tb.typeSystem();
135
136         FieldDecl n;
137
138         if (init != null) {
139             ClassType ct = tb.currentClass();
140             Flags f = (flags.isStatic()) ? Flags.STATIC : Flags.NONE;
141             InitializerInstance ii = ts.initializerInstance(init.position(),
142                                                             ct, f);
143             n = initializerInstance(ii);
144         }
145         else {
146             n = this;
147         }
148
149         FieldInstance fi = ts.fieldInstance(n.position(), ts.Object(),
150                                             Flags.NONE,
151                                             ts.unknownType(position()),
152                                             n.name());
153
154         return n.fieldInstance(fi);
155     }
156
157     /** Build type objects for the declaration. */
158     public NodeVisitor disambiguateEnter(AmbiguityRemover ar)
159         throws SemanticException
160     {
161         if (ar.kind() == AmbiguityRemover.SUPER) {
162             return ar.bypassChildren(this);
163         }
164         else if (ar.kind() == AmbiguityRemover.SIGNATURES) {
165             if (init != null) {
166                 return ar.bypass(init);
167             }
168         }
169
170         return ar;
171     }
172
173     public Node disambiguate(AmbiguityRemover ar) throws SemanticException {
174         if (ar.kind() == AmbiguityRemover.SIGNATURES) {
175             Context c = ar.context();
176             TypeSystem ts = ar.typeSystem();
177
178             ParsedClassType ct = c.currentClassScope();
179
180             Flags f = flags;
181
182             if (ct.flags().isInterface()) {
183                 f = f.Public().Static().Final();
184             }
185
186             FieldInstance fi = ts.fieldInstance(position(), ct, f,
187                                                 declType(), name);
188
189             return flags(f).fieldInstance(fi);
190         }
191
192         if (ar.kind() == AmbiguityRemover.ALL) {
193             checkFieldInstanceConstant();
194         }
195
196         return this;
197     }
198
199     protected void checkFieldInstanceConstant() {
200         FieldInstance fi = this.fi;
201
202         if (init != null && fi.flags().isFinal() && init.isConstant()) {
203             Object JavaDoc value = init.constantValue();
204             fi.setConstantValue(value);
205         }
206     }
207
208     public NodeVisitor addMembersEnter(AddMemberVisitor am) {
209         ParsedClassType ct = am.context().currentClassScope();
210
211         FieldInstance fi = this.fi;
212
213         if (fi == null) {
214             throw new InternalCompilerError("null field instance");
215         }
216
217         if (Report.should_report(Report.types, 5))
218             Report.report(5, "adding " + fi + " to " + ct);
219
220         ct.addField(fi);
221
222         return am.bypassChildren(this);
223     }
224
225     public Context enterScope(Context c) {
226         if (ii != null) {
227             return c.pushCode(ii);
228         }
229         return c;
230     }
231
232     /** Type check the declaration. */
233     public Node typeCheck(TypeChecker tc) throws SemanticException {
234         TypeSystem ts = tc.typeSystem();
235
236         checkFieldInstanceConstant();
237         
238         try {
239             ts.checkFieldFlags(flags);
240         }
241         catch (SemanticException e) {
242             throw new SemanticException(e.getMessage(), position());
243         }
244
245         if (tc.context().currentClass().flags().isInterface()) {
246             if (flags.isProtected() || flags.isPrivate()) {
247                 throw new SemanticException("Interface members must be public.",
248                                             position());
249             }
250         }
251
252         if (init != null) {
253             if (init instanceof ArrayInit) {
254                 ((ArrayInit) init).typeCheckElements(type.type());
255             }
256             else {
257                 boolean intConversion = false;
258
259                 if (! ts.isImplicitCastValid(init.type(), type.type()) &&
260                     ! ts.equals(init.type(), type.type()) &&
261                     ! ts.numericConversionValid(type.type(),
262                                                 init.constantValue())) {
263
264                     throw new SemanticException("The type of the variable " +
265                                                 "initializer \"" + init.type() +
266                                                 "\" does not match that of " +
267                                                 "the declaration \"" +
268                                                 type.type() + "\".",
269                                                 init.position());
270                 }
271             }
272         }
273
274         // check that inner classes do not declare static fields, unless they
275
// are compile-time constants
276
if (flags().isStatic() &&
277               fieldInstance().container().toClass().isInnerClass()) {
278             // it's a static field in an inner class.
279
if (!flags().isFinal() || init == null || !init.isConstant()) {
280                 throw new SemanticException("Inner classes cannot declare " +
281                         "static fields, unless they are compile-time " +
282                         "constant fields.", this.position());
283             }
284
285         }
286
287         return this;
288     }
289
290     public Node exceptionCheck(ExceptionChecker ec) throws SemanticException {
291         TypeSystem ts = ec.typeSystem();
292
293         SubtypeSet s = (SubtypeSet) ec.throwsSet();
294
295         for (Iterator i = s.iterator(); i.hasNext(); ) {
296             Type t = (Type) i.next();
297
298             if (! t.isUncheckedException()) {
299                 ec.throwsSet().clear();
300                 throw new SemanticException(
301                     "A field initializer may not throw a "
302                     + t + ".", position());
303             }
304         }
305
306         ec.throwsSet().clear();
307
308         return super.exceptionCheck(ec);
309     }
310
311     public Type childExpectedType(Expr child, AscriptionVisitor av) {
312         if (child == init) {
313             TypeSystem ts = av.typeSystem();
314
315             // If the RHS is an integral constant, we can relax the expected
316
// type to the type of the constant.
317
if (ts.numericConversionValid(type.type(), child.constantValue())) {
318                 return child.type();
319             }
320             else {
321                 return type.type();
322             }
323         }
324
325         return child.type();
326     }
327
328     /**
329      * Return the first (sub)term performed when evaluating this
330      * term.
331      */

332     public Term entry() {
333         return init != null ? init.entry() : this;
334     }
335
336     /**
337      * Visit this term in evaluation order.
338      */

339     public List acceptCFG(CFGBuilder v, List succs) {
340         if (init != null) {
341             v.visitCFG(init, this);
342         }
343         return succs;
344     }
345
346
347     public String JavaDoc toString() {
348         return flags.translate() + type + " " + name +
349                 (init != null ? " = " + init : "");
350     }
351
352     public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
353         boolean isInterface = fi != null && fi.container() != null &&
354                               fi.container().toClass().flags().isInterface();
355
356         Flags f = flags;
357
358         if (isInterface) {
359             f = f.clearPublic();
360             f = f.clearStatic();
361             f = f.clearFinal();
362         }
363
364         w.write(f.translate());
365         print(type, w, tr);
366         w.write(" ");
367         w.write(name);
368
369         if (init != null) {
370             w.write(" =");
371             w.allowBreak(2, " ");
372             print(init, w, tr);
373         }
374
375         w.write(";");
376     }
377
378     public void dump(CodeWriter w) {
379         super.dump(w);
380
381         if (fi != null) {
382             w.allowBreak(4, " ");
383             w.begin(0);
384             w.write("(instance " + fi + ")");
385             w.end();
386         }
387
388     w.allowBreak(4, " ");
389     w.begin(0);
390     w.write("(name " + name + ")");
391     w.end();
392     }
393 }
394
Popular Tags