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 ConditionalExpression extends OperatorExpression {
	public Expression condition, valueIfTrue, valueIfFalse;
	private int returnTypeSlotSize = 1;

	// for local variables table attributes
	int thenInitStateIndex = -1;
	int elseInitStateIndex = -1;
	int mergedInitStateIndex = -1;
public ConditionalExpression(Expression condition, Expression valueIfTrue, Expression valueIfFalse) {
	this.condition = condition;
	this.valueIfTrue = valueIfTrue;
	this.valueIfFalse = valueIfFalse;
	sourceStart = condition.sourceStart ;
	sourceEnd = valueIfFalse.sourceEnd;
}
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	Constant inlinedCondition = condition.constant;
	if (inlinedCondition == NotAConstant) inlinedCondition = condition.conditionalConstant();
	if (inlinedCondition != NotAConstant) {
		if (inlinedCondition.booleanValue() == true) {
			FlowInfo resultInfo = valueIfTrue.analyseCode(currentScope, flowContext, flowInfo);
			// analyse valueIfFalse, but do not take into account any of its infos
			valueIfFalse.analyseCode(currentScope, flowContext, flowInfo.copy().markAsFakeReachable(true));
			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(resultInfo);
			return resultInfo;
		} else {
			// analyse valueIfTrue, but do not take into account any of its infos			
			valueIfTrue.analyseCode(currentScope, flowContext, flowInfo.copy().markAsFakeReachable(true));
			FlowInfo mergeInfo = valueIfFalse.analyseCode(currentScope, flowContext, flowInfo);
			mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergeInfo);
			return mergeInfo;
		}
	}
	// notice that the receiver investigation is not performed in the previous case, since there is
	// not a chance it is worth trying to check anything on a constant expression.

	flowInfo = condition.analyseCode(currentScope, flowContext, flowInfo);

	// store a copy of the merged info, so as to compute the local variable attributes afterwards
	thenInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo.initsWhenTrue());
	elseInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo.initsWhenFalse());
	FlowInfo mergedInfo = valueIfTrue.analyseCode(
		currentScope,
		flowContext,
		flowInfo.initsWhenTrue().copy()).
			unconditionalInits().
				mergedWith(
					valueIfFalse.analyseCode(
						currentScope,
						flowContext,
						flowInfo.initsWhenFalse().copy()).
							unconditionalInits());
	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
	return mergedInfo;
}
/**
 * Code generation for the conditional operator ?:
 *
 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
 * @param valueRequired boolean
*/
public void generateCode(
	BlockScope currentScope, 
	CodeStream codeStream, 
	boolean valueRequired) {

	/* Reset the selector of the message pattern to use the optimized selectors,
	 * when compiling full Java messages, if compiling macroexpanded controls, then
	 * the selector is supposed correctly positionned.
	 */

	int pc = codeStream.position, divergePC;
	Label endifLabel, falseLabel;
	if (constant != NotAConstant) {
		if (valueRequired)
			codeStream.generateConstant(constant, implicitConversion);
		codeStream.recordPositionsFrom(pc, this);
		return;
	}

	Constant cst = condition.constant;
	Constant condCst = condition.conditionalConstant();
	boolean needTruePart = 
		!(((cst != NotAConstant) && (cst.booleanValue() == false))
			|| ((condCst != NotAConstant) && (condCst.booleanValue() == false))); 
	boolean needFalsePart = 
		!(((cst != NotAConstant) && (cst.booleanValue() == true))
			|| ((condCst != NotAConstant) && (condCst.booleanValue() == true))); 

	endifLabel = new Label(codeStream);

	// Generate code for the condition
	boolean needConditionValue = (cst == NotAConstant) && (condCst == NotAConstant); 
	condition.generateOptimizedBoolean(
		currentScope, 
		codeStream, 
		null, 
		(falseLabel = new Label(codeStream)), 
		needConditionValue); 

	if (thenInitStateIndex != -1) {
		codeStream.removeNotDefinitelyAssignedVariables(
			currentScope, 
			thenInitStateIndex); 
		codeStream.addDefinitelyAssignedVariables(currentScope, thenInitStateIndex);
	}

	// Then code generation
	if (needTruePart) {
		valueIfTrue.generateCode(currentScope, codeStream, valueRequired);

		if (needFalsePart) {
			// Jump over the else part
			int position = codeStream.position;
			codeStream.goto_(endifLabel);
			codeStream.updateLastRecordedEndPC(position);
			// Tune codestream stack size
			if (valueRequired) {
				codeStream.decrStackSize(returnTypeSlotSize);
			}
		}

	}
	if (needFalsePart) {
		falseLabel.place();
		if (elseInitStateIndex != -1) {
			codeStream.removeNotDefinitelyAssignedVariables(
				currentScope, 
				elseInitStateIndex); 
			codeStream.addDefinitelyAssignedVariables(currentScope, elseInitStateIndex);
		}
		valueIfFalse.generateCode(currentScope, codeStream, valueRequired);

		// End of if statement
		endifLabel.place();
	}
	// May loose some local variable initializations : affecting the local variable attributes
	if (mergedInitStateIndex != -1) {
		codeStream.removeNotDefinitelyAssignedVariables(
			currentScope, 
			mergedInitStateIndex); 
	}
	// implicit conversion
	if (valueRequired)
		codeStream.generateImplicitConversion(implicitConversion);
	codeStream.recordPositionsFrom(pc, this);
}
public TypeBinding resolveType(BlockScope scope) {
	// specs p.368
	constant = NotAConstant;
	TypeBinding condTb = condition.resolveTypeExpecting(scope, BooleanBinding);
	TypeBinding trueTb = valueIfTrue.resolveType(scope);
	TypeBinding falseTb = valueIfFalse.resolveType(scope);
	if (condTb == null || trueTb == null || falseTb == null)
		return null;

	// Propagate the constant value from the valueIfTrue and valueIFFalse expression if it is possible
	if (condition.constant != NotAConstant && valueIfTrue.constant != NotAConstant && valueIfFalse.constant != NotAConstant) {
		// all terms are constant expression so we can propagate the constant
		// from valueIFTrue or valueIfFalse to teh receiver constant
		constant = (condition.constant.booleanValue()) ? valueIfTrue.constant : valueIfFalse.constant;
	}
	if (trueTb == falseTb) { // harmed the implicit conversion 
		valueIfTrue.implicitWidening(trueTb, trueTb);
		valueIfFalse.implicitConversion = valueIfTrue.implicitConversion;
		if (trueTb == LongBinding || trueTb == DoubleBinding) {
			returnTypeSlotSize = 2;
		}
		return trueTb;
	}

	// Determine the return type depending on argument types
	// Numeric types
	if (trueTb.isNumericType() && falseTb.isNumericType()) {
		// (Short x Byte) or (Byte x Short)"
		if ((trueTb == ByteBinding && falseTb == ShortBinding) || (trueTb == ShortBinding && falseTb == ByteBinding)) {
			valueIfTrue.implicitWidening(ShortBinding, trueTb);
			valueIfFalse.implicitWidening(ShortBinding, falseTb);
			return ShortBinding;
		}

		// <Byte|Short|Char> x constant(Int)  ---> <Byte|Short|Char>   and reciprocally
		if ((trueTb == ByteBinding || trueTb == ShortBinding || trueTb == CharBinding) &&
			(falseTb == IntBinding && valueIfFalse.isConstantValueOfTypeAssignableToType(falseTb, trueTb))) {
				valueIfTrue.implicitWidening(trueTb, trueTb);
				valueIfFalse.implicitWidening(trueTb, falseTb);
				return trueTb;
		}
		if ((falseTb == ByteBinding || falseTb == ShortBinding || falseTb == CharBinding) &&
			(trueTb == IntBinding && valueIfTrue.isConstantValueOfTypeAssignableToType(trueTb, falseTb))) {
				valueIfTrue.implicitWidening(falseTb, trueTb);
				valueIfFalse.implicitWidening(falseTb, falseTb);
				return falseTb;
		}

		// Manual binary numeric promotion
		// int
		if (BaseTypeBinding.isNarrowing(trueTb.id, T_int) && BaseTypeBinding.isNarrowing(falseTb.id, T_int)) {
			valueIfTrue.implicitWidening(IntBinding, trueTb);
			valueIfFalse.implicitWidening(IntBinding, falseTb);
			return IntBinding;
		}
		// long
		if (BaseTypeBinding.isNarrowing(trueTb.id, T_long) && BaseTypeBinding.isNarrowing(falseTb.id, T_long)) {
			valueIfTrue.implicitWidening(LongBinding, trueTb);
			valueIfFalse.implicitWidening(LongBinding, falseTb);
			returnTypeSlotSize = 2;
			return LongBinding;
		}
		// float
		if (BaseTypeBinding.isNarrowing(trueTb.id, T_float) && BaseTypeBinding.isNarrowing(falseTb.id, T_float)) {
			valueIfTrue.implicitWidening(FloatBinding, trueTb);
			valueIfFalse.implicitWidening(FloatBinding, falseTb);
			return FloatBinding;
		}
		// double
		valueIfTrue.implicitWidening(DoubleBinding, trueTb);
		valueIfFalse.implicitWidening(DoubleBinding, falseTb);
		returnTypeSlotSize = 2;
		return DoubleBinding;
	}

	// Type references (null null is already tested)
	if ((trueTb.isBaseType() && trueTb != NullBinding) || (falseTb.isBaseType() && falseTb != NullBinding)) {
		scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, trueTb, falseTb);
		return null;
	}
	if (scope.areTypesCompatible(falseTb, trueTb)) {
		valueIfTrue.implicitWidening(trueTb, trueTb);
		valueIfFalse.implicitWidening(trueTb, falseTb);
		return trueTb;
	}
	if (scope.areTypesCompatible(trueTb, falseTb)) {
		valueIfTrue.implicitWidening(falseTb, trueTb);
		valueIfFalse.implicitWidening(falseTb, falseTb);
		return falseTb;
	}
	scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, trueTb, falseTb);
	return null;
}
public String toStringExpressionNoParenthesis(){
	/* slow code*/

	return	condition.toStringExpression() + " ? "/*nonNLS*/ +
			valueIfTrue.toStringExpression() + " : "/*nonNLS*/ +
			valueIfFalse.toStringExpression() ; }
public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
	if (visitor.visit(this, scope)) {
		condition.traverse(visitor, scope);
		valueIfTrue.traverse(visitor, scope);
		valueIfFalse.traverse(visitor, scope);
	}
	visitor.endVisit(this, scope);
}
}
