1 17 package org.apache.bcel.generic; 18 19 import java.util.ArrayList ; 20 import java.util.List ; 21 import org.apache.bcel.Constants; 22 import org.apache.bcel.classfile.ClassFormatException; 23 import org.apache.bcel.classfile.Utility; 24 25 32 public abstract class Type implements java.io.Serializable { 33 34 protected byte type; 35 protected String signature; 38 public static final BasicType VOID = new BasicType(Constants.T_VOID); 39 public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN); 40 public static final BasicType INT = new BasicType(Constants.T_INT); 41 public static final BasicType SHORT = new BasicType(Constants.T_SHORT); 42 public static final BasicType BYTE = new BasicType(Constants.T_BYTE); 43 public static final BasicType LONG = new BasicType(Constants.T_LONG); 44 public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE); 45 public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT); 46 public static final BasicType CHAR = new BasicType(Constants.T_CHAR); 47 public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); 48 public static final ObjectType CLASS = new ObjectType("java.lang.Class"); 49 public static final ObjectType STRING = new ObjectType("java.lang.String"); 50 public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); 51 public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); 52 public static final Type[] NO_ARGS = new Type[0]; 53 public static final ReferenceType NULL = new ReferenceType() { 54 }; 55 public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, "<unknown object>") { 56 }; 57 58 59 protected Type(byte t, String s) { 60 type = t; 61 signature = s; 62 } 63 64 65 68 public int hashCode() { 69 return type ^ signature.hashCode(); 70 } 71 72 73 76 public boolean equals(Object o) { 77 if (o instanceof Type) { 78 Type t = (Type)o; 79 return (type == t.type) && signature.equals(t.signature); 80 } 81 return false; 82 } 83 84 85 88 public String getSignature() { 89 return signature; 90 } 91 92 93 96 public byte getType() { 97 return type; 98 } 99 100 101 104 public int getSize() { 105 switch (type) { 106 case Constants.T_DOUBLE: 107 case Constants.T_LONG: 108 return 2; 109 case Constants.T_VOID: 110 return 0; 111 default: 112 return 1; 113 } 114 } 115 116 117 120 public String toString() { 121 return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN))) ? signature : Utility 122 .signatureToString(signature, false); 123 } 124 125 126 134 public static String getMethodSignature( Type return_type, Type[] arg_types ) { 135 StringBuffer buf = new StringBuffer ("("); 136 int length = (arg_types == null) ? 0 : arg_types.length; 137 for (int i = 0; i < length; i++) { 138 buf.append(arg_types[i].getSignature()); 139 } 140 buf.append(')'); 141 buf.append(return_type.getSignature()); 142 return buf.toString(); 143 } 144 145 private static ThreadLocal consumed_chars = new ThreadLocal () { 146 147 protected Object initialValue() { 148 return new Integer (0); 149 } 150 }; 152 153 private static int unwrap( ThreadLocal tl ) { 154 return ((Integer ) tl.get()).intValue(); 155 } 156 157 158 private static void wrap( ThreadLocal tl, int value ) { 159 tl.set(new Integer (value)); 160 } 161 162 163 168 public static final Type getType( String signature ) throws StringIndexOutOfBoundsException { 169 byte type = Utility.typeOfSignature(signature); 170 if (type <= Constants.T_VOID) { 171 wrap(consumed_chars, 1); 173 return BasicType.getType(type); 174 } else if (type == Constants.T_ARRAY) { 175 int dim = 0; 176 do { dim++; 178 } while (signature.charAt(dim) == '['); 179 Type t = getType(signature.substring(dim)); 181 int _temp = unwrap(consumed_chars) + dim; 184 wrap(consumed_chars, _temp); 185 return new ArrayType(t, dim); 186 } else { int index = signature.indexOf(';'); if (index < 0) { 189 throw new ClassFormatException("Invalid signature: " + signature); 190 } 191 wrap(consumed_chars, index + 1); return new ObjectType(signature.substring(1, index).replace('/', '.')); 194 } 195 } 196 197 198 204 public static Type getReturnType( String signature ) { 205 try { 206 int index = signature.lastIndexOf(')') + 1; 208 return getType(signature.substring(index)); 209 } catch (StringIndexOutOfBoundsException e) { throw new ClassFormatException("Invalid method signature: " + signature); 211 } 212 } 213 214 215 220 public static Type[] getArgumentTypes( String signature ) { 221 List vec = new ArrayList (); 222 int index; 223 Type[] types; 224 try { if (signature.charAt(0) != '(') { 226 throw new ClassFormatException("Invalid method signature: " + signature); 227 } 228 index = 1; while (signature.charAt(index) != ')') { 230 vec.add(getType(signature.substring(index))); 231 index += unwrap(consumed_chars); } 234 } catch (StringIndexOutOfBoundsException e) { throw new ClassFormatException("Invalid method signature: " + signature); 236 } 237 types = new Type[vec.size()]; 238 vec.toArray(types); 239 return types; 240 } 241 242 243 247 public static Type getType( java.lang.Class cl ) { 248 if (cl == null) { 249 throw new IllegalArgumentException ("Class must not be null"); 250 } 251 254 if (cl.isArray()) { 255 return getType(cl.getName()); 256 } else if (cl.isPrimitive()) { 257 if (cl == Integer.TYPE) { 258 return INT; 259 } else if (cl == Void.TYPE) { 260 return VOID; 261 } else if (cl == Double.TYPE) { 262 return DOUBLE; 263 } else if (cl == Float.TYPE) { 264 return FLOAT; 265 } else if (cl == Boolean.TYPE) { 266 return BOOLEAN; 267 } else if (cl == Byte.TYPE) { 268 return BYTE; 269 } else if (cl == Short.TYPE) { 270 return SHORT; 271 } else if (cl == Byte.TYPE) { 272 return BYTE; 273 } else if (cl == Long.TYPE) { 274 return LONG; 275 } else if (cl == Character.TYPE) { 276 return CHAR; 277 } else { 278 throw new IllegalStateException ("Ooops, what primitive type is " + cl); 279 } 280 } else { return new ObjectType(cl.getName()); 282 } 283 } 284 285 286 291 public static Type[] getTypes( java.lang.Class [] classes ) { 292 Type[] ret = new Type[classes.length]; 293 for (int i = 0; i < ret.length; i++) { 294 ret[i] = getType(classes[i]); 295 } 296 return ret; 297 } 298 299 300 public static String getSignature( java.lang.reflect.Method meth ) { 301 StringBuffer sb = new StringBuffer ("("); 302 Class [] params = meth.getParameterTypes(); for (int j = 0; j < params.length; j++) { 304 sb.append(getType(params[j]).getSignature()); 305 } 306 sb.append(")"); 307 sb.append(getType(meth.getReturnType()).getSignature()); 308 return sb.toString(); 309 } 310 } 311 | Popular Tags |