checking outstanding changes in my CVS
[IRC.git] / Robust / src / IR / TypeUtil.java
index 443ba4f0b066d787d04b577cb2d61c781442314b..d289a9535e8d20ba2956d174d2826fbc65460b41 100644 (file)
@@ -1,5 +1,8 @@
 package IR;
 import java.util.*;
+import IR.Tree.*;
+import java.io.File;
+import Main.Main;
 
 public class TypeUtil {
   public static final String StringClass="String";
@@ -7,35 +10,64 @@ public class TypeUtil {
   public static final String StartupClass="StartupObject";
   public static final String TagClass="TagDescriptor";
   public static final String ThreadClass="Thread";
+  public static final String TaskClass="Task";
   State state;
   Hashtable supertable;
   Hashtable subclasstable;
+  BuildIR bir;
 
-  public TypeUtil(State state) {
+  public TypeUtil(State state, BuildIR bir) {
     this.state=state;
+    this.bir=bir;
     createTables();
   }
 
+  public void addNewClass(String cl, Set todo) {
+    for(int i=0;i<state.classpath.size();i++) {
+      String path=(String)state.classpath.get(i);
+      File f=new File(path, cl+".java");
+      if (f.exists()) {
+       try {
+         ParseNode pn=Main.readSourceFile(state, f.getCanonicalPath());
+         bir.buildtree(pn, todo);
+         return;
+       } catch (Exception e) {
+         throw new Error(e);
+       }
+      }
+    }
+    throw new Error("Couldn't find class "+cl);
+  }
+
+
+
   public ClassDescriptor getClass(String classname) {
     ClassDescriptor cd=(ClassDescriptor)state.getClassSymbolTable().get(classname);
     return cd;
   }
 
-  private void createTables() {
-    supertable=new Hashtable();
+  public ClassDescriptor getClass(String classname, HashSet todo) {
+    ClassDescriptor cd=(ClassDescriptor)state.getClassSymbolTable().get(classname);
+    if (cd==null) {
+      //have to find class
+      addNewClass(classname, todo);
+      cd=(ClassDescriptor)state.getClassSymbolTable().get(classname);
 
-    Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
-    while(classit.hasNext()) {
-      ClassDescriptor cd=(ClassDescriptor)classit.next();
+      System.out.println("Build class:"+cd);
+      todo.add(cd);
+    }
+    if (!supertable.containsKey(cd)) {
       String superc=cd.getSuper();
       if (superc!=null) {
-       ClassDescriptor cd_super=getClass(superc);
-       if (cd_super==null) {
-         throw new Error("Couldn't find class:"+superc);
-       }
+       ClassDescriptor cd_super=getClass(superc, todo);
        supertable.put(cd,cd_super);
       }
     }
+    return cd;
+  }
+
+  private void createTables() {
+    supertable=new Hashtable();
   }
 
   public ClassDescriptor getMainClass() {
@@ -52,6 +84,22 @@ public class TypeUtil {
     }
     throw new Error("Can't find Thread.run");
   }
+  
+  public MethodDescriptor getExecute() {
+    ClassDescriptor cd = getClass(TypeUtil.TaskClass);
+
+    if(cd == null && state.DSMTASK)
+      throw new Error("Task.java is not included");
+
+    for(Iterator methodit = cd.getMethodTable().getSet("execute").iterator(); methodit.hasNext();) {
+      MethodDescriptor md = (MethodDescriptor) methodit.next();
+      if (md.numParameters()!=0 || md.getModifiers().isStatic())
+        continue;
+      return md;
+    }
+    throw new Error("Can't find Task.execute");
+  }
+
 
   public MethodDescriptor getMain() {
     ClassDescriptor cd=getMainClass();
@@ -87,8 +135,12 @@ public class TypeUtil {
       if (!this.isSuperorType(md2.getParamType(i), md1.getParamType(i)))
        return false;
     }
-    if (!this.isSuperorType(md2.getReturnType(), md1.getReturnType()))
-      return false;
+    if (md1.getReturnType()==null||md2.getReturnType()==null) {
+       if (md1.getReturnType()!=md2.getReturnType())
+           return false;
+    } else
+       if (!this.isSuperorType(md2.getReturnType(), md1.getReturnType()))
+           return false;
 
     if (!this.isSuperorType(md2.getClassDesc(), md1.getClassDesc()))
       return false;
@@ -172,6 +224,7 @@ NextMethod:
   }
 
   public boolean isSuperorType(TypeDescriptor possiblesuper, TypeDescriptor cd2) {
+    if (possiblesuper.isOffset() || cd2.isOffset()) return true;
     //Matching type are always okay
     if (possiblesuper.equals(cd2))
       return true;
@@ -197,6 +250,10 @@ NextMethod:
           &&(possiblesuper.getArrayCount()<cd2.getArrayCount()))
        return true;
 
+      //Allow arraytype=null statements
+      if (possiblesuper.isArray()&&cd2.isNull())
+       return true;
+
       return false;
     }
 
@@ -248,6 +305,19 @@ NextMethod:
       throw new Error("Case not handled:"+possiblesuper+" "+cd2);
   }
 
+  public TypeDescriptor mostSpecific(TypeDescriptor td1, TypeDescriptor td2) {
+    if( isSuperorType( td1, td2 ) ) {
+      return td2;
+    }
+    if( isSuperorType( td2, td1 ) ) {
+      return td1;
+    }
+    throw new Error( td1+" and "+td2+" have no superclass relationship" );
+  }
+
+  public TypeDescriptor mostSpecific(TypeDescriptor td1, TypeDescriptor td2, TypeDescriptor td3) {
+    return mostSpecific( td1, mostSpecific( td2, td3 ) );
+  }
 
   public boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
     if (possiblesuper==cd2)
@@ -257,6 +327,7 @@ NextMethod:
   }
 
   private boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
+
     while(cd2!=null) {
       cd2=getSuper(cd2);
       if (cd2==possiblesuper)