package org.eclipse.jdt.internal.compiler.ast;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.codegen.*;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;

public class DoStatement extends Statement {
	public Expression condition;
	public Statement action ;

	private Label breakLabel, continueLabel;

	// for local variables table attributes
	int mergedInitStateIndex = -1;
public DoStatement(Expression condition, Statement action, int s, int e) {
	this.sourceStart =  s;
	this.sourceEnd = e;
	this.condition = condition;
	this.action = action;
}
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	breakLabel = new Label();
	continueLabel = new Label();
	LoopingFlowContext loopingContext = new LoopingFlowContext(flowContext, this, breakLabel, continueLabel, currentScope);

	Constant conditionConstant = condition.constant;
	Constant conditionalConstant = condition.conditionalConstant();	
	boolean isFalseCondition = 
		((conditionConstant != NotAConstant) && (conditionConstant.booleanValue() == false))
			|| ((conditionalConstant != NotAConstant) && (conditionalConstant.booleanValue() == false));
	
	if ((action != null) && !action.isEmptyBlock()) {
		//if (!flowInfo.complainIfUnreachable(this, currentScope)){ // probably useless since would be tested outside the do
		flowInfo = action.analyseCode(currentScope, loopingContext, flowInfo.copy());
		// unnecessary to check here}

		// code generation can be optimized when no need to continue in the loop
		if ((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable()){
			if ((loopingContext.initsOnContinue == FlowInfo.DeadEnd) || loopingContext.initsOnContinue.isFakeReachable()){
				continueLabel = null;
			} else {
				flowInfo = loopingContext.initsOnContinue; // for condition
				if (isFalseCondition){
					//	continueLabel = null; - cannot nil the label since may be targeted already by 'continue' statements
				} else {
					loopingContext.complainOnFinalAssignmentsInLoop(currentScope, flowInfo);
				}
			}
		} else {
			if (isFalseCondition){
				//	continueLabel = null; - cannot nil the label since may be targeted already by 'continue' statements
			} else {
				loopingContext.complainOnFinalAssignmentsInLoop(currentScope, flowInfo);
			}
		}
	}
	LoopingFlowContext condLoopContext;
	flowInfo = condition.analyseCode(currentScope, (condLoopContext = new LoopingFlowContext(flowContext, this, null, null, currentScope)), (action == null ? flowInfo : (flowInfo.mergedWith(loopingContext.initsOnContinue))));
	condLoopContext.complainOnFinalAssignmentsInLoop(currentScope, flowInfo);

	// infinite loop
	FlowInfo mergedInfo;
	if ((condition.constant != NotAConstant) && (condition.constant.booleanValue() == true)) {
		mergedInfo = loopingContext.initsOnBreak;
		mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
		return mergedInfo;
	}

	// end of loop: either condition false or break
	mergedInfo = flowInfo.initsWhenFalse().unconditionalInits().mergedWith(loopingContext.initsOnBreak);
	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
	return mergedInfo;
}
/**
 * Do statement code generation
 *
 */
public void generateCode(BlockScope currentScope, CodeStream codeStream) {

	if ((bits & IsReachableMASK) == 0) {
		return;
	}
	int pc = codeStream.position;

	// labels management
	Label actionLabel = new Label(codeStream);
	actionLabel.place();
	breakLabel.codeStream = codeStream;
	if (continueLabel != null) {
		continueLabel.codeStream = codeStream;
	}

	// generate action
	if (action != null){
		action.generateCode(currentScope, codeStream);
	}
	// generate condition
	if (continueLabel != null){
		continueLabel.place();
		condition.generateOptimizedBoolean(currentScope, codeStream, actionLabel, null, true);
	}
	breakLabel.place();

	// May loose some local variable initializations : affecting the local variable attributes
	if (mergedInitStateIndex != -1) {
		codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
	}
	codeStream.recordPositionsFrom(pc, this);
	
}
public void resolve(BlockScope scope) {
	TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding);
	condition.implicitWidening(type, type);
	if (action != null)
		action.resolve(scope);
}
public String toString(int tab) {
	/* slow code */

	String inFront, s = tabString(tab);
	inFront = s;
	s = s + "do"; //$NON-NLS-1$
	if (action == null)
		s = s + " {}\n"; //$NON-NLS-1$
	else
		if (action instanceof Block)
			s = s + "\n" + action.toString(tab + 1) + "\n"; //$NON-NLS-2$ //$NON-NLS-1$
		else
			s = s + " {\n" + action.toString(tab + 1) + ";}\n"; //$NON-NLS-1$ //$NON-NLS-2$
	s = s + inFront + "while (" + condition.toStringExpression() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
	return s;
}
public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
	if (visitor.visit(this, scope)) {
		if (action != null) {
			action.traverse(visitor, scope);
		}
		condition.traverse(visitor, scope);
	}
	visitor.endVisit(this, scope);
}
}
