Fix a shadow field related bug in the compiler. Defined in Java language specificatio...
[IRC.git] / Robust / src / IR / ClassDescriptor.java
1 package IR;
2 import java.util.*;
3 import IR.Tree.*;
4
5 public class ClassDescriptor extends Descriptor {
6   private static int UIDCount=1; // start from 1 instead of 0 for multicore gc
7   private final int classid;
8   String superclass;
9   ClassDescriptor superdesc;
10   boolean hasFlags=false;
11   String packagename;
12
13   Modifiers modifiers;
14
15   SymbolTable fields;
16   Vector fieldvec;
17   SymbolTable flags;
18   SymbolTable methods;
19   
20   int numstaticblocks = 0;
21   int numstaticfields = 0;
22   
23   // for interfaces
24   Vector<String> superinterfaces;
25   SymbolTable superIFdesc;
26   
27   // for inner classes
28   boolean isInnerClass=false;
29   
30   // inner classes/enum can have these
31   String surroundingclass=null;
32   ClassDescriptor surroudingdesc=null;
33   SymbolTable innerdescs;
34   
35   // for enum type
36   boolean isEnum = false;
37   SymbolTable enumdescs;
38   HashMap<String, Integer> enumConstantTbl;
39   int enumconstantid = 0;
40
41   public ClassDescriptor(String classname, boolean isInterface) {
42     this("", classname, isInterface);
43   }
44
45   public ClassDescriptor(String packagename, String classname, boolean isInterface) {
46     super(classname);
47     superclass=null;
48     flags=new SymbolTable();
49     fields=new SymbolTable();
50     fieldvec=new Vector();
51     methods=new SymbolTable();
52     if(isInterface) {
53       classid = -2;
54     } else {
55       classid=UIDCount++;
56     }
57     this.packagename=packagename;
58     superinterfaces = new Vector<String>();
59     superIFdesc = new SymbolTable();
60     this.innerdescs = new SymbolTable();
61     this.enumdescs = new SymbolTable();
62   }
63
64   public int getId() {
65     return classid;
66   }
67
68   public Iterator getMethods() {
69     return methods.getDescriptorsIterator();
70   }
71
72   public Iterator getFields() {
73     return fields.getDescriptorsIterator();
74   }
75
76   public Iterator getFlags() {
77     return flags.getDescriptorsIterator();
78   }
79   
80   public Iterator getSuperInterfaces() {
81     return this.superIFdesc.getDescriptorsIterator();
82   }
83
84   public SymbolTable getFieldTable() {
85     return fields;
86   }
87
88   public Vector getFieldVec() {
89     return fieldvec;
90   }
91
92   public SymbolTable getFlagTable() {
93     return flags;
94   }
95
96   public SymbolTable getMethodTable() {
97     return methods;
98   }
99   
100   public SymbolTable getSuperInterfaceTable() {
101     return this.superIFdesc;
102   }
103
104   public String getSafeDescriptor() {
105     return "L"+safename.replace('.','/');
106   }
107
108   public String printTree(State state) {
109     int indent;
110     String st=modifiers.toString()+"class "+getSymbol();
111     if (superclass!=null)
112       st+="extends "+superclass.toString();
113     if(this.superinterfaces != null) {
114       st += "implements ";
115       boolean needcomma = false;
116       for(int i = 0; i < this.superinterfaces.size(); i++) {
117         if(needcomma) {
118           st += ", ";
119         }
120         st += this.superinterfaces.elementAt(i);
121         needcomma = true;
122       }
123     }
124     st+=" {\n";
125     indent=TreeNode.INDENT;
126     boolean printcr=false;
127
128     for(Iterator it=getFlags(); it.hasNext();) {
129       FlagDescriptor fd=(FlagDescriptor)it.next();
130       st+=TreeNode.printSpace(indent)+fd.toString()+"\n";
131       printcr=true;
132     }
133     if (printcr)
134       st+="\n";
135
136     printcr=false;
137
138     for(Iterator it=getFields(); it.hasNext();) {
139       FieldDescriptor fd=(FieldDescriptor)it.next();
140       st+=TreeNode.printSpace(indent)+fd.toString()+"\n";
141       printcr=true;
142     }
143     if (printcr)
144       st+="\n";
145     
146     for(Iterator it=this.getInnerClasses(); it.hasNext();) {
147       ClassDescriptor icd=(ClassDescriptor)it.next();
148       st+=icd.printTree(state)+"\n";
149       printcr=true;
150     }
151     if (printcr)
152       st+="\n";
153     
154     for(Iterator it=this.getEnum(); it.hasNext();) {
155       ClassDescriptor icd = (ClassDescriptor)it.next();
156       st += icd.getModifier().toString() + " enum " + icd.getSymbol() + " {\n  ";
157       Set keys = icd.getEnumConstantTbl().keySet();
158       String[] econstants = new String[keys.size()];
159       Iterator it_keys = keys.iterator();
160       while(it_keys.hasNext()) {
161         String key = (String)it_keys.next();
162         econstants[icd.getEnumConstant(key)] = key;
163       }
164       for(int i = 0; i < econstants.length; i++) {
165         st += econstants[i];
166         if(i < econstants.length-1) {
167           st += ", ";
168         }
169       }
170       st+="\n}\n";
171       printcr=true;
172     }
173     if (printcr)
174       st+="\n";
175
176     for(Iterator it=getMethods(); it.hasNext();) {
177       MethodDescriptor md=(MethodDescriptor)it.next();
178       st+=TreeNode.printSpace(indent)+md.toString()+" ";
179       BlockNode bn=state.getMethodBody(md);
180       st+=bn.printNode(indent)+"\n\n";
181     }
182     st+="}\n";
183     return st;
184   }
185
186   public void addFlag(FlagDescriptor fd) {
187     if (flags.contains(fd.getSymbol()))
188       throw new Error(fd.getSymbol()+" already defined");
189     hasFlags=true;
190     flags.add(fd);
191   }
192
193   public boolean hasFlags() {
194     return hasFlags||getSuperDesc()!=null&&getSuperDesc().hasFlags();
195   }
196
197   public void addField(FieldDescriptor fd) {
198     if (fields.contains(fd.getSymbol()))
199       throw new Error(fd.getSymbol()+" already defined");
200     fields.add(fd);
201     fieldvec.add(fd);
202     if(fd.isStatic()) {
203       this.incStaticFields();
204     }
205     fd.setClassDescriptor(this);
206   }
207
208   public void addMethod(MethodDescriptor md) {
209     methods.add(md);
210   }
211
212   public void setModifiers(Modifiers modifiers) {
213     this.modifiers=modifiers;
214   }
215
216   public void setSuper(String superclass) {
217     this.superclass=superclass;
218   }
219
220   public ClassDescriptor getSuperDesc() {
221     return superdesc;
222   }
223
224   public void setSuper(ClassDescriptor scd) {
225     this.superdesc=scd;
226   }
227
228   public String getSuper() {
229     return superclass;
230   }
231   
232   public void addSuperInterface(String superif) {
233     this.superinterfaces.addElement(superif);
234   }
235   
236   public Vector<String> getSuperInterface() {
237     return this.superinterfaces;
238   }
239   
240   public void addSuperInterfaces(ClassDescriptor sif) {
241     this.superIFdesc.add(sif);
242   }
243   
244   public void incStaticBlocks() {
245     this.numstaticblocks++;
246   }
247   
248   public int getNumStaticBlocks() {
249     return this.numstaticblocks;
250   }
251   
252   public void incStaticFields() {
253     this.numstaticfields++;
254   }
255   
256   public int getNumStaticFields() {
257     return this.numstaticfields;
258   }
259   
260   public boolean isAbstract() {
261     return this.modifiers.isAbstract();
262   }
263   
264   public boolean isInterface() {
265     return this.classid == -2;
266   }
267   
268   public boolean isStatic() {
269     return this.modifiers.isStatic();
270   }
271   
272   public void setAsInnerClass() {
273     this.isInnerClass = true;
274   }
275   
276   public boolean isInnerClass() {
277     return this.isInnerClass;
278   }
279   
280   public void setSurroundingClass(String sclass) {
281     this.surroundingclass=sclass;
282   }
283
284   public String getSurrounding() {
285     return this.surroundingclass;
286   }
287
288   public ClassDescriptor getSurroundingDesc() {
289     return this.surroudingdesc;
290   }
291
292   public void setSurrounding(ClassDescriptor scd) {
293     this.surroudingdesc=scd;
294   }
295   
296   public void addInnerClass(ClassDescriptor icd) {
297     this.innerdescs.add(icd);
298   }
299   
300   public Iterator getInnerClasses() {
301     return this.innerdescs.getDescriptorsIterator();
302   }
303
304   public SymbolTable getInnerClassTable() {
305     return this.innerdescs;
306   }
307   
308   public void setAsEnum() {
309     this.isEnum = true;
310   }
311   
312   public boolean isEnum() {
313     return this.isEnum;
314   }
315   
316   public void addEnum(ClassDescriptor icd) {
317     this.enumdescs.add(icd);
318   }
319   
320   public Iterator getEnum() {
321     return this.enumdescs.getDescriptorsIterator();
322   }
323
324   public SymbolTable getEnumTable() {
325     return this.enumdescs;
326   }
327   
328   public void addEnumConstant(String econstant) {
329     if(this.enumConstantTbl == null) {
330       this.enumConstantTbl = new HashMap<String, Integer>();
331     }
332     if(this.enumConstantTbl.containsKey(econstant)) {
333       return;
334     } else {
335       this.enumConstantTbl.put(econstant, this.enumconstantid++);
336     }
337     return;
338   }
339   
340   public int getEnumConstant(String econstant) {
341     if(this.enumConstantTbl.containsKey(econstant)) {
342       return this.enumConstantTbl.get(econstant).intValue();
343     } else {
344       return -1;
345     }
346   }
347   
348   public HashMap<String, Integer> getEnumConstantTbl() {
349     return this.enumConstantTbl;
350   }
351   
352   public Modifiers getModifier() {
353     return this.modifiers;
354   }
355 }