Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2000, 2013 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: IBM Corporation - initial API and implementation Stephan Herrmann - Contributions for Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) Bug 388630 -

NonNull:
diagnostics at line 0 Keigo Imai - Contribution for bug 388903 - Cannot extend inner class as an anonymous class when it extends the outer class /
  
  package org.eclipse.jdt.internal.compiler.ast;
  
  
  public class TypeDeclaration extends Statement implements ProblemSeveritiesReferenceContext {
  	// Type decl kinds
  	public static final int CLASS_DECL = 1;
  	public static final int INTERFACE_DECL = 2;
  	public static final int ENUM_DECL = 3;
  	public static final int ANNOTATION_TYPE_DECL = 4;
  
  	public int modifiersSourceStart;
  	public Annotation[] annotations;
  	public char[] name;
  	public FieldDeclaration[] fields;
  	public ClassScope scope;
  	public boolean ignoreFurtherInvestigation = false;
  	public int maxFieldCount;
  	public int declarationSourceStart;
  	public int declarationSourceEnd;
  	public int bodyStart;
  	public int bodyEnd// doesn't include the trailing comment if any.
  	public Javadoc javadoc;
  
  	public QualifiedAllocationExpression allocation// for anonymous only
  	public TypeDeclaration enclosingType// for member types only
  
  	public FieldBinding enumValuesSyntheticfield// for enum
  	public int enumConstantsCounter;
  
  	// 1.5 support
  
  public TypeDeclaration(CompilationResult compilationResult){
  	this. = compilationResult;
  }
  
  /*
   *	We cause the compilation task to abort to a given extent.
   */
  public void abort(int abortLevelCategorizedProblem problem) {
  	switch (abortLevel) {
  		case  :
  			throw new AbortCompilation(this.problem);
  			throw new AbortCompilationUnit(this.problem);
  		case  :
  			throw new AbortMethod(this.problem);
  		default :
  			throw new AbortType(this.problem);
  	}
  }

This method is responsible for adding a <clinit> method declaration to the type method collections. Note that this implementation is inserting it in first place (as VAJ or javac), and that this impacts the behavior of the method ConstantPool.resetForClinit(int. int), in so far as the latter will have to reset the constant pool state accordingly (if it was added first, it does not need to preserve some of the method specific cached entries since this will be the first method). inserts the clinit method declaration in the first position.

  
  public final void addClinit() {
  	//see comment on needClassInitMethod
  	if (needClassInitMethod()) {
 		int length;
 		AbstractMethodDeclaration[] methodDeclarations;
 		if ((methodDeclarations = this.) == null) {
 			length = 0;
 			methodDeclarations = new AbstractMethodDeclaration[1];
 		} else {
 			length = methodDeclarations.length;
 			System.arraycopy(
 				methodDeclarations,
 				0,
 				(methodDeclarations = new AbstractMethodDeclaration[length + 1]),
 				1,
 				length);
 		}
 		Clinit clinit = new Clinit(this.);
 		methodDeclarations[0] = clinit;
 		// clinit is added in first location, so as to minimize the use of ldcw (big consumer of constant inits)
 		clinit.declarationSourceStart = clinit.sourceStart = this.;
 		clinit.declarationSourceEnd = clinit.sourceEnd = this.;
 		clinit.bodyEnd = this.;
 		this. = methodDeclarations;
 	}
 }
 
 /*
  * INTERNAL USE ONLY - Creates a fake method declaration for the corresponding binding.
  * It is used to report errors for missing abstract methods.
  */
 	TypeBinding[] argumentTypes = methodBinding.parameters;
 	int argumentsLength = argumentTypes.length;
 	//the constructor
 	MethodDeclaration methodDeclaration = new MethodDeclaration(this.);
 	methodDeclaration.selector = methodBinding.selector;
 	methodDeclaration.sourceStart = this.;
 	methodDeclaration.sourceEnd = this.;
 	methodDeclaration.modifiers = methodBinding.getAccessFlags() & ~.;
 
 	if (argumentsLength > 0) {
 		String baseName = "arg";//$NON-NLS-1$
 		Argument[] arguments = (methodDeclaration.arguments = new Argument[argumentsLength]);
 		for (int i = argumentsLength; --i >= 0;) {
 			arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/.);
 		}
 	}
 
 	//adding the constructor in the methods list
 	if (this. == null) {
 		this. = new MethodDeclaration[] { methodDeclaration };
 	} else {
 		MethodDeclaration[] newMethods;
 		System.arraycopy(
 			0,
 			newMethods = new MethodDeclaration[this..length + 1],
 			1,
 			this..length);
 		newMethods[0] = methodDeclaration;
 		this. = newMethods;
 	}
 
 	//============BINDING UPDATE==========================
 	methodDeclaration.binding = new MethodBinding(
 			methodDeclaration.modifiers | .//methodDeclaration
 			methodBinding.selector,
 			methodBinding.returnType,
 			argumentsLength == 0 ? . : argumentTypes//arguments bindings
 			methodBinding.thrownExceptions//exceptions
 			this.); //declaringClass
 
 	methodDeclaration.scope = new MethodScope(this.methodDeclarationtrue);
 	methodDeclaration.bindArguments();
 
 /*		if (binding.methods == null) {
 			binding.methods = new MethodBinding[] { methodDeclaration.binding };
 		} else {
 			MethodBinding[] newMethods;
 			System.arraycopy(
 				binding.methods,
 				0,
 				newMethods = new MethodBinding[binding.methods.length + 1],
 				1,
 				binding.methods.length);
 			newMethods[0] = methodDeclaration.binding;
 			binding.methods = newMethods;
 		}*/
 	//===================================================
 
 	return methodDeclaration;
 }

Flow analysis for a local innertype
 
 public FlowInfo analyseCode(BlockScope currentScopeFlowContext flowContextFlowInfo flowInfo) {
 		return flowInfo;
 	try {
 		if ((flowInfo.tagBits & .) == 0) {
 			LocalTypeBinding localType = (LocalTypeBindingthis.;
 		}
 		manageEnclosingInstanceAccessIfNecessary(currentScopeflowInfo);
 		updateMaxFieldCount(); // propagate down the max field count
 		internalAnalyseCode(flowContextflowInfo);
 	} catch (AbortType e) {
 	}
 	return flowInfo;
 }

Flow analysis for a member innertype
 
 public void analyseCode(ClassScope enclosingClassScope) {
 		return;
 	try {
 		// propagate down the max field count
 		internalAnalyseCode(null, FlowInfo.initial(this.));
 	} catch (AbortType e) {
 	}
 }

Flow analysis for a local member innertype
 
 public void analyseCode(ClassScope currentScopeFlowContext flowContextFlowInfo flowInfo) {
 		return;
 	try {
 		if ((flowInfo.tagBits & .) == 0) {
 			LocalTypeBinding localType = (LocalTypeBindingthis.;
 		}
 		manageEnclosingInstanceAccessIfNecessary(currentScopeflowInfo);
 		updateMaxFieldCount(); // propagate down the max field count
 		internalAnalyseCode(flowContextflowInfo);
 	} catch (AbortType e) {
 	}
 }

Flow analysis for a package member type
 
 public void analyseCode(CompilationUnitScope unitScope) {
 		return;
 	try {
 		internalAnalyseCode(null, FlowInfo.initial(this.));
 	} catch (AbortType e) {
 	}
 }

Check for constructor vs. method with no return type. Answers true if at least one constructor is defined
 
 public boolean checkConstructors(Parser parser) {
 	//if a constructor has not the name of the type,
 	//convert it into a method with 'null' as its return type
 	boolean hasConstructor = false;
 	if (this. != null) {
 		for (int i = this..length; --i >= 0;) {
 			if ((am = this.[i]).isConstructor()) {
 				if (!CharOperation.equals(am.selectorthis.)) {
 					// the constructor was in fact a method with no return type
 					// unless an explicit constructor call was supplied
 					if (c.constructorCall == null || c.constructorCall.isImplicitSuper()) { //changed to a method
 						this.[i] = m;
 					}
 				} else {
 					switch (kind(this.)) {
 							// report the problem and continue the parsing
 							break;
 							// report the problem and continue the parsing
 							break;
 
 					}
 					hasConstructor = true;
 				}
 			}
 		}
 	}
 	return hasConstructor;
 }
 
 	return this.;
 }
 
 public ConstructorDeclaration createDefaultConstructor(	boolean needExplicitConstructorCallboolean needToInsert) {
 	//Add to method'set, the default constuctor that just recall the
 	//super constructor with no arguments
 	//The arguments' type will be positionned by the TC so just use
 	//the default int instead of just null (consistency purpose)
 
 	//the constructor
 	constructor.bits |= .;
 	constructor.selector = this.;
 	constructor.modifiers = this. & .;
 
 	//if you change this setting, please update the
 	//SourceIndexer2.buildTypeDeclaration(TypeDeclaration,char[]) method
 	constructor.declarationSourceStart = constructor.sourceStart = this.;
 	constructor.declarationSourceEnd =
 		constructor.sourceEnd = constructor.bodyEnd = this.;
 
 	//the super call inside the constructor
 	if (needExplicitConstructorCall) {
 		constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
 		constructor.constructorCall.sourceStart = this.;
 		constructor.constructorCall.sourceEnd = this.;
 	}
 
 	//adding the constructor in the methods list: rank is not critical since bindings will be sorted
 	if (needToInsert) {
 		if (this. == null) {
 			this. = new AbstractMethodDeclaration[] { constructor };
 		} else {
 			System.arraycopy(
 				this.,
 				0,
 				newMethods = new AbstractMethodDeclaration[this..length + 1],
 				1,
 				this..length);
 			newMethods[0] = constructor;
 			this. = newMethods;
 		}
 	}
 	return constructor;
 }
 
 // anonymous type constructor creation: rank is important since bindings already got sorted
 public MethodBinding createDefaultConstructorWithBinding(MethodBinding inheritedConstructorBindingboolean eraseThrownExceptions) {
 	//Add to method'set, the default constuctor that just recall the
 	//super constructor with the same arguments
 	String baseName = "$anonymous"//$NON-NLS-1$
 	TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters;
 	int argumentsLength = argumentTypes.length;
 	//the constructor
 	constructor.selector = new char[] { 'x' }; //no maining
 	constructor.sourceStart = this.;
 	constructor.sourceEnd = this.;
 	int newModifiers = this. & .;
 	if (inheritedConstructorBinding.isVarargs()) {
 		newModifiers |= .;
 	}
 	constructor.modifiers = newModifiers;
 	constructor.bits |= .;
 
 	if (argumentsLength > 0) {
 		Argument[] arguments = (constructor.arguments = new Argument[argumentsLength]);
 		for (int i = argumentsLength; --i >= 0;) {
 			arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/.);
 		}
 	}
 	//the super call inside the constructor
 	constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
 	constructor.constructorCall.sourceStart = this.;
 	constructor.constructorCall.sourceEnd = this.;
 
 	if (argumentsLength > 0) {
 		Expression[] args;
 		args = constructor.constructorCall.arguments = new Expression[argumentsLength];
 		for (int i = argumentsLength; --i >= 0;) {
 			args[i] = new SingleNameReference((baseName + i).toCharArray(), 0L);
 		}
 	}
 
 	//adding the constructor in the methods list
 	if (this. == null) {
 		this. = new AbstractMethodDeclaration[] { constructor };
 	} else {
 		System.arraycopy(this., 0, newMethods = new AbstractMethodDeclaration[this..length + 1], 1, this..length);
 		newMethods[0] = constructor;
 		this. = newMethods;
 	}
 
 	//============BINDING UPDATE==========================
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
 	ReferenceBinding[] thrownExceptions = eraseThrownExceptions
 			? this..environment().convertToRawTypes(inheritedConstructorBinding.thrownExceptionstruetrue)
 			: inheritedConstructorBinding.thrownExceptions;
 
 	SourceTypeBinding sourceType = this.;
 	constructor.binding = new MethodBinding(
 			constructor.modifiers//methodDeclaration
 			argumentsLength == 0 ? . : argumentTypes//arguments bindings
 			thrownExceptions//exceptions
 			sourceType); //declaringClass
 	constructor.binding.tagBits |= (inheritedConstructorBinding.tagBits & .);
 	constructor.binding.modifiers |= .;
 	if (inheritedConstructorBinding.parameterNonNullness != null // this implies that annotation based null analysis is enabled
 			&& argumentsLength > 0) 
 	{
 		// copy nullness info from inherited constructor to the new constructor:
 		int len = inheritedConstructorBinding.parameterNonNullness.length;
 		System.arraycopy(inheritedConstructorBinding.parameterNonNullness, 0, 
 				constructor.binding.parameterNonNullness = new Boolean[len], 0, len);
 	}
 
 	constructor.scope = new MethodScope(this.constructortrue);
 	constructor.bindArguments();
 	constructor.constructorCall.resolve(constructor.scope);
 
 	MethodBinding[] methodBindings = sourceType.methods(); // trigger sorting
 	int length;
 	System.arraycopy(methodBindings, 0, methodBindings = new MethodBinding[(length = methodBindings.length) + 1], 1, length);
 	methodBindings[0] = constructor.binding;
 	if (++length > 1)
 		ReferenceBinding.sortMethods(methodBindings, 0, length);	// need to resort, since could be valid methods ahead (140643) - DOM needs eager sorting
 	sourceType.setMethods(methodBindings);
 	//===================================================
 
 	return constructor.binding;
 }

Find the matching parse node, answers null if nothing found
 
 public FieldDeclaration declarationOf(FieldBinding fieldBinding) {
 	if (fieldBinding != null && this. != null) {
 		for (int i = 0, max = this..lengthi < maxi++) {
 			FieldDeclaration fieldDecl;
 			if ((fieldDecl = this.[i]). == fieldBinding)
 				return fieldDecl;
 		}
 	}
 	return null;
 }

Find the matching parse node, answers null if nothing found
 
 public TypeDeclaration declarationOf(MemberTypeBinding memberTypeBinding) {
 	if (memberTypeBinding != null && this. != null) {
 		for (int i = 0, max = this..lengthi < maxi++) {
 			TypeDeclaration memberTypeDecl;
 			if ((memberTypeDecl = this.[i]). == memberTypeBinding)
 				return memberTypeDecl;
 		}
 	}
 	return null;
 }

Find the matching parse node, answers null if nothing found
 
 	if (methodBinding != null && this. != null) {
 		for (int i = 0, max = this..lengthi < maxi++) {
 
 			if ((methodDecl = this.[i]). == methodBinding)
 				return methodDecl;
 		}
 	}
 	return null;
 }

Finds the matching type amoung this type's member types. Returns null if no type with this name is found. The type name is a compound name relative to this type e.g. if this type is X and we're looking for Y.X.A.B then a type name would be {X, A, B}
 
 public TypeDeclaration declarationOfType(char[][] typeName) {
 	int typeNameLength = typeName.length;
 	if (typeNameLength < 1 || !CharOperation.equals(typeName[0], this.)) {
 		return null;
 	}
 	if (typeNameLength == 1) {
 		return this;
 	}
 	char[][] subTypeName = new char[typeNameLength - 1][];
 	System.arraycopy(typeName, 1, subTypeName, 0, typeNameLength - 1);
 	for (int i = 0; i < this..lengthi++) {
 		TypeDeclaration typeDecl = this.[i].declarationOfType(subTypeName);
 		if (typeDecl != null) {
 			return typeDecl;
 		}
 	}
 	return null;
 }
 
 	if (this. != null) {
 	}
 	return null;
 }

Generic bytecode generation for type
 
 public void generateCode(ClassFile enclosingClassFile) {
 	if ((this. & .) != 0)
 		return;
 		if (this. == null)
 			return;
 		ClassFile.createProblemType(
 			this,
 		return;
 	}
 	try {
 		// create the result for a compiled type
 		ClassFile classFile = ClassFile.getNewInstance(this.);
 		classFile.initialize(this.enclosingClassFilefalse);
 		if (this..isMemberType()) {
 			classFile.recordInnerClasses(this.);
 		} else if (this..isLocalType()) {
 			enclosingClassFile.recordInnerClasses(this.);
 			classFile.recordInnerClasses(this.);
 		}
 		TypeVariableBinding[] typeVariables = this..typeVariables();
 		for (int i = 0, max = typeVariables.lengthi < maxi++) {
 			TypeVariableBinding typeVariableBinding = typeVariables[i];
 			if ((typeVariableBinding.tagBits & .) != 0) {
 				Util.recordNestedType(classFiletypeVariableBinding);
 			}
 		}
 
 		// generate all fiels
 		classFile.addFieldInfos();
 
 		if (this. != null) {
 			for (int i = 0, max = this..lengthi < maxi++) {
 				TypeDeclaration memberType = this.[i];
 				classFile.recordInnerClasses(memberType.binding);
 				memberType.generateCode(this.classFile);
 			}
 		}
 		// generate all methods
 		classFile.setForMethodInfos();
 		if (this. != null) {
 			for (int i = 0, max = this..lengthi < maxi++) {
 				this.[i].generateCode(this.classFile);
 			}
 		}
 		// generate all synthetic and abstract methods
 		classFile.addSpecialMethods();
 
 		if (this.) { // trigger problem type generation for code gen errors
 		}
 
 		// finalize the compiled type result
 		classFile.addAttributes();
 			classFile);
 	} catch (AbortType e) {
 		if (this. == null)
 			return;
 		ClassFile.createProblemType(
 			this,
 	}
 }

Bytecode generation for a local inner type (API as a normal statement code gen)
 
 public void generateCode(BlockScope blockScopeCodeStream codeStream) {
 	if ((this. & .) == 0) {
 		return;
 	}
 	if ((this. & .) != 0) return;
 	int pc = codeStream.position;
 	if (this. != null) {
 		for (int i = 0, slotSize = 0, count = enclosingInstances == null ? 0 : enclosingInstances.lengthi < counti++){
 			SyntheticArgumentBinding enclosingInstance = enclosingInstances[i];
 			enclosingInstance.resolvedPosition = ++slotSize// shift by 1 to leave room for aload0==this
 			if (slotSize > 0xFF) { // no more than 255 words of arguments
 				blockScope.problemReporter().noMoreAvailableSpaceForArgument(enclosingInstanceblockScope.referenceType());
 			}
 		}
 	}
 	generateCode(codeStream.classFile);
 	codeStream.recordPositionsFrom(pcthis.);
 }

Bytecode generation for a member inner type
 
 public void generateCode(ClassScope classScopeClassFile enclosingClassFile) {
 	if ((this. & .) != 0) return;
 	if (this. != null) {
 		for (int i = 0, slotSize = 0, count = enclosingInstances == null ? 0 : enclosingInstances.lengthi < counti++){
 			SyntheticArgumentBinding enclosingInstance = enclosingInstances[i];
 			enclosingInstance.resolvedPosition = ++slotSize// shift by 1 to leave room for aload0==this
 			if (slotSize > 0xFF) { // no more than 255 words of arguments
 				classScope.problemReporter().noMoreAvailableSpaceForArgument(enclosingInstanceclassScope.referenceType());
 			}
 		}
 	}
 	generateCode(enclosingClassFile);
 }

Bytecode generation for a package member
 
 public void generateCode(CompilationUnitScope unitScope) {
 }
 
 public boolean hasErrors() {
 }

Common flow analysis for all types
 
 private void internalAnalyseCode(FlowContext flowContextFlowInfo flowInfo) {
 	if (!this..isUsed() && this..isOrEnclosedByPrivateType()) {
 		}
 	}
 	
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385780
 	if (this. != null && 
 		for (int i = 0, length = this..lengthi < length; ++i) {
 			TypeParameter typeParameter = this.[i];
 			if ((typeParameter.binding.modifiers & .) == 0) {
 				this..problemReporter().unusedTypeParameter(typeParameter);			
 			}
 		}
 	}
 	
 	// for local classes we use the flowContext as our parent, but never use an initialization context for this purpose
 	// see Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
 	FlowContext parentContext = (flowContext instanceof InitializationFlowContext) ? null : flowContext;
 	InitializationFlowContext initializerContext = new InitializationFlowContext(parentContextthisflowInfoflowContextthis.);
 	// no static initializer in local classes, thus no need to set parent:
 	InitializationFlowContext staticInitializerContext = new InitializationFlowContext(nullthisflowInfoflowContextthis.);
 	FlowInfo nonStaticFieldInfo = flowInfo.unconditionalFieldLessCopy();
 	FlowInfo staticFieldInfo = flowInfo.unconditionalFieldLessCopy();
 	if (this. != null) {
 		for (int i = 0, count = this..lengthi < counti++) {
 			FieldDeclaration field = this.[i];
 			if (field.isStatic()) {
 				if ((staticFieldInfo.tagBits & .) != 0)
 					field.bits &= ~.;
 
 				/*if (field.isField()){
 					staticInitializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
 				} else {*/
 				staticInitializerContext.handledExceptions = .// tolerate them all, and record them
 				/*}*/
 				staticFieldInfo = field.analyseCode(this.staticInitializerContextstaticFieldInfo);
 				// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
 				// branch, since the previous initializer already got the blame.
 				if (staticFieldInfo == .) {
 					staticFieldInfo = FlowInfo.initial(this.).setReachMode(.);
 				}
 			} else {
 				if ((nonStaticFieldInfo.tagBits & .) != 0)
 					field.bits &= ~.;
 
 				/*if (field.isField()){
 					initializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
 				} else {*/
 					initializerContext.handledExceptions = .// tolerate them all, and record them
 				/*}*/
 				nonStaticFieldInfo = field.analyseCode(this.initializerContextnonStaticFieldInfo);
 				// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
 				// branch, since the previous initializer already got the blame.
 				if (nonStaticFieldInfo == .) {
 					nonStaticFieldInfo = FlowInfo.initial(this.).setReachMode(.);
 				}
 			}
 		}
 	}
 	if (this. != null) {
 		for (int i = 0, count = this..lengthi < counti++) {
 			if (flowContext != null){ // local type
 				this.[i].analyseCode(this.flowContextnonStaticFieldInfo.copy().setReachMode(flowInfo.reachMode())); // reset reach mode in case initializers did abrupt completely
 			} else {
 				this.[i].analyseCode(this.);
 			}
 		}
 	}
 	if (this. != null) {
 		FlowInfo constructorInfo = nonStaticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo);
 		for (int i = 0, count = this..lengthi < counti++) {
 			AbstractMethodDeclaration method = this.[i];
 			if (method.ignoreFurtherInvestigation)
 				continue;
 			if (method.isInitializationMethod()) {
 				// pass down the appropriate initializerContext:
 				if (method.isStatic()) { // <clinit>
 					((Clinit)method).analyseCode(
 						this.,
 						staticInitializerContext,
 				} else { // constructor
 					((ConstructorDeclaration)method).analyseCode(this.initializerContextconstructorInfo.copy(), flowInfo.reachMode());
 				}
 			} else { // regular method
 				// pass down the parentContext (NOT an initializer context, see above):
 				((MethodDeclaration)method).analyseCode(this.parentContextflowInfo.copy());
 			}
 		}
 	}
 	// enable enum support ?
 	if (this..isEnum() && !this..isAnonymousType()) {
 	}
 }
 
 public final static int kind(int flags) {
 		default :
 	}
 }
 
 /*
  * Access emulation for a local type
  * force to emulation of access to direct enclosing instance.
  * By using the initializer scope, we actually only request an argument emulation, the
  * field is not added until actually used. However we will force allocations to be qualified
  * with an enclosing instance.
  * 15.9.2
  */
 public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScopeFlowInfo flowInfo) {
 	if ((flowInfo.tagBits & .) != 0) return;
 	NestedTypeBinding nestedType = (NestedTypeBindingthis.;
 
 	MethodScope methodScope = currentScope.methodScope();
 	if (!methodScope.isStatic && !methodScope.isConstructorCall){
 		nestedType.addSyntheticArgumentAndField(nestedType.enclosingType());
 	}
 	// add superclass enclosing instance arg for anonymous types (if necessary)
 	if (nestedType.isAnonymousType()) {
 		ReferenceBinding superclassBinding = (ReferenceBinding)nestedType.superclass.erasure();
 		if (superclassBinding.enclosingType() != null && !superclassBinding.isStatic()) {
 			if (!superclassBinding.isLocalType()
 					|| ((NestedTypeBinding)superclassBinding).getSyntheticField(superclassBinding.enclosingType(), true) != null){
 
 				nestedType.addSyntheticArgument(superclassBinding.enclosingType());
 			}
 		}
 		// From 1.5 on, provide access to enclosing instance synthetic constructor argument when declared inside constructor call
 		// only for direct anonymous type
 		//public class X {
 		//	void foo() {}
 		//	class M {
 		//		M(Object o) {}
 		//		M() { this(new Object() { void baz() { foo(); }}); } // access to #foo() indirects through constructor synthetic arg: val$this$0
 		//	}
 		//}
 		if (!methodScope.isStatic && methodScope.isConstructorCall && currentScope.compilerOptions(). >= .) {
 			ReferenceBinding enclosing = nestedType.enclosingType();
 			if (enclosing.isNestedType()) {
 				NestedTypeBinding nestedEnclosing = (NestedTypeBinding)enclosing;
 //					if (nestedEnclosing.findSuperTypeErasingTo(nestedEnclosing.enclosingType()) == null) { // only if not inheriting
 					SyntheticArgumentBinding syntheticEnclosingInstanceArgument = nestedEnclosing.getSyntheticArgument(nestedEnclosing.enclosingType(), truefalse);
 					if (syntheticEnclosingInstanceArgument != null) {
 						nestedType.addSyntheticArgumentAndField(syntheticEnclosingInstanceArgument);
 					}
 				}
 //				}
 		}
 	}
 }

Access emulation for a local member type force to emulation of access to direct enclosing instance. By using the initializer scope, we actually only request an argument emulation, the field is not added until actually used. However we will force allocations to be qualified with an enclosing instance. Local member cannot be static.
 
 public void manageEnclosingInstanceAccessIfNecessary(ClassScope currentScopeFlowInfo flowInfo) {
 	if ((flowInfo.tagBits & .) == 0) {
 	NestedTypeBinding nestedType = (NestedTypeBindingthis.;
 	}
 }

A <clinit> will be requested as soon as static fields or assertions are present. It will be eliminated during classfile creation if no bytecode was actually produced based on some optimizations/compiler settings.
 
 public final boolean needClassInitMethod() {
 	// always need a <clinit> when assertions are present
 	if ((this. & .) != 0)
 		return true;
 
 	switch (kind(this.)) {
 			return this. != null// fields are implicitly statics
 			return true// even if no enum constants, need to set $VALUES array
 	}
 	if (this. != null) {
 		for (int i = this..length; --i >= 0;) {
 			FieldDeclaration field = this.[i];
 			//need to test the modifier directly while there is no binding yet
 			if ((field.modifiers & .) != 0)
 				return true// TODO (philippe) shouldn't it check whether field is initializer or has some initial value ?
 		}
 	}
 	return false;
 }
 
 public void parseMethods(Parser parserCompilationUnitDeclaration unit) {
 	//connect method bodies
 	if (unit.ignoreMethodBodies)
 		return;
 
 	//members
 	if (this. != null) {
 		int length = this..length;
 		for (int i = 0; i < lengthi++) {
 			TypeDeclaration typeDeclaration = this.[i];
 			typeDeclaration.parseMethods(parserunit);
 			this. |= (typeDeclaration.bits & .);
 		}
 	}
 
 	//methods
 	if (this. != null) {
 		int length = this..length;
 		for (int i = 0; i < lengthi++) {
 			AbstractMethodDeclaration abstractMethodDeclaration = this.[i];
 			abstractMethodDeclaration.parseStatements(parserunit);
 			this. |= (abstractMethodDeclaration.bits & .);
 		}
 	}
 
 	//initializers
 	if (this. != null) {
 		int length = this..length;
 		for (int i = 0; i < lengthi++) {
 			final FieldDeclaration fieldDeclaration = this.[i];
 			switch(fieldDeclaration.getKind()) {
 					((InitializerfieldDeclaration).parseStatements(parserthisunit);
 					this. |= (fieldDeclaration.bits & .);
 					break;
 			}
 		}
 	}
 }
 
 public StringBuffer print(int indentStringBuffer output) {
 	if (this. != null) {
 		this..print(indentoutput);
 	}
 	if ((this. & .) == 0) {
 		printIndent(indentoutput);
 		printHeader(0, output);
 	}
 	return printBody(indentoutput);
 }
 
 public StringBuffer printBody(int indentStringBuffer output) {
 	output.append(" {"); //$NON-NLS-1$
 	if (this. != null) {
 		for (int i = 0; i < this..lengthi++) {
 			if (this.[i] != null) {
 				output.append('\n');
 				this.[i].print(indent + 1, output);
 			}
 		}
 	}
 	if (this. != null) {
 		for (int fieldI = 0; fieldI < this..lengthfieldI++) {
 			if (this.[fieldI] != null) {
 				output.append('\n');
 				this.[fieldI].print(indent + 1, output);
 			}
 		}
 	}
 	if (this. != null) {
 		for (int i = 0; i < this..lengthi++) {
 			if (this.[i] != null) {
 				output.append('\n');
 				this.[i].print(indent + 1, output);
 			}
 		}
 	}
 	output.append('\n');
 	return printIndent(indentoutput).append('}');
 }
 
 public StringBuffer printHeader(int indentStringBuffer output) {
 	printModifiers(this.output);
 	if (this. != nullprintAnnotations(this.output);
 
 	switch (kind(this.)) {
 			output.append("class "); //$NON-NLS-1$
 			break;
 			output.append("interface "); //$NON-NLS-1$
 			break;
 			output.append("enum "); //$NON-NLS-1$
 			break;
 			output.append("@interface "); //$NON-NLS-1$
 			break;
 	}
 	output.append(this.);
 	if (this. != null) {
 		output.append("<");//$NON-NLS-1$
 		for (int i = 0; i < this..lengthi++) {
 			if (i > 0) output.append", "); //$NON-NLS-1$
 			this.[i].print(0, output);
 		}
 		output.append(">");//$NON-NLS-1$
 	}
 	if (this. != null) {
 		output.append(" extends ");  //$NON-NLS-1$
 		this..print(0, output);
 	}
 	if (this. != null && this..length > 0) {
 		switch (kind(this.)) {
 				output.append(" implements "); //$NON-NLS-1$
 				break;
 				output.append(" extends "); //$NON-NLS-1$
 				break;
 		}
 		for (int i = 0; i < this..lengthi++) {
 			if (i > 0) output.append", "); //$NON-NLS-1$
 			this.[i].print(0, output);
 		}
 	}
 	return output;
 }
 
 public StringBuffer printStatement(int tabStringBuffer output) {
 	return print(taboutput);
 }
 
 
 
 public void resolve() {
 	SourceTypeBinding sourceType = this.;
 	if (sourceType == null) {
 		return;
 	}
 	try {
 		try {
 		} finally {
 		}
		// check @Deprecated annotation
		if ((sourceType.getAnnotationTagBits() & .) == 0
				&& (sourceType.modifiers & .) != 0
		if ((this. & .) != 0) {
		boolean needSerialVersion =
						&& sourceType.isClass()
						&& sourceType.findSuperTypeOriginatingFrom(.false /*Externalizable is not a class*/) == null
						&& sourceType.findSuperTypeOriginatingFrom(.false /*Serializable is not a class*/) != null;
		if (needSerialVersion) {
			// if Object writeReplace() throws java.io.ObjectStreamException is present, then no serialVersionUID is needed
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=101476
			CompilationUnitScope compilationUnitScope = this..compilationUnitScope();
			MethodBinding methodBinding = sourceType.getExactMethod(..compilationUnitScope);
			ReferenceBinding[] throwsExceptions;
			needSerialVersion =
				methodBinding == null
					|| !methodBinding.isValidBinding()
					|| methodBinding.returnType.id != .
					|| (throwsExceptions = methodBinding.thrownExceptions).length != 1
					|| throwsExceptions[0]. != .;
			if (needSerialVersion) {
				// check the presence of an implementation of the methods
				// private void writeObject(java.io.ObjectOutputStream out) throws IOException
				// private void readObject(java.io.ObjectInputStream out) throws IOException
				boolean hasWriteObjectMethod = false;
				boolean hasReadObjectMethod = false;
				if (argumentTypeBinding.isValidBinding()) {
					methodBinding = sourceType.getExactMethod(.new TypeBinding[] { argumentTypeBinding }, compilationUnitScope);
					hasWriteObjectMethod = methodBinding != null
							&& methodBinding.isValidBinding()
							&& methodBinding.modifiers == .
							&& methodBinding.returnType == .
							&& (throwsExceptions = methodBinding.thrownExceptions).length == 1
							&& throwsExceptions[0]. == .;
				argumentTypeBinding = this..getType(., 3);
				if (argumentTypeBinding.isValidBinding()) {
					methodBinding = sourceType.getExactMethod(.new