1 19 20 package jode.type; 21 import jode.bytecode.ClassInfo; 22 import java.util.Vector ; 23 24 29 public class ArrayType extends ReferenceType { 30 final static ClassInfo[] arrayIfaces = { 32 ClassInfo.forName("java.lang.Cloneable"), 35 ClassInfo.forName("java.io.Serializable") 36 }; 37 38 Type elementType; 39 40 ArrayType(Type elementType) { 41 super(TC_ARRAY); 42 this.elementType = elementType; 43 } 44 45 public Type getElementType() { 46 return elementType; 47 } 48 49 public Type getSuperType() { 50 if (elementType instanceof IntegerType) 51 return tRange(tObject, this); 52 else 53 return tRange(tObject, 54 (ReferenceType) tArray(elementType.getSuperType())); 55 } 56 57 public Type getSubType() { 58 if (elementType instanceof IntegerType) 59 return this; 60 else 61 return tArray(elementType.getSubType()); 62 } 63 64 public Type getHint() { 65 return tArray(elementType.getHint()); 66 } 67 68 public Type getCanonic() { 69 return tArray(elementType.getCanonic()); 70 } 71 72 77 public Type createRangeType(ReferenceType bottom) { 78 83 if (bottom.getTypeCode() == TC_ARRAY) 84 return tArray(elementType.intersection 85 (((ArrayType)bottom).elementType)); 86 87 if (bottom.getTypeCode() == TC_CLASS) { 88 ClassInterfacesType bottomCIT = (ClassInterfacesType)bottom; 89 if (bottomCIT.clazz == null 90 && implementsAllIfaces(null, arrayIfaces, bottomCIT.ifaces)) 91 return tRange(bottomCIT, this); 92 } 93 return tError; 94 } 95 96 101 public Type getSpecializedType(Type type) { 102 107 if (type.getTypeCode() == TC_RANGE) { 108 type = ((RangeType) type).getBottom(); 109 } 110 if (type == tNull) 111 return this; 112 if (type.getTypeCode() == TC_ARRAY) { 113 Type elType = elementType.intersection 114 (((ArrayType)type).elementType); 115 return elType != tError ? tArray(elType) : tError; 116 } 117 if (type.getTypeCode() == TC_CLASS) { 118 ClassInterfacesType other = (ClassInterfacesType) type; 119 if (other.clazz == null 120 && implementsAllIfaces(null, arrayIfaces, other.ifaces)) 121 return this; 122 } 123 return tError; 124 } 125 126 131 public Type getGeneralizedType(Type type) { 132 137 if (type.getTypeCode() == TC_RANGE) { 138 type = ((RangeType) type).getTop(); 139 } 140 if (type == tNull) 141 return this; 142 if (type.getTypeCode() == TC_ARRAY) { 143 Type elType = elementType.intersection 144 (((ArrayType)type).elementType); 145 if (elType != tError) 146 return tArray(elType); 147 return ClassInterfacesType.create(null, arrayIfaces); 148 } 149 if (type.getTypeCode() == TC_CLASS) { 150 ClassInterfacesType other = (ClassInterfacesType) type; 151 if (implementsAllIfaces(other.clazz, other.ifaces, arrayIfaces)) 152 return ClassInterfacesType.create(null, arrayIfaces); 153 if (other.clazz == null 154 && implementsAllIfaces(null, arrayIfaces, other.ifaces)) 155 return other; 156 157 162 Vector newIfaces = new Vector (); 163 iface_loop: 164 for (int i=0; i < arrayIfaces.length; i++) { 165 168 if (other.clazz != null 169 && arrayIfaces[i].implementedBy(other.clazz)) { 170 newIfaces.addElement(arrayIfaces[i]); 171 continue iface_loop; 172 } 173 for (int j=0; j<other.ifaces.length; j++) { 174 if (arrayIfaces[i].implementedBy(other.ifaces[j])) { 175 newIfaces.addElement(arrayIfaces[i]); 176 continue iface_loop; 177 } 178 } 179 } 180 ClassInfo[] ifaceArray = new ClassInfo[newIfaces.size()]; 181 newIfaces.copyInto(ifaceArray); 182 return ClassInterfacesType.create(null, ifaceArray); 183 } 184 return tError; 185 } 186 187 192 public Type getCastHelper(Type fromType) { 193 Type hintType = fromType.getHint(); 194 switch (hintType.getTypeCode()) { 195 case TC_ARRAY: 196 if (!elementType.isClassType() 197 || !((ArrayType)hintType).elementType.isClassType()) 198 return tObject; 199 Type middleType = elementType.getCastHelper 200 (((ArrayType)hintType).elementType); 201 if (middleType != null) 202 return tArray(middleType); 203 return null; 204 case TC_CLASS: 205 ClassInterfacesType hint = (ClassInterfacesType) hintType; 206 if (hint.clazz == null 207 && implementsAllIfaces(null, arrayIfaces, hint.ifaces)) 208 return null; 209 return tObject; 210 case TC_UNKNOWN: 211 return null; 212 } 213 return tObject; 214 } 215 216 220 public boolean isValidType() { 221 return elementType.isValidType(); 222 } 223 224 public boolean isClassType() { 225 return true; 226 } 227 228 public String getTypeSignature() { 229 return "["+elementType.getTypeSignature(); 230 } 231 232 public Class getTypeClass() throws ClassNotFoundException { 233 return Class.forName("["+elementType.getTypeSignature()); 234 } 235 236 public String toString() { 237 return elementType.toString()+"[]"; 238 } 239 240 private static String pluralize(String singular) { 241 return singular + 242 ((singular.endsWith("s") || singular.endsWith("x") 243 || singular.endsWith("sh") || singular.endsWith("ch")) 244 ? "es" : "s"); 245 } 246 247 public String getDefaultName() { 248 if (elementType instanceof ArrayType) 249 return elementType.getDefaultName(); 250 return pluralize(elementType.getDefaultName()); 251 } 252 253 public boolean equals(Object o) { 254 if (o == this) 255 return true; 256 if (o instanceof ArrayType) { 257 ArrayType type = (ArrayType) o; 258 return type.elementType.equals(elementType); 259 } 260 return false; 261 } 262 } 263 | Popular Tags |