1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.core.compiler.*; 14 import org.eclipse.jdt.internal.compiler.*; 15 import org.eclipse.jdt.internal.compiler.impl.*; 16 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 17 import org.eclipse.jdt.internal.compiler.codegen.*; 18 import org.eclipse.jdt.internal.compiler.flow.*; 19 import org.eclipse.jdt.internal.compiler.lookup.*; 20 import org.eclipse.jdt.internal.compiler.parser.*; 21 import org.eclipse.jdt.internal.compiler.problem.*; 22 23 public class TypeDeclaration extends Statement implements ProblemSeverities, ReferenceContext { 24 public static final int CLASS_DECL = 1; 26 public static final int INTERFACE_DECL = 2; 27 public static final int ENUM_DECL = 3; 28 public static final int ANNOTATION_TYPE_DECL = 4; 29 30 public int modifiers = ClassFileConstants.AccDefault; 31 public int modifiersSourceStart; 32 public Annotation[] annotations; 33 public char[] name; 34 public TypeReference superclass; 35 public TypeReference[] superInterfaces; 36 public FieldDeclaration[] fields; 37 public AbstractMethodDeclaration[] methods; 38 public TypeDeclaration[] memberTypes; 39 public SourceTypeBinding binding; 40 public ClassScope scope; 41 public MethodScope initializerScope; 42 public MethodScope staticInitializerScope; 43 public boolean ignoreFurtherInvestigation = false; 44 public int maxFieldCount; 45 public int declarationSourceStart; 46 public int declarationSourceEnd; 47 public int bodyStart; 48 public int bodyEnd; public CompilationResult compilationResult; 50 public MethodDeclaration[] missingAbstractMethods; 51 public Javadoc javadoc; 52 53 public QualifiedAllocationExpression allocation; public TypeDeclaration enclosingType; 56 public FieldBinding enumValuesSyntheticfield; 58 public TypeParameter[] typeParameters; 60 61 public TypeDeclaration(CompilationResult compilationResult){ 62 this.compilationResult = compilationResult; 63 } 64 65 68 public void abort(int abortLevel, CategorizedProblem problem) { 69 switch (abortLevel) { 70 case AbortCompilation : 71 throw new AbortCompilation(this.compilationResult, problem); 72 case AbortCompilationUnit : 73 throw new AbortCompilationUnit(this.compilationResult, problem); 74 case AbortMethod : 75 throw new AbortMethod(this.compilationResult, problem); 76 default : 77 throw new AbortType(this.compilationResult, problem); 78 } 79 } 80 81 91 public final void addClinit() { 92 if (needClassInitMethod()) { 94 int length; 95 AbstractMethodDeclaration[] methodDeclarations; 96 if ((methodDeclarations = this.methods) == null) { 97 length = 0; 98 methodDeclarations = new AbstractMethodDeclaration[1]; 99 } else { 100 length = methodDeclarations.length; 101 System.arraycopy( 102 methodDeclarations, 103 0, 104 (methodDeclarations = new AbstractMethodDeclaration[length + 1]), 105 1, 106 length); 107 } 108 Clinit clinit = new Clinit(this.compilationResult); 109 methodDeclarations[0] = clinit; 110 clinit.declarationSourceStart = clinit.sourceStart = this.sourceStart; 112 clinit.declarationSourceEnd = clinit.sourceEnd = this.sourceEnd; 113 clinit.bodyEnd = this.sourceEnd; 114 this.methods = methodDeclarations; 115 } 116 } 117 118 122 public MethodDeclaration addMissingAbstractMethodFor(MethodBinding methodBinding) { 123 TypeBinding[] argumentTypes = methodBinding.parameters; 124 int argumentsLength = argumentTypes.length; 125 MethodDeclaration methodDeclaration = new MethodDeclaration(this.compilationResult); 127 methodDeclaration.selector = methodBinding.selector; 128 methodDeclaration.sourceStart = this.sourceStart; 129 methodDeclaration.sourceEnd = this.sourceEnd; 130 methodDeclaration.modifiers = methodBinding.getAccessFlags() & ~ClassFileConstants.AccAbstract; 131 132 if (argumentsLength > 0) { 133 String baseName = "arg"; Argument[] arguments = (methodDeclaration.arguments = new Argument[argumentsLength]); 135 for (int i = argumentsLength; --i >= 0;) { 136 arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null , ClassFileConstants.AccDefault); 137 } 138 } 139 140 if (this.missingAbstractMethods == null) { 142 this.missingAbstractMethods = new MethodDeclaration[] { methodDeclaration }; 143 } else { 144 MethodDeclaration[] newMethods; 145 System.arraycopy( 146 this.missingAbstractMethods, 147 0, 148 newMethods = new MethodDeclaration[this.missingAbstractMethods.length + 1], 149 1, 150 this.missingAbstractMethods.length); 151 newMethods[0] = methodDeclaration; 152 this.missingAbstractMethods = newMethods; 153 } 154 155 methodDeclaration.binding = new MethodBinding( 157 methodDeclaration.modifiers, methodBinding.selector, 159 methodBinding.returnType, 160 argumentsLength == 0 ? Binding.NO_PARAMETERS : argumentTypes, methodBinding.thrownExceptions, this.binding); 164 methodDeclaration.scope = new MethodScope(this.scope, methodDeclaration, true); 165 methodDeclaration.bindArguments(); 166 167 180 182 return methodDeclaration; 183 } 184 185 189 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { 190 if (this.ignoreFurtherInvestigation) 191 return flowInfo; 192 try { 193 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { 194 this.bits |= ASTNode.IsReachable; 195 LocalTypeBinding localType = (LocalTypeBinding) this.binding; 196 localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType)); 197 } 198 manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo); 199 updateMaxFieldCount(); internalAnalyseCode(flowContext, flowInfo); 201 } catch (AbortType e) { 202 this.ignoreFurtherInvestigation = true; 203 } 204 return flowInfo; 205 } 206 207 211 public void analyseCode(ClassScope enclosingClassScope) { 212 if (this.ignoreFurtherInvestigation) 213 return; 214 try { 215 updateMaxFieldCount(); 217 internalAnalyseCode(null, FlowInfo.initial(this.maxFieldCount)); 218 } catch (AbortType e) { 219 this.ignoreFurtherInvestigation = true; 220 } 221 } 222 223 227 public void analyseCode(ClassScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { 228 if (this.ignoreFurtherInvestigation) 229 return; 230 try { 231 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { 232 this.bits |= ASTNode.IsReachable; 233 LocalTypeBinding localType = (LocalTypeBinding) this.binding; 234 localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType)); 235 } 236 manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo); 237 updateMaxFieldCount(); internalAnalyseCode(flowContext, flowInfo); 239 } catch (AbortType e) { 240 this.ignoreFurtherInvestigation = true; 241 } 242 } 243 244 248 public void analyseCode(CompilationUnitScope unitScope) { 249 if (this.ignoreFurtherInvestigation) 250 return; 251 try { 252 internalAnalyseCode(null, FlowInfo.initial(this.maxFieldCount)); 253 } catch (AbortType e) { 254 this.ignoreFurtherInvestigation = true; 255 } 256 } 257 258 262 public boolean checkConstructors(Parser parser) { 263 boolean hasConstructor = false; 266 if (this.methods != null) { 267 for (int i = this.methods.length; --i >= 0;) { 268 AbstractMethodDeclaration am; 269 if ((am = this.methods[i]).isConstructor()) { 270 if (!CharOperation.equals(am.selector, this.name)) { 271 ConstructorDeclaration c = (ConstructorDeclaration) am; 274 if (c.constructorCall == null || c.constructorCall.isImplicitSuper()) { MethodDeclaration m = parser.convertToMethodDeclaration(c, this.compilationResult); 276 this.methods[i] = m; 277 } 278 } else { 279 switch (kind(this.modifiers)) { 280 case TypeDeclaration.INTERFACE_DECL : 281 parser.problemReporter().interfaceCannotHaveConstructors((ConstructorDeclaration) am); 283 break; 284 case TypeDeclaration.ANNOTATION_TYPE_DECL : 285 parser.problemReporter().annotationTypeDeclarationCannotHaveConstructor((ConstructorDeclaration) am); 287 break; 288 289 } 290 hasConstructor = true; 291 } 292 } 293 } 294 } 295 return hasConstructor; 296 } 297 298 public CompilationResult compilationResult() { 299 return this.compilationResult; 300 } 301 302 public ConstructorDeclaration createDefaultConstructor( boolean needExplicitConstructorCall, boolean needToInsert) { 303 308 ConstructorDeclaration constructor = new ConstructorDeclaration(this.compilationResult); 310 constructor.bits |= ASTNode.IsDefaultConstructor; 311 constructor.selector = this.name; 312 constructor.modifiers = this.modifiers & ExtraCompilerModifiers.AccVisibilityMASK; 313 314 constructor.declarationSourceStart = constructor.sourceStart = this.sourceStart; 317 constructor.declarationSourceEnd = 318 constructor.sourceEnd = constructor.bodyEnd = this.sourceEnd; 319 320 if (needExplicitConstructorCall) { 322 constructor.constructorCall = SuperReference.implicitSuperConstructorCall(); 323 constructor.constructorCall.sourceStart = this.sourceStart; 324 constructor.constructorCall.sourceEnd = this.sourceEnd; 325 } 326 327 if (needToInsert) { 329 if (this.methods == null) { 330 this.methods = new AbstractMethodDeclaration[] { constructor }; 331 } else { 332 AbstractMethodDeclaration[] newMethods; 333 System.arraycopy( 334 this.methods, 335 0, 336 newMethods = new AbstractMethodDeclaration[this.methods.length + 1], 337 1, 338 this.methods.length); 339 newMethods[0] = constructor; 340 this.methods = newMethods; 341 } 342 } 343 return constructor; 344 } 345 346 public MethodBinding createDefaultConstructorWithBinding(MethodBinding inheritedConstructorBinding) { 348 String baseName = "$anonymous"; TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters; 352 int argumentsLength = argumentTypes.length; 353 ConstructorDeclaration constructor = new ConstructorDeclaration(this.compilationResult); 355 constructor.selector = new char[] { 'x' }; constructor.sourceStart = this.sourceStart; 357 constructor.sourceEnd = this.sourceEnd; 358 int newModifiers = this.modifiers & ExtraCompilerModifiers.AccVisibilityMASK; 359 if (inheritedConstructorBinding.isVarargs()) { 360 newModifiers |= ClassFileConstants.AccVarargs; 361 } 362 constructor.modifiers = newModifiers; 363 constructor.bits |= ASTNode.IsDefaultConstructor; 364 365 if (argumentsLength > 0) { 366 Argument[] arguments = (constructor.arguments = new Argument[argumentsLength]); 367 for (int i = argumentsLength; --i >= 0;) { 368 arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null , ClassFileConstants.AccDefault); 369 } 370 } 371 constructor.constructorCall = SuperReference.implicitSuperConstructorCall(); 373 constructor.constructorCall.sourceStart = this.sourceStart; 374 constructor.constructorCall.sourceEnd = this.sourceEnd; 375 376 if (argumentsLength > 0) { 377 Expression[] args; 378 args = constructor.constructorCall.arguments = new Expression[argumentsLength]; 379 for (int i = argumentsLength; --i >= 0;) { 380 args[i] = new SingleNameReference((baseName + i).toCharArray(), 0L); 381 } 382 } 383 384 if (this.methods == null) { 386 this.methods = new AbstractMethodDeclaration[] { constructor }; 387 } else { 388 AbstractMethodDeclaration[] newMethods; 389 System.arraycopy(this.methods, 0, newMethods = new AbstractMethodDeclaration[this.methods.length + 1], 1, this.methods.length); 390 newMethods[0] = constructor; 391 this.methods = newMethods; 392 } 393 394 SourceTypeBinding sourceType = this.binding; 396 constructor.binding = new MethodBinding( 397 constructor.modifiers, argumentsLength == 0 ? Binding.NO_PARAMETERS : argumentTypes, inheritedConstructorBinding.thrownExceptions, sourceType); 402 constructor.binding.modifiers |= ExtraCompilerModifiers.AccIsDefaultConstructor; 403 404 constructor.scope = new MethodScope(this.scope, constructor, true); 405 constructor.bindArguments(); 406 constructor.constructorCall.resolve(constructor.scope); 407 408 MethodBinding[] methodBindings = sourceType.methods(); int length; 410 System.arraycopy(methodBindings, 0, methodBindings = new MethodBinding[(length = methodBindings.length) + 1], 1, length); 411 methodBindings[0] = constructor.binding; 412 if (++length > 1) 413 ReferenceBinding.sortMethods(methodBindings, 0, length); sourceType.setMethods(methodBindings); 415 417 return constructor.binding; 418 } 419 420 423 public FieldDeclaration declarationOf(FieldBinding fieldBinding) { 424 if (fieldBinding != null && this.fields != null) { 425 for (int i = 0, max = this.fields.length; i < max; i++) { 426 FieldDeclaration fieldDecl; 427 if ((fieldDecl = this.fields[i]).binding == fieldBinding) 428 return fieldDecl; 429 } 430 } 431 return null; 432 } 433 434 437 public TypeDeclaration declarationOf(MemberTypeBinding memberTypeBinding) { 438 if (memberTypeBinding != null && this.memberTypes != null) { 439 for (int i = 0, max = this.memberTypes.length; i < max; i++) { 440 TypeDeclaration memberTypeDecl; 441 if ((memberTypeDecl = this.memberTypes[i]).binding == memberTypeBinding) 442 return memberTypeDecl; 443 } 444 } 445 return null; 446 } 447 448 451 public AbstractMethodDeclaration declarationOf(MethodBinding methodBinding) { 452 if (methodBinding != null && this.methods != null) { 453 for (int i = 0, max = this.methods.length; i < max; i++) { 454 AbstractMethodDeclaration methodDecl; 455 456 if ((methodDecl = this.methods[i]).binding == methodBinding) 457 return methodDecl; 458 } 459 } 460 return null; 461 } 462 463 470 public TypeDeclaration declarationOfType(char[][] typeName) { 471 int typeNameLength = typeName.length; 472 if (typeNameLength < 1 || !CharOperation.equals(typeName[0], this.name)) { 473 return null; 474 } 475 if (typeNameLength == 1) { 476 return this; 477 } 478 char[][] subTypeName = new char[typeNameLength - 1][]; 479 System.arraycopy(typeName, 1, subTypeName, 0, typeNameLength - 1); 480 for (int i = 0; i < this.memberTypes.length; i++) { 481 TypeDeclaration typeDecl = this.memberTypes[i].declarationOfType(subTypeName); 482 if (typeDecl != null) { 483 return typeDecl; 484 } 485 } 486 return null; 487 } 488 489 492 public void generateCode(ClassFile enclosingClassFile) { 493 if ((this.bits & ASTNode.HasBeenGenerated) != 0) 494 return; 495 this.bits |= ASTNode.HasBeenGenerated; 496 if (this.ignoreFurtherInvestigation) { 497 if (this.binding == null) 498 return; 499 ClassFile.createProblemType( 500 this, 501 this.scope.referenceCompilationUnit().compilationResult); 502 return; 503 } 504 try { 505 ClassFile classFile = ClassFile.getNewInstance(this.binding); 507 classFile.initialize(this.binding, enclosingClassFile, false); 508 if (this.binding.isMemberType()) { 509 classFile.recordInnerClasses(this.binding); 510 } else if (this.binding.isLocalType()) { 511 enclosingClassFile.recordInnerClasses(this.binding); 512 classFile.recordInnerClasses(this.binding); 513 } 514 515 classFile.addFieldInfos(); 517 518 if (this.memberTypes != null) { 519 for (int i = 0, max = this.memberTypes.length; i < max; i++) { 520 TypeDeclaration memberType = this.memberTypes[i]; 521 classFile.recordInnerClasses(memberType.binding); 522 memberType.generateCode(this.scope, classFile); 523 } 524 } 525 classFile.setForMethodInfos(); 527 if (this.methods != null) { 528 for (int i = 0, max = this.methods.length; i < max; i++) { 529 this.methods[i].generateCode(this.scope, classFile); 530 } 531 } 532 classFile.addSpecialMethods(); 534 535 if (this.ignoreFurtherInvestigation) { throw new AbortType(this.scope.referenceCompilationUnit().compilationResult, null); 537 } 538 539 classFile.addAttributes(); 541 this.scope.referenceCompilationUnit().compilationResult.record( 542 this.binding.constantPoolName(), 543 classFile); 544 } catch (AbortType e) { 545 if (this.binding == null) 546 return; 547 ClassFile.createProblemType( 548 this, 549 this.scope.referenceCompilationUnit().compilationResult); 550 } 551 } 552 553 556 public void generateCode(BlockScope blockScope, CodeStream codeStream) { 557 if ((this.bits & ASTNode.IsReachable) == 0) { 558 return; 559 } 560 if ((this.bits & ASTNode.HasBeenGenerated) != 0) return; 561 int pc = codeStream.position; 562 if (this.binding != null) ((NestedTypeBinding) this.binding).computeSyntheticArgumentSlotSizes(); 563 generateCode(codeStream.classFile); 564 codeStream.recordPositionsFrom(pc, this.sourceStart); 565 } 566 567 570 public void generateCode(ClassScope classScope, ClassFile enclosingClassFile) { 571 if ((this.bits & ASTNode.HasBeenGenerated) != 0) return; 572 if (this.binding != null) ((NestedTypeBinding) this.binding).computeSyntheticArgumentSlotSizes(); 573 generateCode(enclosingClassFile); 574 } 575 576 579 public void generateCode(CompilationUnitScope unitScope) { 580 generateCode((ClassFile) null); 581 } 582 583 public boolean hasErrors() { 584 return this.ignoreFurtherInvestigation; 585 } 586 587 590 private void internalAnalyseCode(FlowContext flowContext, FlowInfo flowInfo) { 591 if ((this.binding.isPrivate() || (this.binding.tagBits & (TagBits.IsAnonymousType|TagBits.IsLocalType)) == TagBits.IsLocalType) && !this.binding.isUsed()) { 592 if (!this.scope.referenceCompilationUnit().compilationResult.hasSyntaxError) { 593 this.scope.problemReporter().unusedPrivateType(this); 594 } 595 } 596 InitializationFlowContext initializerContext = new InitializationFlowContext(null, this, this.initializerScope); 597 InitializationFlowContext staticInitializerContext = new InitializationFlowContext(null, this, this.staticInitializerScope); 598 FlowInfo nonStaticFieldInfo = flowInfo.unconditionalFieldLessCopy(); 599 FlowInfo staticFieldInfo = flowInfo.unconditionalFieldLessCopy(); 600 if (this.fields != null) { 601 for (int i = 0, count = this.fields.length; i < count; i++) { 602 FieldDeclaration field = this.fields[i]; 603 if (field.isStatic()) { 604 if ((staticFieldInfo.tagBits & FlowInfo.UNREACHABLE) != 0) 605 field.bits &= ~ASTNode.IsReachable; 606 607 610 staticInitializerContext.handledExceptions = Binding.ANY_EXCEPTION; 612 staticFieldInfo = 613 field.analyseCode( 614 this.staticInitializerScope, 615 staticInitializerContext, 616 staticFieldInfo); 617 if (staticFieldInfo == FlowInfo.DEAD_END) { 620 this.staticInitializerScope.problemReporter().initializerMustCompleteNormally(field); 621 staticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE); 622 } 623 } else { 624 if ((nonStaticFieldInfo.tagBits & FlowInfo.UNREACHABLE) != 0) 625 field.bits &= ~ASTNode.IsReachable; 626 627 630 initializerContext.handledExceptions = Binding.ANY_EXCEPTION; 632 nonStaticFieldInfo = 633 field.analyseCode(this.initializerScope, initializerContext, nonStaticFieldInfo); 634 if (nonStaticFieldInfo == FlowInfo.DEAD_END) { 637 this.initializerScope.problemReporter().initializerMustCompleteNormally(field); 638 nonStaticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE); 639 } 640 } 641 } 642 } 643 if (this.memberTypes != null) { 644 for (int i = 0, count = this.memberTypes.length; i < count; i++) { 645 if (flowContext != null){ this.memberTypes[i].analyseCode(this.scope, flowContext, nonStaticFieldInfo.copy().setReachMode(flowInfo.reachMode())); } else { 648 this.memberTypes[i].analyseCode(this.scope); 649 } 650 } 651 } 652 if (this.methods != null) { 653 UnconditionalFlowInfo outerInfo = flowInfo.unconditionalFieldLessCopy(); 654 FlowInfo constructorInfo = nonStaticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo); 655 for (int i = 0, count = this.methods.length; i < count; i++) { 656 AbstractMethodDeclaration method = this.methods[i]; 657 if (method.ignoreFurtherInvestigation) 658 continue; 659 if (method.isInitializationMethod()) { 660 if (method.isStatic()) { method.analyseCode( 662 this.scope, 663 staticInitializerContext, 664 staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo)); 665 } else { ((ConstructorDeclaration)method).analyseCode(this.scope, initializerContext, constructorInfo.copy(), flowInfo.reachMode()); 667 } 668 } else { method.analyseCode(this.scope, null, flowInfo.copy()); 670 } 671 } 672 } 673 if (this.binding.isEnum() && !this.binding.isAnonymousType()) { 675 this.enumValuesSyntheticfield = this.binding.addSyntheticFieldForEnumValues(); 676 } 677 } 678 679 public final static int kind(int flags) { 680 switch (flags & (ClassFileConstants.AccInterface|ClassFileConstants.AccAnnotation|ClassFileConstants.AccEnum)) { 681 case ClassFileConstants.AccInterface : 682 return TypeDeclaration.INTERFACE_DECL; 683 case ClassFileConstants.AccInterface|ClassFileConstants.AccAnnotation : 684 return TypeDeclaration.ANNOTATION_TYPE_DECL; 685 case ClassFileConstants.AccEnum : 686 return TypeDeclaration.ENUM_DECL; 687 default : 688 return TypeDeclaration.CLASS_DECL; 689 } 690 } 691 692 700 public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) { 701 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return; 702 NestedTypeBinding nestedType = (NestedTypeBinding) this.binding; 703 704 MethodScope methodScope = currentScope.methodScope(); 705 if (!methodScope.isStatic && !methodScope.isConstructorCall){ 706 nestedType.addSyntheticArgumentAndField(nestedType.enclosingType()); 707 } 708 if (nestedType.isAnonymousType()) { 710 ReferenceBinding superclassBinding = (ReferenceBinding)nestedType.superclass.erasure(); 711 if (superclassBinding.enclosingType() != null && !superclassBinding.isStatic()) { 712 if (!superclassBinding.isLocalType() 713 || ((NestedTypeBinding)superclassBinding).getSyntheticField(superclassBinding.enclosingType(), true) != null){ 714 715 nestedType.addSyntheticArgument(superclassBinding.enclosingType()); 716 } 717 } 718 if (!methodScope.isStatic && methodScope.isConstructorCall && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) { 728 ReferenceBinding enclosing = nestedType.enclosingType(); 729 if (enclosing.isNestedType()) { 730 NestedTypeBinding nestedEnclosing = (NestedTypeBinding)enclosing; 731 SyntheticArgumentBinding syntheticEnclosingInstanceArgument = nestedEnclosing.getSyntheticArgument(nestedEnclosing.enclosingType(), true); 733 if (syntheticEnclosingInstanceArgument != null) { 734 nestedType.addSyntheticArgumentAndField(syntheticEnclosingInstanceArgument); 735 } 736 } 737 } 739 } 740 } 741 742 751 public void manageEnclosingInstanceAccessIfNecessary(ClassScope currentScope, FlowInfo flowInfo) { 752 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { 753 NestedTypeBinding nestedType = (NestedTypeBinding) this.binding; 754 nestedType.addSyntheticArgumentAndField(this.binding.enclosingType()); 755 } 756 } 757 758 762 public final boolean needClassInitMethod() { 763 if ((this.bits & ASTNode.ContainsAssertion) != 0) 765 return true; 766 767 switch (kind(this.modifiers)) { 768 case TypeDeclaration.INTERFACE_DECL: 769 case TypeDeclaration.ANNOTATION_TYPE_DECL: 770 return this.fields != null; case TypeDeclaration.ENUM_DECL: 772 return true; } 774 if (this.fields != null) { 775 for (int i = this.fields.length; --i >= 0;) { 776 FieldDeclaration field = this.fields[i]; 777 if ((field.modifiers & ClassFileConstants.AccStatic) != 0) 779 return true; } 781 } 782 return false; 783 } 784 785 public void parseMethod(Parser parser, CompilationUnitDeclaration unit) { 786 if (unit.ignoreMethodBodies) 788 return; 789 790 if (this.memberTypes != null) { 792 int length = this.memberTypes.length; 793 for (int i = 0; i < length; i++) 794 this.memberTypes[i].parseMethod(parser, unit); 795 } 796 797 if (this.methods != null) { 799 int length = this.methods.length; 800 for (int i = 0; i < length; i++) { 801 this.methods[i].parseStatements(parser, unit); 802 } 803 } 804 805 if (this.fields != null) { 807 int length = this.fields.length; 808 for (int i = 0; i < length; i++) { 809 final FieldDeclaration fieldDeclaration = this.fields[i]; 810 switch(fieldDeclaration.getKind()) { 811 case AbstractVariableDeclaration.INITIALIZER: 812 ((Initializer) fieldDeclaration).parseStatements(parser, this, unit); 813 break; 814 } 815 } 816 } 817 } 818 819 public StringBuffer print(int indent, StringBuffer output) { 820 if (this.javadoc != null) { 821 this.javadoc.print(indent, output); 822 } 823 if ((this.bits & ASTNode.IsAnonymousType) == 0) { 824 printIndent(indent, output); 825 printHeader(0, output); 826 } 827 return printBody(indent, output); 828 } 829 830 public StringBuffer printBody(int indent, StringBuffer output) { 831 output.append(" {"); if (this.memberTypes != null) { 833 for (int i = 0; i < this.memberTypes.length; i++) { 834 if (this.memberTypes[i] != null) { 835 output.append('\n'); 836 this.memberTypes[i].print(indent + 1, output); 837 } 838 } 839 } 840 if (this.fields != null) { 841 for (int fieldI = 0; fieldI < this.fields.length; fieldI++) { 842 if (this.fields[fieldI] != null) { 843 output.append('\n'); 844 this.fields[fieldI].print(indent + 1, output); 845 } 846 } 847 } 848 if (this.methods != null) { 849 for (int i = 0; i < this.methods.length; i++) { 850 if (this.methods[i] != null) { 851 output.append('\n'); 852 this.methods[i].print(indent + 1, output); 853 } 854 } 855 } 856 output.append('\n'); 857 return printIndent(indent, output).append('}'); 858 } 859 860 public StringBuffer printHeader(int indent, StringBuffer output) { 861 printModifiers(this.modifiers, output); 862 if (this.annotations != null) printAnnotations(this.annotations, output); 863 864 switch (kind(this.modifiers)) { 865 case TypeDeclaration.CLASS_DECL : 866 output.append("class "); break; 868 case TypeDeclaration.INTERFACE_DECL : 869 output.append("interface "); break; 871 case TypeDeclaration.ENUM_DECL : 872 output.append("enum "); break; 874 case TypeDeclaration.ANNOTATION_TYPE_DECL : 875 output.append("@interface "); break; 877 } 878 output.append(this.name); 879 if (this.typeParameters != null) { 880 output.append("<"); for (int i = 0; i < this.typeParameters.length; i++) { 882 if (i > 0) output.append( ", "); this.typeParameters[i].print(0, output); 884 } 885 output.append(">"); } 887 if (this.superclass != null) { 888 output.append(" extends "); this.superclass.print(0, output); 890 } 891 if (this.superInterfaces != null && this.superInterfaces.length > 0) { 892 switch (kind(this.modifiers)) { 893 case TypeDeclaration.CLASS_DECL : 894 case TypeDeclaration.ENUM_DECL : 895 output.append(" implements "); break; 897 case TypeDeclaration.INTERFACE_DECL : 898 case TypeDeclaration.ANNOTATION_TYPE_DECL : 899 output.append(" extends "); break; 901 } 902 for (int i = 0; i < this.superInterfaces.length; i++) { 903 if (i > 0) output.append( ", "); this.superInterfaces[i].print(0, output); 905 } 906 } 907 return output; 908 } 909 910 public StringBuffer printStatement(int tab, StringBuffer output) { 911 return print(tab, output); 912 } 913 914 915 916 public void resolve() { 917 SourceTypeBinding sourceType = this.binding; 918 if (sourceType == null) { 919 this.ignoreFurtherInvestigation = true; 920 return; 921 } 922 try { 923 boolean old = this.staticInitializerScope.insideTypeAnnotation; 924 try { 925 this.staticInitializerScope.insideTypeAnnotation = true; 926 resolveAnnotations(this.staticInitializerScope, this.annotations, sourceType); 927 } finally { 928 this.staticInitializerScope.insideTypeAnnotation = old; 929 } 930 if ((sourceType.getAnnotationTagBits() & TagBits.AnnotationDeprecated) == 0 932 && (sourceType.modifiers & ClassFileConstants.AccDeprecated) != 0 933 && this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { 934 this.scope.problemReporter().missingDeprecatedAnnotationForType(this); 935 } 936 if ((this.bits & ASTNode.UndocumentedEmptyBlock) != 0) { 937 this.scope.problemReporter().undocumentedEmptyBlock(this.bodyStart-1, this.bodyEnd); 938 } 939 boolean needSerialVersion = 940 this.scope.compilerOptions().getSeverity(CompilerOptions.MissingSerialVersion) != ProblemSeverities.Ignore 941 && sourceType.isClass() 942 && !sourceType.isAbstract() 943 && sourceType.findSuperTypeErasingTo(TypeIds.T_JavaIoExternalizable, false ) == null 944 && sourceType.findSuperTypeErasingTo(TypeIds.T_JavaIoSerializable, false ) != null; 945 946 if (needSerialVersion) { 947 CompilationUnitScope compilationUnitScope = this.scope.compilationUnitScope(); 950 MethodBinding methodBinding = sourceType.getExactMethod(TypeConstants.WRITEREPLACE, new TypeBinding[0], compilationUnitScope); 951 ReferenceBinding[] throwsExceptions; 952 needSerialVersion = 953 methodBinding == null 954 || !methodBinding.isValidBinding() 955 || methodBinding.returnType.id != TypeIds.T_JavaLangObject 956 || (throwsExceptions = methodBinding.thrownExceptions).length != 1 957 || throwsExceptions[0].id != TypeIds.T_JavaIoObjectStreamException; 958 if (needSerialVersion) { 959 boolean hasWriteObjectMethod = false; 963 boolean hasReadObjectMethod = false; 964 TypeBinding argumentTypeBinding = this.scope.getType(TypeConstants.JAVA_IO_OBJECTOUTPUTSTREAM, 3); 965 if (argumentTypeBinding.isValidBinding()) { 966 methodBinding = sourceType.getExactMethod(TypeConstants.WRITEOBJECT, new TypeBinding[] { argumentTypeBinding }, compilationUnitScope); 967 hasWriteObjectMethod = methodBinding != null 968 && methodBinding.isValidBinding() 969 && methodBinding.modifiers == ClassFileConstants.AccPrivate 970 && methodBinding.returnType == TypeBinding.VOID 971 && (throwsExceptions = methodBinding.thrownExceptions).length == 1 972 && throwsExceptions[0].id == TypeIds.T_JavaIoException; 973 } 974 argumentTypeBinding = this.scope.getType(TypeConstants.JAVA_IO_OBJECTINPUTSTREAM, 3); 975 if (argumentTypeBinding.isValidBinding()) { 976 methodBinding = sourceType.getExactMethod(TypeConstants.READOBJECT, new TypeBinding[] { argumentTypeBinding }, compilationUnitScope); 977 hasReadObjectMethod = methodBinding != null 978 && methodBinding.isValidBinding() 979 && methodBinding.modifiers == ClassFileConstants.AccPrivate 980 && methodBinding.returnType == TypeBinding.VOID 981 && (throwsExceptions = methodBinding.thrownExceptions).length == 1 982 && throwsExceptions[0].id == TypeIds.T_JavaIoException; 983 } 984 needSerialVersion = !hasWriteObjectMethod || !hasReadObjectMethod; 985 } 986 } 987 if (sourceType.findSuperTypeErasingTo(TypeIds.T_JavaLangThrowable, true) != null) { 989 ReferenceBinding current = sourceType; 990 checkEnclosedInGeneric : do { 991 if (current.isGenericType()) { 992 this.scope.problemReporter().genericTypeCannotExtendThrowable(this); 993 break checkEnclosedInGeneric; 994 } 995 if (current.isStatic()) break checkEnclosedInGeneric; 996 if (current.isLocalType()) { 997 NestedTypeBinding nestedType = (NestedTypeBinding) current.erasure(); 998 if (nestedType.scope.methodScope().isStatic) break checkEnclosedInGeneric; 999 } 1000 } while ((current = current.enclosingType()) != null); 1001 } 1002 this.maxFieldCount = 0; 1003 int lastVisibleFieldID = -1; 1004 boolean hasEnumConstants = false; 1005 boolean hasEnumConstantsWithoutBody = false; 1006 1007 if (this.typeParameters != null) { 1008 for (int i = 0, count = this.typeParameters.length; i < count; i++) { 1009 this.typeParameters[i].resolve(this.scope); 1010 } 1011 } 1012 if (this.memberTypes != null) { 1013 for (int i = 0, count = this.memberTypes.length; i < count; i++) { 1014 this.memberTypes[i].resolve(this.scope); 1015 } 1016 } 1017 if (this.fields != null) { 1018 for (int i = 0, count = this.fields.length; i < count; i++) { 1019 FieldDeclaration field = this.fields[i]; 1020 switch(field.getKind()) { 1021 case AbstractVariableDeclaration.ENUM_CONSTANT: 1022 hasEnumConstants = true; 1023 if (!(field.initialization instanceof QualifiedAllocationExpression)) 1024 hasEnumConstantsWithoutBody = true; 1025 case AbstractVariableDeclaration.FIELD: 1026 FieldBinding fieldBinding = field.binding; 1027 if (fieldBinding == null) { 1028 if (field.initialization != null) field.initialization.resolve(field.isStatic() ? this.staticInitializerScope : this.initializerScope); 1030 this.ignoreFurtherInvestigation = true; 1031 continue; 1032 } 1033 if (needSerialVersion 1034 && ((fieldBinding.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal)) == (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal)) 1035 && CharOperation.equals(TypeConstants.SERIALVERSIONUID, fieldBinding.name) 1036 && TypeBinding.LONG == fieldBinding.type) { 1037 needSerialVersion = false; 1038 } 1039 this.maxFieldCount++; 1040 lastVisibleFieldID = field.binding.id; 1041 break; 1042 1043 case AbstractVariableDeclaration.INITIALIZER: 1044 ((Initializer) field).lastVisibleFieldID = lastVisibleFieldID + 1; 1045 break; 1046 } 1047 field.resolve(field.isStatic() ? this.staticInitializerScope : this.initializerScope); 1048 } 1049 } 1050 if (needSerialVersion) { 1051 this.scope.problemReporter().missingSerialVersion(this); 1052 } 1053 switch(kind(this.modifiers)) { 1055 case TypeDeclaration.ANNOTATION_TYPE_DECL : 1056 if (this.superclass != null) { 1057 this.scope.problemReporter().annotationTypeDeclarationCannotHaveSuperclass(this); 1058 } 1059 if (this.superInterfaces != null) { 1060 this.scope.problemReporter().annotationTypeDeclarationCannotHaveSuperinterfaces(this); 1061 } 1062 break; 1063 case TypeDeclaration.ENUM_DECL : 1064 if (this.binding.isAbstract()) { 1066 if (!hasEnumConstants || hasEnumConstantsWithoutBody) { 1067 for (int i = 0, count = this.methods.length; i < count; i++) { 1068 final AbstractMethodDeclaration methodDeclaration = this.methods[i]; 1069 if (methodDeclaration.isAbstract() && methodDeclaration.binding != null) { 1070 this.scope.problemReporter().enumAbstractMethodMustBeImplemented(methodDeclaration); 1071 } 1072 } 1073 } 1074 } 1075 break; 1076 } 1077 1078 int missingAbstractMethodslength = this.missingAbstractMethods == null ? 0 : this.missingAbstractMethods.length; 1079 int methodsLength = this.methods == null ? 0 : this.methods.length; 1080 if ((methodsLength + missingAbstractMethodslength) > 0xFFFF) { 1081 this.scope.problemReporter().tooManyMethods(this); 1082 } 1083 if (this.methods != null) { 1084 for (int i = 0, count = this.methods.length; i < count; i++) { 1085 this.methods[i].resolve(this.scope); 1086 } 1087 } 1088 if (this.javadoc != null) { 1090 if (this.scope != null && (this.name != TypeConstants.PACKAGE_INFO_NAME)) { 1091 this.javadoc.resolve(this.scope); 1093 } 1094 } else if (sourceType != null && !sourceType.isLocalType()) { 1095 this.scope.problemReporter().javadocMissing(this.sourceStart, this.sourceEnd, sourceType.modifiers); 1096 } 1097 1098 } catch (AbortType e) { 1099 this.ignoreFurtherInvestigation = true; 1100 return; 1101 } 1102} 1103 1104 1107public void resolve(BlockScope blockScope) { 1108 1109 if ((this.bits & ASTNode.IsAnonymousType) == 0) { 1111 Binding existing = blockScope.getType(this.name); 1113 if (existing instanceof ReferenceBinding 1114 && existing != this.binding 1115 && existing.isValidBinding()) { 1116 ReferenceBinding existingType = (ReferenceBinding) existing; 1117 if (existingType instanceof TypeVariableBinding) { 1118 blockScope.problemReporter().typeHiding(this, (TypeVariableBinding) existingType); 1119 } else if (existingType instanceof LocalTypeBinding 1120 && ((LocalTypeBinding) existingType).scope.methodScope() == blockScope.methodScope()) { 1121 blockScope.problemReporter().duplicateNestedType(this); 1123 } else if (blockScope.isDefinedInType(existingType)) { 1124 blockScope.problemReporter().typeCollidesWithEnclosingType(this); 1126 } else if (blockScope.isDefinedInSameUnit(existingType)){ blockScope.problemReporter().typeHiding(this, existingType); 1129 } 1130 } 1131 blockScope.addLocalType(this); 1132 } 1133 1134 if (this.binding != null) { 1135 blockScope.referenceCompilationUnit().record((LocalTypeBinding)this.binding); 1137 1138 resolve(); 1140 updateMaxFieldCount(); 1141 } 1142} 1143 1144 1147public void resolve(ClassScope upperScope) { 1148 1151 if (this.binding != null && this.binding instanceof LocalTypeBinding) { 1152 upperScope.referenceCompilationUnit().record((LocalTypeBinding)this.binding); 1154 } 1155 resolve(); 1156 updateMaxFieldCount(); 1157} 1158 1159 1162public void resolve(CompilationUnitScope upperScope) { 1163 resolve(); 1165 updateMaxFieldCount(); 1166} 1167 1168public void tagAsHavingErrors() { 1169 this.ignoreFurtherInvestigation = true; 1170} 1171 1172 1176public void traverse(ASTVisitor visitor, CompilationUnitScope unitScope) { 1177 1178 if (this.ignoreFurtherInvestigation) 1179 return; 1180 try { 1181 if (visitor.visit(this, unitScope)) { 1182 if (this.javadoc != null) { 1183 this.javadoc.traverse(visitor, this.scope); 1184 } 1185 if (this.annotations != null) { 1186 int annotationsLength = this.annotations.length; 1187 for (int i = 0; i < annotationsLength; i++) 1188 this.annotations[i].traverse(visitor, this.staticInitializerScope); 1189 } 1190 if (this.superclass != null) 1191 this.superclass.traverse(visitor, this.scope); 1192 if (this.superInterfaces != null) { 1193 int length = this.superInterfaces.length; 1194 for (int i = 0; i < length; i++) 1195 this.superInterfaces[i].traverse(visitor, this.scope); 1196 } 1197 if (this.typeParameters != null) { 1198 int length = this.typeParameters.length; 1199 for (int i = 0; i < length; i++) { 1200 this.typeParameters[i].traverse(visitor, this.scope); 1201 } 1202 } 1203 if (this.memberTypes != null) { 1204 int length = this.memberTypes.length; 1205 for (int i = 0; i < length; i++) 1206 this.memberTypes[i].traverse(visitor, this.scope); 1207 } 1208 if (this.fields != null) { 1209 int length = this.fields.length; 1210 for (int i = 0; i < length; i++) { 1211 FieldDeclaration field; 1212 if ((field = this.fields[i]).isStatic()) { 1213 field.traverse(visitor, this.staticInitializerScope); 1214 } else { 1215 field.traverse(visitor, this.initializerScope); 1216 } 1217 } 1218 } 1219 if (this.methods != null) { 1220 int length = this.methods.length; 1221 for (int i = 0; i < length; i++) 1222 this.methods[i].traverse(visitor, this.scope); 1223 } 1224 } 1225 visitor.endVisit(this, unitScope); 1226 } catch (AbortType e) { 1227 } 1229} 1230 1231 1234public void traverse(ASTVisitor visitor, BlockScope blockScope) { 1235 if (this.ignoreFurtherInvestigation) 1236 return; 1237 try { 1238 if (visitor.visit(this, blockScope)) { 1239 if (this.javadoc != null) { 1240 this.javadoc.traverse(visitor, this.scope); 1241 } 1242 if (this.annotations != null) { 1243 int annotationsLength = this.annotations.length; 1244 for (int i = 0; i < annotationsLength; i++) 1245 this.annotations[i].traverse(visitor, this.staticInitializerScope); 1246 } 1247 if (this.superclass != null) 1248 this.superclass.traverse(visitor, this.scope); 1249 if (this.superInterfaces != null) { 1250 int length = this.superInterfaces.length; 1251 for (int i = 0; i < length; i++) 1252 this.superInterfaces[i].traverse(visitor, this.scope); 1253 } 1254 if (this.typeParameters != null) { 1255 int length = this.typeParameters.length; 1256 for (int i = 0; i < length; i++) { 1257 this.typeParameters[i].traverse(visitor, this.scope); 1258 } 1259 } 1260 if (this.memberTypes != null) { 1261 int length = this.memberTypes.length; 1262 for (int i = 0; i < length; i++) 1263 this.memberTypes[i].traverse(visitor, this.scope); 1264 } 1265 if (this.fields != null) { 1266 int length = this.fields.length; 1267 for (int i = 0; i < length; i++) { 1268 FieldDeclaration field; 1269 if ((field = this.fields[i]).isStatic()) { 1270 } else { 1272 field.traverse(visitor, this.initializerScope); 1273 } 1274 } 1275 } 1276 if (this.methods != null) { 1277 int length = this.methods.length; 1278 for (int i = 0; i < length; i++) 1279 this.methods[i].traverse(visitor, this.scope); 1280 } 1281 } 1282 visitor.endVisit(this, blockScope); 1283 } catch (AbortType e) { 1284 } 1286} 1287 1288 1292public void traverse(ASTVisitor visitor, ClassScope classScope) { 1293 if (this.ignoreFurtherInvestigation) 1294 return; 1295 try { 1296 if (visitor.visit(this, classScope)) { 1297 if (this.javadoc != null) { 1298 this.javadoc.traverse(visitor, scope); 1299 } 1300 if (this.annotations != null) { 1301 int annotationsLength = this.annotations.length; 1302 for (int i = 0; i < annotationsLength; i++) 1303 this.annotations[i].traverse(visitor, this.staticInitializerScope); 1304 } 1305 if (this.superclass != null) 1306 this.superclass.traverse(visitor, this.scope); 1307 if (this.superInterfaces != null) { 1308 int length = this.superInterfaces.length; 1309 for (int i = 0; i < length; i++) 1310 this.superInterfaces[i].traverse(visitor, this.scope); 1311 } 1312 if (this.typeParameters != null) { 1313 int length = this.typeParameters.length; 1314 for (int i = 0; i < length; i++) { 1315 this.typeParameters[i].traverse(visitor, this.scope); 1316 } 1317 } 1318 if (this.memberTypes != null) { 1319 int length = this.memberTypes.length; 1320 for (int i = 0; i < length; i++) 1321 this.memberTypes[i].traverse(visitor, this.scope); 1322 } 1323 if (this.fields != null) { 1324 int length = this.fields.length; 1325 for (int i = 0; i < length; i++) { 1326 FieldDeclaration field; 1327 if ((field = this.fields[i]).isStatic()) { 1328 field.traverse(visitor, this.staticInitializerScope); 1329 } else { 1330 field.traverse(visitor, this.initializerScope); 1331 } 1332 } 1333 } 1334 if (this.methods != null) { 1335 int length = this.methods.length; 1336 for (int i = 0; i < length; i++) 1337 this.methods[i].traverse(visitor, this.scope); 1338 } 1339 } 1340 visitor.endVisit(this, classScope); 1341 } catch (AbortType e) { 1342 } 1344} 1345 1346 1356void updateMaxFieldCount() { 1357 if (this.binding == null) 1358 return; TypeDeclaration outerMostType = this.scope.outerMostClassScope().referenceType(); 1360 if (this.maxFieldCount > outerMostType.maxFieldCount) { 1361 outerMostType.maxFieldCount = this.maxFieldCount; } else { 1363 this.maxFieldCount = outerMostType.maxFieldCount; } 1365} 1366 1367 1370public boolean isSecondary() { 1371 return (this.bits & ASTNode.IsSecondaryType) != 0; 1372} 1373} 1374 | Popular Tags |