4 public class TypeUtil {
5 public static final String StringClass="String";
6 public static final String ObjectClass="Object";
7 public static final String StartupClass="StartupObject";
10 Hashtable subclasstable;
12 public TypeUtil(State state) {
17 public ClassDescriptor getClass(String classname) {
18 ClassDescriptor cd=(ClassDescriptor)state.getClassSymbolTable().get(classname);
22 private void createTables() {
23 supertable=new Hashtable();
25 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
26 while(classit.hasNext()) {
27 ClassDescriptor cd=(ClassDescriptor)classit.next();
28 String superc=cd.getSuper();
30 ClassDescriptor cd_super=getClass(superc);
31 supertable.put(cd,cd_super);
36 public void createFullTable() {
37 subclasstable=new Hashtable();
39 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
40 while(classit.hasNext()) {
41 ClassDescriptor cd=(ClassDescriptor)classit.next();
42 ClassDescriptor tmp=cd.getSuperDesc();
45 if (!subclasstable.containsKey(tmp))
46 subclasstable.put(tmp,new HashSet());
47 HashSet hs=(HashSet)subclasstable.get(tmp);
49 tmp=tmp.getSuperDesc();
54 public Set getSubClasses(ClassDescriptor cd) {
55 return (Set)subclasstable.get(cd);
58 public ClassDescriptor getSuper(ClassDescriptor cd) {
59 return (ClassDescriptor)supertable.get(cd);
62 public boolean isCastable(TypeDescriptor original, TypeDescriptor casttype) {
63 if (original.isChar()&&
68 if (casttype.isChar()&&
80 public boolean isSuperorType(TypeDescriptor possiblesuper, TypeDescriptor cd2) {
81 //Matching type are always okay
82 if (possiblesuper.equals(cd2))
86 if (cd2.isArray()||possiblesuper.isArray()) {
87 // Object is super class of all arrays
88 if (possiblesuper.getSymbol().equals(ObjectClass)&&!possiblesuper.isArray())
91 // If we have the same dimensionality of arrays & both are classes, we can default to the normal test
92 if (cd2.isClass()&&possiblesuper.isClass()
93 &&(possiblesuper.getArrayCount()==cd2.getArrayCount())&&
94 isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc()))
97 // Object is superclass of all array classes
98 if (possiblesuper.getSymbol().equals(ObjectClass)&&cd2.isClass()
99 &&(possiblesuper.getArrayCount()<cd2.getArrayCount()))
105 if (possiblesuper.isClass()&&
107 return isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc());
108 else if (possiblesuper.isClass()&&
111 else if (possiblesuper.isNull())
112 throw new Error(); //not sure when this case would occur
113 else if (possiblesuper.isPrimitive()&&
115 ///Primitive widenings from 5.1.2
116 if (cd2.isByte()&&(possiblesuper.isByte()||possiblesuper.isShort()||
117 possiblesuper.isInt()||possiblesuper.isLong()||
118 possiblesuper.isFloat()||possiblesuper.isDouble()))
120 if (cd2.isShort()&&(possiblesuper.isShort()||
121 possiblesuper.isInt()||possiblesuper.isLong()||
122 possiblesuper.isFloat()||possiblesuper.isDouble()))
124 if (cd2.isChar()&&(possiblesuper.isChar()||
125 possiblesuper.isInt()||possiblesuper.isLong()||
126 possiblesuper.isFloat()||possiblesuper.isDouble()))
128 if (cd2.isInt()&&(possiblesuper.isInt()||possiblesuper.isLong()||
129 possiblesuper.isFloat()||possiblesuper.isDouble()))
131 if (cd2.isLong()&&(possiblesuper.isLong()||
132 possiblesuper.isFloat()||possiblesuper.isDouble()))
134 if (cd2.isFloat()&&(possiblesuper.isFloat()||possiblesuper.isDouble()))
136 if (cd2.isDouble()&&possiblesuper.isDouble())
139 if (cd2.isBoolean()&&possiblesuper.isBoolean())
143 } else if (possiblesuper.isPrimitive()&&(!possiblesuper.isArray())&&
144 (cd2.isArray()||cd2.isPtr()))
146 else if (cd2.isPrimitive()&&(!cd2.isArray())&&
147 (possiblesuper.isArray()||possiblesuper.isPtr()))
154 private boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
155 if (possiblesuper==cd2)
158 return isSuper(possiblesuper, cd2);
161 private boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
164 if (cd2==possiblesuper)