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;
10 ClassDescriptor superdesc;
11 boolean hasFlags=false;
21 Hashtable singleImports;
23 int numstaticblocks = 0;
24 int numstaticfields = 0;
27 Vector<String> superinterfaces;
28 SymbolTable superIFdesc;
29 private int interfaceid;
32 boolean isInnerClass=false;
34 // inner classes/enum can have these
35 String surroundingclass=null;
36 ClassDescriptor surroudingdesc=null;
37 SymbolTable innerdescs;
40 boolean isEnum = false;
41 SymbolTable enumdescs;
42 HashMap<String, Integer> enumConstantTbl;
43 int enumconstantid = 0;
45 String sourceFileName;
47 public ClassDescriptor(String classname, boolean isInterface) {
48 this("", classname, isInterface);
51 public ClassDescriptor(String packagename, String classname, boolean isInterface) {
52 //make the name canonical by class file path (i.e. package)
55 flags=new SymbolTable();
56 fields=new SymbolTable();
57 fieldvec=new Vector();
58 methods=new SymbolTable();
61 this.interfaceid = -1;
65 this.packagename=packagename;
66 superinterfaces = new Vector<String>();
67 superIFdesc = new SymbolTable();
68 this.innerdescs = new SymbolTable();
69 this.enumdescs = new SymbolTable();
73 if(this.isInterface()) {
74 return this.interfaceid;
79 public Iterator getMethods() {
80 return methods.getDescriptorsIterator();
83 public Iterator getFields() {
84 return fields.getDescriptorsIterator();
87 public Iterator getFlags() {
88 return flags.getDescriptorsIterator();
91 public Iterator getSuperInterfaces() {
92 return this.superIFdesc.getDescriptorsIterator();
95 public SymbolTable getFieldTable() {
99 public Vector getFieldVec() {
103 public String getPackage() {
107 public SymbolTable getFlagTable() {
111 public SymbolTable getMethodTable() {
115 public SymbolTable getSuperInterfaceTable() {
116 return this.superIFdesc;
119 public String getSafeDescriptor() {
120 return "L"+safename.replace('.','/');
123 public String printTree(State state) {
125 String st=modifiers.toString()+"class "+getSymbol();
126 if (superclass!=null)
127 st+="extends "+superclass.toString();
128 if(this.superinterfaces != null) {
130 boolean needcomma = false;
131 for(int i = 0; i < this.superinterfaces.size(); i++) {
135 st += this.superinterfaces.elementAt(i);
140 indent=TreeNode.INDENT;
141 boolean printcr=false;
143 for(Iterator it=getFlags(); it.hasNext(); ) {
144 FlagDescriptor fd=(FlagDescriptor)it.next();
145 st+=TreeNode.printSpace(indent)+fd.toString()+"\n";
153 for(Iterator it=getFields(); it.hasNext(); ) {
154 FieldDescriptor fd=(FieldDescriptor)it.next();
155 st+=TreeNode.printSpace(indent)+fd.toString()+"\n";
161 for(Iterator it=this.getInnerClasses(); it.hasNext(); ) {
162 ClassDescriptor icd=(ClassDescriptor)it.next();
163 st+=icd.printTree(state)+"\n";
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;
179 for(int i = 0; i < econstants.length; i++) {
181 if(i < econstants.length-1) {
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";
201 public MethodDescriptor getCalledMethod(MethodDescriptor md) {
202 ClassDescriptor cn=this;
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.");
213 Set possiblematches=cn.getMethodTable().getSetFromSameScope(md.getSymbol());
214 for(Iterator matchit=possiblematches.iterator(); matchit.hasNext(); ) {
215 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
217 if (md.matches(matchmd)) {
222 //Not found...walk one level up
223 cn=cn.getSuperDesc();
227 public void addFlag(FlagDescriptor fd) {
228 if (flags.contains(fd.getSymbol()))
229 throw new Error(fd.getSymbol()+" already defined");
234 public boolean hasFlags() {
235 return hasFlags||getSuperDesc()!=null&&getSuperDesc().hasFlags();
238 public void addField(FieldDescriptor fd) {
239 if (fields.contains(fd.getSymbol()))
240 throw new Error(fd.getSymbol()+" already defined");
244 this.incStaticFields();
246 fd.setClassDescriptor(this);
249 public void addMethod(MethodDescriptor md) {
253 public void setModifiers(Modifiers modifiers) {
254 this.modifiers=modifiers;
257 public void setSuper(String superclass) {
258 this.superclass=superclass;
261 public ClassDescriptor getSuperDesc() {
265 public void setSuper(ClassDescriptor scd) {
269 public String getSuper() {
273 public void addSuperInterface(String superif) {
274 this.superinterfaces.addElement(superif);
277 public Vector<String> getSuperInterface() {
278 return this.superinterfaces;
281 public void addSuperInterfaces(ClassDescriptor sif) {
282 this.superIFdesc.add(sif);
285 public void incStaticBlocks() {
286 this.numstaticblocks++;
289 public int getNumStaticBlocks() {
290 return this.numstaticblocks;
293 public void incStaticFields() {
294 this.numstaticfields++;
297 public int getNumStaticFields() {
298 return this.numstaticfields;
301 public boolean isAbstract() {
302 return this.modifiers.isAbstract();
305 public boolean isInterface() {
306 return (this.classid == -2);
309 public void setInterfaceId(int id) {
310 this.interfaceid = id;
313 public boolean isStatic() {
314 return this.modifiers.isStatic();
317 public void setAsInnerClass() {
318 this.isInnerClass = true;
321 public boolean isInnerClass() {
322 return this.isInnerClass;
325 public void setSurroundingClass(String sclass) {
326 this.surroundingclass=sclass;
329 public String getSurrounding() {
330 return this.surroundingclass;
333 public ClassDescriptor getSurroundingDesc() {
334 return this.surroudingdesc;
337 public void setSurrounding(ClassDescriptor scd) {
338 this.surroudingdesc=scd;
341 public void addInnerClass(ClassDescriptor icd) {
342 this.innerdescs.add(icd);
345 public Iterator getInnerClasses() {
346 return this.innerdescs.getDescriptorsIterator();
349 public SymbolTable getInnerClassTable() {
350 return this.innerdescs;
353 public void setAsEnum() {
357 public boolean isEnum() {
361 public void addEnum(ClassDescriptor icd) {
362 this.enumdescs.add(icd);
365 public Iterator getEnum() {
366 return this.enumdescs.getDescriptorsIterator();
369 public SymbolTable getEnumTable() {
370 return this.enumdescs;
373 public void addEnumConstant(String econstant) {
374 if(this.enumConstantTbl == null) {
375 this.enumConstantTbl = new HashMap<String, Integer>();
377 if(this.enumConstantTbl.containsKey(econstant)) {
380 this.enumConstantTbl.put(econstant, this.enumconstantid++);
385 public int getEnumConstant(String econstant) {
386 if(this.enumConstantTbl.containsKey(econstant)) {
387 return this.enumConstantTbl.get(econstant).intValue();
393 public HashMap<String, Integer> getEnumConstantTbl() {
394 return this.enumConstantTbl;
397 public Modifiers getModifier() {
398 return this.modifiers;
401 public void setSourceFileName(String sourceFileName) {
402 this.sourceFileName=sourceFileName;
405 public void setImports(Hashtable singleImports) {
406 this.singleImports = singleImports;
409 public String getSourceFileName() {
410 return this.sourceFileName;
413 public Hashtable getSingleImportMappings() {
414 return this.singleImports;