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