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.ClassFile; 15 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 16 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 17 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 18 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 19 import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; 20 21 public class MethodBinding extends Binding { 22 23 public int modifiers; 24 public char[] selector; 25 public TypeBinding returnType; 26 public TypeBinding[] parameters; 27 public ReferenceBinding[] thrownExceptions; 28 public ReferenceBinding declaringClass; 29 public TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES; 30 char[] signature; 31 public long tagBits; 32 33 protected MethodBinding() { 34 } 36 public MethodBinding(int modifiers, char[] selector, TypeBinding returnType, TypeBinding[] parameters, ReferenceBinding[] thrownExceptions, ReferenceBinding declaringClass) { 37 this.modifiers = modifiers; 38 this.selector = selector; 39 this.returnType = returnType; 40 this.parameters = (parameters == null || parameters.length == 0) ? Binding.NO_PARAMETERS : parameters; 41 this.thrownExceptions = (thrownExceptions == null || thrownExceptions.length == 0) ? Binding.NO_EXCEPTIONS : thrownExceptions; 42 this.declaringClass = declaringClass; 43 44 if (this.declaringClass != null) { 46 if (this.declaringClass.isStrictfp()) 47 if (!(isNative() || isAbstract())) 48 this.modifiers |= ClassFileConstants.AccStrictfp; 49 } 50 } 51 public MethodBinding(int modifiers, TypeBinding[] parameters, ReferenceBinding[] thrownExceptions, ReferenceBinding declaringClass) { 52 this(modifiers, TypeConstants.INIT, TypeBinding.VOID, parameters, thrownExceptions, declaringClass); 53 } 54 public MethodBinding(MethodBinding initialMethodBinding, ReferenceBinding declaringClass) { 56 this.modifiers = initialMethodBinding.modifiers; 57 this.selector = initialMethodBinding.selector; 58 this.returnType = initialMethodBinding.returnType; 59 this.parameters = initialMethodBinding.parameters; 60 this.thrownExceptions = initialMethodBinding.thrownExceptions; 61 this.declaringClass = declaringClass; 62 declaringClass.storeAnnotationHolder(this, initialMethodBinding.declaringClass.retrieveAnnotationHolder(initialMethodBinding, true)); 63 } 64 66 public final boolean areParameterErasuresEqual(MethodBinding method) { 67 TypeBinding[] args = method.parameters; 68 if (parameters == args) 69 return true; 70 71 int length = parameters.length; 72 if (length != args.length) 73 return false; 74 75 for (int i = 0; i < length; i++) 76 if (parameters[i] != args[i] && parameters[i].erasure() != args[i].erasure()) 77 return false; 78 return true; 79 } 80 82 public final boolean areParametersEqual(MethodBinding method) { 83 TypeBinding[] args = method.parameters; 84 if (parameters == args) 85 return true; 86 87 int length = parameters.length; 88 if (length != args.length) 89 return false; 90 91 for (int i = 0; i < length; i++) 92 if (parameters[i] != args[i]) 93 return false; 94 return true; 95 } 96 101 public final boolean areParametersCompatibleWith(TypeBinding[] arguments) { 102 int paramLength = this.parameters.length; 103 int argLength = arguments.length; 104 int lastIndex = argLength; 105 if (isVarargs()) { 106 lastIndex = paramLength - 1; 107 if (paramLength == argLength) { TypeBinding varArgType = parameters[lastIndex]; TypeBinding lastArgument = arguments[lastIndex]; 110 if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType)) 111 return false; 112 } else if (paramLength < argLength) { TypeBinding varArgType = ((ArrayBinding) parameters[lastIndex]).elementsType(); 114 for (int i = lastIndex; i < argLength; i++) 115 if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType)) 116 return false; 117 } else if (lastIndex != argLength) { return false; 119 } 120 } 122 for (int i = 0; i < lastIndex; i++) 123 if (parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(parameters[i])) 124 return false; 125 return true; 126 } 127 128 131 132 public final int kind() { 133 return Binding.METHOD; 134 } 135 137 138 public final boolean canBeSeenBy(PackageBinding invocationPackage) { 139 if (isPublic()) return true; 140 if (isPrivate()) return false; 141 142 return invocationPackage == declaringClass.getPackage(); 144 } 145 147 public final boolean areTypeVariableErasuresEqual(MethodBinding method) { 148 TypeVariableBinding[] vars = method.typeVariables; 149 if (this.typeVariables == vars) 150 return true; 151 152 int length = this.typeVariables.length; 153 if (length != vars.length) 154 return false; 155 156 for (int i = 0; i < length; i++) 157 if (this.typeVariables[i] != vars[i] && this.typeVariables[i].erasure() != vars[i].erasure()) 158 return false; 159 return true; 160 } 161 169 170 public final boolean canBeSeenBy(InvocationSite invocationSite, Scope scope) { 171 if (isPublic()) return true; 172 173 SourceTypeBinding invocationType = scope.enclosingSourceType(); 174 if (invocationType == declaringClass) return true; 175 176 if (isProtected()) { 177 if (invocationType.fPackage == declaringClass.fPackage) return true; 179 return invocationSite.isSuperAccess(); 180 } 181 182 if (isPrivate()) { 183 ReferenceBinding outerInvocationType = invocationType; 186 ReferenceBinding temp = outerInvocationType.enclosingType(); 187 while (temp != null) { 188 outerInvocationType = temp; 189 temp = temp.enclosingType(); 190 } 191 192 ReferenceBinding outerDeclaringClass = (ReferenceBinding)declaringClass.erasure(); 193 temp = outerDeclaringClass.enclosingType(); 194 while (temp != null) { 195 outerDeclaringClass = temp; 196 temp = temp.enclosingType(); 197 } 198 return outerInvocationType == outerDeclaringClass; 199 } 200 201 return invocationType.fPackage == declaringClass.fPackage; 203 } 204 210 public final boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) { 211 if (isPublic()) return true; 212 213 SourceTypeBinding invocationType = scope.enclosingSourceType(); 214 if (invocationType == declaringClass && invocationType == receiverType) return true; 215 216 if (invocationType == null) return !isPrivate() && scope.getCurrentPackage() == declaringClass.fPackage; 218 219 if (isProtected()) { 220 if (invocationType == declaringClass) return true; 226 if (invocationType.fPackage == declaringClass.fPackage) return true; 227 228 ReferenceBinding currentType = invocationType; 229 TypeBinding receiverErasure = receiverType.erasure(); 230 ReferenceBinding declaringErasure = (ReferenceBinding) declaringClass.erasure(); 231 int depth = 0; 232 do { 233 if (currentType.findSuperTypeWithSameErasure(declaringErasure) != null) { 234 if (invocationSite.isSuperAccess()) 235 return true; 236 if (receiverType instanceof ArrayBinding) 238 return false; 239 if (isStatic()) { 240 if (depth > 0) invocationSite.setDepth(depth); 241 return true; } 243 if (currentType == receiverErasure || receiverErasure.findSuperTypeWithSameErasure(currentType) != null) { 244 if (depth > 0) invocationSite.setDepth(depth); 245 return true; 246 } 247 } 248 depth++; 249 currentType = currentType.enclosingType(); 250 } while (currentType != null); 251 return false; 252 } 253 254 if (isPrivate()) { 255 receiverCheck: { 258 if (receiverType != declaringClass) { 259 if (receiverType.isTypeVariable() && ((TypeVariableBinding) receiverType).isErasureBoundTo(declaringClass.erasure())) 261 break receiverCheck; 262 return false; 263 } 264 } 265 266 if (invocationType != declaringClass) { 267 ReferenceBinding outerInvocationType = invocationType; 268 ReferenceBinding temp = outerInvocationType.enclosingType(); 269 while (temp != null) { 270 outerInvocationType = temp; 271 temp = temp.enclosingType(); 272 } 273 274 ReferenceBinding outerDeclaringClass = (ReferenceBinding)declaringClass.erasure(); 275 temp = outerDeclaringClass.enclosingType(); 276 while (temp != null) { 277 outerDeclaringClass = temp; 278 temp = temp.enclosingType(); 279 } 280 if (outerInvocationType != outerDeclaringClass) return false; 281 } 282 return true; 283 } 284 285 PackageBinding declaringPackage = declaringClass.fPackage; 287 if (invocationType.fPackage != declaringPackage) return false; 288 289 if (receiverType instanceof ArrayBinding) 291 return false; 292 ReferenceBinding currentType = (ReferenceBinding) receiverType; 293 do { 294 if (declaringClass == currentType) return true; 295 PackageBinding currentPackage = currentType.fPackage; 296 if (currentPackage != null && currentPackage != declaringPackage) return false; 298 } while ((currentType = currentType.superclass()) != null); 299 return false; 300 } 301 MethodBinding computeSubstitutedMethod(MethodBinding method, LookupEnvironment env) { 302 int length = this.typeVariables.length; 303 TypeVariableBinding[] vars = method.typeVariables; 304 if (length != vars.length) 305 return null; 306 307 ParameterizedGenericMethodBinding substitute = 311 env.createParameterizedGenericMethod(method, this.typeVariables); 312 for (int i = 0; i < length; i++) 313 if (!this.typeVariables[i].isInterchangeableWith(vars[i], substitute)) 314 return null; 315 return substitute; 316 } 317 321 public char[] computeUniqueKey(boolean isLeaf) { 322 char[] declaringKey = this.declaringClass.computeUniqueKey(false); 324 int declaringLength = declaringKey.length; 325 326 int selectorLength = this.selector == TypeConstants.INIT ? 0 : this.selector.length; 328 329 char[] sig = genericSignature(); 331 boolean isGeneric = sig != null; 332 if (!isGeneric) sig = signature(); 333 int signatureLength = sig.length; 334 335 int thrownExceptionsLength = this.thrownExceptions.length; 337 int thrownExceptionsSignatureLength = 0; 338 char[][] thrownExceptionsSignatures = null; 339 boolean addThrownExceptions = thrownExceptionsLength > 0 && (!isGeneric || CharOperation.lastIndexOf('^', sig) < 0); 340 if (addThrownExceptions) { 341 thrownExceptionsSignatures = new char[thrownExceptionsLength][]; 342 for (int i = 0; i < thrownExceptionsLength; i++) { 343 if (this.thrownExceptions[i] != null) { 344 thrownExceptionsSignatures[i] = this.thrownExceptions[i].signature(); 345 thrownExceptionsSignatureLength += thrownExceptionsSignatures[i].length + 1; } 347 } 348 } 349 350 char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength + thrownExceptionsSignatureLength]; 351 int index = 0; 352 System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength); 353 index = declaringLength; 354 uniqueKey[index++] = '.'; 355 System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength); 356 index += selectorLength; 357 System.arraycopy(sig, 0, uniqueKey, index, signatureLength); 358 if (thrownExceptionsSignatureLength > 0) { 359 index += signatureLength; 360 for (int i = 0; i < thrownExceptionsLength; i++) { 361 char[] thrownExceptionSignature = thrownExceptionsSignatures[i]; 362 if (thrownExceptionSignature != null) { 363 uniqueKey[index++] = '|'; 364 int length = thrownExceptionSignature.length; 365 System.arraycopy(thrownExceptionSignature, 0, uniqueKey, index, length); 366 index += length; 367 } 368 } 369 } 370 371 return uniqueKey; 372 } 373 377 public TypeBinding constantPoolDeclaringClass() { 378 return this.declaringClass; 379 } 380 386 public final char[] constantPoolName() { 387 return selector; 388 } 389 395 public char[] genericSignature() { 396 if ((this.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) return null; 397 StringBuffer sig = new StringBuffer (10); 398 if (this.typeVariables != Binding.NO_TYPE_VARIABLES) { 399 sig.append('<'); 400 for (int i = 0, length = this.typeVariables.length; i < length; i++) { 401 sig.append(this.typeVariables[i].genericSignature()); 402 } 403 sig.append('>'); 404 } 405 sig.append('('); 406 for (int i = 0, length = this.parameters.length; i < length; i++) { 407 sig.append(this.parameters[i].genericTypeSignature()); 408 } 409 sig.append(')'); 410 if (this.returnType != null) 411 sig.append(this.returnType.genericTypeSignature()); 412 413 boolean needExceptionSignatures = false; 415 int length = this.thrownExceptions.length; 416 for (int i = 0; i < length; i++) { 417 if((this.thrownExceptions[i].modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) { 418 needExceptionSignatures = true; 419 break; 420 } 421 } 422 if (needExceptionSignatures) { 423 for (int i = 0; i < length; i++) { 424 sig.append('^'); 425 sig.append(this.thrownExceptions[i].genericTypeSignature()); 426 } 427 } 428 int sigLength = sig.length(); 429 char[] genericSignature = new char[sigLength]; 430 sig.getChars(0, sigLength, genericSignature, 0); 431 return genericSignature; 432 } 433 public AnnotationBinding[] getAnnotations() { 434 MethodBinding originalMethod = this.original(); 435 return originalMethod.declaringClass.retrieveAnnotations(originalMethod); 436 } 437 442 public AnnotationBinding[] getParameterAnnotations(int index) { 443 MethodBinding originalMethod = this.original(); 444 AnnotationHolder holder = originalMethod.declaringClass.retrieveAnnotationHolder(originalMethod, true); 445 return holder == null ? Binding.NO_ANNOTATIONS : holder.getParameterAnnotations(index); 446 } 447 public final int getAccessFlags() { 448 return modifiers & ExtraCompilerModifiers.AccJustFlag; 449 } 450 451 456 public long getAnnotationTagBits() { 457 MethodBinding originalMethod = this.original(); 458 if ((originalMethod.tagBits & TagBits.AnnotationResolved) == 0 && originalMethod.declaringClass instanceof SourceTypeBinding) { 459 ClassScope scope = ((SourceTypeBinding) originalMethod.declaringClass).scope; 460 if (scope != null) { 461 TypeDeclaration typeDecl = scope.referenceContext; 462 AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(originalMethod); 463 if (methodDecl != null) 464 ASTNode.resolveAnnotations(methodDecl.scope, methodDecl.annotations, originalMethod); 465 } 466 } 467 return originalMethod.tagBits; 468 } 469 472 public Object getDefaultValue() { 473 MethodBinding originalMethod = this.original(); 474 if ((originalMethod.tagBits & TagBits.DefaultValueResolved) == 0) { 475 if (originalMethod.declaringClass instanceof SourceTypeBinding) { 478 SourceTypeBinding sourceType = (SourceTypeBinding) originalMethod.declaringClass; 479 if (sourceType.scope != null) { 480 AbstractMethodDeclaration methodDeclaration = originalMethod.sourceMethod(); 481 if (methodDeclaration != null && methodDeclaration.isAnnotationMethod()) { 482 methodDeclaration.resolve(sourceType.scope); 483 } 484 } 485 } 486 originalMethod.tagBits |= TagBits.DefaultValueResolved; 487 } 488 AnnotationHolder holder = originalMethod.declaringClass.retrieveAnnotationHolder(originalMethod, true); 489 return holder == null ? null : holder.getDefaultValue(); 490 } 491 public TypeVariableBinding getTypeVariable(char[] variableName) { 492 for (int i = this.typeVariables.length; --i >= 0;) 493 if (CharOperation.equals(this.typeVariables[i].sourceName, variableName)) 494 return this.typeVariables[i]; 495 return null; 496 } 497 501 public boolean hasSubstitutedParameters() { 502 return false; 503 } 504 505 507 public boolean hasSubstitutedReturnType() { 508 return false; 509 } 510 511 513 public final boolean isAbstract() { 514 return (modifiers & ClassFileConstants.AccAbstract) != 0; 515 } 516 517 519 public final boolean isBridge() { 520 return (modifiers & ClassFileConstants.AccBridge) != 0; 521 } 522 523 525 public final boolean isConstructor() { 526 return selector == TypeConstants.INIT; 527 } 528 529 531 public final boolean isDefault() { 532 return !isPublic() && !isProtected() && !isPrivate(); 533 } 534 535 537 public final boolean isDefaultAbstract() { 538 return (modifiers & ExtraCompilerModifiers.AccDefaultAbstract) != 0; 539 } 540 541 543 public final boolean isDeprecated() { 544 return (modifiers & ClassFileConstants.AccDeprecated) != 0; 545 } 546 547 549 public final boolean isFinal() { 550 return (modifiers & ClassFileConstants.AccFinal) != 0; 551 } 552 553 557 public final boolean isImplementing() { 558 return (modifiers & ExtraCompilerModifiers.AccImplementing) != 0; 559 } 560 561 563 public final boolean isNative() { 564 return (modifiers & ClassFileConstants.AccNative) != 0; 565 } 566 567 570 public final boolean isOverriding() { 571 return (modifiers & ExtraCompilerModifiers.AccOverriding) != 0; 572 } 573 576 public final boolean isMain() { 577 if (this.selector.length == 4 && CharOperation.equals(this.selector, TypeConstants.MAIN) 578 && ((this.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccStatic)) != 0) 579 && TypeBinding.VOID == this.returnType 580 && this.parameters.length == 1) { 581 TypeBinding paramType = this.parameters[0]; 582 if (paramType.dimensions() == 1 && paramType.leafComponentType().id == TypeIds.T_JavaLangString) { 583 return true; 584 } 585 } 586 return false; 587 } 588 590 public final boolean isPrivate() { 591 return (modifiers & ClassFileConstants.AccPrivate) != 0; 592 } 593 594 596 public final boolean isUsed() { 597 return (modifiers & ExtraCompilerModifiers.AccLocallyUsed) != 0; 598 } 599 600 602 public final boolean isProtected() { 603 return (modifiers & ClassFileConstants.AccProtected) != 0; 604 } 605 606 608 public final boolean isPublic() { 609 return (modifiers & ClassFileConstants.AccPublic) != 0; 610 } 611 612 614 public final boolean isStatic() { 615 return (modifiers & ClassFileConstants.AccStatic) != 0; 616 } 617 618 620 public final boolean isStrictfp() { 621 return (modifiers & ClassFileConstants.AccStrictfp) != 0; 622 } 623 624 626 public final boolean isSynchronized() { 627 return (modifiers & ClassFileConstants.AccSynchronized) != 0; 628 } 629 630 632 public final boolean isSynthetic() { 633 return (modifiers & ClassFileConstants.AccSynthetic) != 0; 634 } 635 636 638 public final boolean isVarargs() { 639 return (modifiers & ClassFileConstants.AccVarargs) != 0; 640 } 641 642 644 public final boolean isViewedAsDeprecated() { 645 return (modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0; 646 } 647 648 651 public MethodBinding original() { 652 return this; 653 } 654 655 public char[] readableName() { 656 StringBuffer buffer = new StringBuffer (parameters.length + 1 * 20); 657 if (isConstructor()) 658 buffer.append(declaringClass.sourceName()); 659 else 660 buffer.append(selector); 661 buffer.append('('); 662 if (parameters != Binding.NO_PARAMETERS) { 663 for (int i = 0, length = parameters.length; i < length; i++) { 664 if (i > 0) 665 buffer.append(", "); buffer.append(parameters[i].sourceName()); 667 } 668 } 669 buffer.append(')'); 670 return buffer.toString().toCharArray(); 671 } 672 public void setAnnotations(AnnotationBinding[] annotations) { 673 this.declaringClass.storeAnnotations(this, annotations); 674 } 675 public void setAnnotations(AnnotationBinding[] annotations, AnnotationBinding[][] parameterAnnotations, Object defaultValue) { 676 this.declaringClass.storeAnnotationHolder(this, AnnotationHolder.storeAnnotations(annotations, parameterAnnotations, defaultValue)); 677 } 678 public void setDefaultValue(Object defaultValue) { 679 MethodBinding originalMethod = this.original(); 680 originalMethod.tagBits |= TagBits.DefaultValueResolved; 681 682 AnnotationHolder holder = this.declaringClass.retrieveAnnotationHolder(this, false); 683 if (holder == null) 684 setAnnotations(null, null, defaultValue); 685 else 686 setAnnotations(holder.getAnnotations(), holder.getParameterAnnotations(), defaultValue); 687 } 688 public void setParameterAnnotations(AnnotationBinding[][] parameterAnnotations) { 689 AnnotationHolder holder = this.declaringClass.retrieveAnnotationHolder(this, false); 690 if (holder == null) 691 setAnnotations(null, parameterAnnotations, null); 692 else 693 setAnnotations(holder.getAnnotations(), parameterAnnotations, holder.getDefaultValue()); 694 } 695 698 public char[] shortReadableName() { 699 StringBuffer buffer = new StringBuffer (parameters.length + 1 * 20); 700 if (isConstructor()) 701 buffer.append(declaringClass.shortReadableName()); 702 else 703 buffer.append(selector); 704 buffer.append('('); 705 if (parameters != Binding.NO_PARAMETERS) { 706 for (int i = 0, length = parameters.length; i < length; i++) { 707 if (i > 0) 708 buffer.append(", "); buffer.append(parameters[i].shortReadableName()); 710 } 711 } 712 buffer.append(')'); 713 int nameLength = buffer.length(); 714 char[] shortReadableName = new char[nameLength]; 715 buffer.getChars(0, nameLength, shortReadableName, 0); 716 return shortReadableName; 717 } 718 719 protected final void setSelector(char[] selector) { 720 this.selector = selector; 721 this.signature = null; 722 } 723 724 730 public final char[] signature() { 731 if (signature != null) 732 return signature; 733 734 StringBuffer buffer = new StringBuffer (parameters.length + 1 * 20); 735 buffer.append('('); 736 737 TypeBinding[] targetParameters = this.parameters; 738 boolean isConstructor = isConstructor(); 739 if (isConstructor && declaringClass.isEnum()) { buffer.append(ConstantPool.JavaLangStringSignature); 741 buffer.append(TypeBinding.INT.signature()); 742 } 743 boolean needSynthetics = isConstructor && declaringClass.isNestedType(); 744 if (needSynthetics) { 745 ReferenceBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes(); 747 if (syntheticArgumentTypes != null) { 748 for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) { 749 buffer.append(syntheticArgumentTypes[i].signature()); 750 } 751 } 752 753 if (this instanceof SyntheticMethodBinding) { 754 targetParameters = ((SyntheticMethodBinding)this).targetMethod.parameters; 755 } 756 } 757 758 if (targetParameters != Binding.NO_PARAMETERS) { 759 for (int i = 0; i < targetParameters.length; i++) { 760 buffer.append(targetParameters[i].signature()); 761 } 762 } 763 if (needSynthetics) { 764 SyntheticArgumentBinding[] syntheticOuterArguments = declaringClass.syntheticOuterLocalVariables(); 765 int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length; 766 for (int i = 0; i < count; i++) { 767 buffer.append(syntheticOuterArguments[i].type.signature()); 768 } 769 for (int i = targetParameters.length, extraLength = parameters.length; i < extraLength; i++) { 771 buffer.append(parameters[i].signature()); 772 } 773 } 774 buffer.append(')'); 775 if (this.returnType != null) 776 buffer.append(this.returnType.signature()); 777 int nameLength = buffer.length(); 778 signature = new char[nameLength]; 779 buffer.getChars(0, nameLength, signature, 0); 780 781 return signature; 782 } 783 789 public final char[] signature(ClassFile classFile) { 790 if (signature != null) { 791 if ((this.tagBits & TagBits.ContainsNestedTypesInSignature) != 0) { 792 boolean isConstructor = isConstructor(); 794 TypeBinding[] targetParameters = this.parameters; 795 boolean needSynthetics = isConstructor && declaringClass.isNestedType(); 796 if (needSynthetics) { 797 ReferenceBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes(); 799 if (syntheticArgumentTypes != null) { 800 for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) { 801 ReferenceBinding syntheticArgumentType = syntheticArgumentTypes[i]; 802 if (syntheticArgumentType.isNestedType()) { 803 classFile.recordInnerClasses(syntheticArgumentType); 804 } 805 } 806 } 807 if (this instanceof SyntheticMethodBinding) { 808 targetParameters = ((SyntheticMethodBinding)this).targetMethod.parameters; 809 } 810 } 811 812 if (targetParameters != Binding.NO_PARAMETERS) { 813 for (int i = 0; i < targetParameters.length; i++) { 814 TypeBinding targetParameter = targetParameters[i]; 815 TypeBinding leafTargetParameterType = targetParameter.leafComponentType(); 816 if (leafTargetParameterType.isNestedType()) { 817 classFile.recordInnerClasses(leafTargetParameterType); 818 } 819 } 820 } 821 if (needSynthetics) { 822 for (int i = targetParameters.length, extraLength = parameters.length; i < extraLength; i++) { 824 TypeBinding parameter = parameters[i]; 825 TypeBinding leafParameterType = parameter.leafComponentType(); 826 if (leafParameterType.isNestedType()) { 827 classFile.recordInnerClasses(leafParameterType); 828 } 829 } 830 } 831 if (this.returnType != null) { 832 TypeBinding ret = this.returnType.leafComponentType(); 833 if (ret.isNestedType()) { 834 classFile.recordInnerClasses(ret); 835 } 836 } 837 } 838 return signature; 839 } 840 841 StringBuffer buffer = new StringBuffer (parameters.length + 1 * 20); 842 buffer.append('('); 843 844 TypeBinding[] targetParameters = this.parameters; 845 boolean isConstructor = isConstructor(); 846 if (isConstructor && declaringClass.isEnum()) { buffer.append(ConstantPool.JavaLangStringSignature); 848 buffer.append(TypeBinding.INT.signature()); 849 } 850 boolean needSynthetics = isConstructor && declaringClass.isNestedType(); 851 if (needSynthetics) { 852 ReferenceBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes(); 854 if (syntheticArgumentTypes != null) { 855 for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) { 856 ReferenceBinding syntheticArgumentType = syntheticArgumentTypes[i]; 857 if (syntheticArgumentType.isNestedType()) { 858 this.tagBits |= TagBits.ContainsNestedTypesInSignature; 859 classFile.recordInnerClasses(syntheticArgumentType); 860 } 861 buffer.append(syntheticArgumentType.signature()); 862 } 863 } 864 865 if (this instanceof SyntheticMethodBinding) { 866 targetParameters = ((SyntheticMethodBinding)this).targetMethod.parameters; 867 } 868 } 869 870 if (targetParameters != Binding.NO_PARAMETERS) { 871 for (int i = 0; i < targetParameters.length; i++) { 872 TypeBinding targetParameter = targetParameters[i]; 873 TypeBinding leafTargetParameterType = targetParameter.leafComponentType(); 874 if (leafTargetParameterType.isNestedType()) { 875 this.tagBits |= TagBits.ContainsNestedTypesInSignature; 876 classFile.recordInnerClasses(leafTargetParameterType); 877 } 878 buffer.append(targetParameter.signature()); 879 } 880 } 881 if (needSynthetics) { 882 SyntheticArgumentBinding[] syntheticOuterArguments = declaringClass.syntheticOuterLocalVariables(); 883 int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length; 884 for (int i = 0; i < count; i++) { 885 buffer.append(syntheticOuterArguments[i].type.signature()); 886 } 887 for (int i = targetParameters.length, extraLength = parameters.length; i < extraLength; i++) { 889 TypeBinding parameter = parameters[i]; 890 TypeBinding leafParameterType = parameter.leafComponentType(); 891 if (leafParameterType.isNestedType()) { 892 this.tagBits |= TagBits.ContainsNestedTypesInSignature; 893 classFile.recordInnerClasses(leafParameterType); 894 } 895 buffer.append(parameter.signature()); 896 } 897 } 898 buffer.append(')'); 899 if (this.returnType != null) { 900 TypeBinding ret = this.returnType.leafComponentType(); 901 if (ret.isNestedType()) { 902 this.tagBits |= TagBits.ContainsNestedTypesInSignature; 903 classFile.recordInnerClasses(ret); 904 } 905 buffer.append(this.returnType.signature()); 906 } 907 int nameLength = buffer.length(); 908 signature = new char[nameLength]; 909 buffer.getChars(0, nameLength, signature, 0); 910 911 return signature; 912 } 913 public final int sourceEnd() { 914 AbstractMethodDeclaration method = sourceMethod(); 915 if (method == null) { 916 if (this.declaringClass instanceof SourceTypeBinding) 917 return ((SourceTypeBinding) this.declaringClass).sourceEnd(); 918 return 0; 919 } 920 return method.sourceEnd; 921 } 922 public AbstractMethodDeclaration sourceMethod() { 923 SourceTypeBinding sourceType; 924 try { 925 sourceType = (SourceTypeBinding) declaringClass; 926 } catch (ClassCastException e) { 927 return null; 928 } 929 930 AbstractMethodDeclaration[] methods = sourceType.scope.referenceContext.methods; 931 for (int i = methods.length; --i >= 0;) 932 if (this == methods[i].binding) 933 return methods[i]; 934 return null; 935 } 936 public final int sourceStart() { 937 AbstractMethodDeclaration method = sourceMethod(); 938 if (method == null) { 939 if (this.declaringClass instanceof SourceTypeBinding) 940 return ((SourceTypeBinding) this.declaringClass).sourceStart(); 941 return 0; 942 } 943 return method.sourceStart; 944 } 945 946 public String toString() { 947 String s = (returnType != null) ? returnType.debugName() : "NULL TYPE"; s += " "; s += (selector != null) ? new String (selector) : "UNNAMED METHOD"; 951 s += "("; if (parameters != null) { 953 if (parameters != Binding.NO_PARAMETERS) { 954 for (int i = 0, length = parameters.length; i < length; i++) { 955 if (i > 0) 956 s += ", "; s += (parameters[i] != null) ? parameters[i].debugName() : "NULL TYPE"; } 959 } 960 } else { 961 s += "NULL PARAMETERS"; } 963 s += ") "; 965 if (thrownExceptions != null) { 966 if (thrownExceptions != Binding.NO_EXCEPTIONS) { 967 s += "throws "; for (int i = 0, length = thrownExceptions.length; i < length; i++) { 969 if (i > 0) 970 s += ", "; s += (thrownExceptions[i] != null) ? thrownExceptions[i].debugName() : "NULL TYPE"; } 973 } 974 } else { 975 s += "NULL THROWN EXCEPTIONS"; } 977 return s; 978 } 979 983 public MethodBinding tiebreakMethod() { 984 return this; 985 } 986 public TypeVariableBinding[] typeVariables() { 987 return this.typeVariables; 988 } 989 } 990 | Popular Tags |