1 15 16 package javassist.bytecode; 17 18 import javassist.ClassPool; 19 import javassist.CtClass; 20 import javassist.CtPrimitiveType; 21 import javassist.NotFoundException; 22 import java.util.Map ; 23 24 29 public class Descriptor { 30 37 public static String toJvmName(String classname) { 38 return classname.replace('.', '/'); 39 } 40 41 45 public static String toJavaName(String classname) { 46 return classname.replace('/', '.'); 47 } 48 49 53 public static String toJvmName(CtClass clazz) { 54 if (clazz.isArray()) 55 return of(clazz); 56 else 57 return toJvmName(clazz.getName()); 58 } 59 60 63 public static String toClassName(String descriptor) { 64 if (descriptor.equals("V")) 65 return "void"; 66 else if (descriptor.equals("I")) 67 return "int"; 68 else if (descriptor.equals("B")) 69 return "byte"; 70 else if (descriptor.equals("J")) 71 return "long"; 72 else if (descriptor.equals("D")) 73 return "double"; 74 else if (descriptor.equals("F")) 75 return "float"; 76 else if (descriptor.equals("C")) 77 return "char"; 78 else if (descriptor.equals("S")) 79 return "short"; 80 else if (descriptor.equals("Z")) 81 return "boolean"; 82 else { 83 String newname = toJavaName(descriptor); 84 return newname.substring(1, newname.length() - 1); 85 } 86 } 87 88 91 public static String of(String classname) { 92 if (classname.equals("void")) 93 return "V"; 94 else if (classname.equals("int")) 95 return "I"; 96 else if (classname.equals("byte")) 97 return "B"; 98 else if (classname.equals("long")) 99 return "J"; 100 else if (classname.equals("double")) 101 return "D"; 102 else if (classname.equals("float")) 103 return "F"; 104 else if (classname.equals("char")) 105 return "C"; 106 else if (classname.equals("short")) 107 return "S"; 108 else if (classname.equals("boolean")) 109 return "Z"; 110 else 111 return "L" + toJvmName(classname) + ";"; 112 } 113 114 124 public static String rename(String desc, String oldname, String newname) { 125 if (desc.indexOf(oldname) < 0) 126 return desc; 127 128 StringBuffer newdesc = new StringBuffer (); 129 int head = 0; 130 int i = 0; 131 for (;;) { 132 int j = desc.indexOf('L', i); 133 if (j < 0) 134 break; 135 else if (desc.startsWith(oldname, j + 1) 136 && desc.charAt(j + oldname.length() + 1) == ';') { 137 newdesc.append(desc.substring(head, j)); 138 newdesc.append('L'); 139 newdesc.append(newname); 140 newdesc.append(';'); 141 head = i = j + oldname.length() + 2; 142 } 143 else { 144 i = desc.indexOf(';', j) + 1; 145 if (i < 1) 146 break; } 148 } 149 150 if (head == 0) 151 return desc; 152 else { 153 int len = desc.length(); 154 if (head < len) 155 newdesc.append(desc.substring(head, len)); 156 157 return newdesc.toString(); 158 } 159 } 160 161 169 public static String rename(String desc, Map map) { 170 if (map == null) 171 return desc; 172 173 StringBuffer newdesc = new StringBuffer (); 174 int head = 0; 175 int i = 0; 176 for (;;) { 177 int j = desc.indexOf('L', i); 178 if (j < 0) 179 break; 180 181 int k = desc.indexOf(';', j); 182 if (k < 0) 183 break; 184 185 i = k + 1; 186 String name = desc.substring(j + 1, k); 187 String name2 = (String )map.get(name); 188 if (name2 != null) { 189 newdesc.append(desc.substring(head, j)); 190 newdesc.append('L'); 191 newdesc.append(name2); 192 newdesc.append(';'); 193 head = i; 194 } 195 } 196 197 if (head == 0) 198 return desc; 199 else { 200 int len = desc.length(); 201 if (head < len) 202 newdesc.append(desc.substring(head, len)); 203 204 return newdesc.toString(); 205 } 206 } 207 208 211 public static String of(CtClass type) { 212 StringBuffer sbuf = new StringBuffer (); 213 toDescriptor(sbuf, type); 214 return sbuf.toString(); 215 } 216 217 private static void toDescriptor(StringBuffer desc, CtClass type) { 218 if (type.isArray()) { 219 desc.append('['); 220 try { 221 toDescriptor(desc, type.getComponentType()); 222 } 223 catch (NotFoundException e) { 224 desc.append('L'); 225 String name = type.getName(); 226 desc.append(toJvmName(name.substring(0, name.length() - 2))); 227 desc.append(';'); 228 } 229 } 230 else if (type.isPrimitive()) { 231 CtPrimitiveType pt = (CtPrimitiveType)type; 232 desc.append(pt.getDescriptor()); 233 } 234 else { desc.append('L'); 236 desc.append(type.getName().replace('.', '/')); 237 desc.append(';'); 238 } 239 } 240 241 247 public static String ofConstructor(CtClass[] paramTypes) { 248 return ofMethod(CtClass.voidType, paramTypes); 249 } 250 251 258 public static String ofMethod(CtClass returnType, CtClass[] paramTypes) { 259 StringBuffer desc = new StringBuffer (); 260 desc.append('('); 261 if (paramTypes != null) { 262 int n = paramTypes.length; 263 for (int i = 0; i < n; ++i) 264 toDescriptor(desc, paramTypes[i]); 265 } 266 267 desc.append(')'); 268 if (returnType != null) 269 toDescriptor(desc, returnType); 270 271 return desc.toString(); 272 } 273 274 281 public static String ofParameters(CtClass[] paramTypes) { 282 return ofMethod(null, paramTypes); 283 } 284 285 294 public static String appendParameter(String classname, String desc) { 295 int i = desc.indexOf(')'); 296 if (i < 0) 297 return desc; 298 else { 299 StringBuffer newdesc = new StringBuffer (); 300 newdesc.append(desc.substring(0, i)); 301 newdesc.append('L'); 302 newdesc.append(classname.replace('.', '/')); 303 newdesc.append(';'); 304 newdesc.append(desc.substring(i)); 305 return newdesc.toString(); 306 } 307 } 308 309 319 public static String insertParameter(String classname, String desc) { 320 if (desc.charAt(0) != '(') 321 return desc; 322 else 323 return "(L" + classname.replace('.', '/') + ';' 324 + desc.substring(1); 325 } 326 327 335 public static String changeReturnType(String classname, String desc) { 336 int i = desc.indexOf(')'); 337 if (i < 0) 338 return desc; 339 else { 340 StringBuffer newdesc = new StringBuffer (); 341 newdesc.append(desc.substring(0, i + 1)); 342 newdesc.append('L'); 343 newdesc.append(classname.replace('.', '/')); 344 newdesc.append(';'); 345 return newdesc.toString(); 346 } 347 } 348 349 357 public static CtClass[] getParameterTypes(String desc, ClassPool cp) 358 throws NotFoundException 359 { 360 if (desc.charAt(0) != '(') 361 return null; 362 else { 363 int num = numOfParameters(desc); 364 CtClass[] args = new CtClass[num]; 365 int n = 0; 366 int i = 1; 367 do { 368 i = toCtClass(cp, desc, i, args, n++); 369 } while (i > 0); 370 return args; 371 } 372 } 373 374 379 public static boolean eqParamTypes(String desc1, String desc2) { 380 if (desc1.charAt(0) != '(') 381 return false; 382 383 for (int i = 0; true; ++i) { 384 char c = desc1.charAt(i); 385 if (c != desc2.charAt(i)) 386 return false; 387 388 if (c == ')') 389 return true; 390 } 391 } 392 393 398 public static String getParamDescriptor(String decl) { 399 return decl.substring(0, decl.indexOf(')') + 1); 400 } 401 402 410 public static CtClass getReturnType(String desc, ClassPool cp) 411 throws NotFoundException 412 { 413 int i = desc.indexOf(')'); 414 if (i < 0) 415 return null; 416 else { 417 CtClass[] type = new CtClass[1]; 418 toCtClass(cp, desc, i + 1, type, 0); 419 return type[0]; 420 } 421 } 422 423 429 public static int numOfParameters(String desc) { 430 int n = 0; 431 int i = 1; 432 for (;;) { 433 char c = desc.charAt(i); 434 if (c == ')') 435 break; 436 437 while (c == '[') 438 c = desc.charAt(++i); 439 440 if (c == 'L') { 441 i = desc.indexOf(';', i) + 1; 442 if (i <= 0) 443 throw new IndexOutOfBoundsException ("bad descriptor"); 444 } 445 else 446 ++i; 447 448 ++n; 449 } 450 451 return n; 452 } 453 454 467 public static CtClass toCtClass(String desc, ClassPool cp) 468 throws NotFoundException 469 { 470 CtClass[] clazz = new CtClass[1]; 471 int res = toCtClass(cp, desc, 0, clazz, 0); 472 if (res >= 0) 473 return clazz[0]; 474 else { 475 return cp.get(desc.replace('/', '.')); 478 } 479 } 480 481 private static int toCtClass(ClassPool cp, String desc, int i, 482 CtClass[] args, int n) 483 throws NotFoundException 484 { 485 int i2; 486 String name; 487 488 int arrayDim = 0; 489 char c = desc.charAt(i); 490 while (c == '[') { 491 ++arrayDim; 492 c = desc.charAt(++i); 493 } 494 495 if (c == 'L') { 496 i2 = desc.indexOf(';', ++i); 497 name = desc.substring(i, i2++).replace('/', '.'); 498 } 499 else { 500 CtClass type = toPrimitiveClass(c); 501 if (type == null) 502 return -1; 504 i2 = i + 1; 505 if (arrayDim == 0) { 506 args[n] = type; 507 return i2; } 509 else 510 name = type.getName(); 511 } 512 513 if (arrayDim > 0) { 514 StringBuffer sbuf = new StringBuffer (name); 515 while (arrayDim-- > 0) 516 sbuf.append("[]"); 517 518 name = sbuf.toString(); 519 } 520 521 args[n] = cp.get(name); 522 return i2; 523 } 524 525 private static CtClass toPrimitiveClass(char c) { 526 CtClass type = null; 527 switch (c) { 528 case 'Z' : 529 type = CtClass.booleanType; 530 break; 531 case 'C' : 532 type = CtClass.charType; 533 break; 534 case 'B' : 535 type = CtClass.byteType; 536 break; 537 case 'S' : 538 type = CtClass.shortType; 539 break; 540 case 'I' : 541 type = CtClass.intType; 542 break; 543 case 'J' : 544 type = CtClass.longType; 545 break; 546 case 'F' : 547 type = CtClass.floatType; 548 break; 549 case 'D' : 550 type = CtClass.doubleType; 551 break; 552 case 'V' : 553 type = CtClass.voidType; 554 break; 555 } 556 557 return type; 558 } 559 560 568 public static int arrayDimension(String desc) { 569 int dim = 0; 570 while (desc.charAt(dim) == '[') 571 ++dim; 572 573 return dim; 574 } 575 576 585 public static String toArrayComponent(String desc, int dim) { 586 return desc.substring(dim); 587 } 588 589 600 public static int dataSize(String desc) { 601 int n = 0; 602 char c = desc.charAt(0); 603 if (c == '(') { 604 int i = 1; 605 for (;;) { 606 c = desc.charAt(i); 607 if (c == ')') { 608 c = desc.charAt(i + 1); 609 break; 610 } 611 612 boolean array = false; 613 while (c == '[') { 614 array = true; 615 c = desc.charAt(++i); 616 } 617 618 if (c == 'L') { 619 i = desc.indexOf(';', i) + 1; 620 if (i <= 0) 621 throw new IndexOutOfBoundsException ("bad descriptor"); 622 } 623 else 624 ++i; 625 626 if (!array && (c == 'J' || c == 'D')) 627 n -= 2; 628 else 629 --n; 630 } 631 } 632 633 if (c == 'J' || c == 'D') 634 n += 2; 635 else if (c != 'V') 636 ++n; 637 638 return n; 639 } 640 } 641 | Popular Tags |