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