start of new file
[IRC.git] / Robust / src / IR / TypeUtil.java
index e5ce84bc70fda79a0df2e37c9ccbcfad1aaf2949..92e4e5861b45b6483e7a1dedf14b70ef882ff5df 100644 (file)
@@ -30,6 +30,9 @@ public class TypeUtil {
            String superc=cd.getSuper();
            if (superc!=null) {
                ClassDescriptor cd_super=getClass(superc);
+               if (cd_super==null) {
+                   throw new Error("Couldn't find class:"+superc);
+               }
                supertable.put(cd,cd_super);
            }
        }
@@ -72,6 +75,58 @@ public class TypeUtil {
        throw new Error(cd+" has no main");
     }
 
+    /** Check to see if md1 is more specific than md2...  Informally
+       if md2 could always be called given the arguments passed into
+       md1 */
+
+    public boolean isMoreSpecific(MethodDescriptor md1, MethodDescriptor md2) {
+       /* Checks if md1 is more specific than md2 */
+       if (md1.numParameters()!=md2.numParameters())
+           throw new Error();
+       for(int i=0;i<md1.numParameters();i++) {
+           if (!this.isSuperorType(md2.getParamType(i), md1.getParamType(i)))
+               return false;
+       }
+       if (!this.isSuperorType(md2.getReturnType(), md1.getReturnType()))
+               return false;
+
+       if (!this.isSuperorType(md2.getClassDesc(), md1.getClassDesc()))
+               return false;
+
+       return true;
+    }
+
+    public MethodDescriptor getMethod(ClassDescriptor cd, String name, TypeDescriptor[] types) {
+       Set methoddescriptorset=cd.getMethodTable().getSet(name);
+        MethodDescriptor bestmd=null;
+        NextMethod:
+        for(Iterator methodit=methoddescriptorset.iterator();methodit.hasNext();) {
+            MethodDescriptor currmd=(MethodDescriptor)methodit.next();
+            /* Need correct number of parameters */
+            if (types.length!=currmd.numParameters())
+                continue;
+            for(int i=0;i<types.length;i++) {
+                if (!this.isSuperorType(currmd.getParamType(i),types[i]))
+                    continue NextMethod;
+            }
+            /* Method okay so far */
+            if (bestmd==null)
+                bestmd=currmd;
+            else {
+                if (isMoreSpecific(currmd,bestmd)) {
+                    bestmd=currmd;
+                } else if (!isMoreSpecific(bestmd, currmd))
+                    throw new Error("No method is most specific");
+                
+                /* Is this more specific than bestmd */
+            }
+        }
+       if (bestmd==null)
+           throw new Error("Could find: "+name + " in "+cd);
+
+       return bestmd;
+    }
+
     public void createFullTable() {
        subclasstable=new Hashtable();
     
@@ -184,10 +239,10 @@ public class TypeUtil {
            
            return false;
        } else if (possiblesuper.isPrimitive()&&(!possiblesuper.isArray())&&
-                  (cd2.isArray()||cd2.isPtr()))
+                  cd2.isPtr())
            return false;
        else if (cd2.isPrimitive()&&(!cd2.isArray())&&
-                (possiblesuper.isArray()||possiblesuper.isPtr()))
+                possiblesuper.isPtr())
            return false;
        else
            throw new Error("Case not handled:"+possiblesuper+" "+cd2);