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