/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;

import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.codegen.Label;
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.flow.LoopingFlowContext;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;

public class ForeachStatement extends Statement {
    
	public LocalDeclaration elementVariable;
	public int elementVariableImplicitWidening = -1; 
	public Expression collection;
	public Statement action;
	
	// set the kind of foreach
	private int kind;
	// possible kinds of iterating behavior
	private static final int ARRAY = 0;
	private static final int RAW_ITERABLE = 1;
	private static final int GENERIC_ITERABLE = 2;

	private TypeBinding collectionElementType;

	// loop labels
	private Label breakLabel;
	private Label continueLabel;
	
	public BlockScope scope;

	// secret variables for codegen
	public LocalVariableBinding indexVariable;
	public LocalVariableBinding collectionVariable;	// to store the collection expression value
	public LocalVariableBinding maxVariable;
	// secret variable names
	private static final char[] SecretIndexVariableName = " index".toCharArray(); //$NON-NLS-1$
	private static final char[] SecretCollectionVariableName = " collection".toCharArray(); //$NON-NLS-1$
	private static final char[] SecretMaxVariableName = " max".toCharArray(); //$NON-NLS-1$
	
	int postCollectionInitStateIndex = -1;
	int mergedInitStateIndex = -1;
	
	public ForeachStatement(
		LocalDeclaration elementVariable,
		Expression collection,
		int start) {

		this.elementVariable = elementVariable;
		this.collection = collection;
		this.sourceStart = start;
		this.kind = -1;
	}

	public FlowInfo analyseCode(
		BlockScope currentScope,
		FlowContext flowContext,
		FlowInfo flowInfo) {
		// initialize break and continue labels
		breakLabel = new Label();
		continueLabel = new Label();

		// process the element variable and collection
		flowInfo = this.elementVariable.analyseCode(scope, flowContext, flowInfo);
		FlowInfo condInfo = flowInfo.copy().unconditionalInits().discardNullRelatedInitializations();
		condInfo = this.collection.analyseCode(scope, flowContext, condInfo);

		// element variable will be assigned when iterating
		condInfo.markAsDefinitelyAssigned(this.elementVariable.binding);

		this.postCollectionInitStateIndex = currentScope.methodScope().recordInitializationStates(condInfo);
		
		// process the action
		LoopingFlowContext loopingContext = new LoopingFlowContext(flowContext, this, breakLabel, continueLabel, scope);
		FlowInfo actionInfo = condInfo.initsWhenTrue().copy();
		FlowInfo exitBranch;
		if (!(action == null || (action.isEmptyBlock() 
		        	&& currentScope.environment().options.complianceLevel <= ClassFileConstants.JDK1_3))) {

			if (!this.action.complainIfUnreachable(actionInfo, scope, false)) {
				actionInfo = action.analyseCode(scope, loopingContext, actionInfo);
			}

			// code generation can be optimized when no need to continue in the loop
			exitBranch = condInfo.initsWhenFalse();
			exitBranch.addInitializationsFrom(flowInfo); // recover null inits from before condition analysis			
			if (!actionInfo.isReachable() && !loopingContext.initsOnContinue.isReachable()) {
				continueLabel = null;
			} else {
				actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue.unconditionalInits());
				loopingContext.complainOnDeferredChecks(scope, actionInfo);
				exitBranch.addPotentialInitializationsFrom(actionInfo.unconditionalInits());
			}
		} else {
			exitBranch = condInfo.initsWhenFalse();
		}

		// we need the variable to iterate the collection even if the 
		// element variable is not used
		if (!(this.action == null
				|| this.action.isEmptyBlock()
				|| ((this.action.bits & IsUsefulEmptyStatementMASK) != 0))) {
			switch(this.kind) {
				case ARRAY :
					this.collectionVariable.useFlag = LocalVariableBinding.USED;
					this.indexVariable.useFlag = LocalVariableBinding.USED;
					this.maxVariable.useFlag = LocalVariableBinding.USED;
					break;
				case RAW_ITERABLE :
				case GENERIC_ITERABLE :
					this.indexVariable.useFlag = LocalVariableBinding.USED;
					break;
			}
		}
		//end of loop
		FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches(
				loopingContext.initsOnBreak, 
				false, 
				exitBranch, 
				false, 
				true /*for(;;){}while(true); unreachable(); */);
		mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
		return mergedInfo;
	}

	/**
	 * For statement code generation
	 *
	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
	 */
	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
	    
		if ((bits & IsReachableMASK) == 0) {
			return;
		}
		int pc = codeStream.position;
		if (this.action == null
				|| this.action.isEmptyBlock()
				|| ((this.action.bits & IsUsefulEmptyStatementMASK) != 0)) {
			codeStream.exitUserScope(scope);
			if (mergedInitStateIndex != -1) {
				codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
				codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);				
			}
			codeStream.recordPositionsFrom(pc, this.sourceStart);
			return;
		}
		// generate the initializations
		switch(this.kind) {
			case ARRAY :
				collection.generateCode(scope, codeStream, true);
				codeStream.store(this.collectionVariable, false);
				codeStream.iconst_0();
				codeStream.store(this.indexVariable, false);
				codeStream.load(this.collectionVariable);
				codeStream.arraylength();
				codeStream.store(this.maxVariable, false);
				break;
			case RAW_ITERABLE :
			case GENERIC_ITERABLE :
				collection.generateCode(scope, codeStream, true);
				// declaringClass.iterator();
				final TypeBinding collectionTypeBinding = collection.resolvedType;
				MethodBinding iteratorMethodBinding =
					new MethodBinding(
							AccPublic,
							"iterator".toCharArray(),//$NON-NLS-1$
							scope.getJavaUtilIterator(),
							TypeConstants.NoParameters,
							TypeConstants.NoExceptions,
							(ReferenceBinding) collectionTypeBinding);
				if (collectionTypeBinding.isInterface()) {
					codeStream.invokeinterface(iteratorMethodBinding);
				} else {
					codeStream.invokevirtual(iteratorMethodBinding);
				}
				codeStream.store(this.indexVariable, false);
				break;
		}
		
		// label management
		Label actionLabel = new Label(codeStream);
		Label conditionLabel = new Label(codeStream);
		breakLabel.initialize(codeStream);
		if (this.continueLabel != null) {
			this.continueLabel.initialize(codeStream);
		}
		// jump over the actionBlock
		codeStream.goto_(conditionLabel);

		// generate the loop action
		actionLabel.place();

		// generate the loop action
		if (this.elementVariable.binding.resolvedPosition != -1) {
			switch(this.kind) {
				case ARRAY :
					codeStream.load(this.collectionVariable);
					codeStream.load(this.indexVariable);
					codeStream.arrayAt(this.collectionElementType.id);
					if (this.elementVariableImplicitWidening != -1) {
						codeStream.generateImplicitConversion(this.elementVariableImplicitWidening);
					}
					codeStream.store(this.elementVariable.binding, false);
					break;
				case RAW_ITERABLE :
				case GENERIC_ITERABLE :
					codeStream.load(this.indexVariable);
					codeStream.invokeJavaUtilIteratorNext();
					if (this.elementVariable.binding.type.id != T_JavaLangObject) {
						if (this.elementVariableImplicitWidening != -1) {
							codeStream.checkcast(this.collectionElementType);
							codeStream.generateImplicitConversion(this.elementVariableImplicitWidening);
						} else {
							codeStream.checkcast(this.elementVariable.binding.type);
						}
					}
					codeStream.store(this.elementVariable.binding, false);
					break;
			}
			codeStream.addVisibleLocalVariable(this.elementVariable.binding);
			if (this.postCollectionInitStateIndex != -1) {
				codeStream.addDefinitelyAssignedVariables(
					currentScope,
					this.postCollectionInitStateIndex);
			}
		}
		this.action.generateCode(scope, codeStream);

		// continuation point
		int continuationPC = codeStream.position;
		if (this.continueLabel != null) {
			this.continueLabel.place();
			// generate the increments for next iteration
			switch(this.kind) {
				case ARRAY :
					codeStream.iinc(this.indexVariable.resolvedPosition, 1);
					break;
				case RAW_ITERABLE :
				case GENERIC_ITERABLE :
					break;
			}
		}
		// generate the condition
		conditionLabel.place();
		if (this.postCollectionInitStateIndex != -1) {
			codeStream.removeNotDefinitelyAssignedVariables(currentScope, postCollectionInitStateIndex);
		}
		switch(this.kind) {
			case ARRAY :
				codeStream.load(this.indexVariable);
				codeStream.load(this.maxVariable);
				codeStream.if_icmplt(actionLabel);
				break;
			case RAW_ITERABLE :
			case GENERIC_ITERABLE :
				codeStream.load(this.indexVariable);
				codeStream.invokeJavaUtilIteratorHasNext();
				codeStream.ifne(actionLabel);
				break;
		}
		codeStream.recordPositionsFrom(continuationPC, this.elementVariable.sourceStart);

		breakLabel.place();
		codeStream.exitUserScope(scope);
		if (mergedInitStateIndex != -1) {
			codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
			codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);			
		}
		codeStream.recordPositionsFrom(pc, this.sourceStart);
	}

	public StringBuffer printStatement(int tab, StringBuffer output) {

		printIndent(tab, output).append("for ("); //$NON-NLS-1$
		this.elementVariable.print(0, output); 
		output.append(" : ");//$NON-NLS-1$
		this.collection.print(0, output).append(") "); //$NON-NLS-1$
		//block
		if (this.action == null) {
			output.append(';');
		} else {
			output.append('\n');
			this.action.printStatement(tab + 1, output); //$NON-NLS-1$
		}
		return output;
	}

	public void resolve(BlockScope upperScope) {
		// use the scope that will hold the init declarations
		scope = new BlockScope(upperScope);
		this.elementVariable.resolve(scope); // collection expression can see itemVariable
		TypeBinding elementType = this.elementVariable.type.resolvedType;
		TypeBinding collectionType = this.collection.resolveType(scope);
		this.collection.computeConversion(scope, collectionType, collectionType);
		boolean hasError = elementType == null || collectionType == null;

		if (!hasError) {
			if (collectionType.isArrayType()) { // for(E e : E[])
				this.kind = ARRAY;
				this.collectionElementType = ((ArrayBinding) collectionType).elementsType();
				if (!collectionElementType.isCompatibleWith(elementType)
						&& !scope.isBoxingCompatibleWith(collectionElementType, elementType)) {
					scope.problemReporter().notCompatibleTypesErrorInForeach(collection, collectionElementType, elementType);
				}
				// in case we need to do a conversion
				int compileTimeTypeID = collectionElementType.id;
				if (elementType.isBaseType()) {
					if (!collectionElementType.isBaseType()) {
						compileTimeTypeID = scope.environment().computeBoxingType(collectionElementType).id;
						this.elementVariableImplicitWidening = UNBOXING;
						if (elementType.isBaseType()) {
							this.elementVariableImplicitWidening |= (elementType.id << 4) + compileTimeTypeID;
							scope.problemReporter().autoboxing(collection, collectionElementType, elementType);
						}
					} else {
						this.elementVariableImplicitWidening = (elementType.id << 4) + compileTimeTypeID;
					}
				} else {
					if (collectionElementType.isBaseType()) {
						int boxedID = scope.environment().computeBoxingType(collectionElementType).id;
						this.elementVariableImplicitWidening = BOXING | (compileTimeTypeID << 4) | compileTimeTypeID; // use primitive type in implicit conversion
						compileTimeTypeID = boxedID;
						scope.problemReporter().autoboxing(collection, collectionElementType, elementType);
					}
				}
			} else if (collectionType instanceof ReferenceBinding) {
			    ReferenceBinding iterableType = ((ReferenceBinding)collectionType).findSuperTypeErasingTo(T_JavaLangIterable, false /*Iterable is not a class*/);
			    if (iterableType != null) {
				    if (iterableType.isParameterizedType()) { // for(E e : Iterable<E>)
					    ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding)iterableType;
						if (parameterizedType.arguments.length == 1) { // per construction can only be one
							this.kind = GENERIC_ITERABLE;
							this.collectionElementType = parameterizedType.arguments[0]; 
							if (!collectionElementType.isCompatibleWith(elementType)
									&& !scope.isBoxingCompatibleWith(collectionElementType, elementType)) {
								scope.problemReporter().notCompatibleTypesErrorInForeach(collection, collectionElementType, elementType);
							}
							int compileTimeTypeID = collectionElementType.id;
							// no conversion needed as only for reference types
							if (elementType.isBaseType()) {
								if (!collectionElementType.isBaseType()) {
									compileTimeTypeID = scope.environment().computeBoxingType(collectionElementType).id;
									this.elementVariableImplicitWidening = UNBOXING;
									if (elementType.isBaseType()) {
										this.elementVariableImplicitWidening |= (elementType.id << 4) + compileTimeTypeID;
									}
								} else {
									this.elementVariableImplicitWidening = (elementType.id << 4) + compileTimeTypeID;
								}
							} else {
								if (collectionElementType.isBaseType()) {
									int boxedID = scope.environment().computeBoxingType(collectionElementType).id;
									this.elementVariableImplicitWidening = BOXING | (compileTimeTypeID << 4) | compileTimeTypeID; // use primitive type in implicit conversion
									compileTimeTypeID = boxedID;
								}
							}
						}
				    } else if (iterableType.isGenericType()) { // for (T t : Iterable<T>) - in case used inside Iterable itself
						if (iterableType.typeVariables().length == 1) {
							this.kind = GENERIC_ITERABLE;
							this.collectionElementType = iterableType.typeVariables()[0]; 
							if (!collectionElementType.isCompatibleWith(elementType)
									&& !scope.isBoxingCompatibleWith(collectionElementType, elementType)) {
								scope.problemReporter().notCompatibleTypesErrorInForeach(collection, collectionElementType, elementType);
							}
							int compileTimeTypeID = collectionElementType.id;
							// no conversion needed as only for reference types
							if (elementType.isBaseType()) {
								if (!collectionElementType.isBaseType()) {
									compileTimeTypeID = scope.environment().computeBoxingType(collectionElementType).id;
									this.elementVariableImplicitWidening = UNBOXING;
									if (elementType.isBaseType()) {
										this.elementVariableImplicitWidening |= (elementType.id << 4) + compileTimeTypeID;
									}
								} else {
									this.elementVariableImplicitWidening = (elementType.id << 4) + compileTimeTypeID;
								}
							} else {
								if (collectionElementType.isBaseType()) {
									int boxedID = scope.environment().computeBoxingType(collectionElementType).id;
									this.elementVariableImplicitWidening = BOXING | (compileTimeTypeID << 4) | compileTimeTypeID; // use primitive type in implicit conversion
									compileTimeTypeID = boxedID;
								}
							}
						}
					} else if (iterableType.isRawType()) { // for(Object o : Iterable)
						this.kind = RAW_ITERABLE;
						this.collectionElementType = scope.getJavaLangObject();
						if (!collectionElementType.isCompatibleWith(elementType)
								&& !scope.isBoxingCompatibleWith(collectionElementType, elementType)) {
							scope.problemReporter().notCompatibleTypesErrorInForeach(collection, collectionElementType, elementType);
						}
						// no conversion needed as only for reference types
					}			    
			    }
			}
			switch(this.kind) {
				case ARRAY :
					// allocate #index secret variable (of type int)
					this.indexVariable = new LocalVariableBinding(SecretIndexVariableName, IntBinding, AccDefault, false);
					scope.addLocalVariable(this.indexVariable);
					this.indexVariable.setConstant(NotAConstant); // not inlinable
					
					// allocate #max secret variable
					this.maxVariable = new LocalVariableBinding(SecretMaxVariableName, IntBinding, AccDefault, false);
					scope.addLocalVariable(this.maxVariable);
					this.maxVariable.setConstant(NotAConstant); // not inlinable
					// add #array secret variable (of collection type)
					this.collectionVariable = new LocalVariableBinding(SecretCollectionVariableName, collectionType, AccDefault, false);
					scope.addLocalVariable(this.collectionVariable);
					this.collectionVariable.setConstant(NotAConstant); // not inlinable
					break;
				case RAW_ITERABLE :
				case GENERIC_ITERABLE :
					// allocate #index secret variable (of type Iterator)
					this.indexVariable = new LocalVariableBinding(SecretIndexVariableName, scope.getJavaUtilIterator(), AccDefault, false);
					scope.addLocalVariable(this.indexVariable);
					this.indexVariable.setConstant(NotAConstant); // not inlinable
					break;
				default :
					scope.problemReporter().invalidTypeForCollection(collection);
			}
		}
		if (action != null) {
			action.resolve(scope);
		}
	}
	
	public void traverse(
		ASTVisitor visitor,
		BlockScope blockScope) {

		if (visitor.visit(this, blockScope)) {
			this.elementVariable.traverse(visitor, scope);
			this.collection.traverse(visitor, scope);
			if (action != null) {
				action.traverse(visitor, scope);
			}
		}
		visitor.endVisit(this, blockScope);
	}
}
