1 11 12 package org.eclipse.jdt.core.dom; 13 14 import java.io.File ; 15 16 import org.eclipse.core.resources.IContainer; 17 import org.eclipse.core.resources.IWorkspaceRoot; 18 import org.eclipse.core.resources.ResourcesPlugin; 19 import org.eclipse.core.runtime.Path; 20 import org.eclipse.jdt.core.IClassFile; 21 import org.eclipse.jdt.core.ICompilationUnit; 22 import org.eclipse.jdt.core.IJavaElement; 23 import org.eclipse.jdt.core.IJavaProject; 24 import org.eclipse.jdt.core.IMethod; 25 import org.eclipse.jdt.core.IPackageFragment; 26 import org.eclipse.jdt.core.IPackageFragmentRoot; 27 import org.eclipse.jdt.core.IType; 28 import org.eclipse.jdt.core.JavaCore; 29 import org.eclipse.jdt.core.JavaModelException; 30 import org.eclipse.jdt.core.compiler.CharOperation; 31 import org.eclipse.jdt.internal.compiler.ast.Expression; 32 import org.eclipse.jdt.internal.compiler.ast.Wildcard; 33 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 34 import org.eclipse.jdt.internal.compiler.env.IDependent; 35 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; 36 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; 37 import org.eclipse.jdt.internal.compiler.lookup.Binding; 38 import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding; 39 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 40 import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding; 41 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 42 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; 43 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; 44 import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding; 45 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 46 import org.eclipse.jdt.internal.compiler.lookup.Scope; 47 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 48 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; 49 import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding; 50 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; 51 import org.eclipse.jdt.internal.compiler.util.SuffixConstants; 52 import org.eclipse.jdt.internal.compiler.util.Util; 53 import org.eclipse.jdt.internal.core.ClassFile; 54 import org.eclipse.jdt.internal.core.JavaElement; 55 56 59 class TypeBinding implements ITypeBinding { 60 protected static final IMethodBinding[] NO_METHOD_BINDINGS = new IMethodBinding[0]; 61 62 private static final String NO_NAME = ""; protected static final ITypeBinding[] NO_TYPE_BINDINGS = new ITypeBinding[0]; 64 protected static final IVariableBinding[] NO_VARIABLE_BINDINGS = new IVariableBinding[0]; 65 66 private static final int VALID_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | 67 Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.STRICTFP; 68 69 org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding; 70 private String key; 71 private BindingResolver resolver; 72 private IVariableBinding[] fields; 73 private IAnnotationBinding[] annotations; 74 private IMethodBinding[] methods; 75 private ITypeBinding[] members; 76 private ITypeBinding[] interfaces; 77 private ITypeBinding[] typeArguments; 78 private ITypeBinding[] bounds; 79 private ITypeBinding[] typeParameters; 80 81 public TypeBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding) { 82 this.binding = binding; 83 this.resolver = resolver; 84 } 85 86 public ITypeBinding createArrayType(int dimension) { 87 int realDimensions = dimension; 88 realDimensions += this.getDimensions(); 89 if (realDimensions < 1 || realDimensions > 255) { 90 throw new IllegalArgumentException (); 91 } 92 return this.resolver.resolveArrayType(this, dimension); 93 } 94 95 public IAnnotationBinding[] getAnnotations() { 96 if (this.annotations != null) { 97 return this.annotations; 98 } 99 if (this.binding.isAnnotationType() || this.binding.isClass() || this.binding.isEnum() || this.binding.isInterface()) { 100 org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding refType = 101 (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) this.binding; 102 org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations = refType.getAnnotations(); 103 int length = internalAnnotations == null ? 0 : internalAnnotations.length; 104 if (length != 0) { 105 IAnnotationBinding[] tempAnnotations = new IAnnotationBinding[length]; 106 int annotationsCounter = 0; 107 for (int i = 0; i < length; i++) { 108 final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotations[i]); 109 if (annotationInstance == null) { 110 continue; 111 } 112 tempAnnotations[annotationsCounter++] = annotationInstance; 113 } 114 if (length != annotationsCounter) { 115 System.arraycopy(tempAnnotations, 0, (tempAnnotations = new IAnnotationBinding[annotationsCounter]), 0, annotationsCounter); 116 } 117 return this.annotations = tempAnnotations; 118 } 119 } 120 return this.annotations = AnnotationBinding.NoAnnotations; 121 } 122 123 127 public String getBinaryName() { 128 if (this.binding.isCapture()) { 129 return null; } else if (this.binding.isTypeVariable()) { 131 TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding; 132 org.eclipse.jdt.internal.compiler.lookup.Binding declaring = typeVariableBinding.declaringElement; 133 StringBuffer binaryName = new StringBuffer (); 134 switch(declaring.kind()) { 135 case org.eclipse.jdt.internal.compiler.lookup.Binding.METHOD : 136 MethodBinding methodBinding = (MethodBinding) declaring; 137 char[] constantPoolName = methodBinding.declaringClass.constantPoolName(); 138 if (constantPoolName == null) return null; 139 binaryName 140 .append(CharOperation.replaceOnCopy(constantPoolName, '/', '.')) 141 .append('$') 142 .append(methodBinding.signature()) 143 .append('$') 144 .append(typeVariableBinding.sourceName); 145 break; 146 default : 147 org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaring; 148 constantPoolName = typeBinding.constantPoolName(); 149 if (constantPoolName == null) return null; 150 binaryName 151 .append(CharOperation.replaceOnCopy(constantPoolName, '/', '.')) 152 .append('$') 153 .append(typeVariableBinding.sourceName); 154 } 155 return String.valueOf(binaryName); 156 } 157 char[] constantPoolName = this.binding.constantPoolName(); 158 if (constantPoolName == null) return null; 159 char[] dotSeparated = CharOperation.replaceOnCopy(constantPoolName, '/', '.'); 160 return new String (dotSeparated); 161 } 162 163 166 public ITypeBinding getBound() { 167 if (this.binding.isWildcard()) { 168 WildcardBinding wildcardBinding = (WildcardBinding) this.binding; 169 if (wildcardBinding.bound != null) { 170 return this.resolver.getTypeBinding(wildcardBinding.bound); 171 } 172 } 173 return null; 174 } 175 176 180 private IClassFile getClassFile(char[] fileName) { 181 int jarSeparator = CharOperation.indexOf(IDependent.JAR_FILE_ENTRY_SEPARATOR, fileName); 182 int pkgEnd = CharOperation.lastIndexOf('/', fileName); if (pkgEnd == -1) 184 pkgEnd = CharOperation.lastIndexOf(File.separatorChar, fileName); 185 if (jarSeparator != -1 && pkgEnd < jarSeparator) pkgEnd = jarSeparator; 187 if (pkgEnd == -1) 188 return null; 189 IPackageFragment pkg = getPackageFragment(fileName, pkgEnd, jarSeparator); 190 if (pkg == null) return null; 191 int start; 192 return pkg.getClassFile(new String (fileName, start = pkgEnd + 1, fileName.length - start)); 193 } 194 195 199 private ICompilationUnit getCompilationUnit(char[] fileName) { 200 char[] slashSeparatedFileName = CharOperation.replaceOnCopy(fileName, File.separatorChar, '/'); 201 int pkgEnd = CharOperation.lastIndexOf('/', slashSeparatedFileName); if (pkgEnd == -1) 203 return null; 204 IPackageFragment pkg = getPackageFragment(slashSeparatedFileName, pkgEnd, -1); 205 if (pkg == null) return null; 206 int start; 207 ICompilationUnit cu = pkg.getCompilationUnit(new String (slashSeparatedFileName, start = pkgEnd+1, slashSeparatedFileName.length - start)); 208 if (this.resolver instanceof DefaultBindingResolver) { 209 ICompilationUnit workingCopy = cu.findWorkingCopy(((DefaultBindingResolver) this.resolver).workingCopyOwner); 210 if (workingCopy != null) 211 return workingCopy; 212 } 213 return cu; 214 } 215 216 219 public ITypeBinding getComponentType() { 220 if (!this.isArray()) { 221 return null; 222 } 223 ArrayBinding arrayBinding = (ArrayBinding) binding; 224 return resolver.getTypeBinding(arrayBinding.elementsType()); 225 } 226 227 230 public synchronized IVariableBinding[] getDeclaredFields() { 231 if (this.fields != null) { 232 return this.fields; 233 } 234 try { 235 if (isClass() || isInterface() || isEnum()) { 236 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 237 FieldBinding[] fieldBindings = referenceBinding.availableFields(); int length = fieldBindings.length; 239 if (length != 0) { 240 IVariableBinding[] newFields = new IVariableBinding[length]; 241 for (int i = 0; i < length; i++) { 242 IVariableBinding variableBinding = this.resolver.getVariableBinding(fieldBindings[i]); 243 if (variableBinding == null) { 244 return this.fields = NO_VARIABLE_BINDINGS; 245 } 246 newFields[i] = variableBinding; 247 } 248 return this.fields = newFields; 249 } 250 } 251 } catch (RuntimeException e) { 252 257 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declared fields"); } 259 return this.fields = NO_VARIABLE_BINDINGS; 260 } 261 262 265 public synchronized IMethodBinding[] getDeclaredMethods() { 266 if (this.methods != null) { 267 return this.methods; 268 } 269 try { 270 if (isClass() || isInterface() || isEnum()) { 271 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 272 org.eclipse.jdt.internal.compiler.lookup.MethodBinding[] internalMethods = referenceBinding.availableMethods(); int length = internalMethods.length; 274 if (length != 0) { 275 int removeSyntheticsCounter = 0; 276 IMethodBinding[] newMethods = new IMethodBinding[length]; 277 for (int i = 0; i < length; i++) { 278 org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding = internalMethods[i]; 279 if (!shouldBeRemoved(methodBinding)) { 280 IMethodBinding methodBinding2 = this.resolver.getMethodBinding(methodBinding); 281 if (methodBinding2 != null) { 282 newMethods[removeSyntheticsCounter++] = methodBinding2; 283 } 284 } 285 } 286 if (removeSyntheticsCounter != length) { 287 System.arraycopy(newMethods, 0, (newMethods = new IMethodBinding[removeSyntheticsCounter]), 0, removeSyntheticsCounter); 288 } 289 return this.methods = newMethods; 290 } 291 } 292 } catch (RuntimeException e) { 293 298 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declared methods"); } 300 return this.methods = NO_METHOD_BINDINGS; 301 } 302 303 306 public int getDeclaredModifiers() { 307 return getModifiers(); 308 } 309 310 313 public synchronized ITypeBinding[] getDeclaredTypes() { 314 if (this.members != null) { 315 return this.members; 316 } 317 try { 318 if (isClass() || isInterface() || isEnum()) { 319 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 320 ReferenceBinding[] internalMembers = referenceBinding.memberTypes(); 321 int length = internalMembers.length; 322 if (length != 0) { 323 ITypeBinding[] newMembers = new ITypeBinding[length]; 324 for (int i = 0; i < length; i++) { 325 ITypeBinding typeBinding = this.resolver.getTypeBinding(internalMembers[i]); 326 if (typeBinding == null) { 327 return this.members = NO_TYPE_BINDINGS; 328 } 329 newMembers[i] = typeBinding; 330 } 331 return this.members = newMembers; 332 } 333 } 334 } catch (RuntimeException e) { 335 340 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declared methods"); } 342 return this.members = NO_TYPE_BINDINGS; 343 } 344 345 348 public synchronized IMethodBinding getDeclaringMethod() { 349 if (this.binding instanceof LocalTypeBinding) { 350 LocalTypeBinding localTypeBinding = (LocalTypeBinding) this.binding; 351 MethodBinding methodBinding = localTypeBinding.enclosingMethod; 352 if (methodBinding != null) { 353 try { 354 return this.resolver.getMethodBinding(localTypeBinding.enclosingMethod); 355 } catch (RuntimeException e) { 356 361 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declaring method"); } 363 } 364 } else if (this.binding.isTypeVariable()) { 365 TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding; 366 Binding declaringElement = typeVariableBinding.declaringElement; 367 if (declaringElement instanceof MethodBinding) { 368 try { 369 return this.resolver.getMethodBinding((MethodBinding)declaringElement); 370 } catch (RuntimeException e) { 371 376 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declaring method"); } 378 } 379 } 380 return null; 381 } 382 383 386 public synchronized ITypeBinding getDeclaringClass() { 387 if (isClass() || isInterface() || isEnum()) { 388 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 389 if (referenceBinding.isNestedType()) { 390 try { 391 return this.resolver.getTypeBinding(referenceBinding.enclosingType()); 392 } catch (RuntimeException e) { 393 398 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declaring class"); } 400 } 401 } else if (this.binding.isTypeVariable()) { 402 TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding; 403 Binding declaringElement = typeVariableBinding.isCapture() ? ((CaptureBinding) typeVariableBinding).sourceType : typeVariableBinding.declaringElement; 404 if (declaringElement instanceof ReferenceBinding) { 405 try { 406 return this.resolver.getTypeBinding((ReferenceBinding)declaringElement); 407 } catch (RuntimeException e) { 408 413 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declaring class"); } 415 } 416 } 417 return null; 418 } 419 420 423 public int getDimensions() { 424 if (!this.isArray()) { 425 return 0; 426 } 427 ArrayBinding arrayBinding = (ArrayBinding) binding; 428 return arrayBinding.dimensions; 429 } 430 431 434 public ITypeBinding getElementType() { 435 if (!this.isArray()) { 436 return null; 437 } 438 ArrayBinding arrayBinding = (ArrayBinding) binding; 439 return resolver.getTypeBinding(arrayBinding.leafComponentType); 440 } 441 442 445 public ITypeBinding getTypeDeclaration() { 446 if (this.binding instanceof ParameterizedTypeBinding) 447 return this.resolver.getTypeBinding(((ParameterizedTypeBinding)this.binding).genericType()); 448 return this; 449 } 450 451 454 public ITypeBinding getErasure() { 455 return this.resolver.getTypeBinding(this.binding.erasure()); 456 } 457 458 public synchronized ITypeBinding[] getInterfaces() { 459 if (this.interfaces != null) { 460 return this.interfaces; 461 } 462 if (this.binding == null) 463 return this.interfaces = NO_TYPE_BINDINGS; 464 switch (this.binding.kind()) { 465 case Binding.ARRAY_TYPE : 466 case Binding.BASE_TYPE : 467 return this.interfaces = NO_TYPE_BINDINGS; 468 } 469 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 470 ReferenceBinding[] internalInterfaces = null; 471 try { 472 internalInterfaces = referenceBinding.superInterfaces(); 473 } catch (RuntimeException e) { 474 479 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve interfaces"); } 481 int length = internalInterfaces == null ? 0 : internalInterfaces.length; 482 if (length != 0) { 483 ITypeBinding[] newInterfaces = new ITypeBinding[length]; 484 int interfacesCounter = 0; 485 for (int i = 0; i < length; i++) { 486 ITypeBinding typeBinding = this.resolver.getTypeBinding(internalInterfaces[i]); 487 if (typeBinding == null) { 488 continue; 489 } 490 newInterfaces[interfacesCounter++] = typeBinding; 491 } 492 if (length != interfacesCounter) { 493 System.arraycopy(newInterfaces, 0, (newInterfaces = new ITypeBinding[interfacesCounter]), 0, interfacesCounter); 494 } 495 return this.interfaces = newInterfaces; 496 } 497 return this.interfaces = NO_TYPE_BINDINGS; 498 } 499 500 public IJavaElement getJavaElement() { 501 JavaElement element = getUnresolvedJavaElement(); 502 if (element == null) 503 return null; 504 return element.resolved(this.binding); 505 } 506 507 private JavaElement getUnresolvedJavaElement() { 508 return getUnresolvedJavaElement(this.binding); 509 } 510 private JavaElement getUnresolvedJavaElement(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding ) { 511 if (typeBinding == null) 512 return null; 513 switch (typeBinding.kind()) { 514 case Binding.ARRAY_TYPE : 515 typeBinding = ((ArrayBinding) typeBinding).leafComponentType(); 516 return getUnresolvedJavaElement(typeBinding); 517 case Binding.BASE_TYPE : 518 case Binding.WILDCARD_TYPE : 519 return null; 520 default : 521 if (typeBinding.isCapture()) 522 return null; 523 } 524 ReferenceBinding referenceBinding; 525 if (typeBinding.isParameterizedType() || typeBinding.isRawType()) 526 referenceBinding = (ReferenceBinding) typeBinding.erasure(); 527 else 528 referenceBinding = (ReferenceBinding) typeBinding; 529 char[] fileName = referenceBinding.getFileName(); 530 if (referenceBinding.isLocalType() || referenceBinding.isAnonymousType()) { 531 if (Util.isClassFileName(fileName)) { 533 int jarSeparator = CharOperation.indexOf(IDependent.JAR_FILE_ENTRY_SEPARATOR, fileName); 534 int pkgEnd = CharOperation.lastIndexOf('/', fileName); if (pkgEnd == -1) 536 pkgEnd = CharOperation.lastIndexOf(File.separatorChar, fileName); 537 if (jarSeparator != -1 && pkgEnd < jarSeparator) pkgEnd = jarSeparator; 539 if (pkgEnd == -1) 540 return null; 541 IPackageFragment pkg = getPackageFragment(fileName, pkgEnd, jarSeparator); 542 char[] constantPoolName = referenceBinding.constantPoolName(); 543 if (constantPoolName == null) { 544 ClassFile classFile = (ClassFile) getClassFile(fileName); 545 return classFile == null ? null : (JavaElement) classFile.getType(); 546 } 547 pkgEnd = CharOperation.lastIndexOf('/', constantPoolName); 548 char[] classFileName = CharOperation.subarray(constantPoolName, pkgEnd+1, constantPoolName.length); 549 ClassFile classFile = (ClassFile) pkg.getClassFile(new String (classFileName) + SuffixConstants.SUFFIX_STRING_class); 550 return (JavaElement) classFile.getType(); 551 } 552 ICompilationUnit cu = getCompilationUnit(fileName); 553 if (cu == null) return null; 554 try { 556 int sourceStart = ((LocalTypeBinding) referenceBinding).sourceStart; 557 return (JavaElement) cu.getElementAt(sourceStart); 558 } catch (JavaModelException e) { 559 return null; 561 } 562 } else if (referenceBinding.isTypeVariable()) { 563 final String typeVariableName = new String (referenceBinding.sourceName()); 565 Binding declaringElement = ((TypeVariableBinding) referenceBinding).declaringElement; 566 IBinding declaringTypeBinding = null; 567 if (declaringElement instanceof MethodBinding) { 568 declaringTypeBinding = this.resolver.getMethodBinding((MethodBinding) declaringElement); 569 IMethod declaringMethod = (IMethod) declaringTypeBinding.getJavaElement(); 570 return (JavaElement) declaringMethod.getTypeParameter(typeVariableName); 571 } else { 572 ITypeBinding typeBinding2 = this.resolver.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement); 573 if (typeBinding2 == null) return null; 574 declaringTypeBinding = typeBinding2; 575 IType declaringType = (IType) declaringTypeBinding.getJavaElement(); 576 return (JavaElement) declaringType.getTypeParameter(typeVariableName); 577 } 578 } else { 579 if (fileName == null) return null; ITypeBinding declaringTypeBinding = null; 582 if (this.isArray()) { 583 declaringTypeBinding = this.getElementType().getDeclaringClass(); 584 } else { 585 declaringTypeBinding = this.getDeclaringClass(); 586 } 587 if (declaringTypeBinding == null) { 588 if (Util.isClassFileName(fileName)) { 590 ClassFile classFile = (ClassFile) getClassFile(fileName); 591 if (classFile == null) return null; 592 return (JavaElement) classFile.getType(); 593 } 594 ICompilationUnit cu = getCompilationUnit(fileName); 595 if (cu == null) return null; 596 return (JavaElement) cu.getType(new String (referenceBinding.sourceName())); 597 } else { 598 IType declaringType = (IType) declaringTypeBinding.getJavaElement(); 600 if (declaringType == null) return null; 601 return (JavaElement) declaringType.getType(new String (referenceBinding.sourceName())); 602 } 603 } 604 } 605 606 609 public String getKey() { 610 if (this.key == null) { 611 this.key = new String (this.binding.computeUniqueKey()); 612 } 613 return this.key; 614 } 615 616 619 public int getKind() { 620 return IBinding.TYPE; 621 } 622 623 626 public int getModifiers() { 627 if (isClass()) { 628 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 629 final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS; 630 if (referenceBinding.isAnonymousType()) { 631 return accessFlags & ~Modifier.FINAL; 632 } 633 return accessFlags; 634 } else if (isAnnotation()) { 635 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 636 final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS; 637 return accessFlags & ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation); 639 } else if (isInterface()) { 640 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 641 final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS; 642 return accessFlags & ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface); 644 } else if (isEnum()) { 645 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 646 final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS; 647 return accessFlags & ~ClassFileConstants.AccEnum; 649 } else { 650 return Modifier.NONE; 651 } 652 } 653 654 public String getName() { 655 StringBuffer buffer; 656 switch (this.binding.kind()) { 657 658 case Binding.WILDCARD_TYPE : 659 WildcardBinding wildcardBinding = (WildcardBinding) this.binding; 660 buffer = new StringBuffer (); 661 buffer.append(TypeConstants.WILDCARD_NAME); 662 if (wildcardBinding.bound != null) { 663 switch(wildcardBinding.boundKind) { 664 case Wildcard.SUPER : 665 buffer.append(TypeConstants.WILDCARD_SUPER); 666 break; 667 case Wildcard.EXTENDS : 668 buffer.append(TypeConstants.WILDCARD_EXTENDS); 669 } 670 buffer.append(getBound().getName()); 671 } 672 return String.valueOf(buffer); 673 674 case Binding.TYPE_PARAMETER : 675 if (isCapture()) { 676 return NO_NAME; 677 } 678 TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding; 679 return new String (typeVariableBinding.sourceName); 680 681 case Binding.PARAMETERIZED_TYPE : 682 ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding; 683 buffer = new StringBuffer (); 684 buffer.append(parameterizedTypeBinding.sourceName()); 685 ITypeBinding[] tArguments = getTypeArguments(); 686 final int typeArgumentsLength = tArguments.length; 687 if (typeArgumentsLength != 0) { 688 buffer.append('<'); 689 for (int i = 0; i < typeArgumentsLength; i++) { 690 if (i > 0) { 691 buffer.append(','); 692 } 693 buffer.append(tArguments[i].getName()); 694 } 695 buffer.append('>'); 696 } 697 return String.valueOf(buffer); 698 699 case Binding.RAW_TYPE : 700 return getTypeDeclaration().getName(); 701 702 case Binding.ARRAY_TYPE : 703 ITypeBinding elementType = getElementType(); 704 if (elementType.isLocal() || elementType.isAnonymous() || elementType.isCapture()) { 705 return NO_NAME; 706 } 707 int dimensions = getDimensions(); 708 char[] brackets = new char[dimensions * 2]; 709 for (int i = dimensions * 2 - 1; i >= 0; i -= 2) { 710 brackets[i] = ']'; 711 brackets[i - 1] = '['; 712 } 713 buffer = new StringBuffer (elementType.getName()); 714 buffer.append(brackets); 715 return String.valueOf(buffer); 716 717 default : 718 if (isPrimitive() || isNullType()) { 719 BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding; 720 return new String (baseTypeBinding.simpleName); 721 } 722 if (isAnonymous()) { 723 return NO_NAME; 724 } 725 return new String (this.binding.sourceName()); 726 } 727 } 728 729 732 public IPackageBinding getPackage() { 733 switch (this.binding.kind()) { 734 case Binding.BASE_TYPE : 735 case Binding.ARRAY_TYPE : 736 case Binding.TYPE_PARAMETER : case Binding.WILDCARD_TYPE : 738 return null; 739 } 740 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 741 return this.resolver.getPackageBinding(referenceBinding.getPackage()); 742 } 743 744 752 private IPackageFragment getPackageFragment(char[] fileName, int pkgEnd, int jarSeparator) { 753 if (jarSeparator != -1) { 754 String jarMemento = new String (fileName, 0, jarSeparator); 755 IPackageFragmentRoot root = (IPackageFragmentRoot) JavaCore.create(jarMemento); 756 if (pkgEnd == jarSeparator) 757 return root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME); 758 char[] pkgName = CharOperation.subarray(fileName, jarSeparator+1, pkgEnd); 759 CharOperation.replace(pkgName, '/', '.'); 760 return root.getPackageFragment(new String (pkgName)); 761 } else { 762 Path path = new Path(new String (fileName, 0, pkgEnd)); 763 IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 764 IContainer folder = path.segmentCount() == 1 ? workspaceRoot.getProject(path.lastSegment()) : (IContainer) workspaceRoot.getFolder(path); 765 IJavaElement element = JavaCore.create(folder); 766 if (element == null) return null; 767 switch (element.getElementType()) { 768 case IJavaElement.PACKAGE_FRAGMENT: 769 return (IPackageFragment) element; 770 case IJavaElement.PACKAGE_FRAGMENT_ROOT: 771 return ((IPackageFragmentRoot) element).getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME); 772 case IJavaElement.JAVA_PROJECT: 773 IPackageFragmentRoot root = ((IJavaProject) element).getPackageFragmentRoot(folder); 774 if (root == null) return null; 775 return root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME); 776 } 777 return null; 778 } 779 } 780 781 784 public String getQualifiedName() { 785 StringBuffer buffer; 786 switch (this.binding.kind()) { 787 788 case Binding.WILDCARD_TYPE : 789 WildcardBinding wildcardBinding = (WildcardBinding) this.binding; 790 buffer = new StringBuffer (); 791 buffer.append(TypeConstants.WILDCARD_NAME); 792 final ITypeBinding bound = getBound(); 793 if (bound != null) { 794 switch(wildcardBinding.boundKind) { 795 case Wildcard.SUPER : 796 buffer.append(TypeConstants.WILDCARD_SUPER); 797 break; 798 case Wildcard.EXTENDS : 799 buffer.append(TypeConstants.WILDCARD_EXTENDS); 800 } 801 buffer.append(bound.getQualifiedName()); 802 } 803 return String.valueOf(buffer); 804 805 case Binding.RAW_TYPE : 806 return getTypeDeclaration().getQualifiedName(); 807 808 case Binding.ARRAY_TYPE : 809 ITypeBinding elementType = getElementType(); 810 if (elementType.isLocal() || elementType.isAnonymous() || elementType.isCapture()) { 811 return NO_NAME; 812 } 813 final int dimensions = getDimensions(); 814 char[] brackets = new char[dimensions * 2]; 815 for (int i = dimensions * 2 - 1; i >= 0; i -= 2) { 816 brackets[i] = ']'; 817 brackets[i - 1] = '['; 818 } 819 buffer = new StringBuffer (elementType.getQualifiedName()); 820 buffer.append(brackets); 821 return String.valueOf(buffer); 822 823 case Binding.TYPE_PARAMETER : 824 if (isCapture()) { 825 return NO_NAME; 826 } 827 TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding; 828 return new String (typeVariableBinding.sourceName); 829 830 case Binding.PARAMETERIZED_TYPE : 831 buffer = new StringBuffer (); 832 if (isMember()) { 833 buffer 834 .append(getDeclaringClass().getQualifiedName()) 835 .append('.'); 836 ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding; 837 buffer.append(parameterizedTypeBinding.sourceName()); 838 ITypeBinding[] tArguments = getTypeArguments(); 839 final int typeArgumentsLength = tArguments.length; 840 if (typeArgumentsLength != 0) { 841 buffer.append('<'); 842 for (int i = 0; i < typeArgumentsLength; i++) { 843 if (i > 0) { 844 buffer.append(','); 845 } 846 buffer.append(tArguments[i].getQualifiedName()); 847 } 848 buffer.append('>'); 849 } 850 return String.valueOf(buffer); 851 } 852 buffer.append(getTypeDeclaration().getQualifiedName()); 853 ITypeBinding[] tArguments = getTypeArguments(); 854 final int typeArgumentsLength = tArguments.length; 855 if (typeArgumentsLength != 0) { 856 buffer.append('<'); 857 for (int i = 0; i < typeArgumentsLength; i++) { 858 if (i > 0) { 859 buffer.append(','); 860 } 861 buffer.append(tArguments[i].getQualifiedName()); 862 } 863 buffer.append('>'); 864 } 865 return String.valueOf(buffer); 866 867 default : 868 if (isAnonymous() || isLocal()) { 869 return NO_NAME; 870 } 871 if (isPrimitive() || isNullType()) { 872 BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding; 873 return new String (baseTypeBinding.simpleName); 874 } 875 if (isMember()) { 876 buffer = new StringBuffer (); 877 buffer 878 .append(getDeclaringClass().getQualifiedName()) 879 .append('.'); 880 buffer.append(getName()); 881 return String.valueOf(buffer); 882 } 883 PackageBinding packageBinding = this.binding.getPackage(); 884 buffer = new StringBuffer (); 885 if (packageBinding != null && packageBinding.compoundName != CharOperation.NO_CHAR_CHAR) { 886 buffer.append(CharOperation.concatWith(packageBinding.compoundName, '.')).append('.'); 887 } 888 buffer.append(getName()); 889 return String.valueOf(buffer); 890 } 891 } 892 893 896 public synchronized ITypeBinding getSuperclass() { 897 if (this.binding == null) 898 return null; 899 switch (this.binding.kind()) { 900 case Binding.ARRAY_TYPE : 901 case Binding.BASE_TYPE : 902 return null; 903 default: 904 if (this.binding.isInterface()) 906 return null; 907 } 908 ReferenceBinding superclass = null; 909 try { 910 superclass = ((ReferenceBinding)this.binding).superclass(); 911 } catch (RuntimeException e) { 912 917 org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve superclass"); return this.resolver.resolveWellKnownType("java.lang.Object"); } 920 if (superclass == null) { 921 return null; 922 } 923 return this.resolver.getTypeBinding(superclass); 924 } 925 926 929 public ITypeBinding[] getTypeArguments() { 930 if (this.typeArguments != null) { 931 return this.typeArguments; 932 } 933 if (this.binding.isParameterizedType()) { 934 ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding; 935 final org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] arguments = parameterizedTypeBinding.arguments; 936 if (arguments != null) { 937 int argumentsLength = arguments.length; 938 ITypeBinding[] newTypeArguments = new ITypeBinding[argumentsLength]; 939 for (int i = 0; i < argumentsLength; i++) { 940 ITypeBinding typeBinding = this.resolver.getTypeBinding(arguments[i]); 941 if (typeBinding == null) { 942 return this.typeArguments = NO_TYPE_BINDINGS; 943 } 944 newTypeArguments[i] = typeBinding; 945 } 946 return this.typeArguments = newTypeArguments; 947 } 948 } 949 return this.typeArguments = NO_TYPE_BINDINGS; 950 } 951 952 955 public ITypeBinding[] getTypeBounds() { 956 if (this.bounds != null) { 957 return this.bounds; 958 } 959 if (this.binding instanceof TypeVariableBinding) { 960 TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding; 961 ReferenceBinding varSuperclass = typeVariableBinding.superclass(); 962 org.eclipse.jdt.internal.compiler.lookup.TypeBinding firstClassOrArrayBound = typeVariableBinding.firstBound; 963 int boundsLength = 0; 964 if (firstClassOrArrayBound != null) { 965 if (firstClassOrArrayBound == varSuperclass) { 966 boundsLength++; 967 } else if (firstClassOrArrayBound.isArrayType()) { boundsLength++; 969 } else { 970 firstClassOrArrayBound = null; 971 } 972 } 973 ReferenceBinding[] superinterfaces = typeVariableBinding.superInterfaces(); 974 int superinterfacesLength = 0; 975 if (superinterfaces != null) { 976 superinterfacesLength = superinterfaces.length; 977 boundsLength += superinterfacesLength; 978 } 979 if (boundsLength != 0) { 980 ITypeBinding[] typeBounds = new ITypeBinding[boundsLength]; 981 int boundsIndex = 0; 982 if (firstClassOrArrayBound != null) { 983 ITypeBinding typeBinding = this.resolver.getTypeBinding(firstClassOrArrayBound); 984 if (typeBinding == null) { 985 return this.bounds = NO_TYPE_BINDINGS; 986 } 987 typeBounds[boundsIndex++] = typeBinding; 988 } 989 if (superinterfaces != null) { 990 for (int i = 0; i < superinterfacesLength; i++, boundsIndex++) { 991 ITypeBinding typeBinding = this.resolver.getTypeBinding(superinterfaces[i]); 992 if (typeBinding == null) { 993 return this.bounds = NO_TYPE_BINDINGS; 994 } 995 typeBounds[boundsIndex] = typeBinding; 996 } 997 } 998 return this.bounds = typeBounds; 999 } 1000 } 1001 return this.bounds = NO_TYPE_BINDINGS; 1002 } 1003 1004 1007 public ITypeBinding[] getTypeParameters() { 1008 if (this.typeParameters != null) { 1009 return this.typeParameters; 1010 } 1011 switch(this.binding.kind()) { 1012 case Binding.RAW_TYPE : 1013 case Binding.PARAMETERIZED_TYPE : 1014 return this.typeParameters = NO_TYPE_BINDINGS; 1015 } 1016 TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables(); 1017 int typeVariableBindingsLength = typeVariableBindings == null ? 0 : typeVariableBindings.length; 1018 if (typeVariableBindingsLength != 0) { 1019 ITypeBinding[] newTypeParameters = new ITypeBinding[typeVariableBindingsLength]; 1020 for (int i = 0; i < typeVariableBindingsLength; i++) { 1021 ITypeBinding typeBinding = this.resolver.getTypeBinding(typeVariableBindings[i]); 1022 if (typeBinding == null) { 1023 return this.typeParameters = NO_TYPE_BINDINGS; 1024 } 1025 newTypeParameters[i] = typeBinding; 1026 } 1027 return this.typeParameters = newTypeParameters; 1028 } 1029 return this.typeParameters = NO_TYPE_BINDINGS; 1030 } 1031 1032 1036 public ITypeBinding getWildcard() { 1037 if (this.binding instanceof CaptureBinding) { 1038 CaptureBinding captureBinding = (CaptureBinding) this.binding; 1039 return this.resolver.getTypeBinding(captureBinding.wildcard); 1040 } 1041 return null; 1042 } 1043 1044 1048 public boolean isGenericType() { 1049 if (isRawType()) { 1051 return false; 1052 } 1053 TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables(); 1054 return (typeVariableBindings != null && typeVariableBindings.length > 0); 1055 } 1056 1057 1060 public boolean isAnnotation() { 1061 return this.binding.isAnnotationType(); 1062 } 1063 1064 1067 public boolean isAnonymous() { 1068 if (isClass() || isInterface() || isEnum()) { 1069 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 1070 return referenceBinding.isAnonymousType(); 1071 } 1072 return false; 1073 } 1074 1075 1078 public boolean isArray() { 1079 return binding.isArrayType(); 1080 } 1081 1082 1085 public boolean isAssignmentCompatible(ITypeBinding type) { 1086 try { 1087 if (this == type) return true; 1088 if (!(type instanceof TypeBinding)) return false; 1089 TypeBinding other = (TypeBinding) type; 1090 Scope scope = this.resolver.scope(); 1091 if (scope == null) return false; 1092 return this.binding.isCompatibleWith(other.binding) || scope.isBoxingCompatibleWith(this.binding, other.binding); 1093 } catch (AbortCompilation e) { 1094 return false; 1097 } 1098 } 1099 1100 1103 public boolean isCapture() { 1104 return this.binding.isCapture(); 1105 } 1106 1107 1110 public boolean isCastCompatible(ITypeBinding type) { 1111 try { 1112 Expression expression = new Expression() { 1113 public StringBuffer printExpression(int indent,StringBuffer output) { 1114 return null; 1115 } 1116 }; 1117 Scope scope = this.resolver.scope(); 1118 if (scope == null) return false; 1119 if (!(type instanceof TypeBinding)) return false; 1120 org.eclipse.jdt.internal.compiler.lookup.TypeBinding expressionType = ((TypeBinding) type).binding; 1121 expressionType = expressionType.capture(scope, 0); 1123 return expression.checkCastTypesCompatibility(scope, this.binding, expressionType, null); 1124 } catch (AbortCompilation e) { 1125 return false; 1128 } 1129 } 1130 1131 1134 public boolean isClass() { 1135 return this.binding.isClass() && !this.binding.isTypeVariable() && !this.binding.isWildcard(); 1136 } 1137 1138 1141 public boolean isDeprecated() { 1142 if (isClass() || isInterface() || isEnum()) { 1143 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 1144 return referenceBinding.isDeprecated(); 1145 } 1146 return false; 1147 } 1148 1149 1152 public boolean isEnum() { 1153 return this.binding.isEnum(); 1154 } 1155 1156 1160 public boolean isEqualTo(IBinding other) { 1161 if (other == this) { 1162 return true; 1164 } 1165 if (other == null) { 1166 return false; 1168 } 1169 if (!(other instanceof TypeBinding)) { 1170 return false; 1171 } 1172 org.eclipse.jdt.internal.compiler.lookup.TypeBinding otherBinding = ((TypeBinding) other).binding; 1173 return BindingComparator.isEqual(this.binding, otherBinding); 1175 } 1176 1177 1180 public boolean isFromSource() { 1181 if (isClass() || isInterface() || isEnum()) { 1182 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 1183 if (referenceBinding.isRawType()) { 1184 return !((RawTypeBinding) referenceBinding).genericType().isBinaryBinding(); 1185 } else if (referenceBinding.isParameterizedType()) { 1186 ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) referenceBinding; 1187 org.eclipse.jdt.internal.compiler.lookup.TypeBinding erasure = parameterizedTypeBinding.erasure(); 1188 if (erasure instanceof ReferenceBinding) { 1189 return !((ReferenceBinding) erasure).isBinaryBinding(); 1190 } 1191 return false; 1192 } else { 1193 return !referenceBinding.isBinaryBinding(); 1194 } 1195 } else if (isTypeVariable()) { 1196 final TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding; 1197 final Binding declaringElement = typeVariableBinding.declaringElement; 1198 if (declaringElement instanceof MethodBinding) { 1199 MethodBinding methodBinding = (MethodBinding) declaringElement; 1200 return !methodBinding.declaringClass.isBinaryBinding(); 1201 } else { 1202 final org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement; 1203 if (typeBinding instanceof ReferenceBinding) { 1204 return !((ReferenceBinding) typeBinding).isBinaryBinding(); 1205 } else if (typeBinding instanceof ArrayBinding) { 1206 final ArrayBinding arrayBinding = (ArrayBinding) typeBinding; 1207 final org.eclipse.jdt.internal.compiler.lookup.TypeBinding leafComponentType = arrayBinding.leafComponentType; 1208 if (leafComponentType instanceof ReferenceBinding) { 1209 return !((ReferenceBinding) leafComponentType).isBinaryBinding(); 1210 } 1211 } 1212 } 1213 1214 } else if (isCapture()) { 1215 CaptureBinding captureBinding = (CaptureBinding) this.binding; 1216 return !captureBinding.sourceType.isBinaryBinding(); 1217 } 1218 return false; 1219 } 1220 1221 1224 public boolean isInterface() { 1225 return this.binding.isInterface() && !this.binding.isTypeVariable() && !this.binding.isWildcard(); 1226 } 1227 1228 1231 public boolean isLocal() { 1232 if (isClass() || isInterface() || isEnum()) { 1233 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 1234 return referenceBinding.isLocalType() && !referenceBinding.isMemberType(); 1235 } 1236 return false; 1237 } 1238 1239 1242 public boolean isMember() { 1243 if (isClass() || isInterface() || isEnum()) { 1244 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 1245 return referenceBinding.isMemberType(); 1246 } 1247 return false; 1248 } 1249 1250 1253 public boolean isNested() { 1254 if (isClass() || isInterface() || isEnum()) { 1255 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 1256 return referenceBinding.isNestedType(); 1257 } 1258 return false; 1259 } 1260 1261 1264 public boolean isNullType() { 1265 return this.binding == org.eclipse.jdt.internal.compiler.lookup.TypeBinding.NULL; 1266 } 1267 1268 1271 public boolean isParameterizedType() { 1272 return this.binding.isParameterizedType() && ((ParameterizedTypeBinding) this.binding).arguments != null; 1273 } 1274 1275 1278 public boolean isPrimitive() { 1279 return !isNullType() && binding.isBaseType(); 1280 } 1281 1282 1285 public boolean isRawType() { 1286 return this.binding.isRawType(); 1287 } 1288 1289 1292 public boolean isRecovered() { 1293 return false; 1294 } 1295 1296 1299 public boolean isSubTypeCompatible(ITypeBinding type) { 1300 try { 1301 if (this == type) return true; 1302 if (this.binding.isBaseType()) return false; 1303 if (!(type instanceof TypeBinding)) return false; 1304 TypeBinding other = (TypeBinding) type; 1305 if (other.binding.isBaseType()) return false; 1306 return this.binding.isCompatibleWith(other.binding); 1307 } catch (AbortCompilation e) { 1308 return false; 1311 } 1312 } 1313 1314 1317 public boolean isSynthetic() { 1318 return false; 1319 } 1320 1321 1324 public boolean isTopLevel() { 1325 if (isClass() || isInterface() || isEnum()) { 1326 ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; 1327 return !referenceBinding.isNestedType(); 1328 } 1329 return false; 1330 } 1331 1332 1335 public boolean isTypeVariable() { 1336 return this.binding.isTypeVariable() && !this.binding.isCapture(); 1337 } 1338 1339 1342 public boolean isUpperbound() { 1343 return this.binding.isWildcard() && ((WildcardBinding) this.binding).boundKind == Wildcard.EXTENDS; 1344 } 1345 1346 1349 public boolean isWildcardType() { 1350 return this.binding.isWildcard(); 1351 } 1352 1353 private boolean shouldBeRemoved(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding) { 1354 return methodBinding.isDefaultAbstract() || methodBinding.isSynthetic() || (methodBinding.isConstructor() && isInterface()); 1355 } 1356 1357 1361 public String toString() { 1362 return this.binding.toString(); 1363 } 1364} 1365 | Popular Tags |