KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > kawa > reflect > FieldLocation


1 package gnu.kawa.reflect;
2 import gnu.bytecode.*;
3 import gnu.mapping.*;
4 import gnu.mapping.Location; // As opposed to gnu.bytecode.Location.
5
import gnu.expr.*;
6
7 public class FieldLocation extends ClassMemberLocation
8 {
9   Declaration decl;
10   /** The cached location of the field, if final.
11    * This is the value of this Location. Howeve, if INDIRECT_LOCATION is
12    * set and CONSTANT is cleared, then we need to do an extra indirection. */

13   Object JavaDoc value;
14   static final int SETUP_DONE = 1; // FIXME - do we still need this?
15

16   /** Flag that indicates that field value has type Location.
17    * Hence <code>get</code> of this Location requires an extra indirection. */

18   static final int INDIRECT_LOCATION = 2;
19   /** The actual value (following any indirection) is constant.
20    * I.e. if INDIRECT_LOCATION is set, then that Location has isConstant set,
21    * Otherwise the actual value is a final field. */

22   static final int CONSTANT = 4;
23   /** Flag that indicates that the value field has been set.
24    * If INDIRECT_LOCATION has been set, but not CONSTANT, then
25    * the <code>value</code> is a Location we need to indirect.
26    * If CONSTANT is set, then this is the actual (final) value.
27    * Not set unless at least one of INDIRECT_LOCATION or CONSTANT are set. */

28   static final int VALUE_SET = 8;
29   // The PROCEDURE and SYNTAX flags aren't current used by getDeclaration,
30
// but probably should be, assuming we can count on them.
31
public static final int PROCEDURE = 16;
32   public static final int SYNTAX = 32;
33   /** True if the flags <code>PROCEDURE|SYNTAX|INDIRECT_LOCATION|CONSTANT</code>
34    * are valid. */

35   public static final int KIND_FLAGS_SET = 64;
36   private int flags;
37
38   public boolean isIndirectLocation ()
39   { return (flags & INDIRECT_LOCATION) != 0; }
40
41   public void setProcedure ()
42   {
43     flags |= PROCEDURE|CONSTANT|KIND_FLAGS_SET;
44   }
45
46   public void setSyntax ()
47   {
48     flags |= SYNTAX|CONSTANT|KIND_FLAGS_SET;
49   }
50
51   void setKindFlags ()
52   {
53     String JavaDoc fname = getMemberName();
54     gnu.bytecode.Field fld = getDeclaringClass().getDeclaredField(fname);
55     int fflags = fld.getModifiers();
56     Type ftype = fld.getType();
57     if (ftype.isSubtype(Compilation.typeLocation))
58       flags |= INDIRECT_LOCATION;
59     if ((fflags & Access.FINAL) != 0)
60       {
61         if ((flags & INDIRECT_LOCATION) == 0)
62           {
63             flags |= CONSTANT;
64             if (ftype.isSubtype(Compilation.typeProcedure))
65               flags |= PROCEDURE;
66             if (ftype.isSubtype(ClassType.make("kawa.lang.Syntax")))
67               flags |= SYNTAX;
68           }
69         else
70           {
71             Location loc = (Location) getFieldValue();
72             if (loc instanceof FieldLocation)
73               {
74                 FieldLocation floc = (FieldLocation) loc;
75                 if ((floc.flags & KIND_FLAGS_SET) == 0)
76                   floc.setKindFlags();
77                 flags |= (floc.flags & (SYNTAX|PROCEDURE|CONSTANT));
78                 if ((floc.flags & CONSTANT) != 0)
79                   {
80                     if ((floc.flags & VALUE_SET) != 0)
81                       {
82                         value = floc.value;
83                         flags |= VALUE_SET;
84                       }
85                   }
86                 else
87                   {
88                     value = floc;
89                     flags |= VALUE_SET;
90                   }
91               }
92             else if (loc.isConstant())
93               {
94                 Object JavaDoc val = loc.get(null);
95                 // if (val == null) ????;
96
if (val instanceof Procedure)
97                   flags |= PROCEDURE;
98                 if (val instanceof kawa.lang.Syntax) // FIXME
99
flags |= SYNTAX;
100                 flags |= CONSTANT|VALUE_SET;
101                 value = val;
102               }
103           }
104       }
105     flags |= KIND_FLAGS_SET;
106   }
107
108   public boolean isProcedureOrSyntax ()
109   {
110     if ((flags & KIND_FLAGS_SET) == 0)
111       setKindFlags();
112     return (flags & (PROCEDURE+SYNTAX)) != 0;
113   }
114
115   public FieldLocation(Object JavaDoc instance, String JavaDoc cname, String JavaDoc fname)
116   {
117     super(instance, ClassType.make(cname), fname);
118   }
119
120   public FieldLocation(Object JavaDoc instance, ClassType type, String JavaDoc mname)
121   {
122     super(instance, type, mname);
123   }
124
125
126   public void setDeclaration (Declaration decl)
127   {
128     this.decl = decl;
129   }
130
131   public Field getField ()
132   {
133     return type.getDeclaredField(mname);
134   }
135
136   /** Get the type of the field. */
137   public Type getFType ()
138   {
139     return type.getDeclaredField(mname).getType();
140   }
141
142   public synchronized Declaration getDeclaration ()
143   {
144     if ((flags & KIND_FLAGS_SET) == 0)
145       setKindFlags();
146     Declaration d = decl;
147     if (d == null)
148       {
149     String JavaDoc fname = getMemberName();
150     ClassType t = getDeclaringClass();
151     gnu.bytecode.Field procField = t.getDeclaredField(fname);
152     if (procField == null)
153       return null;
154         ModuleInfo info = ModuleInfo.find(t.getName());
155         ModuleExp mexp = info.getModuleExp();
156         for (d = mexp.firstDecl(); d != null; d = d.nextDecl())
157           {
158             if (d.field != null && d.field.getName().equals(fname))
159               break;
160           }
161         if (d == null)
162           throw new RuntimeException JavaDoc("no field found for "+this);
163         decl = d;
164       }
165     return d;
166   }
167
168   void setup ()
169   {
170     synchronized (this)
171       {
172     if ((flags & SETUP_DONE) != 0)
173       return;
174     super.setup();
175         if ((flags & KIND_FLAGS_SET) == 0)
176           setKindFlags();
177         flags |= SETUP_DONE;
178       }
179   }
180
181   public Object JavaDoc get (Object JavaDoc defaultValue)
182   {
183     try
184       {
185         setup();
186       }
187     catch (Throwable JavaDoc ex)
188       {
189         return defaultValue;
190       }
191     Object JavaDoc v;
192     if ((flags & VALUE_SET) != 0)
193       {
194         v = value;
195         if ((flags & CONSTANT) != 0)
196           return v;
197       }
198     else
199       {
200     v = getFieldValue();
201     if ((type.getDeclaredField(mname).getModifiers() & Access.FINAL) != 0)
202       {
203         flags |= VALUE_SET;
204         if ((flags & INDIRECT_LOCATION) == 0)
205               flags |= CONSTANT;
206         value = v;
207       }
208       }
209     if ((flags & INDIRECT_LOCATION) != 0)
210       {
211     Object JavaDoc unb = Location.UNBOUND;
212     Location loc = (Location) v;
213     v = loc.get(unb);
214     if (v == unb)
215       return defaultValue;
216     if (loc.isConstant())
217       {
218         flags |= CONSTANT;
219         value = v;
220       }
221       }
222     return v;
223   }
224
225   private Object JavaDoc getFieldValue ()
226   {
227     super.setup(); // Set rfield, if needed.
228
try
229       {
230     return rfield.get(instance);
231       }
232     catch (Throwable JavaDoc ex)
233       {
234     throw WrappedException.wrapIfNeeded(ex);
235       }
236   }
237
238   public void set (Object JavaDoc newValue)
239   {
240     setup();
241     if ((flags & INDIRECT_LOCATION) == 0)
242       {
243     try
244       {
245         rfield.set(instance, newValue);
246       }
247     catch (Throwable JavaDoc ex)
248       {
249         throw WrappedException.wrapIfNeeded(ex);
250       }
251       }
252     else
253       {
254     Object JavaDoc v;
255     if ((flags & VALUE_SET) != 0)
256       v = value;
257     else
258       {
259         flags |= VALUE_SET;
260         v = getFieldValue();
261         value = v;
262       }
263     ((Location) v).set(newValue);
264       }
265   }
266
267   public boolean isConstant ()
268   {
269     if ((flags & KIND_FLAGS_SET) == 0)
270       setKindFlags();
271     if ((flags & CONSTANT) != 0)
272       return true;
273     if (isIndirectLocation())
274       {
275     Object JavaDoc v;
276     if ((flags & VALUE_SET) != 0)
277       v = value;
278     else
279       {
280             try
281               {
282                 setup();
283               }
284             catch (Throwable JavaDoc ex)
285               {
286                 return false;
287               }
288         v = getFieldValue();
289         flags |= VALUE_SET;
290         value = v;
291       }
292     return ((Location) v).isConstant();
293       }
294     return false;
295   }
296
297   public boolean isBound ()
298   {
299     if ((flags & KIND_FLAGS_SET) == 0)
300       setKindFlags();
301     if ((flags & CONSTANT) != 0 || (flags & INDIRECT_LOCATION) == 0)
302       return true;
303     Object JavaDoc v;
304     if ((flags & VALUE_SET) != 0)
305       v = value;
306     else
307       {
308         try
309           {
310             setup();
311           }
312         catch (Throwable JavaDoc ex)
313           {
314             return false;
315           }
316     v = getFieldValue();
317     flags |= VALUE_SET;
318     value = v;
319       }
320     return ((Location) v).isBound();
321   }
322
323   public static FieldLocation make (Object JavaDoc instance, Declaration decl)
324   {
325     gnu.bytecode.Field fld = decl.field;
326     ClassType ctype = fld.getDeclaringClass();
327     FieldLocation loc = new FieldLocation(instance, ctype, fld.getName());
328     loc.setDeclaration(decl);
329     //maybe setKindFlags();
330
return loc;
331   }
332
333   public static FieldLocation make (/*Object name,*/ Object JavaDoc instance, String JavaDoc cname, String JavaDoc fldName)
334   {
335     return new FieldLocation(/*name,*/ instance, ClassType.make(cname), fldName);
336   }
337
338   public String JavaDoc toString()
339   {
340     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
341     sbuf.append("FieldLocation[");
342     if (instance != null)
343       {
344     sbuf.append(instance);
345     sbuf.append(' ');
346       }
347     sbuf.append(type.getName());
348     sbuf.append('.');
349     sbuf.append(mname);
350     /* DEBGUGGING:
351     sbuf.append(" #:");
352     sbuf.append(id);
353     */

354     sbuf.append(']');
355     return sbuf.toString();
356   }
357 }
358
Popular Tags