1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import java.util.Arrays ; 14 import java.util.Comparator ; 15 16 import org.eclipse.jdt.core.compiler.CharOperation; 17 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; 18 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 19 import org.eclipse.jdt.internal.compiler.env.IDependent; 20 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; 21 22 32 33 abstract public class ReferenceBinding extends TypeBinding implements IDependent { 34 35 public char[][] compoundName; 36 public char[] sourceName; 37 public int modifiers; 38 public PackageBinding fPackage; 39 char[] fileName; 40 char[] constantPoolName; 41 char[] signature; 42 43 private SimpleLookupTable compatibleCache; 44 45 public static ReferenceBinding LUB_GENERIC = new ReferenceBinding() { }; 46 47 private static final Comparator FIELD_COMPARATOR = new Comparator () { 48 public int compare(Object o1, Object o2) { 49 char[] n1 = ((FieldBinding) o1).name; 50 char[] n2 = ((FieldBinding) o2).name; 51 return ReferenceBinding.compare(n1, n2, n1.length, n2.length); 52 } 53 }; 54 private static final Comparator METHOD_COMPARATOR = new Comparator () { 55 public int compare(Object o1, Object o2) { 56 MethodBinding m1 = (MethodBinding) o1; 57 MethodBinding m2 = (MethodBinding) o2; 58 char[] s1 = m1.selector; 59 char[] s2 = m2.selector; 60 int c = ReferenceBinding.compare(s1, s2, s1.length, s2.length); 61 return c == 0 ? m1.parameters.length - m2.parameters.length : c; 62 } 63 }; 64 65 public static FieldBinding binarySearch(char[] name, FieldBinding[] sortedFields) { 66 if (sortedFields == null) 67 return null; 68 int max = sortedFields.length; 69 if (max == 0) 70 return null; 71 int left = 0, right = max - 1, nameLength = name.length; 72 int mid = 0; 73 char[] midName; 74 while (left <= right) { 75 mid = left + (right - left) /2; 76 int compare = compare(name, midName = sortedFields[mid].name, nameLength, midName.length); 77 if (compare < 0) { 78 right = mid-1; 79 } else if (compare > 0) { 80 left = mid+1; 81 } else { 82 return sortedFields[mid]; 83 } 84 } 85 return null; 86 } 87 88 97 public static long binarySearch(char[] selector, MethodBinding[] sortedMethods) { 98 if (sortedMethods == null) 99 return -1; 100 int max = sortedMethods.length; 101 if (max == 0) 102 return -1; 103 int left = 0, right = max - 1, selectorLength = selector.length; 104 int mid = 0; 105 char[] midSelector; 106 while (left <= right) { 107 mid = left + (right - left) /2; 108 int compare = compare(selector, midSelector = sortedMethods[mid].selector, selectorLength, midSelector.length); 109 if (compare < 0) { 110 right = mid-1; 111 } else if (compare > 0) { 112 left = mid+1; 113 } else { 114 int start = mid, end = mid; 115 while (start > left && CharOperation.equals(sortedMethods[start-1].selector, selector)){ start--; } 117 while (end < right && CharOperation.equals(sortedMethods[end+1].selector, selector)){ end++; } 119 return start + ((long)end<< 32); 120 } 121 } 122 return -1; 123 } 124 125 136 static int compare(char[] str1, char[] str2, int len1, int len2) { 137 int n= Math.min(len1, len2); 138 int i= 0; 139 while (n-- != 0) { 140 char c1= str1[i]; 141 char c2= str2[i++]; 142 if (c1 != c2) { 143 return c1 - c2; 144 } 145 } 146 return len1 - len2; 147 } 148 149 152 public static void sortFields(FieldBinding[] sortedFields, int left, int right) { 153 Arrays.sort(sortedFields, left, right, FIELD_COMPARATOR); 154 } 155 156 159 public static void sortMethods(MethodBinding[] sortedMethods, int left, int right) { 160 Arrays.sort(sortedMethods, left, right, METHOD_COMPARATOR); 161 } 162 163 166 public FieldBinding[] availableFields() { 167 return fields(); 168 } 169 170 173 public MethodBinding[] availableMethods() { 174 return methods(); 175 } 176 178 public boolean canBeInstantiated() { 179 return (this.modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation)) == 0; 180 } 181 183 public final boolean canBeSeenBy(PackageBinding invocationPackage) { 184 if (isPublic()) return true; 185 if (isPrivate()) return false; 186 187 return invocationPackage == this.fPackage; 189 } 190 192 193 public final boolean canBeSeenBy(ReferenceBinding receiverType, ReferenceBinding invocationType) { 194 if (isPublic()) return true; 195 196 if (invocationType == this && invocationType == receiverType) return true; 197 198 if (isProtected()) { 199 if (invocationType == this) return true; 205 if (invocationType.fPackage == this.fPackage) return true; 206 207 ReferenceBinding currentType = invocationType; 208 ReferenceBinding declaringClass = enclosingType(); if (declaringClass == invocationType) return true; 210 if (declaringClass == null) return false; do { 213 if (currentType.findSuperTypeWithSameErasure(declaringClass) != null) return true; 214 currentType = currentType.enclosingType(); 216 } while (currentType != null); 217 return false; 218 } 219 220 if (isPrivate()) { 221 receiverCheck: { 224 if (!(receiverType == this || receiverType == enclosingType())) { 225 if (receiverType.isTypeVariable()) { 227 TypeVariableBinding typeVariable = (TypeVariableBinding) receiverType; 228 if (typeVariable.isErasureBoundTo(this.erasure()) || typeVariable.isErasureBoundTo(enclosingType().erasure())) 229 break receiverCheck; 230 } 231 return false; 232 } 233 } 234 235 if (invocationType != this) { 236 ReferenceBinding outerInvocationType = invocationType; 237 ReferenceBinding temp = outerInvocationType.enclosingType(); 238 while (temp != null) { 239 outerInvocationType = temp; 240 temp = temp.enclosingType(); 241 } 242 243 ReferenceBinding outerDeclaringClass = (ReferenceBinding)this.erasure(); 244 temp = outerDeclaringClass.enclosingType(); 245 while (temp != null) { 246 outerDeclaringClass = temp; 247 temp = temp.enclosingType(); 248 } 249 if (outerInvocationType != outerDeclaringClass) return false; 250 } 251 return true; 252 } 253 254 if (invocationType.fPackage != this.fPackage) return false; 256 257 ReferenceBinding currentType = receiverType; 258 ReferenceBinding declaringClass = enclosingType() == null ? this : enclosingType(); 259 do { 260 if (declaringClass == currentType) return true; 261 PackageBinding currentPackage = currentType.fPackage; 262 if (currentPackage != null && currentPackage != this.fPackage) return false; 264 } while ((currentType = currentType.superclass()) != null); 265 return false; 266 } 267 270 public final boolean canBeSeenBy(Scope scope) { 271 if (isPublic()) return true; 272 273 SourceTypeBinding invocationType = scope.enclosingSourceType(); 274 if (invocationType == this) return true; 275 276 if (invocationType == null) return !isPrivate() && scope.getCurrentPackage() == this.fPackage; 278 279 if (isProtected()) { 280 if (invocationType.fPackage == this.fPackage) return true; 286 287 ReferenceBinding currentType = invocationType; 288 ReferenceBinding declaringClass = enclosingType(); if (declaringClass == null) return false; do { 292 if (declaringClass == invocationType) return true; 293 if (declaringClass.isSuperclassOf(currentType)) return true; 294 currentType = currentType.enclosingType(); 296 } while (currentType != null); 297 return false; 298 } 299 if (isPrivate()) { 300 ReferenceBinding outerInvocationType = invocationType; 303 ReferenceBinding temp = outerInvocationType.enclosingType(); 304 while (temp != null) { 305 outerInvocationType = temp; 306 temp = temp.enclosingType(); 307 } 308 309 ReferenceBinding outerDeclaringClass = (ReferenceBinding)this.erasure(); 310 temp = outerDeclaringClass.enclosingType(); 311 while (temp != null) { 312 outerDeclaringClass = temp; 313 temp = temp.enclosingType(); 314 } 315 return outerInvocationType == outerDeclaringClass; 316 } 317 318 return invocationType.fPackage == this.fPackage; 320 } 321 322 326 public ReferenceBinding closestMatch() { 327 return this; } 329 330 public char[] computeGenericTypeSignature(TypeVariableBinding[] typeVariables) { 331 332 boolean isMemberOfGeneric = isMemberType() && (enclosingType().modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0; 333 if (typeVariables == Binding.NO_TYPE_VARIABLES && !isMemberOfGeneric) { 334 return signature(); 335 } 336 StringBuffer sig = new StringBuffer (10); 337 if (isMemberOfGeneric) { 338 char[] typeSig = enclosingType().genericTypeSignature(); 339 for (int i = 0; i < typeSig.length-1; i++) { sig.append(typeSig[i]); 341 } 342 sig.append('.'); sig.append(this.sourceName); 344 } else { 345 char[] typeSig = signature(); 346 for (int i = 0; i < typeSig.length-1; i++) { sig.append(typeSig[i]); 348 } 349 } 350 if (typeVariables == Binding.NO_TYPE_VARIABLES) { 351 sig.append(';'); 352 } else { 353 sig.append('<'); 354 for (int i = 0, length = typeVariables.length; i < length; i++) { 355 sig.append(typeVariables[i].genericTypeSignature()); 356 } 357 sig.append(">;"); } 359 int sigLength = sig.length(); 360 char[] result = new char[sigLength]; 361 sig.getChars(0, sigLength, result, 0); 362 return result; 363 } 364 public void computeId() { 365 366 switch (this.compoundName.length) { 367 368 case 3 : 369 if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) 370 return; 371 372 if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1])) { 374 if (CharOperation.equals(TypeConstants.IO, this.compoundName[1])) { 375 if (CharOperation.equals(TypeConstants.JAVA_IO_PRINTSTREAM[2], this.compoundName[2])) 376 this.id = TypeIds.T_JavaIoPrintStream; 377 else if (CharOperation.equals(TypeConstants.JAVA_IO_SERIALIZABLE[2], this.compoundName[2])) 378 this.id = TypeIds.T_JavaIoSerializable; 379 else if (CharOperation.equals(TypeConstants.JAVA_IO_EXTERNALIZABLE[2], this.compoundName[2])) 380 this.id = TypeIds.T_JavaIoExternalizable; 381 else if (CharOperation.equals(TypeConstants.JAVA_IO_OBJECTSTREAMEXCEPTION[2], this.compoundName[2])) 382 this.id = TypeIds.T_JavaIoObjectStreamException; 383 else if (CharOperation.equals(TypeConstants.JAVA_IO_IOEXCEPTION[2], this.compoundName[2])) 384 this.id = TypeIds.T_JavaIoException; 385 } else if (CharOperation.equals(TypeConstants.UTIL, this.compoundName[1]) 386 && CharOperation.equals(TypeConstants.JAVA_UTIL_ITERATOR[2], this.compoundName[2])) { 387 this.id = TypeIds.T_JavaUtilIterator; 388 } 389 return; 390 } 391 392 char[] typeName = this.compoundName[2]; 394 if (typeName.length == 0) return; switch (typeName[0]) { 396 case 'A' : 397 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2])) 398 this.id = TypeIds.T_JavaLangAssertionError; 399 return; 400 case 'B' : 401 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BOOLEAN[2])) 402 this.id = TypeIds.T_JavaLangBoolean; 403 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BYTE[2])) 404 this.id = TypeIds.T_JavaLangByte; 405 return; 406 case 'C' : 407 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CHARACTER[2])) 408 this.id = TypeIds.T_JavaLangCharacter; 409 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASS[2])) 410 this.id = TypeIds.T_JavaLangClass; 411 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASSNOTFOUNDEXCEPTION[2])) 412 this.id = TypeIds.T_JavaLangClassNotFoundException; 413 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLONEABLE[2])) 414 this.id = TypeIds.T_JavaLangCloneable; 415 return; 416 case 'D' : 417 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DOUBLE[2])) 418 this.id = TypeIds.T_JavaLangDouble; 419 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DEPRECATED[2])) 420 this.id = TypeIds.T_JavaLangDeprecated; 421 return; 422 case 'E' : 423 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ERROR[2])) 424 this.id = TypeIds.T_JavaLangError; 425 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_EXCEPTION[2])) 426 this.id = TypeIds.T_JavaLangException; 427 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ENUM[2])) 428 this.id = TypeIds.T_JavaLangEnum; 429 return; 430 case 'F' : 431 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FLOAT[2])) 432 this.id = TypeIds.T_JavaLangFloat; 433 return; 434 case 'I' : 435 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INTEGER[2])) 436 this.id = TypeIds.T_JavaLangInteger; 437 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ITERABLE[2])) 438 this.id = TypeIds.T_JavaLangIterable; 439 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ILLEGALARGUMENTEXCEPTION[2])) 440 this.id = TypeIds.T_JavaLangIllegalArgumentException; 441 return; 442 case 'L' : 443 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_LONG[2])) 444 this.id = TypeIds.T_JavaLangLong; 445 return; 446 case 'N' : 447 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_NOCLASSDEFERROR[2])) 448 this.id = TypeIds.T_JavaLangNoClassDefError; 449 return; 450 case 'O' : 451 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OBJECT[2])) 452 this.id = TypeIds.T_JavaLangObject; 453 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OVERRIDE[2])) 454 this.id = TypeIds.T_JavaLangOverride; 455 return; 456 case 'R' : 457 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION[2])) 458 this.id = TypeIds.T_JavaLangRuntimeException; 459 break; 460 case 'S' : 461 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRING[2])) 462 this.id = TypeIds.T_JavaLangString; 463 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUFFER[2])) 464 this.id = TypeIds.T_JavaLangStringBuffer; 465 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUILDER[2])) 466 this.id = TypeIds.T_JavaLangStringBuilder; 467 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SYSTEM[2])) 468 this.id = TypeIds.T_JavaLangSystem; 469 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SHORT[2])) 470 this.id = TypeIds.T_JavaLangShort; 471 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS[2])) 472 this.id = TypeIds.T_JavaLangSuppressWarnings; 473 return; 474 case 'T' : 475 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_THROWABLE[2])) 476 this.id = TypeIds.T_JavaLangThrowable; 477 return; 478 case 'V' : 479 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_VOID[2])) 480 this.id = TypeIds.T_JavaLangVoid; 481 return; 482 } 483 break; 484 485 case 4: 486 if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) 487 return; 488 if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1])) 489 return; 490 char[] packageName = this.compoundName[2]; 491 if (packageName.length == 0) return; typeName = this.compoundName[3]; 493 if (typeName.length == 0) return; if (CharOperation.equals(packageName, TypeConstants.REFLECT)) { 495 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_CONSTRUCTOR[3])) { 496 this.id = TypeIds.T_JavaLangReflectConstructor; 497 } else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_FIELD[3])) { 498 this.id = TypeIds.T_JavaLangReflectField; 499 } else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_METHOD[3])) { 500 this.id = TypeIds.T_JavaLangReflectMethod; 501 } 502 return; 503 } else if (CharOperation.equals(packageName, TypeConstants.ANNOTATION)) { 504 switch (typeName[0]) { 505 case 'A' : 506 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ANNOTATION[3])) 507 this.id = TypeIds.T_JavaLangAnnotationAnnotation; 508 return; 509 case 'D' : 510 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED[3])) 511 this.id = TypeIds.T_JavaLangAnnotationDocumented; 512 return; 513 case 'E' : 514 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE[3])) 515 this.id = TypeIds.T_JavaLangAnnotationElementType; 516 return; 517 case 'I' : 518 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED[3])) 519 this.id = TypeIds.T_JavaLangAnnotationInherited; 520 return; 521 case 'R' : 522 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION[3])) 523 this.id = TypeIds.T_JavaLangAnnotationRetention; 524 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY[3])) 525 this.id = TypeIds.T_JavaLangAnnotationRetentionPolicy; 526 return; 527 case 'T' : 528 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_TARGET[3])) 529 this.id = TypeIds.T_JavaLangAnnotationTarget; 530 return; 531 } 532 } 533 break; 534 } 535 } 536 539 public char[] computeUniqueKey(boolean isLeaf) { 540 if (!isLeaf) return signature(); 541 return genericTypeSignature(); 542 } 543 547 public char[] constantPoolName() { 548 if (this.constantPoolName != null) return this.constantPoolName; 549 return this.constantPoolName = CharOperation.concatWith(this.compoundName, '/'); 550 } 551 public String debugName() { 552 return (this.compoundName != null) ? new String (readableName()) : "UNNAMED TYPE"; } 554 public final int depth() { 555 int depth = 0; 556 ReferenceBinding current = this; 557 while ((current = current.enclosingType()) != null) 558 depth++; 559 return depth; 560 } 561 public boolean detectAnnotationCycle() { 562 if ((this.tagBits & TagBits.EndAnnotationCheck) != 0) return false; if ((this.tagBits & TagBits.BeginAnnotationCheck) != 0) return true; 565 this.tagBits |= TagBits.BeginAnnotationCheck; 566 MethodBinding[] currentMethods = methods(); 567 boolean inCycle = false; for (int i = 0, l = currentMethods.length; i < l; i++) { 569 TypeBinding returnType = currentMethods[i].returnType.leafComponentType(); 570 if (this == returnType) { 571 if (this instanceof SourceTypeBinding) { 572 MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod(); 573 ((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, this, decl != null ? decl.returnType : null); 574 } 575 } else if (returnType.isAnnotationType() && ((ReferenceBinding) returnType).detectAnnotationCycle()) { 576 if (this instanceof SourceTypeBinding) { 577 MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod(); 578 ((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, returnType, decl != null ? decl.returnType : null); 579 } 580 inCycle = true; 581 } 582 } 583 if (inCycle) 584 return true; 585 this.tagBits |= TagBits.EndAnnotationCheck; 586 return false; 587 } 588 589 public final ReferenceBinding enclosingTypeAt(int relativeDepth) { 590 ReferenceBinding current = this; 591 while (relativeDepth-- > 0 && current != null) 592 current = current.enclosingType(); 593 return current; 594 } 595 596 public int enumConstantCount() { 597 int count = 0; 598 FieldBinding[] fields = fields(); 599 for (int i = 0, length = fields.length; i < length; i++) { 600 if ((fields[i].modifiers & ClassFileConstants.AccEnum) != 0) count++; 601 } 602 return count; 603 } 604 605 public int fieldCount() { 606 return fields().length; 607 } 608 609 public FieldBinding[] fields() { 610 return Binding.NO_FIELDS; 611 } 612 613 public final int getAccessFlags() { 614 return this.modifiers & ExtraCompilerModifiers.AccJustFlag; 615 } 616 619 public AnnotationBinding[] getAnnotations() { 620 return retrieveAnnotations(this); 621 } 622 625 public long getAnnotationTagBits() { 626 return this.tagBits; 627 } 628 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) { 629 return null; 630 } 631 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) { 632 return null; 633 } 634 public FieldBinding getField(char[] fieldName, boolean needResolve) { 635 return null; 636 } 637 640 public char[] getFileName() { 641 return this.fileName; 642 } 643 public ReferenceBinding getMemberType(char[] typeName) { 644 ReferenceBinding[] memberTypes = memberTypes(); 645 for (int i = memberTypes.length; --i >= 0;) 646 if (CharOperation.equals(memberTypes[i].sourceName, typeName)) 647 return memberTypes[i]; 648 return null; 649 } 650 651 public MethodBinding[] getMethods(char[] selector) { 652 return Binding.NO_METHODS; 653 } 654 655 public PackageBinding getPackage() { 656 return this.fPackage; 657 } 658 659 public TypeVariableBinding getTypeVariable(char[] variableName) { 660 TypeVariableBinding[] typeVariables = typeVariables(); 661 for (int i = typeVariables.length; --i >= 0;) 662 if (CharOperation.equals(typeVariables[i].sourceName, variableName)) 663 return typeVariables[i]; 664 return null; 665 } 666 667 public int hashCode() { 668 return (this.compoundName == null || this.compoundName.length == 0) 671 ? super.hashCode() 672 : CharOperation.hashCode(this.compoundName[this.compoundName.length - 1]); 673 } 674 675 679 public boolean hasIncompatibleSuperType(ReferenceBinding otherType) { 680 681 if (this == otherType) return false; 682 683 ReferenceBinding[] interfacesToVisit = null; 684 int nextPosition = 0; 685 ReferenceBinding currentType = this; 686 TypeBinding match; 687 do { 688 match = otherType.findSuperTypeWithSameErasure(currentType); 689 if (match != null && !match.isIntersectingWith(currentType)) 690 return true; 691 692 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 693 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { 694 if (interfacesToVisit == null) { 695 interfacesToVisit = itsInterfaces; 696 nextPosition = interfacesToVisit.length; 697 } else { 698 int itsLength = itsInterfaces.length; 699 if (nextPosition + itsLength >= interfacesToVisit.length) 700 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 701 nextInterface : for (int a = 0; a < itsLength; a++) { 702 ReferenceBinding next = itsInterfaces[a]; 703 for (int b = 0; b < nextPosition; b++) 704 if (next == interfacesToVisit[b]) continue nextInterface; 705 interfacesToVisit[nextPosition++] = next; 706 } 707 } 708 } 709 } while ((currentType = currentType.superclass()) != null); 710 711 for (int i = 0; i < nextPosition; i++) { 712 currentType = interfacesToVisit[i]; 713 if (currentType == otherType) return false; 714 match = otherType.findSuperTypeWithSameErasure(currentType); 715 if (match != null && !match.isIntersectingWith(currentType)) 716 return true; 717 718 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 719 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { 720 int itsLength = itsInterfaces.length; 721 if (nextPosition + itsLength >= interfacesToVisit.length) 722 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 723 nextInterface : for (int a = 0; a < itsLength; a++) { 724 ReferenceBinding next = itsInterfaces[a]; 725 for (int b = 0; b < nextPosition; b++) 726 if (next == interfacesToVisit[b]) continue nextInterface; 727 interfacesToVisit[nextPosition++] = next; 728 } 729 } 730 } 731 return false; 732 } 733 public boolean hasMemberTypes() { 734 return false; 735 } 736 public final boolean hasRestrictedAccess() { 737 return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0; 738 } 739 740 745 public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) { 746 if (this == anInterface) 747 return true; 748 749 ReferenceBinding[] interfacesToVisit = null; 750 int nextPosition = 0; 751 ReferenceBinding currentType = this; 752 do { 753 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 754 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { if (interfacesToVisit == null) { 756 interfacesToVisit = itsInterfaces; 757 nextPosition = interfacesToVisit.length; 758 } else { 759 int itsLength = itsInterfaces.length; 760 if (nextPosition + itsLength >= interfacesToVisit.length) 761 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 762 nextInterface : for (int a = 0; a < itsLength; a++) { 763 ReferenceBinding next = itsInterfaces[a]; 764 for (int b = 0; b < nextPosition; b++) 765 if (next == interfacesToVisit[b]) continue nextInterface; 766 interfacesToVisit[nextPosition++] = next; 767 } 768 } 769 } 770 } while (searchHierarchy && (currentType = currentType.superclass()) != null); 771 772 for (int i = 0; i < nextPosition; i++) { 773 currentType = interfacesToVisit[i]; 774 if (currentType.isEquivalentTo(anInterface)) 775 return true; 776 777 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 778 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { int itsLength = itsInterfaces.length; 780 if (nextPosition + itsLength >= interfacesToVisit.length) 781 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 782 nextInterface : for (int a = 0; a < itsLength; a++) { 783 ReferenceBinding next = itsInterfaces[a]; 784 for (int b = 0; b < nextPosition; b++) 785 if (next == interfacesToVisit[b]) continue nextInterface; 786 interfacesToVisit[nextPosition++] = next; 787 } 788 } 789 } 790 return false; 791 } 792 793 boolean implementsMethod(MethodBinding method) { 795 char[] selector = method.selector; 796 ReferenceBinding type = this; 797 while (type != null) { 798 MethodBinding[] methods = type.methods(); 799 long range; 800 if ((range = ReferenceBinding.binarySearch(selector, methods)) >= 0) { 801 int start = (int) range, end = (int) (range >> 32); 802 for (int i = start; i <= end; i++) { 803 if (methods[i].areParametersEqual(method)) 804 return true; 805 } 806 } 807 type = type.superclass(); 808 } 809 return false; 810 } 811 812 815 public final boolean isAbstract() { 816 return (this.modifiers & ClassFileConstants.AccAbstract) != 0; 817 } 818 819 public boolean isAnnotationType() { 820 return (this.modifiers & ClassFileConstants.AccAnnotation) != 0; 821 } 822 823 public final boolean isBinaryBinding() { 824 return (this.tagBits & TagBits.IsBinaryBinding) != 0; 825 } 826 827 public boolean isClass() { 828 return (this.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) == 0; 829 } 830 831 836 public boolean isCompatibleWith(TypeBinding otherType) { 837 if (otherType == this) 838 return true; 839 if (otherType.id == TypeIds.T_JavaLangObject) 840 return true; 841 Object result; 842 if (this.compatibleCache == null) { 843 this.compatibleCache = new SimpleLookupTable(3); 844 result = null; 845 } else { 846 result = this.compatibleCache.get(otherType); 847 if (result != null) { 848 return result == Boolean.TRUE; 849 } 850 } 851 this.compatibleCache.put(otherType, Boolean.FALSE); if (isCompatibleWith0(otherType)) { 853 this.compatibleCache.put(otherType, Boolean.TRUE); 854 return true; 855 } 856 return false; 857 } 858 859 862 private boolean isCompatibleWith0(TypeBinding otherType) { 863 if (otherType == this) 864 return true; 865 if (otherType.id == TypeIds.T_JavaLangObject) 866 return true; 867 if (this.isEquivalentTo(otherType)) 870 return true; 871 switch (otherType.kind()) { 872 case Binding.WILDCARD_TYPE : 873 return false; case Binding.TYPE_PARAMETER : 876 if (otherType.isCapture()) { 878 CaptureBinding otherCapture = (CaptureBinding) otherType; 879 TypeBinding otherLowerBound; 880 if ((otherLowerBound = otherCapture.lowerBound) != null) { 881 if (otherLowerBound.isArrayType()) return false; 882 return this.isCompatibleWith(otherLowerBound); 883 } 884 } 885 case Binding.GENERIC_TYPE : 886 case Binding.TYPE : 887 case Binding.PARAMETERIZED_TYPE : 888 case Binding.RAW_TYPE : 889 switch (this.kind()) { 890 case Binding.GENERIC_TYPE : 891 case Binding.PARAMETERIZED_TYPE : 892 case Binding.RAW_TYPE : 893 if (this.erasure() == otherType.erasure()) 894 return false; } 897 ReferenceBinding otherReferenceType = (ReferenceBinding) otherType; 898 if (otherReferenceType.isInterface()) return implementsInterface(otherReferenceType, true); 900 if (this.isInterface()) return false; 903 return otherReferenceType.isSuperclassOf(this); 904 default : 905 return false; 906 } 907 } 908 909 912 public final boolean isDefault() { 913 return (this.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate)) == 0; 914 } 915 916 919 public final boolean isDeprecated() { 920 return (this.modifiers & ClassFileConstants.AccDeprecated) != 0; 921 } 922 923 public boolean isEnum() { 924 return (this.modifiers & ClassFileConstants.AccEnum) != 0; 925 } 926 927 930 public final boolean isFinal() { 931 return (this.modifiers & ClassFileConstants.AccFinal) != 0; 932 } 933 934 937 public boolean isHierarchyBeingConnected() { 938 return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0; 939 } 940 941 public boolean isInterface() { 942 return (this.modifiers & ClassFileConstants.AccInterface) != 0; 944 } 945 946 949 public final boolean isPrivate() { 950 return (this.modifiers & ClassFileConstants.AccPrivate) != 0; 951 } 952 953 956 public final boolean isProtected() { 957 return (this.modifiers & ClassFileConstants.AccProtected) != 0; 958 } 959 960 963 public final boolean isPublic() { 964 return (this.modifiers & ClassFileConstants.AccPublic) != 0; 965 } 966 967 970 public final boolean isStatic() { 971 return (this.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccInterface)) != 0 || (this.tagBits & TagBits.IsNestedType) == 0; 972 } 973 976 public final boolean isStrictfp() { 977 return (this.modifiers & ClassFileConstants.AccStrictfp) != 0; 978 } 979 980 984 public boolean isSuperclassOf(ReferenceBinding otherType) { 985 while ((otherType = otherType.superclass()) != null) { 986 if (otherType.isEquivalentTo(this)) return true; 987 } 988 return false; 989 } 990 993 public boolean isThrowable() { 994 ReferenceBinding current = this; 995 do { 996 switch (current.id) { 997 case TypeIds.T_JavaLangThrowable : 998 case TypeIds.T_JavaLangError : 999 case TypeIds.T_JavaLangRuntimeException : 1000 case TypeIds.T_JavaLangException : 1001 return true; 1002 } 1003 } while ((current = current.superclass()) != null); 1004 return false; 1005} 1006 1014public boolean isUncheckedException(boolean includeSupertype) { 1015 switch (this.id) { 1016 case TypeIds.T_JavaLangError : 1017 case TypeIds.T_JavaLangRuntimeException : 1018 return true; 1019 case TypeIds.T_JavaLangThrowable : 1020 case TypeIds.T_JavaLangException : 1021 return includeSupertype; 1022 } 1023 ReferenceBinding current = this; 1024 while ((current = current.superclass()) != null) { 1025 switch (current.id) { 1026 case TypeIds.T_JavaLangError : 1027 case TypeIds.T_JavaLangRuntimeException : 1028 return true; 1029 case TypeIds.T_JavaLangThrowable : 1030 case TypeIds.T_JavaLangException : 1031 return false; 1032 } 1033 } 1034 return false; 1035} 1036 1039public final boolean isUsed() { 1040 return (this.modifiers & ExtraCompilerModifiers.AccLocallyUsed) != 0; 1041} 1042 1043 1045public final boolean isViewedAsDeprecated() { 1046 return (this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0 1047 || (this.getPackage().tagBits & TagBits.AnnotationDeprecated) != 0; 1048} 1049public ReferenceBinding[] memberTypes() { 1050 return Binding.NO_MEMBER_TYPES; 1051} 1052public MethodBinding[] methods() { 1053 return Binding.NO_METHODS; 1054} 1055public final ReferenceBinding outermostEnclosingType() { 1056 ReferenceBinding current = this; 1057 while (true) { 1058 ReferenceBinding last = current; 1059 if ((current = current.enclosingType()) == null) 1060 return last; 1061 } 1062} 1063 1068 1069public char[] qualifiedSourceName() { 1070 if (isMemberType()) 1071 return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.'); 1072 return sourceName(); 1073} 1074 1075 1079 1080public char[] readableName() { 1081 char[] readableName; 1082 if (isMemberType()) { 1083 readableName = CharOperation.concat(enclosingType().readableName(), this.sourceName, '.'); 1084 } else { 1085 readableName = CharOperation.concatWith(this.compoundName, '.'); 1086 } 1087 TypeVariableBinding[] typeVars; 1088 if ((typeVars = this.typeVariables()) != Binding.NO_TYPE_VARIABLES) { 1089 StringBuffer nameBuffer = new StringBuffer (10); 1090 nameBuffer.append(readableName).append('<'); 1091 for (int i = 0, length = typeVars.length; i < length; i++) { 1092 if (i > 0) nameBuffer.append(','); 1093 nameBuffer.append(typeVars[i].readableName()); 1094 } 1095 nameBuffer.append('>'); 1096 int nameLength = nameBuffer.length(); 1097 readableName = new char[nameLength]; 1098 nameBuffer.getChars(0, nameLength, readableName, 0); 1099 } 1100 return readableName; 1101} 1102 1103public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) { 1104 SimpleLookupTable store = storedAnnotations(false); 1105 return store == null ? null : (AnnotationHolder) store.get(binding); 1106} 1107AnnotationBinding[] retrieveAnnotations(Binding binding) { 1108 AnnotationHolder holder = retrieveAnnotationHolder(binding, true); 1109 return holder == null ? Binding.NO_ANNOTATIONS : holder.getAnnotations(); 1110} 1111public void setAnnotations(AnnotationBinding[] annotations) { 1112 storeAnnotations(this, annotations); 1113} 1114public char[] shortReadableName() { 1115 char[] shortReadableName; 1116 if (isMemberType()) { 1117 shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), this.sourceName, '.'); 1118 } else { 1119 shortReadableName = this.sourceName; 1120 } 1121 TypeVariableBinding[] typeVars; 1122 if ((typeVars = this.typeVariables()) != Binding.NO_TYPE_VARIABLES) { 1123 StringBuffer nameBuffer = new StringBuffer (10); 1124 nameBuffer.append(shortReadableName).append('<'); 1125 for (int i = 0, length = typeVars.length; i < length; i++) { 1126 if (i > 0) nameBuffer.append(','); 1127 nameBuffer.append(typeVars[i].shortReadableName()); 1128 } 1129 nameBuffer.append('>'); 1130 int nameLength = nameBuffer.length(); 1131 shortReadableName = new char[nameLength]; 1132 nameBuffer.getChars(0, nameLength, shortReadableName, 0); 1133 } 1134 return shortReadableName; 1135} 1136public char[] signature() { 1137 if (this.signature != null) 1138 return this.signature; 1139 1140 return this.signature = CharOperation.concat('L', constantPoolName(), ';'); 1141} 1142public char[] sourceName() { 1143 return this.sourceName; 1144} 1145void storeAnnotationHolder(Binding binding, AnnotationHolder holder) { 1146 if (holder == null) { 1147 SimpleLookupTable store = storedAnnotations(false); 1148 if (store != null) 1149 store.removeKey(binding); 1150 } else { 1151 SimpleLookupTable store = storedAnnotations(true); 1152 if (store != null) 1153 store.put(binding, holder); 1154 } 1155} 1156void storeAnnotations(Binding binding, AnnotationBinding[] annotations) { 1157 AnnotationHolder holder = null; 1158 if (annotations == null || annotations.length == 0) { 1159 SimpleLookupTable store = storedAnnotations(false); 1160 if (store != null) 1161 holder = (AnnotationHolder) store.get(binding); 1162 if (holder == null) return; } else { 1164 SimpleLookupTable store = storedAnnotations(true); 1165 if (store == null) return; holder = (AnnotationHolder) store.get(binding); 1167 if (holder == null) 1168 holder = new AnnotationHolder(); 1169 } 1170 storeAnnotationHolder(binding, holder.setAnnotations(annotations)); 1171} 1172SimpleLookupTable storedAnnotations(boolean forceInitialize) { 1173 return null; } 1175public ReferenceBinding superclass() { 1176 return null; 1177} 1178public ReferenceBinding[] superInterfaces() { 1179 return Binding.NO_SUPERINTERFACES; 1180} 1181public ReferenceBinding[] syntheticEnclosingInstanceTypes() { 1182 if (isStatic()) return null; 1183 1184 ReferenceBinding enclosingType = enclosingType(); 1185 if (enclosingType == null) 1186 return null; 1187 return new ReferenceBinding[] {enclosingType}; 1188} 1189public SyntheticArgumentBinding[] syntheticOuterLocalVariables() { 1190 return null; } 1192 1193MethodBinding[] unResolvedMethods() { return methods(); 1195} 1196} 1197 | Popular Tags |