KickJava   Java API By Example, From Geeks To Geeks.

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


1 package polyglot.ext.jl.ast;
2
3 import java.util.Collections JavaDoc;
4 import java.util.List JavaDoc;
5
6 import polyglot.ast.AmbReceiver;
7 import polyglot.ast.Expr;
8 import polyglot.ast.Field;
9 import polyglot.ast.Node;
10 import polyglot.ast.Precedence;
11 import polyglot.ast.Receiver;
12 import polyglot.ast.Special;
13 import polyglot.ast.Term;
14 import polyglot.ast.TypeNode;
15 import polyglot.types.Context;
16 import polyglot.types.FieldInstance;
17 import polyglot.types.Flags;
18 import polyglot.types.SemanticException;
19 import polyglot.types.Type;
20 import polyglot.types.TypeSystem;
21 import polyglot.types.VarInstance;
22 import polyglot.util.CodeWriter;
23 import polyglot.util.InternalCompilerError;
24 import polyglot.util.Position;
25 import polyglot.visit.AscriptionVisitor;
26 import polyglot.visit.CFGBuilder;
27 import polyglot.visit.NodeVisitor;
28 import polyglot.visit.PrettyPrinter;
29 import polyglot.visit.TypeBuilder;
30 import polyglot.visit.TypeChecker;
31
32 /**
33  * A <code>Field</code> is an immutable representation of a Java field
34  * access. It consists of field name and may also have either a
35  * <code>Type</code> or an <code>Expr</code> containing the field being
36  * accessed.
37  */

38 public class Field_c extends Expr_c implements Field
39 {
40   protected Receiver target;
41   protected String JavaDoc name;
42   protected FieldInstance fi;
43   protected boolean targetImplicit;
44
45   public Field_c(Position pos, Receiver target, String JavaDoc name) {
46     super(pos);
47     this.target = target;
48     this.name = name;
49     this.targetImplicit = false;
50
51     if (target == null) {
52       throw new InternalCompilerError("Cannot create a field with a null "
53                                       + "target. Use AmbExpr or prefix "
54                                       + "with the appropriate type node or "
55                                       + "this.");
56     }
57   }
58
59   /** Get the precedence of the field. */
60   public Precedence precedence() {
61     return Precedence.LITERAL;
62   }
63
64   /** Get the target of the field. */
65   public Receiver target() {
66     return this.target;
67   }
68
69   /** Set the target of the field. */
70   public Field target(Receiver target) {
71     Field_c n = (Field_c) copy();
72     n.target = target;
73     return n;
74   }
75
76   /** Get the name of the field. */
77   public String JavaDoc name() {
78     return this.name;
79   }
80
81   /** Set the name of the field. */
82   public Field name(String JavaDoc name) {
83     Field_c n = (Field_c) copy();
84     n.name = name;
85     return n;
86   }
87
88   /** Return the access flags of the variable. */
89   public Flags flags() {
90     return fi.flags();
91   }
92
93   /** Get the field instance of the field. */
94   public FieldInstance fieldInstance() {
95     return fi;
96   }
97
98   /** Set the field instance of the field. */
99   public Field fieldInstance(FieldInstance fi) {
100     /*
101     if (! fi.type().isCanonical()) {
102       throw new InternalCompilerError("Type of " + fi + " in " +
103                                       fi.container() + " is not canonical.");
104     }
105     */

106
107     Field_c n = (Field_c) copy();
108     n.fi = fi;
109     return n;
110   }
111
112   public boolean isTargetImplicit() {
113       return this.targetImplicit;
114   }
115
116   public Field targetImplicit(boolean implicit) {
117       Field_c n = (Field_c) copy();
118       n.targetImplicit = implicit;
119       return n;
120   }
121
122   /** Reconstruct the field. */
123   protected Field_c reconstruct(Receiver target) {
124     if (target != this.target) {
125       Field_c n = (Field_c) copy();
126       n.target = target;
127       return n;
128     }
129
130     return this;
131   }
132
133   /** Visit the children of the field. */
134   public Node visitChildren(NodeVisitor v) {
135     Receiver target = (Receiver) visitChild(this.target, v);
136     return reconstruct(target);
137   }
138
139   public Node buildTypes(TypeBuilder tb) throws SemanticException {
140       Field_c n = (Field_c) super.buildTypes(tb);
141
142       TypeSystem ts = tb.typeSystem();
143
144       FieldInstance fi = ts.fieldInstance(position(), ts.Object(), Flags.NONE,
145                                           ts.unknownType(position()), name);
146       return n.fieldInstance(fi);
147   }
148
149   /** Type check the field. */
150   public Node typeCheck(TypeChecker tc) throws SemanticException {
151       Context c = tc.context();
152       TypeSystem ts = tc.typeSystem();
153       
154       if (! target.type().isReference()) {
155       throw new SemanticException("Cannot access field \"" + name +
156                       "\" " + (target instanceof Expr
157                            ? "on an expression "
158                            : "") +
159                       "of non-reference type \"" +
160                       target.type() + "\".", target.position());
161       }
162       
163       FieldInstance fi = ts.findField(target.type().toReference(), name, c.currentClass());
164       
165       if (fi == null) {
166       throw new InternalCompilerError("Cannot access field on node of type " +
167                       target.getClass().getName() + ".");
168       }
169       
170       Field_c f = (Field_c)fieldInstance(fi).type(fi.type());
171       f.checkConsistency(c);
172       
173       return f;
174   }
175   
176   public Type childExpectedType(Expr child, AscriptionVisitor av)
177   {
178       if (child == target) {
179           return fi.container();
180       }
181
182       return child.type();
183   }
184
185   /** Write the field to an output file. */
186   public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
187     if (!targetImplicit) {
188         // explicit target.
189
if (target instanceof Expr) {
190           printSubExpr((Expr) target, w, tr);
191         }
192         else if (target instanceof TypeNode || target instanceof AmbReceiver) {
193           print(target, w, tr);
194         }
195     
196         w.write(".");
197     }
198     w.write(name);
199   }
200
201   public void dump(CodeWriter w) {
202     super.dump(w);
203
204     w.allowBreak(4, " ");
205     w.begin(0);
206     w.write("(name \"" + name + "\")");
207     w.end();
208   }
209
210   public Term entry() {
211       if (target instanceof Expr) {
212           return ((Expr) target).entry();
213       }
214       return this;
215   }
216
217   public List JavaDoc acceptCFG(CFGBuilder v, List JavaDoc succs) {
218       if (target instanceof Expr) {
219           v.visitCFG((Expr) target, this);
220       }
221       return succs;
222   }
223
224
225   public String JavaDoc toString() {
226     return ((target != null && !targetImplicit)? target + "." : "") + name;
227   }
228
229
230   public List JavaDoc throwTypes(TypeSystem ts) {
231       if (target instanceof Expr && ! (target instanceof Special)) {
232           return Collections.singletonList(ts.NullPointerException());
233       }
234
235       return Collections.EMPTY_LIST;
236   }
237
238   public boolean isConstant() {
239     if (fi != null &&
240         (target instanceof TypeNode ||
241          (target instanceof Special && targetImplicit))) {
242       return fi.isConstant();
243     }
244
245     return false;
246   }
247
248   public Object JavaDoc constantValue() {
249     if (isConstant()) {
250       return fi.constantValue();
251     }
252
253     return null;
254   }
255   
256   // check that the implicit target setting is correct.
257
protected void checkConsistency(Context c) {
258       if (targetImplicit) {
259           VarInstance vi = c.findVariableSilent(name);
260           if (vi instanceof FieldInstance) {
261               FieldInstance rfi = (FieldInstance) vi;
262               if (c.typeSystem().equals(rfi, fi)) {
263                   // all is OK.
264
return;
265               }
266           }
267           throw new InternalCompilerError("Field " + this + " has an " +
268                "implicit target, but the name " + name + " resolves to " +
269                vi + " instead of " + target, position());
270       }
271   }
272
273 }
274
Popular Tags