/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
 *							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
 *							bug 292478 - Report potentially null across variable assignment
 *							bug 335093 - [compiler][null] minimal hook for future null annotation support
 *							bug 349326 - [1.7] new warning for missing try-with-resources
 *							bug 186342 - [compiler][null] Using annotations for null checking
 *							bug 358903 - Filter practically unimportant resource leak warnings
 *							bug 370639 - [compiler][resource] restore the default for resource leak warnings
 *							bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
 *							bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
 *							bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
 *							bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
 *							bug 383368 - [compiler][null] syntactic null analysis for field references
 *							bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
 *							Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
 *							Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
 *							Bug 427438 - [1.8][compiler] NPE at org.eclipse.jdt.internal.compiler.ast.ConditionalExpression.generateCode(ConditionalExpression.java:280)
 *							Bug 430150 - [1.8][null] stricter checking against type variables
 *							Bug 453483 - [compiler][null][loop] Improve null analysis for loops
 *     Jesper S Moller - Contributions for
 *							Bug 378674 - "The method can be declared as static" is wrong
 *							Bug 527554 - [18.3] Compiler support for JEP 286 Local-Variable Type
 *							Bug 529556 - [18.3] Add content assist support for 'var' as a type
 *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
 *							Bug 409250 - [1.8][compiler] Various loose ends in 308 code generation
 *							Bug 426616 - [1.8][compiler] Type Annotations, multiple problems
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;

import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.ASSIGNMENT_CONTEXT;
import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.VANILLA_CONTEXT;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.ast.TypeReference.AnnotationCollector;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.*;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.IAlienScopeTypeReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator;

/**
 * OTDT changes:
 *
 * What: Flag "isGenerated"
 * Why:  Signal that generated variables have no source position
 *
 * What: Locals with flag "isPlaceHolde" reserve a slot for an argument to be added later
 * Why:  Arguments and locals are assigned consecutive slots, if a marker arg
 *       is to be added later during copy, a slot must have been reserved for it.
 *
 * What: Locals with flag "isPreparingForLifting" support declared lifting in constructors.
 * How:  See class comment in class Lifting (item C.2.).
 *
 * What: Wrap role types for declared type and initialization expression.
 *
 * What: Record team anchor equivalence in TeamAnchor.bestNamePath.
 *
 * @version $Id: LocalDeclaration.java 23405 2010-02-03 17:02:18Z stephan $
 */
public class LocalDeclaration extends AbstractVariableDeclaration {

	public LocalVariableBinding binding;

//{ObjectTeams: additional flags for generated local vars:

	/** is this a faked var preparing a team ctor for arg-lifting? */
	public boolean isPreparingForLifting = false;

	/** is this a dummy variable just reserving a slot
	 *  for a marker arg that might be added during copy? */
	public boolean isPlaceHolder = false;

	/** Has this declaration been generated when translating specific OT constructs? */
	public boolean isGenerated = false;
// SH}

	public LocalDeclaration(
		char[] name,
		int sourceStart,
		int sourceEnd) {

		this.name = name;
		this.sourceStart = sourceStart;
		this.sourceEnd = sourceEnd;
		this.declarationEnd = sourceEnd;
	}

@Override
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	// record variable initialization if any
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
		this.bits |= ASTNode.IsLocalDeclarationReachable; // only set if actually reached
	}
//{ObjectTeams: pretend place holder is used:
	if (this.isPlaceHolder)
		this.binding.useFlag = LocalVariableBinding.USED;
// SH}
	if (this.initialization == null) {
		return flowInfo;
	}
	this.initialization.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);

	FlowInfo preInitInfo = null;
	boolean shouldAnalyseResource = this.binding != null
			&& flowInfo.reachMode() == FlowInfo.REACHABLE
			&& currentScope.compilerOptions().analyseResourceLeaks
//{ObjectTeams: notably lift methods of Closeable roles would trigger warnings against synthetic code
			&& !currentScope.isGeneratedScope()
// SH}
			&& FakedTrackingVariable.isAnyCloseable(this.initialization.resolvedType);
	if (shouldAnalyseResource) {
		preInitInfo = flowInfo.unconditionalCopy();
		// analysis of resource leaks needs additional context while analyzing the RHS:
		FakedTrackingVariable.preConnectTrackerAcrossAssignment(this, this.binding, this.initialization, flowInfo);
	}

	flowInfo =
		this.initialization
			.analyseCode(currentScope, flowContext, flowInfo)
			.unconditionalInits();

	if (shouldAnalyseResource)
		FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, flowContext, this, this.initialization, this.binding);
	else
		FakedTrackingVariable.cleanUpAfterAssignment(currentScope, Binding.LOCAL, this.initialization);

	int nullStatus = this.initialization.nullStatus(flowInfo, flowContext);
	if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes
		this.bits |= FirstAssignmentToLocal;
	} else {
		this.bits &= ~FirstAssignmentToLocal;  // int i = (i = 0);
	}
	flowInfo.markAsDefinitelyAssigned(this.binding);
	if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
		nullStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, this.binding, flowInfo, nullStatus, this.initialization, this.initialization.resolvedType);
	}
	if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) {
		flowInfo.markNullStatus(this.binding, nullStatus);
		// no need to inform enclosing try block since its locals won't get
		// known by the finally block
	}
	return flowInfo;
}

	public void checkModifiers() {

		//only potential valid modifier is <<final>>
		if (((this.modifiers & ExtraCompilerModifiers.AccJustFlag) & ~ClassFileConstants.AccFinal) != 0)
			//AccModifierProblem -> other (non-visibility problem)
			//AccAlternateModifierProblem -> duplicate modifier
			//AccModifierProblem | AccAlternateModifierProblem -> visibility problem"

			this.modifiers = (this.modifiers & ~ExtraCompilerModifiers.AccAlternateModifierProblem) | ExtraCompilerModifiers.AccModifierProblem;
	}

	/**
	 * Code generation for a local declaration:
	 *	i.e.&nbsp;normal assignment to a local variable + unused variable handling
	 */
	@Override
	public void generateCode(BlockScope currentScope, CodeStream codeStream) {

		// even if not reachable, variable must be added to visible if allocated (28298)
		if (this.binding.resolvedPosition != -1) {
			codeStream.addVisibleLocalVariable(this.binding);
		}
		if ((this.bits & IsReachable) == 0) {
			return;
		}
		int pc = codeStream.position;

		// something to initialize?
		generateInit: {
			if (this.initialization == null)
				break generateInit;
			// forget initializing unused or final locals set to constant value (final ones are inlined)
			if (this.binding.resolvedPosition < 0) {
				if (this.initialization.constant != Constant.NotAConstant)
					break generateInit;
				// if binding unused generate then discard the value
				this.initialization.generateCode(currentScope, codeStream, false);
				break generateInit;
			}
//{ObjectTeams: prepare for lifting (see comments in Lifting!)
			if (this.isPreparingForLifting) {
				for (int i=0;i<6;i++)
					codeStream.nop();          // space for: aload_0; invokevirtual _OT$initCaches();pop;
											   //            aload_0;
			}
// SH}
			this.initialization.generateCode(currentScope, codeStream, true);
//{ObjectTeams: prepare for lifting:
			if (this.isPreparingForLifting)
                for (int i=0;i<3;i++)
                	codeStream.nop();      // space for: invokevirtual _OT$liftTo$<R>(base);
// SH}
			// 26903, need extra cast to store null in array local var
			if (this.binding.type.isArrayType()
				&& ((this.initialization instanceof CastExpression)	// arrayLoc = (type[])null
						&& (((CastExpression)this.initialization).innermostCastedExpression().resolvedType == TypeBinding.NULL))){
				codeStream.checkcast(this.binding.type);
			}
			codeStream.store(this.binding, false);
			if ((this.bits & ASTNode.FirstAssignmentToLocal) != 0) {
				/* Variable may have been initialized during the code initializing it
					e.g. int i = (i = 1);
				*/
				this.binding.recordInitializationStartPC(codeStream.position);
			}
		}
		codeStream.recordPositionsFrom(pc, this.sourceStart);
	}

	/**
	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration#getKind()
	 */
	@Override
	public int getKind() {
		return LOCAL_VARIABLE;
	}

	// for local variables
	public void getAllAnnotationContexts(int targetType, LocalVariableBinding localVariable, List<AnnotationContext> allAnnotationContexts) {
		AnnotationCollector collector = new AnnotationCollector(this, targetType, localVariable, allAnnotationContexts);
		this.traverseWithoutInitializer(collector, (BlockScope) null);
	}

	// for arguments
	public void getAllAnnotationContexts(int targetType, int parameterIndex, List<AnnotationContext> allAnnotationContexts) {
		AnnotationCollector collector = new AnnotationCollector(this, targetType, parameterIndex, allAnnotationContexts);
		this.traverse(collector, (BlockScope) null);
	}

	public boolean isArgument() {
		return false;
	}
	public boolean isReceiver() {
		return false;
	}
	public TypeBinding patchType(TypeBinding newType) {
		// Perform upwards projection on type wrt mentioned type variables
		TypeBinding[] mentionedTypeVariables= findCapturedTypeVariables(newType);
		if (mentionedTypeVariables != null && mentionedTypeVariables.length > 0) {
			newType = newType.upwardsProjection(this.binding.declaringScope, mentionedTypeVariables);
		}
		this.type.resolvedType = newType;
		if (this.binding != null) {
			this.binding.type = newType;
			this.binding.markInitialized();
		}
		return this.type.resolvedType;
	}

	private TypeVariableBinding[] findCapturedTypeVariables(TypeBinding typeBinding) {
		final Set<TypeVariableBinding> mentioned = new HashSet<>();
		TypeBindingVisitor.visit(new TypeBindingVisitor() {
			@Override
			public boolean visit(TypeVariableBinding typeVariable) {
				if (typeVariable.isCapture())
					mentioned.add(typeVariable);
				return super.visit(typeVariable);
			}
		}, typeBinding);
		if (mentioned.isEmpty()) return null;
		return mentioned.toArray(new TypeVariableBinding[mentioned.size()]);
	}

	private static Expression findPolyExpression(Expression e) {
		// This is simpler than using an ASTVisitor, since we only care about a very few select cases.
		if (e instanceof FunctionalExpression) {
			return e;
		}
		if (e instanceof ConditionalExpression) {
			ConditionalExpression ce = (ConditionalExpression)e;
			Expression candidate = findPolyExpression(ce.valueIfTrue);
			if (candidate == null) {
				candidate = findPolyExpression(ce.valueIfFalse);
			}
			if (candidate != null) return candidate;
		}
		if (e instanceof SwitchExpression) {
			SwitchExpression se = (SwitchExpression)e;
			for (Expression re : se.resultExpressions) {
				Expression candidate = findPolyExpression(re);
				if (candidate != null) return candidate;
			}
		}
		return null;
	}

	@Override
	public void resolve(BlockScope scope) {
		resolve(scope, false);
	}
	public void resolve(BlockScope scope, boolean isPatternVariable) {
		// prescan NNBD
		handleNonNullByDefault(scope, this.annotations, this);

		TypeBinding variableType = null;
		boolean variableTypeInferenceError = false;
		boolean isTypeNameVar = isTypeNameVar(scope);
//{ObjectTeams: avoid duplicate resolving:
	  if (this.binding == null) {
// SH}
		if (isTypeNameVar && !isPatternVariable) {
			if ((this.bits & ASTNode.IsForeachElementVariable) == 0) {
				// infer a type from the initializer
				if (this.initialization != null) {
					variableType = checkInferredLocalVariableInitializer(scope);
					variableTypeInferenceError = variableType != null;
				} else {
					// That's always an error
					scope.problemReporter().varLocalWithoutInitizalier(this);
					variableType = scope.getJavaLangObject();
					variableTypeInferenceError = true;
				}
			}
		} else {
			variableType = this.type.resolveType(scope, true /* check bounds*/);
		}

//{ObjectTeams: wrap declared type
		{
			Scope typeScope = scope;
			if (this.type instanceof IAlienScopeTypeReference)
				typeScope = ((IAlienScopeTypeReference)this.type).getAlienScope();
			variableType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(variableType, typeScope, this);
		}
// SH}
		this.bits |= (this.type.bits & ASTNode.HasTypeAnnotations);
		checkModifiers();
		if (variableType != null) {
			if (variableType == TypeBinding.VOID) {
				scope.problemReporter().variableTypeCannotBeVoid(this);
				return;
			}
			if (variableType.isArrayType() && ((ArrayBinding) variableType).leafComponentType == TypeBinding.VOID) {
				scope.problemReporter().variableTypeCannotBeVoidArray(this);
				return;
			}
		}

		Binding existingVariable = scope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/);
		if (existingVariable != null && existingVariable.isValidBinding()){
			boolean localExists = existingVariable instanceof LocalVariableBinding;
			if (localExists && (this.bits & ASTNode.ShadowsOuterLocal) != 0 && scope.isLambdaSubscope() && this.hiddenVariableDepth == 0) {
				scope.problemReporter().lambdaRedeclaresLocal(this);
			} else if (localExists && this.hiddenVariableDepth == 0) {
				scope.problemReporter().redefineLocal(this);
			} else {
				scope.problemReporter().localVariableHiding(this, existingVariable, false);
			}
		}

		if ((this.modifiers & ClassFileConstants.AccFinal)!= 0 && this.initialization == null) {
			this.modifiers |= ExtraCompilerModifiers.AccBlankFinal;
		}
		if (isTypeNameVar) {
			// Create binding for the initializer's type
			// In order to resolve self-referential initializers, we must declare the variable with a placeholder type (j.l.Object), and then patch it later
			this.binding = new LocalVariableBinding(this, variableType != null ? variableType : scope.getJavaLangObject(), this.modifiers, false) {
				private boolean isInitialized = false;

				@Override
				public void markReferenced() {
					if (! this.isInitialized) {
						scope.problemReporter().varLocalReferencesItself(LocalDeclaration.this);
						this.type = null;
						this.isInitialized = true; // Quell additional type errors
					}
				}
				@Override
				public void markInitialized() {
					this.isInitialized = true;
				}
			};
		} else {
			// create a binding from the specified type
			this.binding = new LocalVariableBinding(this, variableType, this.modifiers, false /*isArgument*/);
		}
		scope.addLocalVariable(this.binding);
		this.binding.setConstant(Constant.NotAConstant);
		// allow to recursivelly target the binding....
		// the correct constant is harmed if correctly computed at the end of this method
//{ObjectTeams: end if (this.binding == null)
	  } else {
		variableType = this.binding.type;
	  }
// SH}

		if (variableType == null) {
			if (this.initialization != null) {
				if (this.initialization instanceof CastExpression) {
					((CastExpression)this.initialization).setVarTypeDeclaration(true);
				}
				this.initialization.resolveType(scope); // want to report all possible errors
				if (isTypeNameVar && this.initialization.resolvedType != null) {
					if (TypeBinding.equalsEquals(TypeBinding.NULL, this.initialization.resolvedType)) {
						scope.problemReporter().varLocalInitializedToNull(this);
						variableTypeInferenceError = true;
					} else if (TypeBinding.equalsEquals(TypeBinding.VOID, this.initialization.resolvedType)) {
						scope.problemReporter().varLocalInitializedToVoid(this);
						variableTypeInferenceError = true;
					}
					variableType = patchType(this.initialization.resolvedType);
				} else {
					variableTypeInferenceError = true;
				}
			}
		}
		this.binding.markInitialized();
		if (variableTypeInferenceError) {
			return;
		}
		boolean resolveAnnotationsEarly = false;
		if (scope.environment().usesNullTypeAnnotations()
				&& !isTypeNameVar // 'var' does not provide a target type
				&& variableType != null && variableType.isValidBinding()) {
			resolveAnnotationsEarly = this.initialization instanceof Invocation
					|| this.initialization instanceof ConditionalExpression
					|| this.initialization instanceof SwitchExpression
					|| this.initialization instanceof ArrayInitializer;
		}
		if (resolveAnnotationsEarly) {
			// these are definitely no constants, so resolving annotations early should be safe
			resolveAnnotations(scope, this.annotations, this.binding, true);
			// for type inference having null annotations upfront gives better results
			variableType = this.type.resolvedType;
		}
		if (this.initialization != null) {
			if (this.initialization instanceof ArrayInitializer) {
				TypeBinding initializationType = this.initialization.resolveTypeExpecting(scope, variableType);
				if (initializationType != null) {
					((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType;
					this.initialization.computeConversion(scope, variableType, initializationType);
				}
			} else {
				this.initialization.setExpressionContext(isTypeNameVar ? VANILLA_CONTEXT : ASSIGNMENT_CONTEXT);
				this.initialization.setExpectedType(variableType);
				TypeBinding initializationType = this.initialization.resolvedType != null ? this.initialization.resolvedType : this.initialization.resolveType(scope);
				if (initializationType != null) {
//{ObjectTeams: wrap rhs type:
					initializationType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(initializationType, scope, this.initialization);
// SH}
					if (TypeBinding.notEquals(variableType, initializationType)) // must call before computeConversion() and typeMismatchError()
						scope.compilationUnitScope().recordTypeConversion(variableType, initializationType);
					if (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, variableType)
						|| initializationType.isCompatibleWith(variableType, scope)) {
						this.initialization.computeConversion(scope, variableType, initializationType);
						if (initializationType.needsUncheckedConversion(variableType)) {
						    scope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, variableType);
						}
						if (this.initialization instanceof CastExpression
								&& (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) {
							CastExpression.checkNeedForAssignedCast(scope, variableType, (CastExpression) this.initialization);
						}
					} else if (isBoxingCompatible(initializationType, variableType, this.initialization, scope)) {
						this.initialization.computeConversion(scope, variableType, initializationType);
						if (this.initialization instanceof CastExpression
								&& (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) {
							CastExpression.checkNeedForAssignedCast(scope, variableType, (CastExpression) this.initialization);
						}
					} else {
						if ((variableType.tagBits & TagBits.HasMissingType) == 0) {
							// if problem already got signaled on type, do not report secondary problem
							scope.problemReporter().typeMismatchError(initializationType, variableType, this.initialization, null);
						}
					}
//{ObjectTeams: additional re-check:
					if (Config.getLoweringPossible() && initializationType != null && initializationType.isRoleType())
						((DependentTypeBinding)initializationType).recheckAmbiguousLowering(variableType, this, scope, null);
// SH}
				}
			}
			// check for assignment with no effect
			if (this.binding == Expression.getDirectBinding(this.initialization)) {
				scope.problemReporter().assignmentHasNoEffect(this, this.name);
			}
			// change the constant in the binding when it is final
			// (the optimization of the constant propagation will be done later on)
			// cast from constant actual type to variable type
			this.binding.setConstant(
				this.binding.isFinal()
					? this.initialization.constant.castTo((variableType.id << 4) + this.initialization.constant.typeID())
					: Constant.NotAConstant);
//{ObjectTeams: record team anchor equivalence:
			this.binding.setBestNameFromStat(this.initialization);
// SH}
		}
		// if init could be a constant only resolve annotation at the end, for constant to be positioned before (96991)
		if (!resolveAnnotationsEarly)
			resolveAnnotations(scope, this.annotations, this.binding, true);
		Annotation.isTypeUseCompatible(this.type, scope, this.annotations);
		validateNullAnnotations(scope);
	}

	void validateNullAnnotations(BlockScope scope) {
		if (!scope.validateNullAnnotation(this.binding.tagBits, this.type, this.annotations))
			this.binding.tagBits &= ~TagBits.AnnotationNullMASK;
	}

	/*
	 * Checks the initializer for simple errors, and reports an error as needed. If error is found,
	 * returns a reasonable match for further type checking.
	 */
	private TypeBinding checkInferredLocalVariableInitializer(BlockScope scope) {
		TypeBinding errorType = null;
		if (this.initialization instanceof ArrayInitializer) {
			scope.problemReporter().varLocalCannotBeArrayInitalizers(this);
			errorType = scope.createArrayType(scope.getJavaLangObject(), 1); // Treat as array of anything
		} else {
			// Catch-22: isPolyExpression() is not reliable BEFORE resolveType, so we need to peek to suppress the errors
			Expression polyExpression = findPolyExpression(this.initialization);
			if (polyExpression instanceof ReferenceExpression) {
				scope.problemReporter().varLocalCannotBeMethodReference(this);
				errorType = TypeBinding.NULL;
			} else if (polyExpression != null) { // Should be instanceof LambdaExpression, but this is safer
				scope.problemReporter().varLocalCannotBeLambda(this);
				errorType = TypeBinding.NULL;
			}
		}
		if (this.type.dimensions() > 0 || this.type.extraDimensions() > 0) {
			scope.problemReporter().varLocalCannotBeArray(this);
			errorType = scope.createArrayType(scope.getJavaLangObject(), 1); // This is just to quell some warnings
		}
		if ((this.bits & ASTNode.IsAdditionalDeclarator) != 0) {
			scope.problemReporter().varLocalMultipleDeclarators(this);
			errorType = this.initialization.resolveType(scope);
		}
		return errorType;
	}

	@Override
	public void traverse(ASTVisitor visitor, BlockScope scope) {

		if (visitor.visit(this, scope)) {
			if (this.annotations != null) {
				int annotationsLength = this.annotations.length;
				for (int i = 0; i < annotationsLength; i++)
					this.annotations[i].traverse(visitor, scope);
			}
			this.type.traverse(visitor, scope);
			if (this.initialization != null)
				this.initialization.traverse(visitor, scope);
		}
		visitor.endVisit(this, scope);
	}

	private void traverseWithoutInitializer(ASTVisitor visitor, BlockScope scope) {
		if (visitor.visit(this, scope)) {
			if (this.annotations != null) {
				int annotationsLength = this.annotations.length;
				for (int i = 0; i < annotationsLength; i++)
					this.annotations[i].traverse(visitor, scope);
			}
			this.type.traverse(visitor, scope);
		}
		visitor.endVisit(this, scope);
	}

	public boolean isRecoveredFromLoneIdentifier() { // recovered from lonely identifier or identifier cluster ?
		return this.name == RecoveryScanner.FAKE_IDENTIFIER &&
				(this.type instanceof SingleTypeReference || (this.type instanceof QualifiedTypeReference && !(this.type instanceof ArrayQualifiedTypeReference))) && this.initialization == null && !this.type.isBaseTypeReference();
	}

	public boolean isTypeNameVar(Scope scope) {
		return this.type != null && this.type.isTypeNameVar(scope);
	}

}
