code to generate calls into JNI native code...
[IRC.git] / Robust / src / IR / ClassDescriptor.java
index 6c3735b283105feae79bcbf61546ce79cf7ac6a6..6a8c210897aabdd1f083ebbbb9bf3a8809dba13e 100644 (file)
@@ -1,6 +1,7 @@
 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
@@ -21,28 +22,56 @@ public class ClassDescriptor extends Descriptor {
   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;
   }
 
@@ -70,6 +99,10 @@ public class ClassDescriptor extends Descriptor {
     return fieldvec;
   }
 
+  public String getPackage() {
+    return packagename;
+  }
+
   public SymbolTable getFlagTable() {
     return flags;
   }
@@ -123,6 +156,36 @@ public class ClassDescriptor extends Descriptor {
     }
     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();
@@ -134,6 +197,32 @@ public class ClassDescriptor extends Descriptor {
     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");
@@ -153,6 +242,7 @@ public class ClassDescriptor extends Descriptor {
     if(fd.isStatic()) {
       this.incStaticFields();
     }
+    fd.setClassDescriptor(this);
   }
 
   public void addMethod(MethodDescriptor md) {
@@ -212,10 +302,115 @@ public class ClassDescriptor extends Descriptor {
   }
   
   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;
+  }
+  
 }