4 public class TypeUtil {
5 public static final String StringClass="String";
6 public static final String ObjectClass="Object";
9 Hashtable subclasstable;
11 public TypeUtil(State state) {
16 public ClassDescriptor getClass(String classname) {
17 ClassDescriptor cd=(ClassDescriptor)state.getClassSymbolTable().get(classname);
21 private void createTables() {
22 supertable=new Hashtable();
24 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
25 while(classit.hasNext()) {
26 ClassDescriptor cd=(ClassDescriptor)classit.next();
27 String superc=cd.getSuper();
29 ClassDescriptor cd_super=getClass(superc);
30 supertable.put(cd,cd_super);
35 public void createFullTable() {
36 subclasstable=new Hashtable();
38 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
39 while(classit.hasNext()) {
40 ClassDescriptor cd=(ClassDescriptor)classit.next();
41 ClassDescriptor tmp=cd.getSuperDesc();
44 if (!subclasstable.containsKey(tmp))
45 subclasstable.put(tmp,new HashSet());
46 HashSet hs=(HashSet)subclasstable.get(tmp);
48 tmp=tmp.getSuperDesc();
53 public Set getSubClasses(ClassDescriptor cd) {
54 return (Set)subclasstable.get(cd);
57 public ClassDescriptor getSuper(ClassDescriptor cd) {
58 return (ClassDescriptor)supertable.get(cd);
61 public boolean isSuperorType(TypeDescriptor possiblesuper, TypeDescriptor cd2) {
62 //Matching type are always okay
63 if (possiblesuper.equals(cd2))
67 if (cd2.isArray()||possiblesuper.isArray()) {
68 // Object is super class of all arrays
69 if (possiblesuper.getSymbol().equals(ObjectClass)&&!possiblesuper.isArray())
72 // If we have the same dimensionality of arrays & both are classes, we can default to the normal test
73 if (cd2.isClass()&&possiblesuper.isClass()
74 &&(possiblesuper.getArrayCount()==cd2.getArrayCount())&&
75 isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc()))
78 // Object is superclass of all array classes
79 if (possiblesuper.getSymbol().equals(ObjectClass)&&cd2.isClass()
80 &&(possiblesuper.getArrayCount()<cd2.getArrayCount()))
86 if (possiblesuper.isClass()&&
88 return isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc());
89 else if (possiblesuper.isClass()&&
92 else if (possiblesuper.isNull())
93 throw new Error(); //not sure when this case would occur
94 else if (possiblesuper.isPrimitive()&&
96 ///Primitive widenings from 5.1.2
97 if (cd2.isByte()&&(possiblesuper.isByte()||possiblesuper.isShort()||
98 possiblesuper.isInt()||possiblesuper.isLong()||
99 possiblesuper.isFloat()||possiblesuper.isDouble()))
101 if (cd2.isShort()&&(possiblesuper.isShort()||
102 possiblesuper.isInt()||possiblesuper.isLong()||
103 possiblesuper.isFloat()||possiblesuper.isDouble()))
105 if (cd2.isChar()&&(possiblesuper.isChar()||
106 possiblesuper.isInt()||possiblesuper.isLong()||
107 possiblesuper.isFloat()||possiblesuper.isDouble()))
109 if (cd2.isInt()&&(possiblesuper.isInt()||possiblesuper.isLong()||
110 possiblesuper.isFloat()||possiblesuper.isDouble()))
112 if (cd2.isLong()&&(possiblesuper.isLong()||
113 possiblesuper.isFloat()||possiblesuper.isDouble()))
115 if (cd2.isFloat()&&(possiblesuper.isFloat()||possiblesuper.isDouble()))
117 if (cd2.isDouble()&&possiblesuper.isDouble())
120 if (cd2.isBoolean()&&possiblesuper.isBoolean())
124 } else if (possiblesuper.isPrimitive()&&(!possiblesuper.isArray())&&
125 (cd2.isArray()||cd2.isPtr()))
127 else if (cd2.isPrimitive()&&(!cd2.isArray())&&
128 (possiblesuper.isArray()||possiblesuper.isPtr()))
135 private boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
136 if (possiblesuper==cd2)
139 return isSuper(possiblesuper, cd2);
142 private boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
145 if (cd2==possiblesuper)