X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FIR%2FClassDescriptor.java;h=43923d0cff3830e103b83e33840300a2232723a0;hb=bd6155026f555257a526a2e0440b2c9f60eb018f;hp=d1fa7b4942cb58df0c6e2a2c99dddfb309fca292;hpb=3ad6a49a28d6768a6bbbd38c3fea80bc4ea59b16;p=IRC.git diff --git a/Robust/src/IR/ClassDescriptor.java b/Robust/src/IR/ClassDescriptor.java index d1fa7b49..43923d0c 100644 --- a/Robust/src/IR/ClassDescriptor.java +++ b/Robust/src/IR/ClassDescriptor.java @@ -10,6 +10,7 @@ public class ClassDescriptor extends Descriptor { ClassDescriptor superdesc; boolean hasFlags=false; String packagename; + String classname; Modifiers modifiers; @@ -17,54 +18,66 @@ public class ClassDescriptor extends Descriptor { Vector fieldvec; SymbolTable flags; SymbolTable methods; + boolean inline=false; + + ChainHashMap mandatoryImports; + ChainHashMap multiImports; + int numstaticblocks = 0; int numstaticfields = 0; - + // for interfaces Vector superinterfaces; SymbolTable superIFdesc; - private boolean isInterface; - + 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 enumConstantTbl; int enumconstantid = 0; - - // for SSJava - Lattice locOrder; + + String sourceFileName; public ClassDescriptor(String classname, boolean isInterface) { this("", classname, isInterface); } public ClassDescriptor(String packagename, String classname, boolean isInterface) { - super(classname); + //make the name canonical by class file path (i.e. package) + super(packagename!=null?packagename+"."+classname:classname); + this.classname=classname; superclass=null; flags=new SymbolTable(); fields=new SymbolTable(); fieldvec=new Vector(); methods=new SymbolTable(); - this.isInterface = isInterface; - classid=UIDCount++; + if(isInterface) { + this.classid = -2; + this.interfaceid = -1; + } else { + classid=UIDCount++; + } this.packagename=packagename; superinterfaces = new Vector(); superIFdesc = new SymbolTable(); this.innerdescs = new SymbolTable(); this.enumdescs = new SymbolTable(); - this.locOrder=new Lattice(); } public int getId() { + if(this.isInterface()) { + return this.interfaceid; + } return classid; } @@ -79,7 +92,7 @@ public class ClassDescriptor extends Descriptor { public Iterator getFlags() { return flags.getDescriptorsIterator(); } - + public Iterator getSuperInterfaces() { return this.superIFdesc.getDescriptorsIterator(); } @@ -92,6 +105,14 @@ public class ClassDescriptor extends Descriptor { return fieldvec; } + public String getClassName() { + return classname; + } + + public String getPackage() { + return packagename; + } + public SymbolTable getFlagTable() { return flags; } @@ -99,13 +120,17 @@ public class ClassDescriptor extends Descriptor { public SymbolTable getMethodTable() { return methods; } - + public SymbolTable getSuperInterfaceTable() { return this.superIFdesc; } public String getSafeDescriptor() { - return "L"+safename.replace('.','/'); + return "L"+safename.replace(".","___________"); + } + + public String getSafeSymbol() { + return safename.replace(".","___________").replace("$","___DOLLAR___"); } public String printTree(State state) { @@ -128,7 +153,7 @@ public class ClassDescriptor extends Descriptor { indent=TreeNode.INDENT; boolean printcr=false; - for(Iterator it=getFlags(); it.hasNext();) { + for(Iterator it=getFlags(); it.hasNext(); ) { FlagDescriptor fd=(FlagDescriptor)it.next(); st+=TreeNode.printSpace(indent)+fd.toString()+"\n"; printcr=true; @@ -138,23 +163,23 @@ public class ClassDescriptor extends Descriptor { printcr=false; - for(Iterator it=getFields(); it.hasNext();) { + for(Iterator it=getFields(); it.hasNext(); ) { FieldDescriptor fd=(FieldDescriptor)it.next(); st+=TreeNode.printSpace(indent)+fd.toString()+"\n"; printcr=true; } if (printcr) st+="\n"; - - for(Iterator it=this.getInnerClasses(); it.hasNext();) { + + 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();) { + + 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(); @@ -176,7 +201,7 @@ public class ClassDescriptor extends Descriptor { if (printcr) st+="\n"; - for(Iterator it=getMethods(); it.hasNext();) { + for(Iterator it=getMethods(); it.hasNext(); ) { MethodDescriptor md=(MethodDescriptor)it.next(); st+=TreeNode.printSpace(indent)+md.toString()+" "; BlockNode bn=state.getMethodBody(md); @@ -189,18 +214,24 @@ public class ClassDescriptor extends Descriptor { public MethodDescriptor getCalledMethod(MethodDescriptor md) { ClassDescriptor cn=this; while(true) { - Iterator methodit=cn.getMethods(); - //Iterator through methods - while(methodit.hasNext()) { - Set possiblematches=cn.getMethodTable().getSet(md.getSymbol()); - boolean foundmatch=false; - for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) { - MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); - if (md.matches(matchmd)) { - return matchmd; - } - } + 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(); } @@ -236,6 +267,14 @@ public class ClassDescriptor extends Descriptor { this.modifiers=modifiers; } + public void setInline() { + this.inline=true; + } + + public boolean getInline() { + return inline; + } + public void setSuper(String superclass) { this.superclass=superclass; } @@ -244,62 +283,66 @@ public class ClassDescriptor extends Descriptor { return superdesc; } - public void setSuper(ClassDescriptor scd) { + public void setSuperDesc(ClassDescriptor scd) { this.superdesc=scd; } public String getSuper() { return superclass; } - + public void addSuperInterface(String superif) { this.superinterfaces.addElement(superif); } - + public Vector getSuperInterface() { return this.superinterfaces; } - + public void addSuperInterfaces(ClassDescriptor sif) { this.superIFdesc.add(sif); } - + public void incStaticBlocks() { this.numstaticblocks++; } - + public int getNumStaticBlocks() { return this.numstaticblocks; } - + public void incStaticFields() { this.numstaticfields++; } - + public int getNumStaticFields() { return this.numstaticfields; } - + public boolean isAbstract() { return this.modifiers.isAbstract(); } - + 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; } @@ -315,11 +358,11 @@ public class ClassDescriptor extends Descriptor { public void setSurrounding(ClassDescriptor scd) { this.surroudingdesc=scd; } - + public void addInnerClass(ClassDescriptor icd) { this.innerdescs.add(icd); } - + public Iterator getInnerClasses() { return this.innerdescs.getDescriptorsIterator(); } @@ -327,19 +370,19 @@ public class ClassDescriptor extends Descriptor { public SymbolTable getInnerClassTable() { return this.innerdescs; } - + public void setAsEnum() { this.isEnum = true; } - + public boolean isEnum() { return this.isEnum; } - + public void addEnum(ClassDescriptor icd) { this.enumdescs.add(icd); } - + public Iterator getEnum() { return this.enumdescs.getDescriptorsIterator(); } @@ -347,7 +390,7 @@ public class ClassDescriptor extends Descriptor { public SymbolTable getEnumTable() { return this.enumdescs; } - + public void addEnumConstant(String econstant) { if(this.enumConstantTbl == null) { this.enumConstantTbl = new HashMap(); @@ -359,7 +402,7 @@ public class ClassDescriptor extends Descriptor { } return; } - + public int getEnumConstant(String econstant) { if(this.enumConstantTbl.containsKey(econstant)) { return this.enumConstantTbl.get(econstant).intValue(); @@ -367,21 +410,53 @@ public class ClassDescriptor extends Descriptor { return -1; } } - + public HashMap getEnumConstantTbl() { return this.enumConstantTbl; } - + public Modifiers getModifier() { return this.modifiers; } - - public Lattice getLocOrder(){ - return this.locOrder; + + public void setSourceFileName(String sourceFileName) { + this.sourceFileName=sourceFileName; } - - public void setLocOrder(Lattice locOrder){ - this.locOrder=locOrder; + + public void setImports(ChainHashMap singleImports, ChainHashMap multiImports) { + this.mandatoryImports = singleImports; + this.multiImports = multiImports; + } + + public String getSourceFileName() { + return this.sourceFileName; + } + + public ChainHashMap getSingleImportMappings() { + return this.mandatoryImports; } + public ChainHashMap getMultiImportMappings() { + return this.multiImports; + } + + //Returns the full name/path of another class referenced from this class via imports. + public String getCanonicalImportMapName(String otherClassname) { + if(mandatoryImports.containsKey(otherClassname)) { + return (String) mandatoryImports.get(otherClassname); + } else if(multiImports.containsKey(otherClassname)) { + //Test for error + Object o = multiImports.get(otherClassname); + if(o instanceof Error) { + throw new Error("Class " + otherClassname + " is ambiguous. Cause: more than 1 package import contain the same class."); + } else { + //At this point, if we found a unique class + //we can treat it as a single, mandatory import. + mandatoryImports.put(otherClassname, o); + return (String) o; + } + } else { + return otherClassname; + } + } }