1 30 31 package oracle.toplink.libraries.asm; 32 33 import java.lang.reflect.Method ; 34 35 41 42 public class Type { 43 44 47 48 public final static int VOID = 0; 49 50 53 54 public final static int BOOLEAN = 1; 55 56 59 60 public final static int CHAR = 2; 61 62 65 66 public final static int BYTE = 3; 67 68 71 72 public final static int SHORT = 4; 73 74 77 78 public final static int INT = 5; 79 80 83 84 public final static int FLOAT = 6; 85 86 89 90 public final static int LONG = 7; 91 92 95 96 public final static int DOUBLE = 8; 97 98 101 102 public final static int ARRAY = 9; 103 104 107 108 public final static int OBJECT = 10; 109 110 113 114 public final static Type VOID_TYPE = new Type(VOID); 115 116 119 120 public final static Type BOOLEAN_TYPE = new Type(BOOLEAN); 121 122 125 126 public final static Type CHAR_TYPE = new Type(CHAR); 127 128 131 132 public final static Type BYTE_TYPE = new Type(BYTE); 133 134 137 138 public final static Type SHORT_TYPE = new Type(SHORT); 139 140 143 144 public final static Type INT_TYPE = new Type(INT); 145 146 149 150 public final static Type FLOAT_TYPE = new Type(FLOAT); 151 152 155 156 public final static Type LONG_TYPE = new Type(LONG); 157 158 161 162 public final static Type DOUBLE_TYPE = new Type(DOUBLE); 163 164 168 171 172 private final int sort; 173 174 178 179 private char[] buf; 180 181 185 186 private int off; 187 188 191 192 private int len; 193 194 198 203 204 private Type (final int sort) { 205 this.sort = sort; 206 this.len = 1; 207 } 208 209 217 218 private Type ( 219 final int sort, 220 final char[] buf, 221 final int off, 222 final int len) 223 { 224 this.sort = sort; 225 this.buf = buf; 226 this.off = off; 227 this.len = len; 228 } 229 230 236 237 public static Type getType (final String typeDescriptor) { 238 return getType(typeDescriptor.toCharArray(), 0); 239 } 240 241 247 248 public static Type getType (final Class c) { 249 if (c.isPrimitive()) { 250 if (c == Integer.TYPE) { 251 return INT_TYPE; 252 } else if (c == Void.TYPE) { 253 return VOID_TYPE; 254 } else if (c == Boolean.TYPE) { 255 return BOOLEAN_TYPE; 256 } else if (c == Byte.TYPE) { 257 return BYTE_TYPE; 258 } else if (c == Character.TYPE) { 259 return CHAR_TYPE; 260 } else if (c == Short.TYPE) { 261 return SHORT_TYPE; 262 } else if (c == Double.TYPE) { 263 return DOUBLE_TYPE; 264 } else if (c == Float.TYPE) { 265 return FLOAT_TYPE; 266 } else { 267 return LONG_TYPE; 268 } 269 } else { 270 return getType(getDescriptor(c)); 271 } 272 } 273 274 282 283 public static Type[] getArgumentTypes (final String methodDescriptor) { 284 char[] buf = methodDescriptor.toCharArray(); 285 int off = 1; 286 int size = 0; 287 while (true) { 288 char car = buf[off++]; 289 if (car == ')') { 290 break; 291 } else if (car == 'L') { 292 while (buf[off++] != ';') { 293 } 294 ++size; 295 } else if (car != '[') { 296 ++size; 297 } 298 } 299 Type[] args = new Type[size]; 300 off = 1; 301 size = 0; 302 while (buf[off] != ')') { 303 args[size] = getType(buf, off); 304 off += args[size].len; 305 size += 1; 306 } 307 return args; 308 } 309 310 318 319 public static Type[] getArgumentTypes (final Method method) { 320 Class [] classes = method.getParameterTypes(); 321 Type[] types = new Type[classes.length]; 322 for (int i = classes.length - 1; i >= 0; --i) { 323 types[i] = getType(classes[i]); 324 } 325 return types; 326 } 327 328 336 337 public static Type getReturnType (final String methodDescriptor) { 338 char[] buf = methodDescriptor.toCharArray(); 339 return getType(buf, methodDescriptor.indexOf(')') + 1); 340 } 341 342 350 351 public static Type getReturnType (final Method method) { 352 return getType(method.getReturnType()); 353 } 354 355 362 363 private static Type getType (final char[] buf, final int off) { 364 int len; 365 switch (buf[off]) { 366 case 'V': return VOID_TYPE; 367 case 'Z': return BOOLEAN_TYPE; 368 case 'C': return CHAR_TYPE; 369 case 'B': return BYTE_TYPE; 370 case 'S': return SHORT_TYPE; 371 case 'I': return INT_TYPE; 372 case 'F': return FLOAT_TYPE; 373 case 'J': return LONG_TYPE; 374 case 'D': return DOUBLE_TYPE; 375 case '[': 376 len = 1; 377 while (buf[off + len] == '[') { 378 ++len; 379 } 380 if (buf[off + len] == 'L') { 381 ++len; 382 while (buf[off + len] != ';') { 383 ++len; 384 } 385 } 386 return new Type(ARRAY, buf, off, len + 1); 387 default: 389 len = 1; 390 while (buf[off + len] != ';') { 391 ++len; 392 } 393 return new Type(OBJECT, buf, off, len + 1); 394 } 395 } 396 397 401 409 410 public int getSort () { 411 return sort; 412 } 413 414 420 421 public int getDimensions () { 422 int i = 1; 423 while (buf[off + i] == '[') { 424 ++i; 425 } 426 return i; 427 } 428 429 435 436 public Type getElementType () { 437 return getType(buf, off + getDimensions()); 438 } 439 440 445 446 public String getClassName () { 447 switch (sort) { 448 case VOID: return "void"; 449 case BOOLEAN: return "boolean"; 450 case CHAR: return "char"; 451 case BYTE: return "byte"; 452 case SHORT: return "short"; 453 case INT: return "int"; 454 case FLOAT: return "float"; 455 case LONG: return "long"; 456 case DOUBLE: return "double"; 457 case ARRAY: 458 StringBuffer b = new StringBuffer (getElementType().getClassName()); 459 for (int i = getDimensions(); i > 0; --i) { 460 b.append("[]"); 461 } 462 return b.toString(); 463 default: 465 return new String (buf, off + 1, len - 2).replace('/', '.'); 466 } 467 } 468 469 476 477 public String getInternalName () { 478 return new String (buf, off + 1, len - 2); 479 } 480 481 485 490 491 public String getDescriptor () { 492 StringBuffer buf = new StringBuffer (); 493 getDescriptor(buf); 494 return buf.toString(); 495 } 496 497 506 507 public static String getMethodDescriptor ( 508 final Type returnType, 509 final Type[] argumentTypes) 510 { 511 StringBuffer buf = new StringBuffer (); 512 buf.append('('); 513 for (int i = 0; i < argumentTypes.length; ++i) { 514 argumentTypes[i].getDescriptor(buf); 515 } 516 buf.append(')'); 517 returnType.getDescriptor(buf); 518 return buf.toString(); 519 } 520 521 527 528 private void getDescriptor (final StringBuffer buf) { 529 switch (sort) { 530 case VOID: buf.append('V'); return; 531 case BOOLEAN: buf.append('Z'); return; 532 case CHAR: buf.append('C'); return; 533 case BYTE: buf.append('B'); return; 534 case SHORT: buf.append('S'); return; 535 case INT: buf.append('I'); return; 536 case FLOAT: buf.append('F'); return; 537 case LONG: buf.append('J'); return; 538 case DOUBLE: buf.append('D'); return; 539 default: buf.append(this.buf, off, len); 542 } 543 } 544 545 550 557 558 public static String getInternalName (final Class c) { 559 return c.getName().replace('.', '/'); 560 } 561 562 568 569 public static String getDescriptor (final Class c) { 570 StringBuffer buf = new StringBuffer (); 571 getDescriptor(buf, c); 572 return buf.toString(); 573 } 574 575 581 582 public static String getMethodDescriptor (final Method m) { 583 Class [] parameters = m.getParameterTypes(); 584 StringBuffer buf = new StringBuffer (); 585 buf.append('('); 586 for (int i = 0; i < parameters.length; ++i) { 587 getDescriptor(buf, parameters[i]); 588 } 589 buf.append(')'); 590 getDescriptor(buf, m.getReturnType()); 591 return buf.toString(); 592 } 593 594 600 601 private static void getDescriptor (final StringBuffer buf, final Class c) { 602 Class d = c; 603 while (true) { 604 if (d.isPrimitive()) { 605 char car; 606 if (d == Integer.TYPE) { 607 car = 'I'; 608 } else if (d == Void.TYPE) { 609 car = 'V'; 610 } else if (d == Boolean.TYPE) { 611 car = 'Z'; 612 } else if (d == Byte.TYPE) { 613 car = 'B'; 614 } else if (d == Character.TYPE) { 615 car = 'C'; 616 } else if (d == Short.TYPE) { 617 car = 'S'; 618 } else if (d == Double.TYPE) { 619 car = 'D'; 620 } else if (d == Float.TYPE) { 621 car = 'F'; 622 } else { 623 car = 'J'; 624 } 625 buf.append(car); 626 return; 627 } else if (d.isArray()) { 628 buf.append('['); 629 d = d.getComponentType(); 630 } else { 631 buf.append('L'); 632 String name = d.getName(); 633 int len = name.length(); 634 for (int i = 0; i < len; ++i) { 635 char car = name.charAt(i); 636 buf.append(car == '.' ? '/' : car); 637 } 638 buf.append(';'); 639 return; 640 } 641 } 642 } 643 644 648 654 655 public int getSize () { 656 return (sort == LONG || sort == DOUBLE ? 2 : 1); 657 } 658 659 669 670 public int getOpcode (final int opcode) { 671 if (opcode == Constants.IALOAD || opcode == Constants.IASTORE) { 672 switch (sort) { 673 case BOOLEAN: 674 case BYTE: 675 return opcode + 5; 676 case CHAR: 677 return opcode + 6; 678 case SHORT: 679 return opcode + 7; 680 case INT: 681 return opcode; 682 case FLOAT: 683 return opcode + 2; 684 case LONG: 685 return opcode + 1; 686 case DOUBLE: 687 return opcode + 3; 688 default: 691 return opcode + 4; 692 } 693 } else { 694 switch (sort) { 695 case VOID: 696 return opcode + 5; 697 case BOOLEAN: 698 case CHAR: 699 case BYTE: 700 case SHORT: 701 case INT: 702 return opcode; 703 case FLOAT: 704 return opcode + 2; 705 case LONG: 706 return opcode + 1; 707 case DOUBLE: 708 return opcode + 3; 709 default: 712 return opcode + 4; 713 } 714 } 715 } 716 717 721 727 728 public boolean equals (final Object o) { 729 if (this == o) { 730 return true; 731 } 732 if (o == null || !(o instanceof Type)) { 733 return false; 734 } 735 Type t = (Type)o; 736 if (sort != t.sort) { 737 return false; 738 } 739 if (sort == Type.OBJECT || sort == Type.ARRAY) { 740 if (len != t.len) { 741 return false; 742 } 743 for (int i = off, j = t.off, end = i + len; i < end; i++, j++) { 744 if (buf[i] != t.buf[j]) { 745 return false; 746 } 747 } 748 } 749 return true; 750 } 751 752 757 758 public int hashCode () { 759 int hc = 13 * sort; 760 if (sort == Type.OBJECT || sort == Type.ARRAY) { 761 for (int i = off, end = i + len; i < end; i++) { 762 hc = 17 * (hc + buf[i]); 763 } 764 } 765 return hc; 766 } 767 768 773 774 public String toString () { 775 return getDescriptor(); 776 } 777 } 778 | Popular Tags |