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