KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > ast > TypeDeclaration


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

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     // Type decl kinds
25
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; // doesn't include the trailing comment if any.
49
public CompilationResult compilationResult;
50     public MethodDeclaration[] missingAbstractMethods;
51     public Javadoc javadoc;
52     
53     public QualifiedAllocationExpression allocation; // for anonymous only
54
public TypeDeclaration enclosingType; // for member types only
55

56     public FieldBinding enumValuesSyntheticfield; // for enum
57

58     // 1.5 support
59
public TypeParameter[] typeParameters;
60     
61 public TypeDeclaration(CompilationResult compilationResult){
62     this.compilationResult = compilationResult;
63 }
64     
65 /*
66  * We cause the compilation task to abort to a given extent.
67  */

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 /**
82  * This method is responsible for adding a <clinit> method declaration to the type method collections.
83  * Note that this implementation is inserting it in first place (as VAJ or javac), and that this
84  * impacts the behavior of the method ConstantPool.resetForClinit(int. int), in so far as
85  * the latter will have to reset the constant pool state accordingly (if it was added first, it does
86  * not need to preserve some of the method specific cached entries since this will be the first method).
87  * inserts the clinit method declaration in the first position.
88  *
89  * @see org.eclipse.jdt.internal.compiler.codegen.ConstantPool#resetForClinit(int, int)
90  */

91 public final void addClinit() {
92     //see comment on needClassInitMethod
93
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 is added in first location, so as to minimize the use of ldcw (big consumer of constant inits)
111
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 /*
119  * INTERNAL USE ONLY - Creates a fake method declaration for the corresponding binding.
120  * It is used to report errors for missing abstract methods.
121  */

122 public MethodDeclaration addMissingAbstractMethodFor(MethodBinding methodBinding) {
123     TypeBinding[] argumentTypes = methodBinding.parameters;
124     int argumentsLength = argumentTypes.length;
125     //the constructor
126
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 JavaDoc baseName = "arg";//$NON-NLS-1$
134
Argument[] arguments = (methodDeclaration.arguments = new Argument[argumentsLength]);
135         for (int i = argumentsLength; --i >= 0;) {
136             arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/, ClassFileConstants.AccDefault);
137         }
138     }
139
140     //adding the constructor in the methods list
141
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     //============BINDING UPDATE==========================
156
methodDeclaration.binding = new MethodBinding(
157             methodDeclaration.modifiers, //methodDeclaration
158
methodBinding.selector,
159             methodBinding.returnType,
160             argumentsLength == 0 ? Binding.NO_PARAMETERS : argumentTypes, //arguments bindings
161
methodBinding.thrownExceptions, //exceptions
162
this.binding); //declaringClass
163

164     methodDeclaration.scope = new MethodScope(this.scope, methodDeclaration, true);
165     methodDeclaration.bindArguments();
166
167 /* if (binding.methods == null) {
168             binding.methods = new MethodBinding[] { methodDeclaration.binding };
169         } else {
170             MethodBinding[] newMethods;
171             System.arraycopy(
172                 binding.methods,
173                 0,
174                 newMethods = new MethodBinding[binding.methods.length + 1],
175                 1,
176                 binding.methods.length);
177             newMethods[0] = methodDeclaration.binding;
178             binding.methods = newMethods;
179         }*/

180     //===================================================
181

182     return methodDeclaration;
183 }
184
185 /**
186  * Flow analysis for a local innertype
187  *
188  */

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(); // propagate down the max field count
200
internalAnalyseCode(flowContext, flowInfo);
201     } catch (AbortType e) {
202         this.ignoreFurtherInvestigation = true;
203     }
204     return flowInfo;
205 }
206
207 /**
208  * Flow analysis for a member innertype
209  *
210  */

211 public void analyseCode(ClassScope enclosingClassScope) {
212     if (this.ignoreFurtherInvestigation)
213         return;
214     try {
215         // propagate down the max field count
216
updateMaxFieldCount();
217         internalAnalyseCode(null, FlowInfo.initial(this.maxFieldCount));
218     } catch (AbortType e) {
219         this.ignoreFurtherInvestigation = true;
220     }
221 }
222
223 /**
224  * Flow analysis for a local member innertype
225  *
226  */

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(); // propagate down the max field count
238
internalAnalyseCode(flowContext, flowInfo);
239     } catch (AbortType e) {
240         this.ignoreFurtherInvestigation = true;
241     }
242 }
243
244 /**
245  * Flow analysis for a package member type
246  *
247  */

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 /**
259  * Check for constructor vs. method with no return type.
260  * Answers true if at least one constructor is defined
261  */

262 public boolean checkConstructors(Parser parser) {
263     //if a constructor has not the name of the type,
264
//convert it into a method with 'null' as its return type
265
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                     // the constructor was in fact a method with no return type
272
// unless an explicit constructor call was supplied
273
ConstructorDeclaration c = (ConstructorDeclaration) am;
274                     if (c.constructorCall == null || c.constructorCall.isImplicitSuper()) { //changed to a method
275
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                             // report the problem and continue the parsing
282
parser.problemReporter().interfaceCannotHaveConstructors((ConstructorDeclaration) am);
283                             break;
284                         case TypeDeclaration.ANNOTATION_TYPE_DECL :
285                             // report the problem and continue the parsing
286
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     //Add to method'set, the default constuctor that just recall the
304
//super constructor with no arguments
305
//The arguments' type will be positionned by the TC so just use
306
//the default int instead of just null (consistency purpose)
307

308     //the constructor
309
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     //if you change this setting, please update the
315
//SourceIndexer2.buildTypeDeclaration(TypeDeclaration,char[]) method
316
constructor.declarationSourceStart = constructor.sourceStart = this.sourceStart;
317     constructor.declarationSourceEnd =
318         constructor.sourceEnd = constructor.bodyEnd = this.sourceEnd;
319
320     //the super call inside the constructor
321
if (needExplicitConstructorCall) {
322         constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
323         constructor.constructorCall.sourceStart = this.sourceStart;
324         constructor.constructorCall.sourceEnd = this.sourceEnd;
325     }
326
327     //adding the constructor in the methods list: rank is not critical since bindings will be sorted
328
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 // anonymous type constructor creation: rank is important since bindings already got sorted
347
public MethodBinding createDefaultConstructorWithBinding(MethodBinding inheritedConstructorBinding) {
348     //Add to method'set, the default constuctor that just recall the
349
//super constructor with the same arguments
350
String JavaDoc baseName = "$anonymous"; //$NON-NLS-1$
351
TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters;
352     int argumentsLength = argumentTypes.length;
353     //the constructor
354
ConstructorDeclaration constructor = new ConstructorDeclaration(this.compilationResult);
355     constructor.selector = new char[] { 'x' }; //no maining
356
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 /*type ref*/, ClassFileConstants.AccDefault);
369         }
370     }
371     //the super call inside the constructor
372
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     //adding the constructor in the methods list
385
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     //============BINDING UPDATE==========================
395
SourceTypeBinding sourceType = this.binding;
396     constructor.binding = new MethodBinding(
397             constructor.modifiers, //methodDeclaration
398
argumentsLength == 0 ? Binding.NO_PARAMETERS : argumentTypes, //arguments bindings
399
inheritedConstructorBinding.thrownExceptions, //exceptions
400
sourceType); //declaringClass
401

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(); // trigger sorting
409
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); // need to resort, since could be valid methods ahead (140643) - DOM needs eager sorting
414
sourceType.setMethods(methodBindings);
415     //===================================================
416

417     return constructor.binding;
418 }
419
420 /**
421  * Find the matching parse node, answers null if nothing found
422  */

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 /**
435  * Find the matching parse node, answers null if nothing found
436  */

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 /**
449  * Find the matching parse node, answers null if nothing found
450  */

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 /**
464  * Finds the matching type amoung this type's member types.
465  * Returns null if no type with this name is found.
466  * The type name is a compound name relative to this type
467  * eg. if this type is X and we're looking for Y.X.A.B
468  * then a type name would be {X, A, B}
469  */

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 /**
490  * Generic bytecode generation for type
491  */

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         // create the result for a compiled type
506
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         // generate all fiels
516
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         // generate all methods
526
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         // generate all synthetic and abstract methods
533
classFile.addSpecialMethods();
534
535         if (this.ignoreFurtherInvestigation) { // trigger problem type generation for code gen errors
536
throw new AbortType(this.scope.referenceCompilationUnit().compilationResult, null);
537         }
538
539         // finalize the compiled type result
540
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 /**
554  * Bytecode generation for a local inner type (API as a normal statement code gen)
555  */

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 /**
568  * Bytecode generation for a member inner type
569  */

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 /**
577  * Bytecode generation for a package member
578  */

579 public void generateCode(CompilationUnitScope unitScope) {
580     generateCode((ClassFile) null);
581 }
582
583 public boolean hasErrors() {
584     return this.ignoreFurtherInvestigation;
585 }
586
587 /**
588  * Common flow analysis for all types
589  */

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                 /*if (field.isField()){
608                     staticInitializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
609                 } else {*/

610                 staticInitializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
611
/*}*/
612                 staticFieldInfo =
613                     field.analyseCode(
614                         this.staticInitializerScope,
615                         staticInitializerContext,
616                         staticFieldInfo);
617                 // in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
618
// branch, since the previous initializer already got the blame.
619
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                 /*if (field.isField()){
628                     initializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
629                 } else {*/

630                     initializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
631
/*}*/
632                 nonStaticFieldInfo =
633                     field.analyseCode(this.initializerScope, initializerContext, nonStaticFieldInfo);
634                 // in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
635
// branch, since the previous initializer already got the blame.
636
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){ // local type
646
this.memberTypes[i].analyseCode(this.scope, flowContext, nonStaticFieldInfo.copy().setReachMode(flowInfo.reachMode())); // reset reach mode in case initializers did abrupt completely
647
} 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()) { // <clinit>
661
method.analyseCode(
662                         this.scope,
663                         staticInitializerContext,
664                         staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo));
665                 } else { // constructor
666
((ConstructorDeclaration)method).analyseCode(this.scope, initializerContext, constructorInfo.copy(), flowInfo.reachMode());
667                 }
668             } else { // regular method
669
method.analyseCode(this.scope, null, flowInfo.copy());
670             }
671         }
672     }
673     // enable enum support ?
674
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 /*
693  * Access emulation for a local type
694  * force to emulation of access to direct enclosing instance.
695  * By using the initializer scope, we actually only request an argument emulation, the
696  * field is not added until actually used. However we will force allocations to be qualified
697  * with an enclosing instance.
698  * 15.9.2
699  */

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     // add superclass enclosing instance arg for anonymous types (if necessary)
709
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         // From 1.5 on, provide access to enclosing instance synthetic constructor argument when declared inside constructor call
719
// only for direct anonymous type
720
//public class X {
721
// void foo() {}
722
// class M {
723
// M(Object o) {}
724
// M() { this(new Object() { void baz() { foo(); }}); } // access to #foo() indirects through constructor synthetic arg: val$this$0
725
// }
726
//}
727
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 // if (nestedEnclosing.findSuperTypeErasingTo(nestedEnclosing.enclosingType()) == null) { // only if not inheriting
732
SyntheticArgumentBinding syntheticEnclosingInstanceArgument = nestedEnclosing.getSyntheticArgument(nestedEnclosing.enclosingType(), true);
733                     if (syntheticEnclosingInstanceArgument != null) {
734                         nestedType.addSyntheticArgumentAndField(syntheticEnclosingInstanceArgument);
735                     }
736                 }
737 // }
738
}
739     }
740 }
741
742 /**
743  * Access emulation for a local member type
744  * force to emulation of access to direct enclosing instance.
745  * By using the initializer scope, we actually only request an argument emulation, the
746  * field is not added until actually used. However we will force allocations to be qualified
747  * with an enclosing instance.
748  *
749  * Local member cannot be static.
750  */

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 /**
759  * A <clinit> will be requested as soon as static fields or assertions are present. It will be eliminated during
760  * classfile creation if no bytecode was actually produced based on some optimizations/compiler settings.
761  */

762 public final boolean needClassInitMethod() {
763     // always need a <clinit> when assertions are present
764
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; // fields are implicitly statics
771
case TypeDeclaration.ENUM_DECL:
772             return true; // even if no enum constants, need to set $VALUES array
773
}
774     if (this.fields != null) {
775         for (int i = this.fields.length; --i >= 0;) {
776             FieldDeclaration field = this.fields[i];
777             //need to test the modifier directly while there is no binding yet
778
if ((field.modifiers & ClassFileConstants.AccStatic) != 0)
779                 return true; // TODO (philippe) shouldn't it check whether field is initializer or has some initial value ?
780
}
781     }
782     return false;
783 }
784
785 public void parseMethod(Parser parser, CompilationUnitDeclaration unit) {
786     //connect method bodies
787
if (unit.ignoreMethodBodies)
788         return;
789
790     //members
791
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     //methods
798
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     //initializers
806
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 JavaDoc print(int indent, StringBuffer JavaDoc 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 JavaDoc printBody(int indent, StringBuffer JavaDoc output) {
831     output.append(" {"); //$NON-NLS-1$
832
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 JavaDoc printHeader(int indent, StringBuffer JavaDoc 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 "); //$NON-NLS-1$
867
break;
868         case TypeDeclaration.INTERFACE_DECL :
869             output.append("interface "); //$NON-NLS-1$
870
break;
871         case TypeDeclaration.ENUM_DECL :
872             output.append("enum "); //$NON-NLS-1$
873
break;
874         case TypeDeclaration.ANNOTATION_TYPE_DECL :
875             output.append("@interface "); //$NON-NLS-1$
876
break;
877     }
878     output.append(this.name);
879     if (this.typeParameters != null) {
880         output.append("<");//$NON-NLS-1$
881
for (int i = 0; i < this.typeParameters.length; i++) {
882             if (i > 0) output.append( ", "); //$NON-NLS-1$
883
this.typeParameters[i].print(0, output);
884         }
885         output.append(">");//$NON-NLS-1$
886
}
887     if (this.superclass != null) {
888         output.append(" extends "); //$NON-NLS-1$
889
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 "); //$NON-NLS-1$
896
break;
897             case TypeDeclaration.INTERFACE_DECL :
898             case TypeDeclaration.ANNOTATION_TYPE_DECL :
899                 output.append(" extends "); //$NON-NLS-1$
900
break;
901         }
902         for (int i = 0; i < this.superInterfaces.length; i++) {
903             if (i > 0) output.append( ", "); //$NON-NLS-1$
904
this.superInterfaces[i].print(0, output);
905         }
906     }
907     return output;
908 }
909
910 public StringBuffer JavaDoc printStatement(int tab, StringBuffer JavaDoc 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         // check @Deprecated annotation
931
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 /*Serializable is not a class*/) == null
944                         && sourceType.findSuperTypeErasingTo(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null;
945
946         if (needSerialVersion) {
947             // if Object writeReplace() throws java.io.ObjectStreamException is present, then no serialVersionUID is needed
948
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=101476
949
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                 // check the presence of an implementation of the methods
960
// private void writeObject(java.io.ObjectOutputStream out) throws IOException
961
// private void readObject(java.io.ObjectInputStream out) throws IOException
962
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         // generics (and non static generic members) cannot extend Throwable
988
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                            // still discover secondary errors
1029
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        // check extends/implements for annotation type
1054
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                // check enum abstract methods
1065
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        // Resolve javadoc
1089
if (this.javadoc != null) {
1090            if (this.scope != null && (this.name != TypeConstants.PACKAGE_INFO_NAME)) {
1091                // if the type is package-info, the javadoc was resolved as part of the compilation unit javadoc
1092
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/**
1105 * Resolve a local type declaration
1106 */

1107public void resolve(BlockScope blockScope) {
1108    
1109    // need to build its scope first and proceed with binding's creation
1110
if ((this.bits & ASTNode.IsAnonymousType) == 0) {
1111        // check collision scenarii
1112
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                    // dup in same method
1122
blockScope.problemReporter().duplicateNestedType(this);
1123            } else if (blockScope.isDefinedInType(existingType)) {
1124                // collision with enclosing type
1125
blockScope.problemReporter().typeCollidesWithEnclosingType(this);
1126            } else if (blockScope.isDefinedInSameUnit(existingType)){ // only consider hiding inside same unit
1127
// hiding sibling
1128
blockScope.problemReporter().typeHiding(this, existingType);
1129            }
1130        }
1131        blockScope.addLocalType(this);
1132    }
1133
1134    if (this.binding != null) {
1135        // remember local types binding for innerclass emulation propagation
1136
blockScope.referenceCompilationUnit().record((LocalTypeBinding)this.binding);
1137        
1138        // binding is not set if the receiver could not be created
1139
resolve();
1140        updateMaxFieldCount();
1141    }
1142}
1143
1144/**
1145 * Resolve a member type declaration (can be a local member)
1146 */

1147public void resolve(ClassScope upperScope) {
1148    // member scopes are already created
1149
// request the construction of a binding if local member type
1150

1151    if (this.binding != null && this.binding instanceof LocalTypeBinding) {
1152        // remember local types binding for innerclass emulation propagation
1153
upperScope.referenceCompilationUnit().record((LocalTypeBinding)this.binding);
1154    }
1155    resolve();
1156    updateMaxFieldCount();
1157}
1158
1159/**
1160 * Resolve a top level type declaration
1161 */

1162public void resolve(CompilationUnitScope upperScope) {
1163    // top level : scope are already created
1164
resolve();
1165    updateMaxFieldCount();
1166}
1167
1168public void tagAsHavingErrors() {
1169    this.ignoreFurtherInvestigation = true;
1170}
1171
1172/**
1173 * Iteration for a package member type
1174 *
1175 */

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        // silent abort
1228
}
1229}
1230
1231/**
1232 * Iteration for a local innertype
1233 */

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                        // local type cannot have static fields
1271
} 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        // silent abort
1285
}
1286}
1287
1288/**
1289 * Iteration for a member innertype
1290 *
1291 */

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        // silent abort
1343
}
1344}
1345
1346/**
1347 * MaxFieldCount's computation is necessary so as to reserve space for
1348 * the flow info field portions. It corresponds to the maximum amount of
1349 * fields this class or one of its innertypes have.
1350 *
1351 * During name resolution, types are traversed, and the max field count is recorded
1352 * on the outermost type. It is then propagated down during the flow analysis.
1353 *
1354 * This method is doing either up/down propagation.
1355 */

1356void updateMaxFieldCount() {
1357    if (this.binding == null)
1358        return; // error scenario
1359
TypeDeclaration outerMostType = this.scope.outerMostClassScope().referenceType();
1360    if (this.maxFieldCount > outerMostType.maxFieldCount) {
1361        outerMostType.maxFieldCount = this.maxFieldCount; // up
1362
} else {
1363        this.maxFieldCount = outerMostType.maxFieldCount; // down
1364
}
1365}
1366
1367/**
1368 * Returns whether the type is a secondary one or not.
1369 */

1370public boolean isSecondary() {
1371    return (this.bits & ASTNode.IsSecondaryType) != 0;
1372}
1373}
1374
Popular Tags