| 1 19 20 package jode.bytecode; 21 import jode.AssertError; 22 23 26 public class TypeSignature { 27 31 private static final StringBuffer appendSignature(StringBuffer sb, 32 Class javaType) { 33 if (javaType.isPrimitive()) { 34 if (javaType == Boolean.TYPE) 35 return sb.append('Z'); 36 else if (javaType == Byte.TYPE) 37 return sb.append('B'); 38 else if (javaType == Character.TYPE) 39 return sb.append('C'); 40 else if (javaType == Short.TYPE) 41 return sb.append('S'); 42 else if (javaType == Integer.TYPE) 43 return sb.append('I'); 44 else if (javaType == Long.TYPE) 45 return sb.append('J'); 46 else if (javaType == Float.TYPE) 47 return sb.append('F'); 48 else if (javaType == Double.TYPE) 49 return sb.append('D'); 50 else if (javaType == Void.TYPE) 51 return sb.append('V'); 52 else 53 throw new AssertError("Unknown primitive type: "+javaType); 54 } else if (javaType.isArray()) { 55 return appendSignature(sb.append('['), 56 javaType.getComponentType()); 57 } else { 58 return sb.append('L') 59 .append(javaType.getName().replace('.','/')).append(';'); 60 } 61 } 62 63 70 public static String getSignature(Class clazz) { 71 return appendSignature(new StringBuffer (), clazz).toString(); 72 } 73 74 81 public static String getSignature(Class paramT[], Class returnT) { 82 StringBuffer sig = new StringBuffer ("("); 83 for (int i=0; i< paramT.length; i++) 84 appendSignature(sig, paramT[i]); 85 return appendSignature(sig.append(')'), returnT).toString(); 86 } 87 88 94 public static Class getClass(String typeSig) 95 throws ClassNotFoundException 96 { 97 switch(typeSig.charAt(0)) { 98 case 'Z': 99 return Boolean.TYPE; 100 case 'B': 101 return Byte.TYPE; 102 case 'C': 103 return Character.TYPE; 104 case 'S': 105 return Short.TYPE; 106 case 'I': 107 return Integer.TYPE; 108 case 'F': 109 return Float.TYPE; 110 case 'J': 111 return Long.TYPE; 112 case 'D': 113 return Double.TYPE; 114 case 'V': 115 return Void.TYPE; 116 case 'L': 117 typeSig = typeSig.substring(1, typeSig.length()-1) 118 .replace('/','.'); 119 120 case '[': 121 return Class.forName(typeSig); 122 } 123 throw new IllegalArgumentException (typeSig); 124 } 125 126 128 private static boolean usingTwoSlots(char type) { 129 return "JD".indexOf(type) >= 0; 130 } 131 132 136 public static int getTypeSize(String typeSig) { 137 return usingTwoSlots(typeSig.charAt(0)) ? 2 : 1; 138 } 139 140 public static String getElementType(String typeSig) { 141 if (typeSig.charAt(0) != '[') 142 throw new IllegalArgumentException (); 143 return typeSig.substring(1); 144 } 145 146 public static ClassInfo getClassInfo(String typeSig) { 147 if (typeSig.charAt(0) != 'L') 148 throw new IllegalArgumentException (); 149 return ClassInfo.forName 150 (typeSig.substring(1, typeSig.length()-1).replace('/', '.')); 151 } 152 153 public static int skipType(String methodTypeSig, int position) { 154 char c = methodTypeSig.charAt(position++); 155 while (c == '[') 156 c = methodTypeSig.charAt(position++); 157 if (c == 'L') 158 return methodTypeSig.indexOf(';', position) + 1; 159 return position; 160 } 161 162 166 public static int getArgumentSize(String methodTypeSig) { 167 int nargs = 0; 168 int i = 1; 169 for (;;) { 170 char c = methodTypeSig.charAt(i); 171 if (c == ')') 172 return nargs; 173 i = skipType(methodTypeSig, i); 174 if (usingTwoSlots(c)) 175 nargs += 2; 176 else 177 nargs++; 178 } 179 } 180 181 185 public static int getReturnSize(String methodTypeSig) { 186 int length = methodTypeSig.length(); 187 if (methodTypeSig.charAt(length - 2) == ')') { 188 char returnType = methodTypeSig.charAt(length - 1); 190 return returnType == 'V' ? 0 191 : usingTwoSlots(returnType) ? 2 : 1; 192 } else 193 return 1; 195 } 196 197 201 public static String [] getParameterTypes(String methodTypeSig) { 202 int pos = 1; 203 int count = 0; 204 while (methodTypeSig.charAt(pos) != ')') { 205 pos = skipType(methodTypeSig, pos); 206 count++; 207 } 208 String [] params = new String [count]; 209 pos = 1; 210 for (int i = 0; i < count; i++) { 211 int start = pos; 212 pos = skipType(methodTypeSig, pos); 213 params[i] = methodTypeSig.substring(start, pos); 214 } 215 return params; 216 } 217 218 222 public static String getReturnType(String methodTypeSig) { 223 return methodTypeSig.substring(methodTypeSig.lastIndexOf(')')+1); 224 } 225 226 233 private static int checkClassName(String clName, int i) 234 throws IllegalArgumentException , StringIndexOutOfBoundsException 235 { 236 while (true) { 237 char c = clName.charAt(i++); 238 if (c == ';') 239 return i; 240 if (c != '/' && !Character.isJavaIdentifierPart(c)) 241 throw new IllegalArgumentException ("Illegal java class name: " 242 + clName); 243 } 244 } 245 246 253 private static int checkTypeSig(String typesig, int index) { 254 char c = typesig.charAt(index++); 255 while (c == '[') 256 c = typesig.charAt(index++); 257 if (c == 'L') { 258 index = checkClassName(typesig, index); 259 } else { 260 if ("ZBSCIJFD".indexOf(c) == -1) 261 throw new IllegalArgumentException ("Type sig error: "+typesig); 262 } 263 return index; 264 } 265 266 public static void checkTypeSig(String typesig) 267 throws IllegalArgumentException  268 { 269 try { 270 if (checkTypeSig(typesig, 0) != typesig.length()) 271 throw new IllegalArgumentException  272 ("Type sig too long: "+typesig); 273 } catch (StringIndexOutOfBoundsException ex) { 274 throw new IllegalArgumentException  275 ("Incomplete type sig: "+typesig); 276 } 277 } 278 279 public static void checkMethodTypeSig(String typesig) 280 throws IllegalArgumentException  281 { 282 try { 283 if (typesig.charAt(0) != '(') 284 throw new IllegalArgumentException  285 ("No method signature: "+typesig); 286 int i = 1; 287 while (typesig.charAt(i) != ')') 288 i = checkTypeSig(typesig, i); 289 i++; 291 if (typesig.charAt(i) == 'V') 292 i++; 294 else 295 i = checkTypeSig(typesig, i); 296 if (i != typesig.length()) 297 throw new IllegalArgumentException  298 ("Type sig too long: "+typesig); 299 } catch (StringIndexOutOfBoundsException ex) { 300 throw new IllegalArgumentException  301 ("Incomplete type sig: "+typesig); 302 } 303 } 304 } 305 306 | Popular Tags |