package IR;
import java.util.*;
+import IR.Tree.*;
+import java.io.File;
+import Main.Main;
public class TypeUtil {
public static final String StringClass="String";
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() {
}
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();
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;
}
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;
&&(possiblesuper.getArrayCount()<cd2.getArrayCount()))
return true;
+ //Allow arraytype=null statements
+ if (possiblesuper.isArray()&&cd2.isNull())
+ return true;
+
return false;
}
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)
}
private boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
+
while(cd2!=null) {
cd2=getSuper(cd2);
if (cd2==possiblesuper)