/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Stephan Herrmann - Contributions for
 *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
 *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
 *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
 *								Bug 415790 - [compiler][resource]Incorrect potential resource leak warning in for loop with close in try/catch
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;

import org.eclipse.jdt.internal.compiler.ASTVisitor;
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 BranchLabel breakLabel, continueLabel;

	// for local variables table attributes
	int mergedInitStateIndex = -1;
	int preConditionInitStateIndex = -1;

public DoStatement(Expression condition, Statement action, int sourceStart, int sourceEnd) {

	this.sourceStart = sourceStart;
	this.sourceEnd = sourceEnd;
	this.condition = condition;
	this.action = action;
	// remember useful empty statement
	if (action instanceof EmptyStatement) action.bits |= ASTNode.IsUsefulEmptyStatement;
}

@Override
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	this.breakLabel = new BranchLabel();
	this.continueLabel = new BranchLabel();
	LoopingFlowContext loopingContext =
		new LoopingFlowContext(
			flowContext,
			flowInfo,
			this,
			this.breakLabel,
			this.continueLabel,
			currentScope,
			false);

	Constant cst = this.condition.constant;
	boolean isConditionTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
	cst = this.condition.optimizedBooleanConstant();
	boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
	boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;

	int previousMode = flowInfo.reachMode();

	FlowInfo initsOnCondition = flowInfo;
	UnconditionalFlowInfo actionInfo = flowInfo.nullInfoLessUnconditionalCopy();
	// we need to collect the contribution to nulls of the coming paths through the
	// loop, be they falling through normally or branched to break, continue labels
	// or catch blocks
	if ((this.action != null) && !this.action.isEmptyBlock()) {
		actionInfo = this.action.
			analyseCode(currentScope, loopingContext, actionInfo).
			unconditionalInits();

		// code generation can be optimized when no need to continue in the loop
		if ((actionInfo.tagBits &
				loopingContext.initsOnContinue.tagBits &
				FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
			this.continueLabel = null;
		}
		if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
			initsOnCondition = flowInfo.unconditionalInits().
									addInitializationsFrom(
										actionInfo.mergedWith(loopingContext.initsOnContinue));
		}
	}
	this.condition.checkNPEbyUnboxing(currentScope, flowContext, initsOnCondition);
	/* Reset reach mode, to address following scenario.
	 *   final blank;
	 *   do { if (true) break; else blank = 0; } while(false);
	 *   blank = 1; // may be initialized already
	 */
	actionInfo.setReachMode(previousMode);

	LoopingFlowContext condLoopContext;
	FlowInfo condInfo =
		this.condition.analyseCode(
			currentScope,
			(condLoopContext =
				new LoopingFlowContext(flowContext,	flowInfo, this, null,
					null, currentScope, true)),
			(this.action == null
				? actionInfo
				: (actionInfo.mergedWith(loopingContext.initsOnContinue))).copy());
	/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023, we reach the condition at the bottom via two arcs,
	   one by free fall and another by continuing... Merge initializations propagated through the two pathways,
	   cf, while and for loops.
	*/
	this.preConditionInitStateIndex = currentScope.methodScope().recordInitializationStates(actionInfo.mergedWith(loopingContext.initsOnContinue));
	if (!isConditionOptimizedFalse && this.continueLabel != null) {
		loopingContext.complainOnDeferredFinalChecks(currentScope, condInfo);
		condLoopContext.complainOnDeferredFinalChecks(currentScope, condInfo);
		loopingContext.complainOnDeferredNullChecks(currentScope,
				flowInfo.unconditionalCopy().addPotentialNullInfoFrom(
					  condInfo.initsWhenTrue().unconditionalInits()));
		condLoopContext.complainOnDeferredNullChecks(currentScope,
				actionInfo.addPotentialNullInfoFrom(
				  condInfo.initsWhenTrue().unconditionalInits()));
	} else {
		loopingContext.complainOnDeferredNullChecks(currentScope,
				flowInfo.unconditionalCopy().addPotentialNullInfoFrom(
					  condInfo.initsWhenTrue().unconditionalInits()), false);
		condLoopContext.complainOnDeferredNullChecks(currentScope,
				actionInfo.addPotentialNullInfoFrom(
				  condInfo.initsWhenTrue().unconditionalInits()), false);
	}
	if (loopingContext.hasEscapingExceptions()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=321926
		FlowInfo loopbackFlowInfo = flowInfo.copy();
		// loopback | (loopback + action + condition):
		loopbackFlowInfo = loopbackFlowInfo.mergedWith(loopbackFlowInfo.unconditionalCopy().addNullInfoFrom(condInfo.initsWhenTrue()).unconditionalInits());
		loopingContext.simulateThrowAfterLoopBack(loopbackFlowInfo);
	}
	// end of loop
	FlowInfo mergedInfo =
		FlowInfo.mergedOptimizedBranches(
						(loopingContext.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) != 0
								? loopingContext.initsOnBreak
								: flowInfo.unconditionalCopy().addInitializationsFrom(loopingContext.initsOnBreak),
								// recover upstream null info
						isConditionOptimizedTrue,
						(condInfo.tagBits & FlowInfo.UNREACHABLE) == 0
								? flowInfo.copy().addInitializationsFrom(condInfo.initsWhenFalse()) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=380927
								: condInfo,
							// recover null inits from before condition analysis
						false, // never consider opt false case for DO loop, since break can always occur (47776)
						!isConditionTrue /*do{}while(true); unreachable(); */);
	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
	return mergedInfo;
}

/**
 * Do statement code generation
 *
 */
@Override
public void generateCode(BlockScope currentScope, CodeStream codeStream) {
	if ((this.bits & ASTNode.IsReachable) == 0) {
		return;
	}
	int pc = codeStream.position;

	// labels management
	BranchLabel actionLabel = new BranchLabel(codeStream);
	if (this.action != null) actionLabel.tagBits |= BranchLabel.USED;
	actionLabel.place();
	this.breakLabel.initialize(codeStream);
	boolean hasContinueLabel = this.continueLabel != null;
	if (hasContinueLabel) {
		this.continueLabel.initialize(codeStream);
	}

	// generate action
	if (this.action != null) {
		this.action.generateCode(currentScope, codeStream);
	}
	// continue label (135602)
	if (hasContinueLabel) {
		this.continueLabel.place();
		// May loose some local variable initializations : affecting the local variable attributes
		if (this.preConditionInitStateIndex != -1) {
			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preConditionInitStateIndex);
			codeStream.addDefinitelyAssignedVariables(currentScope, this.preConditionInitStateIndex);
		}
		// generate condition
		Constant cst = this.condition.optimizedBooleanConstant();
		boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
		if (isConditionOptimizedFalse){
			this.condition.generateCode(currentScope, codeStream, false);
		} else {
			this.condition.generateOptimizedBoolean(
				currentScope,
				codeStream,
				actionLabel,
				null,
				true);
		}
	}
	// May loose some local variable initializations : affecting the local variable attributes
	if (this.mergedInitStateIndex != -1) {
		codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
		codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
	}
	if (this.breakLabel.forwardReferenceCount() > 0) {
		this.breakLabel.place();
	}

	codeStream.recordPositionsFrom(pc, this.sourceStart);
}

@Override
public StringBuffer printStatement(int indent, StringBuffer output) {
	printIndent(indent, output).append("do"); //$NON-NLS-1$
	if (this.action == null)
		output.append(" ;\n"); //$NON-NLS-1$
	else {
		output.append('\n');
		this.action.printStatement(indent + 1, output).append('\n');
	}
	output.append("while ("); //$NON-NLS-1$
	return this.condition.printExpression(0, output).append(");"); //$NON-NLS-1$
}

@Override
public void resolve(BlockScope scope) {
	TypeBinding type = this.condition.resolveTypeExpecting(scope, TypeBinding.BOOLEAN);
	this.condition.computeConversion(scope, type, type);
	if (this.action != null)
		this.action.resolve(scope);
}

@Override
public void traverse(ASTVisitor visitor, BlockScope scope) {
	if (visitor.visit(this, scope)) {
		if (this.action != null) {
			this.action.traverse(visitor, scope);
		}
		this.condition.traverse(visitor, scope);
	}
	visitor.endVisit(this, scope);
}

@Override
public boolean doesNotCompleteNormally() {
	Constant cst = this.condition.constant;
	boolean isConditionTrue = cst == null || cst != Constant.NotAConstant && cst.booleanValue() == true;
	cst = this.condition.optimizedBooleanConstant();
	boolean isConditionOptimizedTrue = cst == null ? true : cst != Constant.NotAConstant && cst.booleanValue() == true;

	if (isConditionTrue || isConditionOptimizedTrue)
		return this.action == null || !this.action.breaksOut(null);
	if (this.action == null || this.action.breaksOut(null))
		return false;
	return this.action.doesNotCompleteNormally() && !this.action.completesByContinue();
}

@Override
public boolean completesByContinue() {
	return this.action.continuesAtOuterLabel();
}
}
