1 17 package org.apache.bcel.generic; 18 19 import org.apache.bcel.Constants; 20 import org.apache.bcel.Repository; 21 import org.apache.bcel.classfile.JavaClass; 22 23 29 public abstract class ReferenceType extends Type { 30 31 protected ReferenceType(byte t, String s) { 32 super(t, s); 33 } 34 35 36 38 ReferenceType() { 39 super(Constants.T_OBJECT, "<null object>"); 40 } 41 42 43 54 public boolean isCastableTo( Type t ) throws ClassNotFoundException { 55 if (this.equals(Type.NULL)) { 56 return true; } 58 return isAssignmentCompatibleWith(t); 59 62 } 63 64 65 72 public boolean isAssignmentCompatibleWith( Type t ) throws ClassNotFoundException { 73 if (!(t instanceof ReferenceType)) { 74 return false; 75 } 76 ReferenceType T = (ReferenceType) t; 77 if (this.equals(Type.NULL)) { 78 return true; } 80 82 if ((this instanceof ObjectType) && (((ObjectType) this).referencesClassExact())) { 83 86 if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { 87 if (this.equals(T)) { 88 return true; 89 } 90 if (Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T) 91 .getClassName())) { 92 return true; 93 } 94 } 95 97 if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { 98 if (Repository.implementationOf(((ObjectType) this).getClassName(), 99 ((ObjectType) T).getClassName())) { 100 return true; 101 } 102 } 103 } 104 106 if ((this instanceof ObjectType) && (((ObjectType) this).referencesInterfaceExact())) { 107 109 if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { 110 if (T.equals(Type.OBJECT)) { 111 return true; 112 } 113 } 114 117 if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { 118 if (this.equals(T)) { 119 return true; 120 } 121 if (Repository.implementationOf(((ObjectType) this).getClassName(), 122 ((ObjectType) T).getClassName())) { 123 return true; 124 } 125 } 126 } 127 130 if (this instanceof ArrayType) { 131 133 if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { 134 if (T.equals(Type.OBJECT)) { 135 return true; 136 } 137 } 138 141 if (T instanceof ArrayType) { 142 144 Type sc = ((ArrayType) this).getElementType(); 145 Type tc = ((ArrayType) T).getElementType(); 146 if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) { 147 return true; 148 } 149 152 if (tc instanceof ReferenceType && sc instanceof ReferenceType 153 && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { 154 return true; 155 } 156 } 157 158 if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { 164 for (int ii = 0; ii < Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS.length; ii++) { 165 if (T.equals(new ObjectType(Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS[ii]))) { 166 return true; 167 } 168 } 169 } 170 } 171 return false; } 173 174 175 193 public ReferenceType getFirstCommonSuperclass( ReferenceType t ) throws ClassNotFoundException { 194 if (this.equals(Type.NULL)) { 195 return t; 196 } 197 if (t.equals(Type.NULL)) { 198 return this; 199 } 200 if (this.equals(t)) { 201 return this; 202 209 } 210 211 if ((this instanceof ArrayType) && (t instanceof ArrayType)) { 212 ArrayType arrType1 = (ArrayType) this; 213 ArrayType arrType2 = (ArrayType) t; 214 if ((arrType1.getDimensions() == arrType2.getDimensions()) 215 && arrType1.getBasicType() instanceof ObjectType 216 && arrType2.getBasicType() instanceof ObjectType) { 217 return new ArrayType(((ObjectType) arrType1.getBasicType()) 218 .getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()), arrType1 219 .getDimensions()); 220 } 221 } 222 if ((this instanceof ArrayType) || (t instanceof ArrayType)) { 223 return Type.OBJECT; 224 } 226 if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) 227 || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) { 228 return Type.OBJECT; 229 } 233 ObjectType thiz = (ObjectType) this; 235 ObjectType other = (ObjectType) t; 236 JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); 237 JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); 238 if ((thiz_sups == null) || (other_sups == null)) { 239 return null; 240 } 241 JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; 243 JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; 244 System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); 245 System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); 246 this_sups[0] = Repository.lookupClass(thiz.getClassName()); 247 t_sups[0] = Repository.lookupClass(other.getClassName()); 248 for (int i = 0; i < t_sups.length; i++) { 249 for (int j = 0; j < this_sups.length; j++) { 250 if (this_sups[j].equals(t_sups[i])) { 251 return new ObjectType(this_sups[j].getClassName()); 252 } 253 } 254 } 255 return null; 257 } 258 259 260 277 public ReferenceType firstCommonSuperclass( ReferenceType t ) throws ClassNotFoundException { 278 if (this.equals(Type.NULL)) { 279 return t; 280 } 281 if (t.equals(Type.NULL)) { 282 return this; 283 } 284 if (this.equals(t)) { 285 return this; 286 293 } 294 if ((this instanceof ArrayType) || (t instanceof ArrayType)) { 295 return Type.OBJECT; 296 } 298 if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) 299 || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) { 300 return Type.OBJECT; 301 } 305 ObjectType thiz = (ObjectType) this; 307 ObjectType other = (ObjectType) t; 308 JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); 309 JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); 310 if ((thiz_sups == null) || (other_sups == null)) { 311 return null; 312 } 313 JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; 315 JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; 316 System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); 317 System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); 318 this_sups[0] = Repository.lookupClass(thiz.getClassName()); 319 t_sups[0] = Repository.lookupClass(other.getClassName()); 320 for (int i = 0; i < t_sups.length; i++) { 321 for (int j = 0; j < this_sups.length; j++) { 322 if (this_sups[j].equals(t_sups[i])) { 323 return new ObjectType(this_sups[j].getClassName()); 324 } 325 } 326 } 327 return null; 329 } 330 } 331 | Popular Tags |