1 12 package org.eclipse.jdt.core; 13 14 import java.util.ArrayList ; 15 16 import org.eclipse.jdt.core.compiler.CharOperation; 17 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; 18 import org.eclipse.jdt.internal.core.util.Util; 19 20 21 143 public final class Signature { 144 145 149 public static final char C_BOOLEAN = 'Z'; 150 151 155 public static final char C_BYTE = 'B'; 156 157 161 public static final char C_CHAR = 'C'; 162 163 167 public static final char C_DOUBLE = 'D'; 168 169 173 public static final char C_FLOAT = 'F'; 174 175 179 public static final char C_INT = 'I'; 180 181 185 public static final char C_SEMICOLON = ';'; 186 187 192 public static final char C_COLON = ':'; 193 194 198 public static final char C_LONG = 'J'; 199 200 204 public static final char C_SHORT = 'S'; 205 206 210 public static final char C_VOID = 'V'; 211 212 217 public static final char C_TYPE_VARIABLE = 'T'; 218 219 225 public static final char C_STAR = '*'; 226 227 232 public static final char C_EXCEPTION_START = '^'; 233 234 240 public static final char C_EXTENDS = '+'; 241 242 248 public static final char C_SUPER = '-'; 249 250 254 public static final char C_DOT = '.'; 255 256 260 public static final char C_DOLLAR = '$'; 261 262 266 public static final char C_ARRAY = '['; 267 268 272 public static final char C_RESOLVED = 'L'; 273 274 278 public static final char C_UNRESOLVED = 'Q'; 279 280 284 public static final char C_NAME_END = ';'; 285 286 290 public static final char C_PARAM_START = '('; 291 292 296 public static final char C_PARAM_END = ')'; 297 298 303 public static final char C_GENERIC_START = '<'; 304 305 310 public static final char C_GENERIC_END = '>'; 311 312 317 public static final char C_CAPTURE = '!'; 318 319 323 public static final String SIG_BOOLEAN = "Z"; 325 329 public static final String SIG_BYTE = "B"; 331 335 public static final String SIG_CHAR = "C"; 337 341 public static final String SIG_DOUBLE = "D"; 343 347 public static final String SIG_FLOAT = "F"; 349 353 public static final String SIG_INT = "I"; 355 359 public static final String SIG_LONG = "J"; 361 365 public static final String SIG_SHORT = "S"; 367 370 public static final String SIG_VOID = "V"; 372 373 378 public static final int CLASS_TYPE_SIGNATURE = 1; 379 380 385 public static final int BASE_TYPE_SIGNATURE = 2; 386 387 392 public static final int TYPE_VARIABLE_SIGNATURE = 3; 393 394 399 public static final int ARRAY_TYPE_SIGNATURE = 4; 400 401 406 public static final int WILDCARD_TYPE_SIGNATURE = 5; 407 408 413 public static final int CAPTURE_TYPE_SIGNATURE = 6; 414 415 private static final char[] BOOLEAN = "boolean".toCharArray(); private static final char[] BYTE = "byte".toCharArray(); private static final char[] CHAR = "char".toCharArray(); private static final char[] DOUBLE = "double".toCharArray(); private static final char[] FLOAT = "float".toCharArray(); private static final char[] INT = "int".toCharArray(); private static final char[] LONG = "long".toCharArray(); private static final char[] SHORT = "short".toCharArray(); private static final char[] VOID = "void".toCharArray(); private static final char[] EXTENDS = "extends".toCharArray(); private static final char[] SUPER = "super".toCharArray(); private static final char[] CAPTURE = "capture-of".toCharArray(); 428 private Signature() { 429 } 431 432 private static int checkName(char[] name, char[] typeName, int pos, int length) { 433 if (CharOperation.fragmentEquals(name, typeName, pos, true)) { 434 pos += name.length; 435 if (pos == length) return pos; 436 char currentChar = typeName[pos]; 437 switch (currentChar) { 438 case ' ' : 439 case '.' : 440 case '<' : 441 case '>' : 442 case '[' : 443 case ',' : 444 return pos; 445 default: 446 if (ScannerHelper.isWhitespace(currentChar)) 447 return pos; 448 449 } 450 } 451 return -1; 452 } 453 454 464 public static char[] createArraySignature(char[] typeSignature, int arrayCount) { 465 if (arrayCount == 0) return typeSignature; 466 int sigLength = typeSignature.length; 467 char[] result = new char[arrayCount + sigLength]; 468 for (int i = 0; i < arrayCount; i++) { 469 result[i] = C_ARRAY; 470 } 471 System.arraycopy(typeSignature, 0, result, arrayCount, sigLength); 472 return result; 473 } 474 482 public static String createArraySignature(String typeSignature, int arrayCount) { 483 return new String (createArraySignature(typeSignature.toCharArray(), arrayCount)); 484 } 485 486 496 public static char[] createMethodSignature(char[][] parameterTypes, char[] returnType) { 497 int parameterTypesLength = parameterTypes.length; 498 int parameterLength = 0; 499 for (int i = 0; i < parameterTypesLength; i++) { 500 parameterLength += parameterTypes[i].length; 501 502 } 503 int returnTypeLength = returnType.length; 504 char[] result = new char[1 + parameterLength + 1 + returnTypeLength]; 505 result[0] = C_PARAM_START; 506 int index = 1; 507 for (int i = 0; i < parameterTypesLength; i++) { 508 char[] parameterType = parameterTypes[i]; 509 int length = parameterType.length; 510 System.arraycopy(parameterType, 0, result, index, length); 511 index += length; 512 } 513 result[index] = C_PARAM_END; 514 System.arraycopy(returnType, 0, result, index+1, returnTypeLength); 515 return result; 516 } 517 518 529 public static String createMethodSignature(String [] parameterTypes, String returnType) { 530 int parameterTypesLenth = parameterTypes.length; 531 char[][] parameters = new char[parameterTypesLenth][]; 532 for (int i = 0; i < parameterTypesLenth; i++) { 533 parameters[i] = parameterTypes[i].toCharArray(); 534 } 535 return new String (createMethodSignature(parameters, returnType.toCharArray())); 536 } 537 538 547 public static char[] createTypeParameterSignature(char[] typeParameterName, char[][] boundSignatures) { 548 int length = boundSignatures.length; 549 if (length == 0) { 550 return CharOperation.append(typeParameterName, C_COLON); } 552 int boundsSize = 0; 553 for (int i = 0; i < length; i++) { 554 boundsSize += boundSignatures[i].length + 1; 555 } 556 int nameLength = typeParameterName.length; 557 char[] result = new char[nameLength + boundsSize]; 558 System.arraycopy(typeParameterName, 0, result, 0, nameLength); 559 int index = nameLength; 560 for (int i = 0; i < length; i++) { 561 result[index++] = C_COLON; 562 int boundLength = boundSignatures[i].length; 563 System.arraycopy(boundSignatures[i], 0, result, index, boundLength); 564 index += boundLength; 565 } 566 return result; 567 } 568 569 578 public static String createTypeParameterSignature(String typeParameterName, String [] boundSignatures) { 579 int length = boundSignatures.length; 580 char[][] boundSignatureChars = new char[length][]; 581 for (int i = 0; i < length; i++) { 582 boundSignatureChars[i] = boundSignatures[i].toCharArray(); 583 } 584 return new String (createTypeParameterSignature(typeParameterName.toCharArray(), boundSignatureChars)); 585 } 586 587 603 public static String createTypeSignature(char[] typeName, boolean isResolved) { 604 return new String (createCharArrayTypeSignature(typeName, isResolved)); 605 } 606 607 625 public static char[] createCharArrayTypeSignature(char[] typeName, boolean isResolved) { 626 if (typeName == null) throw new IllegalArgumentException ("null"); int length = typeName.length; 628 if (length == 0) throw new IllegalArgumentException (new String (typeName)); 629 StringBuffer buffer = new StringBuffer (5); 630 int pos = encodeTypeSignature(typeName, 0, isResolved, length, buffer); 631 pos = consumeWhitespace(typeName, pos, length); 632 if (pos < length) throw new IllegalArgumentException (new String (typeName)); 633 char[] result = new char[length = buffer.length()]; 634 buffer.getChars(0, length, result, 0); 635 return result; 636 } 637 private static int consumeWhitespace(char[] typeName, int pos, int length) { 638 while (pos < length) { 639 char currentChar = typeName[pos]; 640 if (currentChar != ' ' && !CharOperation.isWhitespace(currentChar)) { 641 break; 642 } 643 pos++; 644 } 645 return pos; 646 } 647 private static int encodeQualifiedName(char[] typeName, int pos, int length, StringBuffer buffer) { 648 int count = 0; 649 char lastAppendedChar = 0; 650 nameLoop: while (pos < length) { 651 char currentChar = typeName[pos]; 652 switch (currentChar) { 653 case '<' : 654 case '>' : 655 case '[' : 656 case ',' : 657 break nameLoop; 658 case '.' : 659 buffer.append(C_DOT); 660 lastAppendedChar = C_DOT; 661 count++; 662 break; 663 default: 664 if (currentChar == ' ' || ScannerHelper.isWhitespace(currentChar)) { 665 if (lastAppendedChar == C_DOT) { pos = consumeWhitespace(typeName, pos, length) - 1; break; 668 } 669 int checkPos = checkNextChar(typeName, '.', pos, length, true); 671 if (checkPos > 0) { 672 buffer.append(C_DOT); lastAppendedChar = C_DOT; 674 count++; 675 pos = checkPos; 676 break; 677 } 678 break nameLoop; 679 } 680 buffer.append(currentChar); 681 lastAppendedChar = currentChar; 682 count++; 683 break; 684 } 685 pos++; 686 } 687 if (count == 0) throw new IllegalArgumentException (new String (typeName)); 688 return pos; 689 } 690 691 private static int encodeArrayDimension(char[] typeName, int pos, int length, StringBuffer buffer) { 692 int checkPos; 693 while (pos < length && (checkPos = checkNextChar(typeName, '[', pos, length, true)) > 0) { 694 pos = checkNextChar(typeName, ']', checkPos, length, false); 695 buffer.append(C_ARRAY); 696 } 697 return pos; 698 } 699 private static int checkArrayDimension(char[] typeName, int pos, int length) { 700 int genericBalance = 0; 701 while (pos < length) { 702 switch(typeName[pos]) { 703 case '<' : 704 genericBalance++; 705 break; 706 case ',' : 707 if (genericBalance == 0) return -1; 708 break; 709 case '>': 710 if (genericBalance == 0) return -1; 711 genericBalance--; 712 break; 713 case '[': 714 if (genericBalance == 0) { 715 return pos; 716 } 717 } 718 pos++; 719 } 720 return -1; 721 } 722 private static int checkNextChar(char[] typeName, char expectedChar, int pos, int length, boolean isOptional) { 723 pos = consumeWhitespace(typeName, pos, length); 724 if (pos < length && typeName[pos] == expectedChar) 725 return pos + 1; 726 if (!isOptional) throw new IllegalArgumentException (new String (typeName)); 727 return -1; 728 } 729 730 private static int encodeTypeSignature(char[] typeName, int start, boolean isResolved, int length, StringBuffer buffer) { 731 int pos = start; 732 pos = consumeWhitespace(typeName, pos, length); 733 if (pos >= length) throw new IllegalArgumentException (new String (typeName)); 734 int checkPos; 735 char currentChar = typeName[pos]; 736 switch (currentChar) { 737 case 'b' : 739 checkPos = checkName(BOOLEAN, typeName, pos, length); 740 if (checkPos > 0) { 741 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 742 buffer.append(C_BOOLEAN); 743 return pos; 744 } 745 checkPos = checkName(BYTE, typeName, pos, length); 746 if (checkPos > 0) { 747 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 748 buffer.append(C_BYTE); 749 return pos; 750 } 751 break; 752 case 'd': 753 checkPos = checkName(DOUBLE, typeName, pos, length); 754 if (checkPos > 0) { 755 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 756 buffer.append(C_DOUBLE); 757 return pos; 758 } 759 break; 760 case 'f': 761 checkPos = checkName(FLOAT, typeName, pos, length); 762 if (checkPos > 0) { 763 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 764 buffer.append(C_FLOAT); 765 return pos; 766 } 767 break; 768 case 'i': 769 checkPos = checkName(INT, typeName, pos, length); 770 if (checkPos > 0) { 771 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 772 buffer.append(C_INT); 773 return pos; 774 } 775 break; 776 case 'l': 777 checkPos = checkName(LONG, typeName, pos, length); 778 if (checkPos > 0) { 779 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 780 buffer.append(C_LONG); 781 return pos; 782 } 783 break; 784 case 's': 785 checkPos = checkName(SHORT, typeName, pos, length); 786 if (checkPos > 0) { 787 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 788 buffer.append(C_SHORT); 789 return pos; 790 } 791 break; 792 case 'v': 793 checkPos = checkName(VOID, typeName, pos, length); 794 if (checkPos > 0) { 795 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 796 buffer.append(C_VOID); 797 return pos; 798 } 799 break; 800 case 'c': 801 checkPos = checkName(CHAR, typeName, pos, length); 802 if (checkPos > 0) { 803 pos = encodeArrayDimension(typeName, checkPos, length, buffer); 804 buffer.append(C_CHAR); 805 return pos; 806 } else { 807 checkPos = checkName(CAPTURE, typeName, pos, length); 808 if (checkPos > 0) { 809 pos = consumeWhitespace(typeName, checkPos, length); 810 if (typeName[pos] != '?') { 811 break; 812 } 813 } else { 814 break; 815 } 816 } 817 buffer.append(C_CAPTURE); 818 case '?': 820 pos = consumeWhitespace(typeName, pos+1, length); 822 checkPos = checkName(EXTENDS, typeName, pos, length); 823 if (checkPos > 0) { 824 buffer.append(C_EXTENDS); 825 pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer); 826 return pos; 827 } 828 checkPos = checkName(SUPER, typeName, pos, length); 829 if (checkPos > 0) { 830 buffer.append(C_SUPER); 831 pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer); 832 return pos; 833 } 834 buffer.append(C_STAR); 835 return pos; 836 } 837 checkPos = checkArrayDimension(typeName, pos, length); 839 int end; 840 if (checkPos > 0) { 841 end = encodeArrayDimension(typeName, checkPos, length, buffer); 842 } else { 843 end = -1; 844 } 845 buffer.append(isResolved ? C_RESOLVED : C_UNRESOLVED); 846 while (true) { pos = encodeQualifiedName(typeName, pos, length, buffer); 848 checkPos = checkNextChar(typeName, '<', pos, length, true); 849 if (checkPos > 0) { 850 buffer.append(C_GENERIC_START); 851 pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer); 852 while ((checkPos = checkNextChar(typeName, ',', pos, length, true)) > 0) { 853 pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer); 854 } 855 pos = checkNextChar(typeName, '>', pos, length, false); 856 buffer.append(C_GENERIC_END); 857 } 858 checkPos = checkNextChar(typeName, '.', pos, length, true); 859 if (checkPos > 0) { 860 buffer.append(C_DOT); 861 pos = checkPos; 862 } else { 863 break; 864 } 865 } 866 buffer.append(C_NAME_END); 867 if (end > 0) pos = end; return pos; 869 } 870 871 895 public static String createTypeSignature(String typeName, boolean isResolved) { 896 return createTypeSignature(typeName == null ? null : typeName.toCharArray(), isResolved); 897 } 898 899 909 public static int getArrayCount(char[] typeSignature) throws IllegalArgumentException { 910 try { 911 int count = 0; 912 while (typeSignature[count] == C_ARRAY) { 913 ++count; 914 } 915 return count; 916 } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException (); 918 } 919 } 920 928 public static int getArrayCount(String typeSignature) throws IllegalArgumentException { 929 return getArrayCount(typeSignature.toCharArray()); 930 } 931 949 public static char[] getElementType(char[] typeSignature) throws IllegalArgumentException { 950 int count = getArrayCount(typeSignature); 951 if (count == 0) return typeSignature; 952 int length = typeSignature.length; 953 char[] result = new char[length-count]; 954 System.arraycopy(typeSignature, count, result, 0, length-count); 955 return result; 956 } 957 973 public static String getElementType(String typeSignature) throws IllegalArgumentException { 974 return new String (getElementType(typeSignature.toCharArray())); 975 } 976 985 public static int getParameterCount(char[] methodSignature) throws IllegalArgumentException { 986 try { 987 int count = 0; 988 int i = CharOperation.indexOf(C_PARAM_START, methodSignature); 989 if (i < 0) { 990 throw new IllegalArgumentException (); 991 } else { 992 i++; 993 } 994 for (;;) { 995 if (methodSignature[i] == C_PARAM_END) { 996 return count; 997 } 998 int e= Util.scanTypeSignature(methodSignature, i); 999 if (e < 0) { 1000 throw new IllegalArgumentException (); 1001 } else { 1002 i = e + 1; 1003 } 1004 count++; 1005 } 1006 } catch (ArrayIndexOutOfBoundsException e) { 1007 throw new IllegalArgumentException (); 1008 } 1009} 1010 1011 1022public static int getTypeSignatureKind(char[] typeSignature) { 1023 if (typeSignature.length < 1) { 1025 throw new IllegalArgumentException (); 1026 } 1027 char c = typeSignature[0]; 1028 if (c == C_GENERIC_START) { 1029 int count = 1; 1030 for (int i = 1, length = typeSignature.length; i < length; i++) { 1031 switch (typeSignature[i]) { 1032 case C_GENERIC_START: 1033 count++; 1034 break; 1035 case C_GENERIC_END: 1036 count--; 1037 break; 1038 } 1039 if (count == 0) { 1040 if (i+1 < length) 1041 c = typeSignature[i+1]; 1042 break; 1043 } 1044 } 1045 } 1046 switch (c) { 1047 case C_ARRAY : 1048 return ARRAY_TYPE_SIGNATURE; 1049 case C_RESOLVED : 1050 case C_UNRESOLVED : 1051 return CLASS_TYPE_SIGNATURE; 1052 case C_TYPE_VARIABLE : 1053 return TYPE_VARIABLE_SIGNATURE; 1054 case C_BOOLEAN : 1055 case C_BYTE : 1056 case C_CHAR : 1057 case C_DOUBLE : 1058 case C_FLOAT : 1059 case C_INT : 1060 case C_LONG : 1061 case C_SHORT : 1062 case C_VOID : 1063 return BASE_TYPE_SIGNATURE; 1064 case C_STAR : 1065 case C_SUPER : 1066 case C_EXTENDS : 1067 return WILDCARD_TYPE_SIGNATURE; 1068 case C_CAPTURE : 1069 return CAPTURE_TYPE_SIGNATURE; 1070 default : 1071 throw new IllegalArgumentException (); 1072 } 1073} 1074 1075 1086public static int getTypeSignatureKind(String typeSignature) { 1087 if (typeSignature.length() < 1) { 1089 throw new IllegalArgumentException (); 1090 } 1091 char c = typeSignature.charAt(0); 1092 if (c == C_GENERIC_START) { 1093 int count = 1; 1094 for (int i = 1, length = typeSignature.length(); i < length; i++) { 1095 switch (typeSignature.charAt(i)) { 1096 case C_GENERIC_START: 1097 count++; 1098 break; 1099 case C_GENERIC_END: 1100 count--; 1101 break; 1102 } 1103 if (count == 0) { 1104 if (i+1 < length) 1105 c = typeSignature.charAt(i+1); 1106 break; 1107 } 1108 } 1109 } 1110 switch (c) { 1111 case C_ARRAY : 1112 return ARRAY_TYPE_SIGNATURE; 1113 case C_RESOLVED : 1114 case C_UNRESOLVED : 1115 return CLASS_TYPE_SIGNATURE; 1116 case C_TYPE_VARIABLE : 1117 return TYPE_VARIABLE_SIGNATURE; 1118 case C_BOOLEAN : 1119 case C_BYTE : 1120 case C_CHAR : 1121 case C_DOUBLE : 1122 case C_FLOAT : 1123 case C_INT : 1124 case C_LONG : 1125 case C_SHORT : 1126 case C_VOID : 1127 return BASE_TYPE_SIGNATURE; 1128 case C_STAR : 1129 case C_SUPER : 1130 case C_EXTENDS : 1131 return WILDCARD_TYPE_SIGNATURE; 1132 case C_CAPTURE : 1133 return CAPTURE_TYPE_SIGNATURE; 1134 default : 1135 throw new IllegalArgumentException (); 1136 } 1137} 1138 1139 1147public static int getParameterCount(String methodSignature) throws IllegalArgumentException { 1148 return getParameterCount(methodSignature.toCharArray()); 1149} 1150 1151 1162public static char[][] getParameterTypes(char[] methodSignature) throws IllegalArgumentException { 1163 try { 1164 int count = getParameterCount(methodSignature); 1165 char[][] result = new char[count][]; 1166 if (count == 0) { 1167 return result; 1168 } 1169 int i = CharOperation.indexOf(C_PARAM_START, methodSignature); 1170 if (i < 0) { 1171 throw new IllegalArgumentException (); 1172 } else { 1173 i++; 1174 } 1175 int t = 0; 1176 for (;;) { 1177 if (methodSignature[i] == C_PARAM_END) { 1178 return result; 1179 } 1180 int e = Util.scanTypeSignature(methodSignature, i); 1181 if (e < 0) { 1182 throw new IllegalArgumentException (); 1183 } 1184 result[t] = CharOperation.subarray(methodSignature, i, e + 1); 1185 t++; 1186 i = e + 1; 1187 } 1188 } catch (ArrayIndexOutOfBoundsException e) { 1189 throw new IllegalArgumentException (); 1190 } 1191} 1192 1193 1202public static String [] getParameterTypes(String methodSignature) throws IllegalArgumentException { 1203 char[][] parameterTypes = getParameterTypes(methodSignature.toCharArray()); 1204 return CharOperation.toStrings(parameterTypes); 1205} 1206 1207 1218public static String [] getThrownExceptionTypes(String methodSignature) throws IllegalArgumentException { 1219 char[][] parameterTypes = getThrownExceptionTypes(methodSignature.toCharArray()); 1220 return CharOperation.toStrings(parameterTypes); 1221} 1222 1223 1234public static char[][] getThrownExceptionTypes(char[] methodSignature) throws IllegalArgumentException { 1235 int exceptionStart = CharOperation.indexOf(C_EXCEPTION_START, methodSignature); 1237 if (exceptionStart == -1) { 1238 int paren = CharOperation.lastIndexOf(C_PARAM_END, methodSignature); 1239 if (paren == -1) { 1240 throw new IllegalArgumentException (); 1241 } 1242 exceptionStart = Util.scanTypeSignature(methodSignature, paren+1) + 1; 1244 int length = methodSignature.length; 1245 if (exceptionStart == length) return CharOperation.NO_CHAR_CHAR; 1246 throw new IllegalArgumentException (); 1247 } 1248 int length = methodSignature.length; 1249 int i = exceptionStart; 1250 ArrayList exceptionList = new ArrayList (1); 1251 while (i < length) { 1252 if (methodSignature[i] == C_EXCEPTION_START) { 1253 exceptionStart++; 1254 i++; 1255 } else { 1256 throw new IllegalArgumentException (); 1257 } 1258 i = Util.scanTypeSignature(methodSignature, i) + 1; 1259 exceptionList.add(CharOperation.subarray(methodSignature, exceptionStart,i)); 1260 exceptionStart = i; 1261 } 1262 char[][] result; 1263 exceptionList.toArray(result = new char[exceptionList.size()][]); 1264 return result; 1265} 1266 1267 1277public static char[][] getTypeArguments(char[] parameterizedTypeSignature) throws IllegalArgumentException { 1278 int length = parameterizedTypeSignature.length; 1279 if (length < 2 || parameterizedTypeSignature[length-2] != C_GENERIC_END) 1280 return CharOperation.NO_CHAR_CHAR; 1282 int count = 1; int start = length - 2; 1284 while (start >= 0 && count > 0) { 1285 switch (parameterizedTypeSignature[--start]) { 1286 case C_GENERIC_START: 1287 count--; 1288 break; 1289 case C_GENERIC_END: 1290 count++; 1291 break; 1292 } 1293 } 1294 if (start < 0) throw new IllegalArgumentException (); 1296 ArrayList args = new ArrayList (); 1297 int p = start + 1; 1298 while (true) { 1299 if (p >= parameterizedTypeSignature.length) { 1300 throw new IllegalArgumentException (); 1301 } 1302 char c = parameterizedTypeSignature[p]; 1303 if (c == C_GENERIC_END) { 1304 int size = args.size(); 1305 char[][] result = new char[size][]; 1306 args.toArray(result); 1307 return result; 1308 } 1309 int e = Util.scanTypeArgumentSignature(parameterizedTypeSignature, p); 1310 args.add(CharOperation.subarray(parameterizedTypeSignature, p, e+1)); 1311 p = e + 1; 1312 } 1313} 1314 1315 1325public static String [] getTypeArguments(String parameterizedTypeSignature) throws IllegalArgumentException { 1326 char[][] args = getTypeArguments(parameterizedTypeSignature.toCharArray()); 1327 return CharOperation.toStrings(args); 1328} 1329 1330 1341public static char[] getTypeErasure(char[] parameterizedTypeSignature) throws IllegalArgumentException { 1342 int end = CharOperation.indexOf(C_GENERIC_START, parameterizedTypeSignature); 1343 if (end == -1) return parameterizedTypeSignature; 1344 int length = parameterizedTypeSignature.length; 1345 char[] result = new char[length]; 1346 int pos = 0; 1347 int start = 0; 1348 int deep= 0; 1349 for (int idx=end; idx<length; idx++) { 1350 switch (parameterizedTypeSignature[idx]) { 1351 case C_GENERIC_START: 1352 if (deep == 0) { 1353 int size = idx-start; 1354 System.arraycopy(parameterizedTypeSignature, start, result, pos, size); 1355 end = idx; 1356 pos += size; 1357 } 1358 deep++; 1359 break; 1360 case C_GENERIC_END: 1361 deep--; 1362 if (deep < 0) throw new IllegalArgumentException (); 1363 if (deep == 0) start = idx+1; 1364 break; 1365 } 1366 } 1367 if (deep > 0) throw new IllegalArgumentException (); 1368 int size = pos+length-start; 1369 char[] resized = new char[size]; 1370 System.arraycopy(result, 0, resized, 0, pos); 1371 System.arraycopy(parameterizedTypeSignature, start, resized, pos, length-start); 1372 return resized; 1373} 1374 1375 1386public static String getTypeErasure(String parameterizedTypeSignature) throws IllegalArgumentException { 1387 return new String (getTypeErasure(parameterizedTypeSignature.toCharArray())); 1388} 1389 1390 1401public static char[][] getTypeParameters(char[] methodOrTypeSignature) throws IllegalArgumentException { 1402 try { 1403 int length = methodOrTypeSignature.length; 1404 if (length == 0) return CharOperation.NO_CHAR_CHAR; 1405 if (methodOrTypeSignature[0] != C_GENERIC_START) return CharOperation.NO_CHAR_CHAR; 1406 1407 ArrayList paramList = new ArrayList (1); 1408 int paramStart = 1, i = 1; while (i < length) { 1410 if (methodOrTypeSignature[i] == C_GENERIC_END) { 1411 int size = paramList.size(); 1412 if (size == 0) throw new IllegalArgumentException (); 1413 char[][] result; 1414 paramList.toArray(result = new char[size][]); 1415 return result; 1416 } 1417 i = CharOperation.indexOf(C_COLON, methodOrTypeSignature, i); 1418 if (i < 0 || i >= length) 1419 throw new IllegalArgumentException (); 1420 while (methodOrTypeSignature[i] == ':') { 1422 i++; switch (methodOrTypeSignature[i]) { 1424 case ':': 1425 break; 1427 case C_GENERIC_END: 1428 break; 1429 case C_RESOLVED: 1430 try { 1431 i = Util.scanClassTypeSignature(methodOrTypeSignature, i); 1432 i++; } catch (IllegalArgumentException e) { 1434 } 1436 break; 1437 case C_ARRAY: 1438 try { 1439 i = Util.scanArrayTypeSignature(methodOrTypeSignature, i); 1440 i++; } catch (IllegalArgumentException e) { 1442 } 1444 break; 1445 case C_TYPE_VARIABLE: 1446 try { 1447 i = Util.scanTypeVariableSignature(methodOrTypeSignature, i); 1448 i++; } catch (IllegalArgumentException e) { 1450 } 1452 break; 1453 } 1455 } 1456 paramList.add(CharOperation.subarray(methodOrTypeSignature, paramStart, i)); 1457 paramStart = i; } 1459 } catch (ArrayIndexOutOfBoundsException e) { 1460 } 1462 throw new IllegalArgumentException (); 1463} 1464 1475public static String [] getTypeParameters(String methodOrTypeSignature) throws IllegalArgumentException { 1476 char[][] params = getTypeParameters(methodOrTypeSignature.toCharArray()); 1477 return CharOperation.toStrings(params); 1478} 1479 1480 1490public static String getTypeVariable(String formalTypeParameterSignature) throws IllegalArgumentException { 1491 return new String (getTypeVariable(formalTypeParameterSignature.toCharArray())); 1492} 1493 1494 1504public static char[] getTypeVariable(char[] formalTypeParameterSignature) throws IllegalArgumentException { 1505 int p = CharOperation.indexOf(C_COLON, formalTypeParameterSignature); 1506 if (p < 0) { 1507 throw new IllegalArgumentException (); 1509 } 1510 return CharOperation.subarray(formalTypeParameterSignature, 0, p); 1511} 1512 1513 1524public static char[][] getTypeParameterBounds(char[] formalTypeParameterSignature) throws IllegalArgumentException { 1525 int p1 = CharOperation.indexOf(C_COLON, formalTypeParameterSignature); 1526 if (p1 < 0) { 1527 throw new IllegalArgumentException (); 1529 } 1530 if (p1 == formalTypeParameterSignature.length - 1) { 1531 return CharOperation.NO_CHAR_CHAR; 1533 } 1534 int p2 = CharOperation.indexOf(C_COLON, formalTypeParameterSignature, p1 + 1); 1535 char[] classBound; 1536 if (p2 < 0) { 1537 classBound = CharOperation.subarray(formalTypeParameterSignature, p1 + 1, formalTypeParameterSignature.length); 1539 return new char[][] {classBound}; 1540 } 1541 if (p2 == p1 + 1) { 1542 classBound = null; 1544 } else { 1545 classBound = CharOperation.subarray(formalTypeParameterSignature, p1 + 1, p2); 1546 } 1547 char[][] interfaceBounds = CharOperation.splitOn(C_COLON, formalTypeParameterSignature, p2 + 1, formalTypeParameterSignature.length); 1548 if (classBound == null) { 1549 return interfaceBounds; 1550 } 1551 int resultLength = interfaceBounds.length + 1; 1552 char[][] result = new char[resultLength][]; 1553 result[0] = classBound; 1554 System.arraycopy(interfaceBounds, 0, result, 1, interfaceBounds.length); 1555 return result; 1556} 1557 1558 1569public static String [] getTypeParameterBounds(String formalTypeParameterSignature) throws IllegalArgumentException { 1570 char[][] bounds = getTypeParameterBounds(formalTypeParameterSignature.toCharArray()); 1571 return CharOperation.toStrings(bounds); 1572} 1573 1574 1594public static char[] getQualifier(char[] name) { 1595 int firstGenericStart = CharOperation.indexOf(C_GENERIC_START, name); 1596 int lastDot = CharOperation.lastIndexOf(C_DOT, name, 0, firstGenericStart == -1 ? name.length-1 : firstGenericStart); 1597 if (lastDot == -1) { 1598 return CharOperation.NO_CHAR; 1599 } 1600 return CharOperation.subarray(name, 0, lastDot); 1601} 1602 1621public static String getQualifier(String name) { 1622 char[] qualifier = getQualifier(name.toCharArray()); 1623 if (qualifier.length == 0) return org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING; 1624 return new String (qualifier); 1625} 1626 1637public static char[] getReturnType(char[] methodSignature) throws IllegalArgumentException { 1638 int paren = CharOperation.lastIndexOf(C_PARAM_END, methodSignature); 1640 if (paren == -1) { 1641 throw new IllegalArgumentException (); 1642 } 1643 int last = Util.scanTypeSignature(methodSignature, paren+1); 1645 return CharOperation.subarray(methodSignature, paren + 1, last+1); 1646} 1647 1656public static String getReturnType(String methodSignature) throws IllegalArgumentException { 1657 return new String (getReturnType(methodSignature.toCharArray())); 1658} 1659 1675public static char[] getSignatureQualifier(char[] typeSignature) { 1676 if(typeSignature == null) return CharOperation.NO_CHAR; 1677 1678 char[] qualifiedType = Signature.toCharArray(typeSignature); 1679 1680 int dotCount = 0; 1681 indexFound: for(int i = 0; i < typeSignature.length; i++) { 1682 switch(typeSignature[i]) { 1683 case C_DOT: 1684 dotCount++; 1685 break; 1686 case C_GENERIC_START: 1687 break indexFound; 1688 case C_DOLLAR: 1689 break indexFound; 1690 } 1691 } 1692 1693 if(dotCount > 0) { 1694 for(int i = 0; i < qualifiedType.length; i++) { 1695 if(qualifiedType[i] == '.') { 1696 dotCount--; 1697 } 1698 if(dotCount <= 0) { 1699 return CharOperation.subarray(qualifiedType, 0, i); 1700 } 1701 } 1702 } 1703 return CharOperation.NO_CHAR; 1704} 1705 1721public static String getSignatureQualifier(String typeSignature) { 1722 return new String (getSignatureQualifier(typeSignature == null ? null : typeSignature.toCharArray())); 1723} 1724 1740public static char[] getSignatureSimpleName(char[] typeSignature) { 1741 if(typeSignature == null) return CharOperation.NO_CHAR; 1742 1743 char[] qualifiedType = Signature.toCharArray(typeSignature); 1744 1745 int dotCount = 0; 1746 indexFound: for(int i = 0; i < typeSignature.length; i++) { 1747 switch(typeSignature[i]) { 1748 case C_DOT: 1749 dotCount++; 1750 break; 1751 case C_GENERIC_START: 1752 break indexFound; 1753 case C_DOLLAR: 1754 break indexFound; 1755 } 1756 } 1757 1758 if(dotCount > 0) { 1759 for(int i = 0; i < qualifiedType.length; i++) { 1760 if(qualifiedType[i] == '.') { 1761 dotCount--; 1762 } 1763 if(dotCount <= 0) { 1764 return CharOperation.subarray(qualifiedType, i + 1, qualifiedType.length); 1765 } 1766 } 1767 } 1768 return qualifiedType; 1769} 1770 1786public static String getSignatureSimpleName(String typeSignature) { 1787 return new String (getSignatureSimpleName(typeSignature == null ? null : typeSignature.toCharArray())); 1788} 1789 1790 1807public static char[] getSimpleName(char[] name) { 1808 1809 int lastDot = -1, lastGenericStart = -1, lastGenericEnd = -1; 1810 int depth = 0; 1811 int length = name.length; 1812 lastDotLookup: for (int i = length -1; i >= 0; i--) { 1813 switch (name[i]) { 1814 case '.': 1815 if (depth == 0) { 1816 lastDot = i; 1817 break lastDotLookup; 1818 } 1819 break; 1820 case '<': 1821 depth--; 1822 if (depth == 0) lastGenericStart = i; 1823 break; 1824 case '>': 1825 if (depth == 0) lastGenericEnd = i; 1826 depth++; 1827 break; 1828 } 1829 } 1830 if (lastGenericStart < 0) { 1831 if (lastDot < 0) { 1832 return name; 1833 } 1834 return CharOperation.subarray(name, lastDot + 1, length); 1835 } 1836 StringBuffer buffer = new StringBuffer (10); 1837 int nameStart = lastDot < 0 ? 0 : lastDot+1; 1838 buffer.append(name, nameStart, lastGenericStart - nameStart); 1839 appendArgumentSimpleNames(name, lastGenericStart, lastGenericEnd, buffer); 1840 buffer.append(name, lastGenericEnd+1, length-lastGenericEnd-1); char[] result = new char[length = buffer.length()]; 1842 buffer.getChars(0, length, result, 0); 1843 return result; 1844} 1845 1864public static String getSimpleName(String name) { 1865 int lastDot = -1, lastGenericStart = -1, lastGenericEnd = -1; 1866 int depth = 0; 1867 int length = name.length(); 1868 lastDotLookup: for (int i = length -1; i >= 0; i--) { 1869 switch (name.charAt(i)) { 1870 case '.': 1871 if (depth == 0) { 1872 lastDot = i; 1873 break lastDotLookup; 1874 } 1875 break; 1876 case '<': 1877 depth--; 1878 if (depth == 0) lastGenericStart = i; 1879 break; 1880 case '>': 1881 if (depth == 0) lastGenericEnd = i; 1882 depth++; 1883 break; 1884 } 1885 } 1886 if (lastGenericStart < 0) { 1887 if (lastDot < 0) { 1888 return name; 1889 } 1890 return name.substring(lastDot + 1, length); 1891 } 1892 StringBuffer buffer = new StringBuffer (10); 1893 char[] nameChars = name.toCharArray(); 1894 int nameStart = lastDot < 0 ? 0 : lastDot+1; 1895 buffer.append(nameChars, nameStart, lastGenericStart - nameStart); 1896 appendArgumentSimpleNames(nameChars, lastGenericStart, lastGenericEnd, buffer); 1897 buffer.append(nameChars, lastGenericEnd+1, length-lastGenericEnd-1); return buffer.toString(); 1899} 1900 1901private static void appendSimpleName(char[] name, int start, int end, StringBuffer buffer) { 1902 int lastDot = -1, lastGenericStart = -1, lastGenericEnd = -1; 1903 int depth = 0; 1904 if (name[start] == '?') { buffer.append("?"); int index = consumeWhitespace(name, start+1, end+1); 1907 switch (name[index]) { 1908 case 'e' : 1909 int checkPos = checkName(EXTENDS, name, index, end); 1910 if (checkPos > 0) { 1911 buffer.append(' ').append(EXTENDS).append(' '); 1912 index = consumeWhitespace(name, checkPos, end+1); 1913 } 1914 break; 1915 case 's' : 1916 checkPos = checkName(SUPER, name, index, end+1); 1917 if (checkPos > 0) { 1918 buffer.append(' ').append(SUPER).append(' '); 1919 index = consumeWhitespace(name, checkPos, end+1); 1920 } 1921 break; 1922 } 1923 start = index; } 1925 lastDotLookup: for (int i = end; i >= start; i--) { 1926 switch (name[i]) { 1927 case '.': 1928 if (depth == 0) { 1929 lastDot = i; 1930 char c = name[start]; 1931 if (c == C_EXTENDS || c == C_SUPER) { 1932 buffer.append(c); 1933 } 1934 break lastDotLookup; 1935 } 1936 break; 1937 case '<': 1938 depth--; 1939 if (depth == 0) lastGenericStart = i; 1940 break; 1941 case '>': 1942 if (depth == 0) lastGenericEnd = i; 1943 depth++; 1944 break; 1945 } 1946 } 1947 int nameStart = lastDot < 0 ? start : lastDot+1; 1948 int nameEnd = lastGenericStart < 0 ? end+1 : lastGenericStart; 1949 buffer.append(name, nameStart, nameEnd - nameStart); 1950 if (lastGenericStart >= 0) { 1951 appendArgumentSimpleNames(name, lastGenericStart, lastGenericEnd, buffer); 1952 buffer.append(name, lastGenericEnd+1, end - lastGenericEnd); } 1954} 1955private static void appendArgumentSimpleNames(char[] name, int start, int end, StringBuffer buffer) { 1957 buffer.append('<'); 1958 int depth = 0; 1959 int argumentStart = -1; 1960 int argumentCount = 0; 1961 for (int i = start; i <= end; i++) { 1962 switch(name[i]) { 1963 case '<' : 1964 depth++; 1965 if (depth == 1) { 1966 argumentStart = i+1; 1967 } 1968 break; 1969 case '>' : 1970 if (depth == 1) { 1971 if (argumentCount > 0) buffer.append(','); 1972 appendSimpleName(name, argumentStart, i-1, buffer); 1973 argumentCount++; 1974 } 1975 depth--; 1976 break; 1977 case ',' : 1978 if (depth == 1) { 1979 if (argumentCount > 0) buffer.append(','); 1980 appendSimpleName(name, argumentStart, i-1, buffer); 1981 argumentCount++; 1982 argumentStart = i+1; 1983 } 1984 break; 1985 } 1986 } 1987 buffer.append('>'); 1988} 1989 2009public static char[][] getSimpleNames(char[] name) { 2010 int length = name == null ? 0 : name.length; 2011 if (length == 0) 2012 return CharOperation.NO_CHAR_CHAR; 2013 2014 int wordCount = 1; 2015 countingWords: for (int i = 0; i < length; i++) 2016 switch(name[i]) { 2017 case C_DOT: 2018 wordCount++; 2019 break; 2020 case C_GENERIC_START: 2021 break countingWords; 2022 } 2023 char[][] split = new char[wordCount][]; 2024 int last = 0, currentWord = 0; 2025 for (int i = 0; i < length; i++) { 2026 if (name[i] == C_GENERIC_START) break; 2027 if (name[i] == C_DOT) { 2028 split[currentWord] = new char[i - last]; 2029 System.arraycopy( 2030 name, 2031 last, 2032 split[currentWord++], 2033 0, 2034 i - last); 2035 last = i + 1; 2036 } 2037 } 2038 split[currentWord] = new char[length - last]; 2039 System.arraycopy(name, last, split[currentWord], 0, length - last); 2040 return split; 2041} 2042 2062public static String [] getSimpleNames(String name) { 2063 return CharOperation.toStrings(getSimpleNames(name.toCharArray())); 2064} 2065 2066 2088public static char[] removeCapture(char[] methodOrTypeSignature) { 2089 return CharOperation.remove(methodOrTypeSignature, C_CAPTURE); 2090} 2091 2092 2114public static String removeCapture(String methodOrTypeSignature) { 2115 char[] array = methodOrTypeSignature.toCharArray(); 2116 char[] result = removeCapture(array); 2117 if (array == result) return methodOrTypeSignature; 2118 return new String (result); 2119} 2120 2121 2147public static char[] toCharArray(char[] methodSignature, char[] methodName, char[][] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType) { 2148 return toCharArray(methodSignature, methodName, parameterNames, fullyQualifyTypeNames, includeReturnType, false); 2149} 2150 2178public static char[] toCharArray(char[] methodSignature, char[] methodName, char[][] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType, boolean isVargArgs) { 2179 int firstParen = CharOperation.indexOf(C_PARAM_START, methodSignature); 2180 if (firstParen == -1) { 2181 throw new IllegalArgumentException (); 2182 } 2183 2184 StringBuffer buffer = new StringBuffer (methodSignature.length + 10); 2185 2186 if (includeReturnType) { 2188 char[] rts = getReturnType(methodSignature); 2189 appendTypeSignature(rts, 0 , fullyQualifyTypeNames, buffer); 2190 buffer.append(' '); 2191 } 2192 2193 if (methodName != null) { 2195 buffer.append(methodName); 2196 } 2197 2198 buffer.append('('); 2200 char[][] pts = getParameterTypes(methodSignature); 2201 for (int i = 0, max = pts.length; i < max; i++) { 2202 if (i == max - 1) { 2203 appendTypeSignature(pts[i], 0 , fullyQualifyTypeNames, buffer, isVargArgs); 2204 } else { 2205 appendTypeSignature(pts[i], 0 , fullyQualifyTypeNames, buffer); 2206 } 2207 if (parameterNames != null) { 2208 buffer.append(' '); 2209 buffer.append(parameterNames[i]); 2210 } 2211 if (i != pts.length - 1) { 2212 buffer.append(','); 2213 buffer.append(' '); 2214 } 2215 } 2216 buffer.append(')'); 2217 char[] result = new char[buffer.length()]; 2218 buffer.getChars(0, buffer.length(), result, 0); 2219 return result; 2220} 2221 2250public static char[] toCharArray(char[] signature) throws IllegalArgumentException { 2251 int sigLength = signature.length; 2252 if (sigLength == 0 || signature[0] == C_PARAM_START || signature[0] == C_GENERIC_START) { 2253 return toCharArray(signature, CharOperation.NO_CHAR, null, true, true); 2254 } 2255 2256 StringBuffer buffer = new StringBuffer (signature.length + 10); 2257 appendTypeSignature(signature, 0, true, buffer); 2258 char[] result = new char[buffer.length()]; 2259 buffer.getChars(0, buffer.length(), result, 0); 2260 return result; 2261} 2262 2263 2277private static int appendTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) { 2278 return appendTypeSignature(string, start, fullyQualifyTypeNames, buffer, false); 2279} 2280 2297private static int appendTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer, boolean isVarArgs) { 2298 if (start >= string.length) { 2300 throw new IllegalArgumentException (); 2301 } 2302 char c = string[start]; 2303 if (isVarArgs) { 2304 switch (c) { 2305 case C_ARRAY : 2306 return appendArrayTypeSignature(string, start, fullyQualifyTypeNames, buffer, true); 2307 case C_RESOLVED : 2308 case C_UNRESOLVED : 2309 case C_TYPE_VARIABLE : 2310 case C_BOOLEAN : 2311 case C_BYTE : 2312 case C_CHAR : 2313 case C_DOUBLE : 2314 case C_FLOAT : 2315 case C_INT : 2316 case C_LONG : 2317 case C_SHORT : 2318 case C_VOID : 2319 case C_STAR: 2320 case C_EXTENDS: 2321 case C_SUPER: 2322 case C_CAPTURE: 2323 default: 2324 throw new IllegalArgumentException (); } 2326 } else { 2327 switch (c) { 2328 case C_ARRAY : 2329 return appendArrayTypeSignature(string, start, fullyQualifyTypeNames, buffer); 2330 case C_RESOLVED : 2331 case C_UNRESOLVED : 2332 return appendClassTypeSignature(string, start, fullyQualifyTypeNames, buffer); 2333 case C_TYPE_VARIABLE : 2334 int e = Util.scanTypeVariableSignature(string, start); 2335 buffer.append(string, start + 1, e - start - 1); 2336 return e; 2337 case C_BOOLEAN : 2338 buffer.append(BOOLEAN); 2339 return start; 2340 case C_BYTE : 2341 buffer.append(BYTE); 2342 return start; 2343 case C_CHAR : 2344 buffer.append(CHAR); 2345 return start; 2346 case C_DOUBLE : 2347 buffer.append(DOUBLE); 2348 return start; 2349 case C_FLOAT : 2350 buffer.append(FLOAT); 2351 return start; 2352 case C_INT : 2353 buffer.append(INT); 2354 return start; 2355 case C_LONG : 2356 buffer.append(LONG); 2357 return start; 2358 case C_SHORT : 2359 buffer.append(SHORT); 2360 return start; 2361 case C_VOID : 2362 buffer.append(VOID); 2363 return start; 2364 case C_CAPTURE : 2365 return appendCaptureTypeSignature(string, start, fullyQualifyTypeNames, buffer); 2366 case C_STAR: 2367 case C_EXTENDS: 2368 case C_SUPER: 2369 return appendTypeArgumentSignature(string, start, fullyQualifyTypeNames, buffer); 2370 default : 2371 throw new IllegalArgumentException (); 2372 } 2373 } 2374} 2375 2388private static int appendArrayTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) { 2389 return appendArrayTypeSignature(string, start, fullyQualifyTypeNames, buffer, false); 2390} 2391 2404private static int appendCaptureTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) { 2405 if (start >= string.length - 1) { 2407 throw new IllegalArgumentException (); 2408 } 2409 char c = string[start]; 2410 if (c != C_CAPTURE) { 2411 throw new IllegalArgumentException (); 2412 } 2413 buffer.append(CAPTURE).append(' '); 2414 return appendTypeArgumentSignature(string, start + 1, fullyQualifyTypeNames, buffer); 2415} 2416 2417 2432private static int appendArrayTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer, boolean isVarArgs) { 2433 int length = string.length; 2434 if (start >= length - 1) { 2436 throw new IllegalArgumentException (); 2437 } 2438 char c = string[start]; 2439 if (c != C_ARRAY) { 2440 throw new IllegalArgumentException (); 2441 } 2442 2443 int index = start; 2444 c = string[++index]; 2445 while(c == C_ARRAY) { 2446 if (index >= length - 1) { 2448 throw new IllegalArgumentException (); 2449 } 2450 c = string[++index]; 2451 } 2452 2453 int e = appendTypeSignature(string, index, fullyQualifyTypeNames, buffer); 2454 2455 for(int i = 1, dims = index - start; i < dims; i++) { 2456 buffer.append('[').append(']'); 2457 } 2458 2459 if (isVarArgs) { 2460 buffer.append('.').append('.').append('.'); 2461 } else { 2462 buffer.append('[').append(']'); 2463 } 2464 return e; 2465} 2466 2480private static int appendClassTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) { 2481 if (start >= string.length - 2) { 2483 throw new IllegalArgumentException (); 2484 } 2485 char c = string[start]; 2487 if (c != C_RESOLVED && c != C_UNRESOLVED) { 2488 throw new IllegalArgumentException (); 2489 } 2490 boolean resolved = (c == C_RESOLVED); 2491 boolean removePackageQualifiers = !fullyQualifyTypeNames; 2492 if (!resolved) { 2493 removePackageQualifiers = false; 2495 } 2496 int p = start + 1; 2497 int checkpoint = buffer.length(); 2498 int innerTypeStart = -1; 2499 boolean inAnonymousType = false; 2500 while (true) { 2501 if (p >= string.length) { 2502 throw new IllegalArgumentException (); 2503 } 2504 c = string[p]; 2505 switch(c) { 2506 case C_SEMICOLON : 2507 return p; 2509 case C_GENERIC_START : 2510 int e = appendTypeArgumentSignatures(string, p, fullyQualifyTypeNames, buffer); 2511 removePackageQualifiers = false; 2513 p = e; 2514 break; 2515 case C_DOT : 2516 if (removePackageQualifiers) { 2517 buffer.setLength(checkpoint); 2519 } else { 2520 buffer.append('.'); 2521 } 2522 break; 2523 case '/' : 2524 if (removePackageQualifiers) { 2525 buffer.setLength(checkpoint); 2527 } else { 2528 buffer.append('/'); 2529 } 2530 break; 2531 case C_DOLLAR : 2532 innerTypeStart = buffer.length(); 2533 inAnonymousType = false; 2534 if (resolved) { 2535 removePackageQualifiers = false; 2537 2543 buffer.append('.'); 2544 } 2545 break; 2546 default : 2547 if (innerTypeStart != -1 && !inAnonymousType && Character.isDigit(c)) { 2548 inAnonymousType = true; 2549 buffer.setLength(innerTypeStart); buffer.insert(checkpoint, "new "); buffer.append("(){}"); } 2553 if (!inAnonymousType) 2554 buffer.append(c); 2555 innerTypeStart = -1; 2556 } 2557 p++; 2558 } 2559} 2560 2561 2576private static int appendTypeArgumentSignatures(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) { 2577 if (start >= string.length - 1) { 2579 throw new IllegalArgumentException (); 2580 } 2581 char c = string[start]; 2582 if (c != C_GENERIC_START) { 2583 throw new IllegalArgumentException (); 2584 } 2585 buffer.append('<'); 2586 int p = start + 1; 2587 int count = 0; 2588 while (true) { 2589 if (p >= string.length) { 2590 throw new IllegalArgumentException (); 2591 } 2592 c = string[p]; 2593 if (c == C_GENERIC_END) { 2594 buffer.append('>'); 2595 return p; 2596 } 2597 if (count != 0) { 2598 buffer.append(','); 2599 } 2600 int e = appendTypeArgumentSignature(string, p, fullyQualifyTypeNames, buffer); 2601 count++; 2602 p = e + 1; 2603 } 2604} 2605 2606 2620private static int appendTypeArgumentSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) { 2621 if (start >= string.length) { 2623 throw new IllegalArgumentException (); 2624 } 2625 char c = string[start]; 2626 switch(c) { 2627 case C_STAR : 2628 buffer.append('?'); 2629 return start; 2630 case C_EXTENDS : 2631 buffer.append("? extends "); return appendTypeSignature(string, start + 1, fullyQualifyTypeNames, buffer); 2633 case C_SUPER : 2634 buffer.append("? super "); return appendTypeSignature(string, start + 1, fullyQualifyTypeNames, buffer); 2636 default : 2637 return appendTypeSignature(string, start, fullyQualifyTypeNames, buffer); 2638 } 2639} 2640 2641 2659public static char[] toQualifiedName(char[][] segments) { 2660 int length = segments.length; 2661 if (length == 0) return CharOperation.NO_CHAR; 2662 if (length == 1) return segments[0]; 2663 2664 int resultLength = 0; 2665 for (int i = 0; i < length; i++) { 2666 resultLength += segments[i].length+1; 2667 } 2668 resultLength--; 2669 char[] result = new char[resultLength]; 2670 int index = 0; 2671 for (int i = 0; i < length; i++) { 2672 char[] segment = segments[i]; 2673 int segmentLength = segment.length; 2674 System.arraycopy(segment, 0, result, index, segmentLength); 2675 index += segmentLength; 2676 if (i != length-1) { 2677 result[index++] = C_DOT; 2678 } 2679 } 2680 return result; 2681} 2682 2698public static String toQualifiedName(String [] segments) { 2699 int length = segments.length; 2700 char[][] charArrays = new char[length][]; 2701 for (int i = 0; i < length; i++) { 2702 charArrays[i] = segments[i].toCharArray(); 2703 } 2704 return new String (toQualifiedName(charArrays)); 2705} 2706 2733public static String toString(String signature) throws IllegalArgumentException { 2734 return new String (toCharArray(signature.toCharArray())); 2735} 2736 2753public static String toString(String methodSignature, String methodName, String [] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType) { 2754 return toString(methodSignature, methodName, parameterNames, fullyQualifyTypeNames, includeReturnType, false); 2755} 2756 2777public static String toString(String methodSignature, String methodName, String [] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType, boolean isVarArgs) { 2778 char[][] params; 2779 if (parameterNames == null) { 2780 params = null; 2781 } else { 2782 int paramLength = parameterNames.length; 2783 params = new char[paramLength][]; 2784 for (int i = 0; i < paramLength; i++) { 2785 params[i] = parameterNames[i].toCharArray(); 2786 } 2787 } 2788 return new String (toCharArray(methodSignature.toCharArray(), methodName == null ? null : methodName.toCharArray(), params, fullyQualifyTypeNames, includeReturnType, isVarArgs)); 2789} 2790} 2791 | Popular Tags |