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