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