package IR;
import java.util.*;
import IR.Tree.*;
+import Util.Lattice;
public class ClassDescriptor extends Descriptor {
private static int UIDCount=1; // start from 1 instead of 0 for multicore gc
int numstaticfields = 0;
// for interfaces
- boolean isInterface=false;
Vector<String> superinterfaces;
SymbolTable superIFdesc;
-
- public ClassDescriptor(String classname) {
- this("", classname);
+ private int interfaceid;
+
+ // for inner classes
+ boolean isInnerClass=false;
+
+ // inner classes/enum can have these
+ String surroundingclass=null;
+ ClassDescriptor surroudingdesc=null;
+ SymbolTable innerdescs;
+
+ // for enum type
+ boolean isEnum = false;
+ SymbolTable enumdescs;
+ HashMap<String, Integer> enumConstantTbl;
+ int enumconstantid = 0;
+
+ boolean isClassLibrary=false;
+
+ String sourceFileName;
+
+ public ClassDescriptor(String classname, boolean isInterface) {
+ this("", classname, isInterface);
}
- public ClassDescriptor(String packagename, String classname) {
+ public ClassDescriptor(String packagename, String classname, boolean isInterface) {
super(classname);
superclass=null;
flags=new SymbolTable();
fields=new SymbolTable();
fieldvec=new Vector();
methods=new SymbolTable();
- classid=UIDCount++;
+ if(isInterface) {
+ this.classid = -2;
+ this.interfaceid = -1;
+ } else {
+ classid=UIDCount++;
+ }
this.packagename=packagename;
superinterfaces = new Vector<String>();
superIFdesc = new SymbolTable();
+ this.innerdescs = new SymbolTable();
+ this.enumdescs = new SymbolTable();
}
public int getId() {
+ if(this.isInterface()) {
+ return this.interfaceid;
+ }
return classid;
}
return fieldvec;
}
+ public String getPackage() {
+ return packagename;
+ }
+
public SymbolTable getFlagTable() {
return flags;
}
}
if (printcr)
st+="\n";
+
+ for(Iterator it=this.getInnerClasses(); it.hasNext();) {
+ ClassDescriptor icd=(ClassDescriptor)it.next();
+ st+=icd.printTree(state)+"\n";
+ printcr=true;
+ }
+ if (printcr)
+ st+="\n";
+
+ for(Iterator it=this.getEnum(); it.hasNext();) {
+ ClassDescriptor icd = (ClassDescriptor)it.next();
+ st += icd.getModifier().toString() + " enum " + icd.getSymbol() + " {\n ";
+ Set keys = icd.getEnumConstantTbl().keySet();
+ String[] econstants = new String[keys.size()];
+ Iterator it_keys = keys.iterator();
+ while(it_keys.hasNext()) {
+ String key = (String)it_keys.next();
+ econstants[icd.getEnumConstant(key)] = key;
+ }
+ for(int i = 0; i < econstants.length; i++) {
+ st += econstants[i];
+ if(i < econstants.length-1) {
+ st += ", ";
+ }
+ }
+ st+="\n}\n";
+ printcr=true;
+ }
+ if (printcr)
+ st+="\n";
for(Iterator it=getMethods(); it.hasNext();) {
MethodDescriptor md=(MethodDescriptor)it.next();
return st;
}
+ public MethodDescriptor getCalledMethod(MethodDescriptor md) {
+ ClassDescriptor cn=this;
+ while(true) {
+ if (cn==null) {
+ // TODO: the original code returned "null" if no super class
+ // ever defines the method. Is there a situation where this is
+ // fine and the client should take other actions? If not, we should
+ // change this warning to an error.
+ System.out.println( "ClassDescriptor.java: WARNING "+md+
+ " did not resolve to an actual method." );
+ return null;
+ }
+ Set possiblematches=cn.getMethodTable().getSetFromSameScope(md.getSymbol());
+ for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
+ MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
+
+ if (md.matches(matchmd)) {
+ return matchmd;
+ }
+ }
+
+ //Not found...walk one level up
+ cn=cn.getSuperDesc();
+ }
+ }
+
public void addFlag(FlagDescriptor fd) {
if (flags.contains(fd.getSymbol()))
throw new Error(fd.getSymbol()+" already defined");
if(fd.isStatic()) {
this.incStaticFields();
}
+ fd.setClassDescriptor(this);
}
public void addMethod(MethodDescriptor md) {
}
public boolean isInterface() {
- return this.isInterface;
+ return (this.classid == -2);
+ }
+
+ public void setInterfaceId(int id) {
+ this.interfaceid = id;
+ }
+
+ public boolean isStatic() {
+ return this.modifiers.isStatic();
+ }
+
+ public void setAsInnerClass() {
+ this.isInnerClass = true;
+ }
+
+ public boolean isInnerClass() {
+ return this.isInnerClass;
+ }
+
+ public void setSurroundingClass(String sclass) {
+ this.surroundingclass=sclass;
+ }
+
+ public String getSurrounding() {
+ return this.surroundingclass;
+ }
+
+ public ClassDescriptor getSurroundingDesc() {
+ return this.surroudingdesc;
+ }
+
+ public void setSurrounding(ClassDescriptor scd) {
+ this.surroudingdesc=scd;
+ }
+
+ public void addInnerClass(ClassDescriptor icd) {
+ this.innerdescs.add(icd);
+ }
+
+ public Iterator getInnerClasses() {
+ return this.innerdescs.getDescriptorsIterator();
+ }
+
+ public SymbolTable getInnerClassTable() {
+ return this.innerdescs;
+ }
+
+ public void setAsEnum() {
+ this.isEnum = true;
+ }
+
+ public boolean isEnum() {
+ return this.isEnum;
}
- public void setAsInterface() {
- this.isInterface = true;
+ public void addEnum(ClassDescriptor icd) {
+ this.enumdescs.add(icd);
}
+
+ public Iterator getEnum() {
+ return this.enumdescs.getDescriptorsIterator();
+ }
+
+ public SymbolTable getEnumTable() {
+ return this.enumdescs;
+ }
+
+ public void addEnumConstant(String econstant) {
+ if(this.enumConstantTbl == null) {
+ this.enumConstantTbl = new HashMap<String, Integer>();
+ }
+ if(this.enumConstantTbl.containsKey(econstant)) {
+ return;
+ } else {
+ this.enumConstantTbl.put(econstant, this.enumconstantid++);
+ }
+ return;
+ }
+
+ public int getEnumConstant(String econstant) {
+ if(this.enumConstantTbl.containsKey(econstant)) {
+ return this.enumConstantTbl.get(econstant).intValue();
+ } else {
+ return -1;
+ }
+ }
+
+ public HashMap<String, Integer> getEnumConstantTbl() {
+ return this.enumConstantTbl;
+ }
+
+ public Modifiers getModifier() {
+ return this.modifiers;
+ }
+
+ public void setClassLibrary(){
+ this.isClassLibrary=true;
+ }
+
+ public boolean isClassLibrary(){
+ return isClassLibrary;
+ }
+
+ public void setSourceFileName(String sourceFileName){
+ this.sourceFileName=sourceFileName;
+ }
+
+ public String getSourceFileName(){
+ return this.sourceFileName;
+ }
+
}