1 11 package org.eclipse.jdt.internal.core.search.indexing; 12 13 import org.eclipse.jdt.core.Signature; 14 import org.eclipse.jdt.core.compiler.CharOperation; 15 import org.eclipse.jdt.core.search.SearchDocument; 16 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 17 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 18 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; 19 import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; 20 import org.eclipse.jdt.internal.compiler.classfmt.FieldInfo; 21 import org.eclipse.jdt.internal.compiler.classfmt.MethodInfo; 22 import org.eclipse.jdt.internal.compiler.env.ClassSignature; 23 import org.eclipse.jdt.internal.compiler.env.EnumConstantSignature; 24 import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation; 25 import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair; 26 import org.eclipse.jdt.internal.compiler.lookup.TagBits; 27 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 28 import org.eclipse.jdt.internal.compiler.util.SuffixConstants; 29 import org.eclipse.jdt.internal.core.util.Util; 30 31 public class BinaryIndexer extends AbstractIndexer implements SuffixConstants { 32 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[] BOOLEAN = "boolean".toCharArray(); private static final char[] VOID = "void".toCharArray(); private static final char[] INIT = "<init>".toCharArray(); 43 public BinaryIndexer(SearchDocument document) { 44 super(document); 45 } 46 private void addBinaryStandardAnnotations(long annotationTagBits) { 47 if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0) { 48 char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_TARGET; 49 addTypeReference(compoundName[compoundName.length-1]); 50 addBinaryTargetAnnotation(annotationTagBits); 51 } 52 if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0) { 53 char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTION; 54 addTypeReference(compoundName[compoundName.length-1]); 55 addBinaryRetentionAnnotation(annotationTagBits); 56 } 57 if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0) { 58 char[][] compoundName = TypeConstants.JAVA_LANG_DEPRECATED; 59 addTypeReference(compoundName[compoundName.length-1]); 60 } 61 if ((annotationTagBits & TagBits.AnnotationDocumented) != 0) { 62 char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED; 63 addTypeReference(compoundName[compoundName.length-1]); 64 } 65 if ((annotationTagBits & TagBits.AnnotationInherited) != 0) { 66 char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_INHERITED; 67 addTypeReference(compoundName[compoundName.length-1]); 68 } 69 if ((annotationTagBits & TagBits.AnnotationOverride) != 0) { 70 char[][] compoundName = TypeConstants.JAVA_LANG_OVERRIDE; 71 addTypeReference(compoundName[compoundName.length-1]); 72 } 73 if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0) { 74 char[][] compoundName = TypeConstants.JAVA_LANG_SUPPRESSWARNINGS; 75 addTypeReference(compoundName[compoundName.length-1]); 76 } 77 } 78 private void addBinaryTargetAnnotation(long bits) { 79 char[][] compoundName = null; 80 if ((bits & TagBits.AnnotationForAnnotationType) != 0) { 81 compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE; 82 addTypeReference(compoundName[compoundName.length-1]); 83 addFieldReference(TypeConstants.UPPER_ANNOTATION_TYPE); 84 } 85 if ((bits & TagBits.AnnotationForConstructor) != 0) { 86 if (compoundName == null) { 87 compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE; 88 addTypeReference(compoundName[compoundName.length-1]); 89 } 90 addFieldReference(TypeConstants.UPPER_CONSTRUCTOR); 91 } 92 if ((bits & TagBits.AnnotationForField) != 0) { 93 if (compoundName == null) { 94 compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE; 95 addTypeReference(compoundName[compoundName.length-1]); 96 } 97 addFieldReference(TypeConstants.UPPER_FIELD); 98 } 99 if ((bits & TagBits.AnnotationForLocalVariable) != 0) { 100 if (compoundName == null) { 101 compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE; 102 addTypeReference(compoundName[compoundName.length-1]); 103 } 104 addFieldReference(TypeConstants.UPPER_LOCAL_VARIABLE); 105 } 106 if ((bits & TagBits.AnnotationForMethod) != 0) { 107 if (compoundName == null) { 108 compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE; 109 addTypeReference(compoundName[compoundName.length-1]); 110 } 111 addFieldReference(TypeConstants.UPPER_METHOD); 112 } 113 if ((bits & TagBits.AnnotationForPackage) != 0) { 114 if (compoundName == null) { 115 compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE; 116 addTypeReference(compoundName[compoundName.length-1]); 117 } 118 addFieldReference(TypeConstants.UPPER_PACKAGE); 119 } 120 if ((bits & TagBits.AnnotationForParameter) != 0) { 121 if (compoundName == null) { 122 compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE; 123 addTypeReference(compoundName[compoundName.length-1]); 124 } 125 addFieldReference(TypeConstants.UPPER_PARAMETER); 126 } 127 if ((bits & TagBits.AnnotationForType) != 0) { 128 if (compoundName == null) { 129 compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE; 130 addTypeReference(compoundName[compoundName.length-1]); 131 } 132 addFieldReference(TypeConstants.TYPE); 133 } 134 } 135 private void addBinaryRetentionAnnotation(long bits) { 136 char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY; 137 addTypeReference(compoundName[compoundName.length-1]); 138 if ((bits & TagBits.AnnotationRuntimeRetention) != 0) { 139 addFieldReference(TypeConstants.UPPER_RUNTIME); 140 } 141 else if ((bits & TagBits.AnnotationClassRetention) != 0) { 142 addFieldReference(TypeConstants.UPPER_CLASS); 143 } 144 else if ((bits & TagBits.AnnotationSourceRetention) != 0) { 145 addFieldReference(TypeConstants.UPPER_SOURCE); 146 } 147 } 148 private void addBinaryAnnotation(IBinaryAnnotation annotation) { 149 addTypeReference(replace('/', '.', Signature.toCharArray(annotation.getTypeName()))); 150 IBinaryElementValuePair[] valuePairs = annotation.getElementValuePairs(); 151 if (valuePairs != null) { 152 for (int j=0, vpLength=valuePairs.length; j<vpLength; j++) { 153 IBinaryElementValuePair valuePair = valuePairs[j]; 154 addMethodReference(valuePair.getName(), 0); 155 Object pairValue = valuePair.getValue(); 156 addPairValue(pairValue); 157 } 158 } 159 } 160 private void addPairValue(Object pairValue) { 161 if (pairValue instanceof EnumConstantSignature) { 162 EnumConstantSignature enumConstant = (EnumConstantSignature) pairValue; 163 addTypeReference(replace('/', '.', Signature.toCharArray(enumConstant.getTypeName()))); 164 addNameReference(enumConstant.getEnumConstantName()); 165 } else if (pairValue instanceof ClassSignature) { 166 ClassSignature classConstant = (ClassSignature) pairValue; 167 addTypeReference(replace('/', '.', Signature.toCharArray(classConstant.getTypeName()))); 168 } else if (pairValue instanceof IBinaryAnnotation) { 169 addBinaryAnnotation((IBinaryAnnotation) pairValue); 170 } else if (pairValue instanceof Object []) { 171 Object [] objects = (Object []) pairValue; 172 for (int i=0,l=objects.length; i<l; i++) { 173 addPairValue(objects[i]); 174 } 175 } 176 } 177 public void addTypeReference(char[] typeName) { 178 int length = typeName.length; 179 if (length > 2 && typeName[length - 2] == '$') { 180 switch (typeName[length - 1]) { 181 case '0' : 182 case '1' : 183 case '2' : 184 case '3' : 185 case '4' : 186 case '5' : 187 case '6' : 188 case '7' : 189 case '8' : 190 case '9' : 191 return; } 193 } 194 195 typeName = CharOperation.replaceOnCopy(typeName, '$', '.'); 199 super.addTypeReference(typeName); 200 } 201 206 private void convertToArrayType(char[][] parameterTypes, int counter, int arrayDim) { 207 int length = parameterTypes[counter].length; 208 char[] arrayType = new char[length + arrayDim*2]; 209 System.arraycopy(parameterTypes[counter], 0, arrayType, 0, length); 210 for (int i = 0; i < arrayDim; i++) { 211 arrayType[length + (i * 2)] = '['; 212 arrayType[length + (i * 2) + 1] = ']'; 213 } 214 parameterTypes[counter] = arrayType; 215 } 216 221 private char[] convertToArrayType(char[] typeName, int arrayDim) { 222 int length = typeName.length; 223 char[] arrayType = new char[length + arrayDim*2]; 224 System.arraycopy(typeName, 0, arrayType, 0, length); 225 for (int i = 0; i < arrayDim; i++) { 226 arrayType[length + (i * 2)] = '['; 227 arrayType[length + (i * 2) + 1] = ']'; 228 } 229 return arrayType; 230 } 231 private char[] decodeFieldType(char[] signature) throws ClassFormatException { 232 if (signature == null) return null; 233 int arrayDim = 0; 234 for (int i = 0, max = signature.length; i < max; i++) { 235 switch(signature[i]) { 236 case 'B': 237 if (arrayDim > 0) 238 return convertToArrayType(BYTE, arrayDim); 239 return BYTE; 240 241 case 'C': 242 if (arrayDim > 0) 243 return convertToArrayType(CHAR, arrayDim); 244 return CHAR; 245 246 case 'D': 247 if (arrayDim > 0) 248 return convertToArrayType(DOUBLE, arrayDim); 249 return DOUBLE; 250 251 case 'F': 252 if (arrayDim > 0) 253 return convertToArrayType(FLOAT, arrayDim); 254 return FLOAT; 255 256 case 'I': 257 if (arrayDim > 0) 258 return convertToArrayType(INT, arrayDim); 259 return INT; 260 261 case 'J': 262 if (arrayDim > 0) 263 return convertToArrayType(LONG, arrayDim); 264 return LONG; 265 266 case 'L': 267 int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1); 268 if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 269 if (arrayDim > 0) { 270 return convertToArrayType(replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)), arrayDim); 271 } 272 return replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)); 273 274 case 'S': 275 if (arrayDim > 0) 276 return convertToArrayType(SHORT, arrayDim); 277 return SHORT; 278 279 case 'Z': 280 if (arrayDim > 0) 281 return convertToArrayType(BOOLEAN, arrayDim); 282 return BOOLEAN; 283 284 case 'V': 285 return VOID; 286 287 case '[': 288 arrayDim++; 289 break; 290 291 default: 292 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 293 } 294 } 295 return null; 296 } 297 302 private char[][] decodeParameterTypes(char[] signature, boolean firstIsSynthetic) throws ClassFormatException { 303 if (signature == null) return null; 304 int indexOfClosingParen = CharOperation.lastIndexOf(')', signature); 305 if (indexOfClosingParen == 1) { 306 return null; 308 } 309 if (indexOfClosingParen == -1) { 310 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 311 } 312 char[][] parameterTypes = new char[3][]; 313 int parameterTypesCounter = 0; 314 int arrayDim = 0; 315 for (int i = 1; i < indexOfClosingParen; i++) { 316 if (parameterTypesCounter == parameterTypes.length) { 317 System.arraycopy(parameterTypes, 0, (parameterTypes = new char[parameterTypesCounter * 2][]), 0, parameterTypesCounter); 319 } 320 switch(signature[i]) { 321 case 'B': 322 parameterTypes[parameterTypesCounter++] = BYTE; 323 if (arrayDim > 0) 324 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 325 arrayDim = 0; 326 break; 327 328 case 'C': 329 parameterTypes[parameterTypesCounter++] = CHAR; 330 if (arrayDim > 0) 331 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 332 arrayDim = 0; 333 break; 334 335 case 'D': 336 parameterTypes[parameterTypesCounter++] = DOUBLE; 337 if (arrayDim > 0) 338 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 339 arrayDim = 0; 340 break; 341 342 case 'F': 343 parameterTypes[parameterTypesCounter++] = FLOAT; 344 if (arrayDim > 0) 345 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 346 arrayDim = 0; 347 break; 348 349 case 'I': 350 parameterTypes[parameterTypesCounter++] = INT; 351 if (arrayDim > 0) 352 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 353 arrayDim = 0; 354 break; 355 356 case 'J': 357 parameterTypes[parameterTypesCounter++] = LONG; 358 if (arrayDim > 0) 359 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 360 arrayDim = 0; 361 break; 362 363 case 'L': 364 int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1); 365 if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 366 if (firstIsSynthetic && parameterTypesCounter == 0) { 367 firstIsSynthetic = false; 369 } else { 370 parameterTypes[parameterTypesCounter++] = replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)); 371 if (arrayDim > 0) 372 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 373 } 374 i = indexOfSemiColon; 375 arrayDim = 0; 376 break; 377 378 case 'S': 379 parameterTypes[parameterTypesCounter++] = SHORT; 380 if (arrayDim > 0) 381 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 382 arrayDim = 0; 383 break; 384 385 case 'Z': 386 parameterTypes[parameterTypesCounter++] = BOOLEAN; 387 if (arrayDim > 0) 388 convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim); 389 arrayDim = 0; 390 break; 391 392 case '[': 393 arrayDim++; 394 break; 395 396 default: 397 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 398 } 399 } 400 if (parameterTypes.length != parameterTypesCounter) { 401 System.arraycopy(parameterTypes, 0, parameterTypes = new char[parameterTypesCounter][], 0, parameterTypesCounter); 402 } 403 return parameterTypes; 404 } 405 private char[] decodeReturnType(char[] signature) throws ClassFormatException { 406 if (signature == null) return null; 407 int indexOfClosingParen = CharOperation.lastIndexOf(')', signature); 408 if (indexOfClosingParen == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 409 int arrayDim = 0; 410 for (int i = indexOfClosingParen + 1, max = signature.length; i < max; i++) { 411 switch(signature[i]) { 412 case 'B': 413 if (arrayDim > 0) 414 return convertToArrayType(BYTE, arrayDim); 415 return BYTE; 416 417 case 'C': 418 if (arrayDim > 0) 419 return convertToArrayType(CHAR, arrayDim); 420 return CHAR; 421 422 case 'D': 423 if (arrayDim > 0) 424 return convertToArrayType(DOUBLE, arrayDim); 425 return DOUBLE; 426 427 case 'F': 428 if (arrayDim > 0) 429 return convertToArrayType(FLOAT, arrayDim); 430 return FLOAT; 431 432 case 'I': 433 if (arrayDim > 0) 434 return convertToArrayType(INT, arrayDim); 435 return INT; 436 437 case 'J': 438 if (arrayDim > 0) 439 return convertToArrayType(LONG, arrayDim); 440 return LONG; 441 442 case 'L': 443 int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1); 444 if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 445 if (arrayDim > 0) { 446 return convertToArrayType(replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)), arrayDim); 447 } 448 return replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)); 449 450 case 'S': 451 if (arrayDim > 0) 452 return convertToArrayType(SHORT, arrayDim); 453 return SHORT; 454 455 case 'Z': 456 if (arrayDim > 0) 457 return convertToArrayType(BOOLEAN, arrayDim); 458 return BOOLEAN; 459 460 case 'V': 461 return VOID; 462 463 case '[': 464 arrayDim++; 465 break; 466 467 default: 468 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 469 } 470 } 471 return null; 472 } 473 private int extractArgCount(char[] signature, char[] className) throws ClassFormatException { 474 int indexOfClosingParen = CharOperation.lastIndexOf(')', signature); 475 if (indexOfClosingParen == 1) { 476 return 0; 478 } 479 if (indexOfClosingParen == -1) { 480 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 481 } 482 int parameterTypesCounter = 0; 483 for (int i = 1; i < indexOfClosingParen; i++) { 484 switch(signature[i]) { 485 case 'B': 486 case 'C': 487 case 'D': 488 case 'F': 489 case 'I': 490 case 'J': 491 case 'S': 492 case 'Z': 493 parameterTypesCounter++; 494 break; 495 case 'L': 496 int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1); 497 if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 498 if (className != null && parameterTypesCounter == 0) { 500 char[] classSignature = Signature.createCharArrayTypeSignature(className, true); 501 int length = indexOfSemiColon-i+1; 502 if (classSignature.length > (length+1)) { 503 for (int j=i, k=0; j<indexOfSemiColon; j++, k++) { 505 if (!(signature[j] == classSignature[k] || (signature[j] == '/' && classSignature[k] == '.' ))) { 506 parameterTypesCounter++; 507 break; 508 } 509 } 510 } else { 511 parameterTypesCounter++; 512 } 513 className = null; } else { 515 parameterTypesCounter++; 516 } 517 i = indexOfSemiColon; 518 break; 519 case '[': 520 break; 521 default: 522 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature); 523 } 524 } 525 return parameterTypesCounter; 526 } 527 private char[] extractClassName(int[] constantPoolOffsets, ClassFileReader reader, int index) { 528 int class_index = reader.u2At(constantPoolOffsets[index] + 1); 530 int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[class_index] + 1)]; 531 return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1)); 532 } 533 private char[] extractName(int[] constantPoolOffsets, ClassFileReader reader, int index) { 534 int nameAndTypeIndex = reader.u2At(constantPoolOffsets[index] + 3); 535 int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[nameAndTypeIndex] + 1)]; 536 return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1)); 537 } 538 private char[] extractClassReference(int[] constantPoolOffsets, ClassFileReader reader, int index) { 539 int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[index] + 1)]; 541 return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1)); 542 } 543 546 private void extractReferenceFromConstantPool(byte[] contents, ClassFileReader reader) throws ClassFormatException { 547 int[] constantPoolOffsets = reader.getConstantPoolOffsets(); 548 int constantPoolCount = constantPoolOffsets.length; 549 for (int i = 1; i < constantPoolCount; i++) { 550 int tag = reader.u1At(constantPoolOffsets[i]); 551 556 char[] name = null; 557 char[] type = null; 558 switch (tag) { 559 case ClassFileConstants.FieldRefTag : 560 name = extractName(constantPoolOffsets, reader, i); 562 addFieldReference(name); 563 break; 564 case ClassFileConstants.MethodRefTag : 565 case ClassFileConstants.InterfaceMethodRefTag : 567 name = extractName(constantPoolOffsets, reader, i); 569 type = extractType(constantPoolOffsets, reader, i); 570 if (CharOperation.equals(INIT, name)) { 571 char[] className = extractClassName(constantPoolOffsets, reader, i); 573 boolean localType = false; 574 if (className != null) { 575 for (int c = 0, max = className.length; c < max; c++) { 576 switch (className[c]) { 577 case '/': 578 className[c] = '.'; 579 break; 580 case '$': 581 localType = true; 582 break; 583 } 584 } 585 } 586 addConstructorReference(className, extractArgCount(type, localType?className:null)); 588 } else { 589 addMethodReference(name, extractArgCount(type, null)); 591 } 592 break; 593 case ClassFileConstants.ClassTag : 594 name = extractClassReference(constantPoolOffsets, reader, i); 596 if (name.length > 0 && name[0] == '[') 597 break; name = replace('/', '.', name); addTypeReference(name); 600 601 char[][] qualification = CharOperation.splitOn('.', name); 603 for (int j = 0, length = qualification.length; j < length; j++) { 604 addNameReference(qualification[j]); 605 } 606 break; 607 } 608 } 609 } 610 private char[] extractType(int[] constantPoolOffsets, ClassFileReader reader, int index) { 611 int constantPoolIndex = reader.u2At(constantPoolOffsets[index] + 3); 612 int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[constantPoolIndex] + 3)]; 613 return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1)); 614 } 615 public void indexDocument() { 616 try { 617 final byte[] contents = this.document.getByteContents(); 618 if (contents == null) return; 621 final String path = this.document.getPath(); 622 ClassFileReader reader = new ClassFileReader(contents, path == null ? null : path.toCharArray()); 623 624 char[] className = replace('/', '.', reader.getName()); int packageNameIndex = CharOperation.lastIndexOf('.', className); 628 char[] packageName = null; 629 char[] name = null; 630 if (packageNameIndex >= 0) { 631 packageName = CharOperation.subarray(className, 0, packageNameIndex); 632 name = CharOperation.subarray(className, packageNameIndex + 1, className.length); 633 } else { 634 packageName = CharOperation.NO_CHAR; 635 name = className; 636 } 637 char[] enclosingTypeName = null; 638 boolean isNestedType = reader.isNestedType(); 639 if (isNestedType) { 640 if (reader.isAnonymous()) { 641 name = CharOperation.NO_CHAR; 642 } else { 643 name = reader.getInnerSourceName(); 644 } 645 if (reader.isLocal() || reader.isAnonymous()) { 646 enclosingTypeName = ONE_ZERO; 648 } else { 649 char[] fullEnclosingName = reader.getEnclosingTypeName(); 650 int nameLength = fullEnclosingName.length - packageNameIndex - 1; 651 if (nameLength <= 0) { 652 return; 654 } 655 enclosingTypeName = new char[nameLength]; 656 System.arraycopy(fullEnclosingName, packageNameIndex + 1, enclosingTypeName, 0, nameLength); 657 } 658 } 659 char[][] typeParameterSignatures = null; 661 char[] genericSignature = reader.getGenericSignature(); 662 if (genericSignature != null) { 663 CharOperation.replace(genericSignature, '/', '.'); 664 typeParameterSignatures = Signature.getTypeParameters(genericSignature); 665 } 666 667 if (name == null) return; 669 670 char[][] superinterfaces = replace('/', '.', reader.getInterfaceNames()); 671 char[][] enclosingTypeNames = enclosingTypeName == null ? null : new char[][] {enclosingTypeName}; 672 int modifiers = reader.getModifiers(); 673 switch (TypeDeclaration.kind(modifiers)) { 674 case TypeDeclaration.CLASS_DECL : 675 char[] superclass = replace('/', '.', reader.getSuperclassName()); 676 addClassDeclaration(modifiers, packageName, name, enclosingTypeNames, superclass, superinterfaces, typeParameterSignatures, false); 677 break; 678 case TypeDeclaration.INTERFACE_DECL : 679 addInterfaceDeclaration(modifiers, packageName, name, enclosingTypeNames, superinterfaces, typeParameterSignatures, false); 680 break; 681 case TypeDeclaration.ENUM_DECL : 682 superclass = replace('/', '.', reader.getSuperclassName()); 683 addEnumDeclaration(modifiers, packageName, name, enclosingTypeNames, superclass, superinterfaces, false); 684 break; 685 case TypeDeclaration.ANNOTATION_TYPE_DECL : 686 addAnnotationTypeDeclaration(modifiers, packageName, name, enclosingTypeNames, false); 687 break; 688 } 689 690 IBinaryAnnotation[] annotations = reader.getAnnotations(); 692 if (annotations != null) { 693 for (int a=0, length=annotations.length; a<length; a++) { 694 IBinaryAnnotation annotation = annotations[a]; 695 addBinaryAnnotation(annotation); 696 } 697 } 698 long tagBits = reader.getTagBits() & TagBits.AllStandardAnnotationsMask; 699 if (tagBits != 0) { 700 addBinaryStandardAnnotations(tagBits); 701 } 702 703 MethodInfo[] methods = (MethodInfo[]) reader.getMethods(); 705 if (methods != null) { 706 for (int i = 0, max = methods.length; i < max; i++) { 707 MethodInfo method = methods[i]; 708 boolean isConstructor = method.isConstructor(); 709 char[] descriptor = method.getMethodDescriptor(); 710 char[][] parameterTypes = decodeParameterTypes(descriptor, isConstructor && isNestedType); 711 char[] returnType = decodeReturnType(descriptor); 712 char[][] exceptionTypes = replace('/', '.', method.getExceptionTypeNames()); 713 if (isConstructor) { 714 addConstructorDeclaration(className, parameterTypes, exceptionTypes); 715 } else { 716 if (!method.isClinit()) { 717 addMethodDeclaration(method.getSelector(), parameterTypes, returnType, exceptionTypes); 718 } 719 } 720 annotations = method.getAnnotations(); 722 if (annotations != null) { 723 for (int a=0, length=annotations.length; a<length; a++) { 724 IBinaryAnnotation annotation = annotations[a]; 725 addBinaryAnnotation(annotation); 726 } 727 } 728 } 729 } 730 FieldInfo[] fields = (FieldInfo[]) reader.getFields(); 731 if (fields != null) { 732 for (int i = 0, max = fields.length; i < max; i++) { 733 FieldInfo field = fields[i]; 734 char[] fieldName = field.getName(); 735 char[] fieldType = decodeFieldType(replace('/', '.', field.getTypeName())); 736 addFieldDeclaration(fieldType, fieldName); 737 annotations = field.getAnnotations(); 739 if (annotations != null) { 740 for (int a=0, length=annotations.length; a<length; a++) { 741 IBinaryAnnotation annotation = annotations[a]; 742 addBinaryAnnotation(annotation); 743 } 744 } 745 } 746 } 747 extractReferenceFromConstantPool(contents, reader); 749 } catch (ClassFormatException e) { 750 this.document.removeAllIndexEntries(); 752 Util.log(e, "ClassFormatException in " + this.document.getPath() + ". Please report this issue to JDT/Core including the problematic document"); } catch (RuntimeException e) { 754 this.document.removeAllIndexEntries(); 758 Util.log(e, "Indexer crashed on document " + this.document.getPath() + ". Please report this issue to JDT/Core including the problematic document"); } 760 } 761 764 private char[][] replace(char toBeReplaced, char newChar, char[][] array) { 765 if (array == null) return null; 766 for (int i = 0, max = array.length; i < max; i++) { 767 replace(toBeReplaced, newChar, array[i]); 768 } 769 return array; 770 } 771 774 private char[] replace(char toBeReplaced, char newChar, char[] array) { 775 if (array == null) return null; 776 for (int i = 0, max = array.length; i < max; i++) { 777 if (array[i] == toBeReplaced) { 778 array[i] = newChar; 779 } 780 } 781 return array; 782 } 783 } 784 | Popular Tags |