1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.ast.TypeReference; 15 import org.eclipse.jdt.internal.compiler.ast.Wildcard; 16 17 20 public class ParameterizedTypeBinding extends ReferenceBinding implements Substitution { 21 22 private ReferenceBinding type; public TypeBinding[] arguments; 24 public LookupEnvironment environment; 25 public char[] genericTypeSignature; 26 public ReferenceBinding superclass; 27 public ReferenceBinding[] superInterfaces; 28 public FieldBinding[] fields; 29 public ReferenceBinding[] memberTypes; 30 public MethodBinding[] methods; 31 private ReferenceBinding enclosingType; 32 33 public ParameterizedTypeBinding(ReferenceBinding type, TypeBinding[] arguments, ReferenceBinding enclosingType, LookupEnvironment environment){ 34 35 this.environment = environment; 36 this.enclosingType = enclosingType; initialize(type, arguments); 43 if (type instanceof UnresolvedReferenceBinding) 44 ((UnresolvedReferenceBinding) type).addWrapper(this, environment); 45 if (arguments != null) { 46 for (int i = 0, l = arguments.length; i < l; i++) 47 if (arguments[i] instanceof UnresolvedReferenceBinding) 48 ((UnresolvedReferenceBinding) arguments[i]).addWrapper(this, environment); 49 } 50 this.tagBits |= TagBits.HasUnresolvedTypeVariables; } 52 53 57 protected ReferenceBinding actualType() { 58 return this.type; 59 } 60 61 64 public void boundCheck(Scope scope, TypeReference[] argumentReferences) { 65 if ((this.tagBits & TagBits.PassedBoundCheck) == 0) { 66 boolean hasErrors = false; 67 TypeVariableBinding[] typeVariables = this.type.typeVariables(); 68 if (this.arguments != null && typeVariables != null) { for (int i = 0, length = typeVariables.length; i < length; i++) { 70 if (typeVariables[i].boundCheck(this, this.arguments[i]) != TypeConstants.OK) { 71 hasErrors = true; 72 scope.problemReporter().typeMismatchError(this.arguments[i], typeVariables[i], this.type, argumentReferences[i]); 73 } 74 } 75 } 76 if (!hasErrors) this.tagBits |= TagBits.PassedBoundCheck; } 78 } 79 82 public boolean canBeInstantiated() { 83 return ((this.tagBits & TagBits.HasDirectWildcard) == 0) && super.canBeInstantiated(); } 85 89 public TypeBinding capture(Scope scope, int position) { 90 if ((this.tagBits & TagBits.HasDirectWildcard) == 0) 91 return this; 92 93 TypeBinding[] originalArguments = arguments; 94 int length = originalArguments.length; 95 TypeBinding[] capturedArguments = new TypeBinding[length]; 96 97 ReferenceBinding contextType = scope.enclosingSourceType(); 99 if (contextType != null) contextType = contextType.outermostEnclosingType(); 101 for (int i = 0; i < length; i++) { 102 TypeBinding argument = originalArguments[i]; 103 if (argument.kind() == Binding.WILDCARD_TYPE && ((WildcardBinding)argument).otherBounds == null) { capturedArguments[i] = new CaptureBinding((WildcardBinding) argument, contextType, position, scope.compilationUnitScope().nextCaptureID()); 105 } else { 106 capturedArguments[i] = argument; 107 } 108 } 109 ParameterizedTypeBinding capturedParameterizedType = this.environment.createParameterizedType(this.type, capturedArguments, enclosingType()); 110 for (int i = 0; i < length; i++) { 111 TypeBinding argument = capturedArguments[i]; 112 if (argument.isCapture()) { 113 ((CaptureBinding)argument).initializeBounds(scope, capturedParameterizedType); 114 } 115 } 116 return capturedParameterizedType; 117 } 118 126 public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) { 127 128 if ((this.tagBits & TagBits.HasTypeVariable) == 0) return; 129 if (actualType == TypeBinding.NULL) return; 130 131 if (!(actualType instanceof ReferenceBinding)) return; 132 TypeBinding formalEquivalent, actualEquivalent; 133 switch (constraint) { 134 case TypeConstants.CONSTRAINT_EQUAL : 135 case TypeConstants.CONSTRAINT_EXTENDS : 136 formalEquivalent = this; 137 actualEquivalent = actualType.findSuperTypeWithSameErasure(this.type); 138 if (actualEquivalent == null) return; 139 break; 140 case TypeConstants.CONSTRAINT_SUPER : 141 default: 142 formalEquivalent = this.findSuperTypeWithSameErasure(actualType); 143 if (formalEquivalent == null) return; 144 actualEquivalent = actualType; 145 break; 146 } 147 ReferenceBinding formalEnclosingType = formalEquivalent.enclosingType(); 149 if (formalEnclosingType != null) { 150 formalEnclosingType.collectSubstitutes(scope, actualEquivalent.enclosingType(), inferenceContext, constraint); 151 } 152 if (this.arguments == null) return; 154 TypeBinding[] formalArguments; 155 switch (formalEquivalent.kind()) { 156 case Binding.GENERIC_TYPE : 157 formalArguments = formalEquivalent.typeVariables(); 158 break; 159 case Binding.PARAMETERIZED_TYPE : 160 formalArguments = ((ParameterizedTypeBinding)formalEquivalent).arguments; 161 break; 162 case Binding.RAW_TYPE : 163 if (!inferenceContext.checkRawSubstitution()) { 164 inferenceContext.status = InferenceContext.FAILED; } 166 return; 167 default : 168 return; 169 } 170 TypeBinding[] actualArguments; 171 switch (actualEquivalent.kind()) { 172 case Binding.GENERIC_TYPE : 173 actualArguments = actualEquivalent.typeVariables(); 174 break; 175 case Binding.PARAMETERIZED_TYPE : 176 actualArguments = ((ParameterizedTypeBinding)actualEquivalent).arguments; 177 break; 178 case Binding.RAW_TYPE : 179 if (!inferenceContext.checkRawSubstitution()) { 180 inferenceContext.status = InferenceContext.FAILED; } 182 return; 183 default : 184 return; 185 } 186 inferenceContext.depth++; 187 for (int i = 0, length = formalArguments.length; i < length; i++) { 188 TypeBinding formalArgument = formalArguments[i]; 189 TypeBinding actualArgument = actualArguments[i]; 190 if (formalArgument.isWildcard()) { 191 formalArgument.collectSubstitutes(scope, actualArgument, inferenceContext, constraint); 192 continue; 193 } else if (actualArgument.isWildcard()){ 194 WildcardBinding actualWildcardArgument = (WildcardBinding) actualArgument; 195 if (actualWildcardArgument.otherBounds == null) { 196 if (constraint == TypeConstants.CONSTRAINT_SUPER) { switch(actualWildcardArgument.boundKind) { 198 case Wildcard.EXTENDS : 199 formalArgument.collectSubstitutes(scope, actualWildcardArgument.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER); 200 continue; 201 case Wildcard.SUPER : 202 formalArgument.collectSubstitutes(scope, actualWildcardArgument.bound, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS); 203 continue; 204 default : 205 continue; } 207 } else { 208 continue; } 210 } 211 } 212 formalArgument.collectSubstitutes(scope, actualArgument, inferenceContext, TypeConstants.CONSTRAINT_EQUAL); 214 } 215 inferenceContext.depth--; 216 } 217 218 221 public void computeId() { 222 this.id = TypeIds.NoId; 223 } 224 225 public char[] computeUniqueKey(boolean isLeaf) { 226 StringBuffer sig = new StringBuffer (10); 227 ReferenceBinding enclosing; 228 if (isMemberType() && ((enclosing = enclosingType()).isParameterizedType() || enclosing.isRawType())) { 229 char[] typeSig = enclosing.computeUniqueKey(false); 230 for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); sig.append('.').append(sourceName()); 232 } else if(this.type.isLocalType()){ 233 LocalTypeBinding localTypeBinding = (LocalTypeBinding) this.type; 234 enclosing = localTypeBinding.enclosingType(); 235 ReferenceBinding temp; 236 while ((temp = enclosing.enclosingType()) != null) 237 enclosing = temp; 238 char[] typeSig = enclosing.computeUniqueKey(false); 239 for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); sig.append('$'); 241 sig.append(localTypeBinding.sourceStart); 242 } else { 243 char[] typeSig = this.type.computeUniqueKey(false); 244 for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); } 246 ReferenceBinding captureSourceType = null; 247 if (this.arguments != null) { 248 sig.append('<'); 249 for (int i = 0, length = this.arguments.length; i < length; i++) { 250 TypeBinding typeBinding = this.arguments[i]; 251 sig.append(typeBinding.computeUniqueKey(false)); 252 if (typeBinding instanceof CaptureBinding) 253 captureSourceType = ((CaptureBinding) typeBinding).sourceType; 254 } 255 sig.append('>'); 256 } 257 sig.append(';'); 258 if (captureSourceType != null && captureSourceType != this.type) { 259 sig.insert(0, "&"); sig.insert(0, captureSourceType.computeUniqueKey(false)); 262 } 263 264 int sigLength = sig.length(); 265 char[] uniqueKey = new char[sigLength]; 266 sig.getChars(0, sigLength, uniqueKey, 0); 267 return uniqueKey; 268 } 269 270 273 public char[] constantPoolName() { 274 return this.type.constantPoolName(); } 276 277 public ParameterizedMethodBinding createParameterizedMethod(MethodBinding originalMethod) { 278 return new ParameterizedMethodBinding(this, originalMethod); 279 } 280 281 284 public String debugName() { 285 StringBuffer nameBuffer = new StringBuffer (10); 286 nameBuffer.append(this.type.sourceName()); 287 if (this.arguments != null) { 288 nameBuffer.append('<'); 289 for (int i = 0, length = this.arguments.length; i < length; i++) { 290 if (i > 0) nameBuffer.append(','); 291 nameBuffer.append(this.arguments[i].debugName()); 292 } 293 nameBuffer.append('>'); 294 } 295 return nameBuffer.toString(); 296 } 297 298 301 public ReferenceBinding enclosingType() { 302 return this.enclosingType; 303 } 304 305 308 public LookupEnvironment environment() { 309 return this.environment; 310 } 311 312 315 public TypeBinding erasure() { 316 return this.type.erasure(); } 318 321 public int fieldCount() { 322 return this.type.fieldCount(); } 324 325 328 public FieldBinding[] fields() { 329 if ((tagBits & TagBits.AreFieldsComplete) != 0) 330 return this.fields; 331 332 try { 333 FieldBinding[] originalFields = this.type.fields(); 334 int length = originalFields.length; 335 FieldBinding[] parameterizedFields = new FieldBinding[length]; 336 for (int i = 0; i < length; i++) 337 parameterizedFields[i] = new ParameterizedFieldBinding(this, originalFields[i]); 339 this.fields = parameterizedFields; 340 } finally { 341 if (this.fields == null) 343 this.fields = Binding.NO_FIELDS; 344 tagBits |= TagBits.AreFieldsComplete; 345 } 346 return this.fields; 347 } 348 349 354 public ReferenceBinding genericType() { 355 if (this.type instanceof UnresolvedReferenceBinding) 356 ((UnresolvedReferenceBinding) this.type).resolve(this.environment, false); 357 return this.type; 358 } 359 360 364 public char[] genericTypeSignature() { 365 if (this.genericTypeSignature == null) { 366 StringBuffer sig = new StringBuffer (10); 367 if (this.isMemberType() && this.enclosingType().isParameterizedType()) { 368 char[] typeSig = this.enclosingType().genericTypeSignature(); 369 for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); sig.append('.').append(this.sourceName()); 371 } else { 372 char[] typeSig = this.type.signature(); 373 for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); } 375 if (this.arguments != null) { 376 sig.append('<'); 377 for (int i = 0, length = this.arguments.length; i < length; i++) { 378 sig.append(this.arguments[i].genericTypeSignature()); 379 } 380 sig.append('>'); 381 } 382 sig.append(';'); 383 int sigLength = sig.length(); 384 this.genericTypeSignature = new char[sigLength]; 385 sig.getChars(0, sigLength, this.genericTypeSignature, 0); 386 } 387 return this.genericTypeSignature; 388 } 389 390 393 public long getAnnotationTagBits() { 394 return this.type.getAnnotationTagBits(); 395 } 396 397 400 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) { 401 int argCount = argumentTypes.length; 402 MethodBinding match = null; 403 404 if ((tagBits & TagBits.AreMethodsComplete) != 0) { long range; 406 if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) { 407 nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) { 408 MethodBinding method = methods[imethod]; 409 if (method.parameters.length == argCount) { 410 TypeBinding[] toMatch = method.parameters; 411 for (int iarg = 0; iarg < argCount; iarg++) 412 if (toMatch[iarg] != argumentTypes[iarg]) 413 continue nextMethod; 414 if (match != null) return null; match = method; 416 } 417 } 418 } 419 } else { 420 MethodBinding[] matchingMethods = getMethods(TypeConstants.INIT); nextMethod : for (int m = matchingMethods.length; --m >= 0;) { 422 MethodBinding method = matchingMethods[m]; 423 TypeBinding[] toMatch = method.parameters; 424 if (toMatch.length == argCount) { 425 for (int p = 0; p < argCount; p++) 426 if (toMatch[p] != argumentTypes[p]) 427 continue nextMethod; 428 if (match != null) return null; match = method; 430 } 431 } 432 } 433 return match; 434 } 435 436 439 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) { 440 int argCount = argumentTypes.length; 442 boolean foundNothing = true; 443 MethodBinding match = null; 444 445 if ((tagBits & TagBits.AreMethodsComplete) != 0) { long range; 447 if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) { 448 nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) { 449 MethodBinding method = methods[imethod]; 450 foundNothing = false; if (method.parameters.length == argCount) { 452 TypeBinding[] toMatch = method.parameters; 453 for (int iarg = 0; iarg < argCount; iarg++) 454 if (toMatch[iarg] != argumentTypes[iarg]) 455 continue nextMethod; 456 if (match != null) return null; match = method; 458 } 459 } 460 } 461 } else { 462 MethodBinding[] matchingMethods = getMethods(selector); foundNothing = matchingMethods == Binding.NO_METHODS; 464 nextMethod : for (int m = matchingMethods.length; --m >= 0;) { 465 MethodBinding method = matchingMethods[m]; 466 TypeBinding[] toMatch = method.parameters; 467 if (toMatch.length == argCount) { 468 for (int p = 0; p < argCount; p++) 469 if (toMatch[p] != argumentTypes[p]) 470 continue nextMethod; 471 if (match != null) return null; match = method; 473 } 474 } 475 } 476 if (match != null) { 477 if (match.hasSubstitutedParameters()) return null; 481 return match; 482 } 483 484 if (foundNothing && (this.arguments == null || this.arguments.length <= 1)) { 485 if (isInterface()) { 486 if (superInterfaces().length == 1) { 487 if (refScope != null) 488 refScope.recordTypeReference(superInterfaces[0]); 489 return superInterfaces[0].getExactMethod(selector, argumentTypes, refScope); 490 } 491 } else if (superclass() != null) { 492 if (refScope != null) 493 refScope.recordTypeReference(superclass); 494 return superclass.getExactMethod(selector, argumentTypes, refScope); 495 } 496 } 497 return null; 498 } 499 500 503 public FieldBinding getField(char[] fieldName, boolean needResolve) { 504 fields(); return ReferenceBinding.binarySearch(fieldName, this.fields); 506 } 507 508 511 public ReferenceBinding getMemberType(char[] typeName) { 512 memberTypes(); int typeLength = typeName.length; 514 for (int i = this.memberTypes.length; --i >= 0;) { 515 ReferenceBinding memberType = this.memberTypes[i]; 516 if (memberType.sourceName.length == typeLength && CharOperation.equals(memberType.sourceName, typeName)) 517 return memberType; 518 } 519 return null; 520 } 521 522 525 public MethodBinding[] getMethods(char[] selector) { 526 if (this.methods != null) { 527 long range; 528 if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) { 529 int start = (int) range; 530 int length = (int) (range >> 32) - start + 1; 531 MethodBinding[] result; 535 System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length); 536 return result; 537 } 538 } 539 if ((tagBits & TagBits.AreMethodsComplete) != 0) 540 return Binding.NO_METHODS; 542 MethodBinding[] parameterizedMethods = null; 543 try { 544 MethodBinding[] originalMethods = this.type.getMethods(selector); 545 int length = originalMethods.length; 546 if (length == 0) return Binding.NO_METHODS; 547 548 parameterizedMethods = new MethodBinding[length]; 549 for (int i = 0; i < length; i++) 550 parameterizedMethods[i] = createParameterizedMethod(originalMethods[i]); 552 if (this.methods == null) { 553 MethodBinding[] temp = new MethodBinding[length]; 554 System.arraycopy(parameterizedMethods, 0, temp, 0, length); 555 this.methods = temp; } else { 557 int total = length + this.methods.length; 558 MethodBinding[] temp = new MethodBinding[total]; 559 System.arraycopy(parameterizedMethods, 0, temp, 0, length); 560 System.arraycopy(this.methods, 0, temp, length, this.methods.length); 561 if (total > 1) 562 ReferenceBinding.sortMethods(temp, 0, total); this.methods = temp; 564 } 565 return parameterizedMethods; 566 } finally { 567 if (parameterizedMethods == null) 569 this.methods = parameterizedMethods = Binding.NO_METHODS; 570 } 571 } 572 573 public boolean hasMemberTypes() { 574 return this.type.hasMemberTypes(); 575 } 576 577 580 public boolean implementsMethod(MethodBinding method) { 581 return this.type.implementsMethod(method); } 583 584 void initialize(ReferenceBinding someType, TypeBinding[] someArguments) { 585 this.type = someType; 586 this.sourceName = someType.sourceName; 587 this.compoundName = someType.compoundName; 588 this.fPackage = someType.fPackage; 589 this.fileName = someType.fileName; 590 this.modifiers = someType.modifiers & ~ExtraCompilerModifiers.AccGenericSignature; if (someArguments != null) { 598 this.modifiers |= ExtraCompilerModifiers.AccGenericSignature; 599 } else if (this.enclosingType != null) { 600 this.modifiers |= (this.enclosingType.modifiers & ExtraCompilerModifiers.AccGenericSignature); 601 this.tagBits |= this.enclosingType.tagBits & TagBits.HasTypeVariable; 602 } 603 if (someArguments != null) { 604 this.arguments = someArguments; 605 for (int i = 0, length = someArguments.length; i < length; i++) { 606 TypeBinding someArgument = someArguments[i]; 607 boolean isWildcardArgument = someArgument.isWildcard(); 608 if (isWildcardArgument) { 609 this.tagBits |= TagBits.HasDirectWildcard; 610 } 611 if (!isWildcardArgument || ((WildcardBinding) someArgument).boundKind != Wildcard.UNBOUND) { 612 this.tagBits |= TagBits.IsBoundParameterizedType; 613 } 614 this.tagBits |= someArgument.tagBits & TagBits.HasTypeVariable; 615 } 616 } 617 this.tagBits |= someType.tagBits & (TagBits.IsLocalType| TagBits.IsMemberType | TagBits.IsNestedType); 618 this.tagBits &= ~(TagBits.AreFieldsComplete|TagBits.AreMethodsComplete); 619 } 620 621 protected void initializeArguments() { 622 } 624 625 public boolean isEquivalentTo(TypeBinding otherType) { 626 if (this == otherType) 627 return true; 628 if (otherType == null) 629 return false; 630 switch(otherType.kind()) { 631 632 case Binding.WILDCARD_TYPE : 633 return ((WildcardBinding) otherType).boundCheck(this); 634 635 case Binding.PARAMETERIZED_TYPE : 636 ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType; 637 if (this.type != otherParamType.type) 638 return false; 639 if (!isStatic()) { ReferenceBinding enclosing = enclosingType(); 641 if (enclosing != null) { 642 ReferenceBinding otherEnclosing = otherParamType.enclosingType(); 643 if (otherEnclosing == null) return false; 644 if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) { 645 if (enclosing != otherEnclosing) return false; 646 } else { 647 if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false; 648 } 649 } 650 } 651 if (this.arguments == null) { 652 return otherParamType.arguments == null; 653 } 654 int length = this.arguments.length; 655 TypeBinding[] otherArguments = otherParamType.arguments; 656 if (otherArguments == null || otherArguments.length != length) return false; 657 for (int i = 0; i < length; i++) { 658 if (!this.arguments[i].isTypeArgumentContainedBy(otherArguments[i])) 659 return false; 660 } 661 return true; 662 663 case Binding.RAW_TYPE : 664 return erasure() == otherType.erasure(); 665 } 666 return false; 667 } 668 669 public boolean isIntersectingWith(TypeBinding otherType) { 670 if (this == otherType) 671 return true; 672 if (otherType == null) 673 return false; 674 switch(otherType.kind()) { 675 676 case Binding.PARAMETERIZED_TYPE : 677 ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType; 678 if (this.type != otherParamType.type) 679 return false; 680 if (!isStatic()) { ReferenceBinding enclosing = enclosingType(); 682 if (enclosing != null) { 683 ReferenceBinding otherEnclosing = otherParamType.enclosingType(); 684 if (otherEnclosing == null) return false; 685 if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) { 686 if (enclosing != otherEnclosing) return false; 687 } else { 688 if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false; 689 } 690 } 691 } 692 int length = this.arguments == null ? 0 : this.arguments.length; 693 TypeBinding[] otherArguments = otherParamType.arguments; 694 int otherLength = otherArguments == null ? 0 : otherArguments.length; 695 if (otherLength != length) 696 return false; 697 for (int i = 0; i < length; i++) { 698 if (!this.arguments[i].isTypeArgumentIntersecting(otherArguments[i])) 699 return false; 700 } 701 return true; 702 703 case Binding.GENERIC_TYPE : 704 SourceTypeBinding otherGenericType = (SourceTypeBinding) otherType; 705 if (this.type != otherGenericType) 706 return false; 707 if (!isStatic()) { ReferenceBinding enclosing = enclosingType(); 709 if (enclosing != null) { 710 ReferenceBinding otherEnclosing = otherGenericType.enclosingType(); 711 if (otherEnclosing == null) return false; 712 if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) { 713 if (enclosing != otherEnclosing) return false; 714 } else { 715 if (!enclosing.isEquivalentTo(otherGenericType.enclosingType())) return false; 716 } 717 } 718 } 719 length = this.arguments == null ? 0 : this.arguments.length; 720 otherArguments = otherGenericType.typeVariables(); 721 otherLength = otherArguments == null ? 0 : otherArguments.length; 722 if (otherLength != length) 723 return false; 724 for (int i = 0; i < length; i++) { 725 if (!this.arguments[i].isTypeArgumentIntersecting(otherArguments[i])) 726 return false; 727 } 728 return true; 729 730 case Binding.RAW_TYPE : 731 return erasure() == otherType.erasure(); 732 } 733 return false; 734 } 735 736 739 public boolean isParameterizedType() { 740 return true; 741 } 742 743 746 public boolean isRawSubstitution() { 747 return isRawType(); 748 } 749 750 public int kind() { 751 return PARAMETERIZED_TYPE; 752 } 753 754 757 public ReferenceBinding[] memberTypes() { 758 if (this.memberTypes == null) { 759 try { 760 ReferenceBinding[] originalMemberTypes = this.type.memberTypes(); 761 int length = originalMemberTypes.length; 762 ReferenceBinding[] parameterizedMemberTypes = new ReferenceBinding[length]; 763 for (int i = 0; i < length; i++) 765 parameterizedMemberTypes[i] = this.environment.createParameterizedType(originalMemberTypes[i], null, this); 769 this.memberTypes = parameterizedMemberTypes; 770 } finally { 771 if (this.memberTypes == null) 773 this.memberTypes = Binding.NO_MEMBER_TYPES; 774 } 775 } 776 return this.memberTypes; 777 } 778 779 782 public MethodBinding[] methods() { 783 if ((tagBits & TagBits.AreMethodsComplete) != 0) 784 return this.methods; 785 786 try { 787 MethodBinding[] originalMethods = this.type.methods(); 788 int length = originalMethods.length; 789 MethodBinding[] parameterizedMethods = new MethodBinding[length]; 790 for (int i = 0; i < length; i++) 791 parameterizedMethods[i] = createParameterizedMethod(originalMethods[i]); 793 this.methods = parameterizedMethods; 794 } finally { 795 if (this.methods == null) 797 this.methods = Binding.NO_METHODS; 798 799 tagBits |= TagBits.AreMethodsComplete; 800 } 801 return this.methods; 802 } 803 804 807 public char[] qualifiedPackageName() { 808 return this.type.qualifiedPackageName(); 809 } 810 811 814 public char[] qualifiedSourceName() { 815 return this.type.qualifiedSourceName(); 816 } 817 818 821 public char[] readableName() { 822 StringBuffer nameBuffer = new StringBuffer (10); 823 if (this.isMemberType()) { 824 nameBuffer.append(CharOperation.concat(this.enclosingType().readableName(), sourceName, '.')); 825 } else { 826 nameBuffer.append(CharOperation.concatWith(this.type.compoundName, '.')); 827 } 828 if (this.arguments != null) { 829 nameBuffer.append('<'); 830 for (int i = 0, length = this.arguments.length; i < length; i++) { 831 if (i > 0) nameBuffer.append(','); 832 nameBuffer.append(this.arguments[i].readableName()); 833 } 834 nameBuffer.append('>'); 835 } 836 int nameLength = nameBuffer.length(); 837 char[] readableName = new char[nameLength]; 838 nameBuffer.getChars(0, nameLength, readableName, 0); 839 return readableName; 840 } 841 842 ReferenceBinding resolve() { 843 if ((this.tagBits & TagBits.HasUnresolvedTypeVariables) == 0) 844 return this; 845 846 this.tagBits &= ~TagBits.HasUnresolvedTypeVariables; ReferenceBinding resolvedType = BinaryTypeBinding.resolveType(this.type, this.environment, false); if (this.arguments != null) { 849 int argLength = this.arguments.length; 850 for (int i = 0; i < argLength; i++) 851 BinaryTypeBinding.resolveType(this.arguments[i], this.environment, this, i); 852 TypeVariableBinding[] refTypeVariables = resolvedType.typeVariables(); 854 if (refTypeVariables == Binding.NO_TYPE_VARIABLES) { this.environment.problemReporter.nonGenericTypeCannotBeParameterized(null, resolvedType, this.arguments); 856 return this; } else if (argLength != refTypeVariables.length) { this.environment.problemReporter.incorrectArityForParameterizedType(null, resolvedType, this.arguments); 859 return this; } 861 } 869 return this; 870 } 871 872 875 public char[] shortReadableName() { 876 StringBuffer nameBuffer = new StringBuffer (10); 877 if (this.isMemberType()) { 878 nameBuffer.append(CharOperation.concat(this.enclosingType().shortReadableName(), sourceName, '.')); 879 } else { 880 nameBuffer.append(this.type.sourceName); 881 } 882 if (this.arguments != null) { 883 nameBuffer.append('<'); 884 for (int i = 0, length = this.arguments.length; i < length; i++) { 885 if (i > 0) nameBuffer.append(','); 886 nameBuffer.append(this.arguments[i].shortReadableName()); 887 } 888 nameBuffer.append('>'); 889 } 890 int nameLength = nameBuffer.length(); 891 char[] shortReadableName = new char[nameLength]; 892 nameBuffer.getChars(0, nameLength, shortReadableName, 0); 893 return shortReadableName; 894 } 895 896 899 public char[] signature() { 900 if (this.signature == null) { 901 this.signature = this.type.signature(); } 903 return this.signature; 904 } 905 906 909 public char[] sourceName() { 910 return this.type.sourceName(); 911 } 912 913 916 public TypeBinding substitute(TypeVariableBinding originalVariable) { 917 918 ParameterizedTypeBinding currentType = this; 919 while (true) { 920 TypeVariableBinding[] typeVariables = currentType.type.typeVariables(); 921 int length = typeVariables.length; 922 if (originalVariable.rank < length && typeVariables[originalVariable.rank] == originalVariable) { 924 if (currentType.arguments == null) 926 currentType.initializeArguments(); if (currentType.arguments != null) 928 return currentType.arguments[originalVariable.rank]; 929 } 930 if (currentType.isStatic()) break; 932 ReferenceBinding enclosing = currentType.enclosingType(); 933 if (!(enclosing instanceof ParameterizedTypeBinding)) 934 break; 935 currentType = (ParameterizedTypeBinding) enclosing; 936 } 937 return originalVariable; 938 } 939 940 943 public ReferenceBinding superclass() { 944 if (this.superclass == null) { 945 ReferenceBinding genericSuperclass = this.type.superclass(); 947 if (genericSuperclass == null) return null; this.superclass = (ReferenceBinding) Scope.substitute(this, genericSuperclass); 949 } 950 return this.superclass; 951 } 952 953 956 public ReferenceBinding[] superInterfaces() { 957 if (this.superInterfaces == null) { 958 if (this.type.isHierarchyBeingConnected()) 959 return Binding.NO_SUPERINTERFACES; this.superInterfaces = Scope.substitute(this, this.type.superInterfaces()); 961 } 962 return this.superInterfaces; 963 } 964 965 public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) { 966 boolean update = false; 967 if (this.type == unresolvedType) { 968 this.type = resolvedType; update = true; 970 ReferenceBinding enclosing = resolvedType.enclosingType(); 971 if (enclosing != null) { 972 this.enclosingType = (ReferenceBinding) env.convertUnresolvedBinaryToRawType(enclosing); } 974 } 975 if (this.arguments != null) { 976 for (int i = 0, l = this.arguments.length; i < l; i++) { 977 if (this.arguments[i] == unresolvedType) { 978 this.arguments[i] = env.convertUnresolvedBinaryToRawType(resolvedType); 979 update = true; 980 } 981 } 982 } 983 if (update) 984 initialize(this.type, this.arguments); 985 } 986 987 990 public ReferenceBinding[] syntheticEnclosingInstanceTypes() { 991 return this.type.syntheticEnclosingInstanceTypes(); 992 } 993 994 997 public SyntheticArgumentBinding[] syntheticOuterLocalVariables() { 998 return this.type.syntheticOuterLocalVariables(); 999 } 1000 1001 1004 public String toString() { 1005 StringBuffer buffer = new StringBuffer (30); 1006 if (isDeprecated()) buffer.append("deprecated "); if (isPublic()) buffer.append("public "); if (isProtected()) buffer.append("protected "); if (isPrivate()) buffer.append("private "); if (isAbstract() && isClass()) buffer.append("abstract "); if (isStatic() && isNestedType()) buffer.append("static "); if (isFinal()) buffer.append("final "); 1014 if (isEnum()) buffer.append("enum "); else if (isAnnotationType()) buffer.append("@interface "); else if (isClass()) buffer.append("class "); else buffer.append("interface "); buffer.append(this.debugName()); 1019 1020 buffer.append("\n\textends "); buffer.append((superclass != null) ? superclass.debugName() : "NULL TYPE"); 1023 if (superInterfaces != null) { 1024 if (superInterfaces != Binding.NO_SUPERINTERFACES) { 1025 buffer.append("\n\timplements : "); for (int i = 0, length = superInterfaces.length; i < length; i++) { 1027 if (i > 0) 1028 buffer.append(", "); buffer.append((superInterfaces[i] != null) ? superInterfaces[i].debugName() : "NULL TYPE"); } 1031 } 1032 } else { 1033 buffer.append("NULL SUPERINTERFACES"); } 1035 1036 if (enclosingType() != null) { 1037 buffer.append("\n\tenclosing type : "); buffer.append(enclosingType().debugName()); 1039 } 1040 1041 if (fields != null) { 1042 if (fields != Binding.NO_FIELDS) { 1043 buffer.append("\n/* fields */"); for (int i = 0, length = fields.length; i < length; i++) 1045 buffer.append('\n').append((fields[i] != null) ? fields[i].toString() : "NULL FIELD"); } 1047 } else { 1048 buffer.append("NULL FIELDS"); } 1050 1051 if (methods != null) { 1052 if (methods != Binding.NO_METHODS) { 1053 buffer.append("\n/* methods */"); for (int i = 0, length = methods.length; i < length; i++) 1055 buffer.append('\n').append((methods[i] != null) ? methods[i].toString() : "NULL METHOD"); } 1057 } else { 1058 buffer.append("NULL METHODS"); } 1060 1061 1071 buffer.append("\n\n"); return buffer.toString(); 1073 1074 } 1075 1076 public TypeVariableBinding[] typeVariables() { 1077 if (this.arguments == null) { 1078 return this.type.typeVariables(); 1080 } 1081 return Binding.NO_TYPE_VARIABLES; 1082 } 1083} 1084 | Popular Tags |