/**
 * 
 */
package edu.udel.cis.vsl.civl.model.common.expression;

import java.util.Set;

import edu.udel.cis.vsl.civl.model.IF.CIVLSource;
import edu.udel.cis.vsl.civl.model.IF.Scope;
import edu.udel.cis.vsl.civl.model.IF.expression.VariableExpression;
import edu.udel.cis.vsl.civl.model.IF.type.CIVLHeapType;
import edu.udel.cis.vsl.civl.model.IF.type.CIVLType;
import edu.udel.cis.vsl.civl.model.IF.variable.Variable;

/**
 * A use of a variable in an expression.
 * 
 * @author Timothy K. Zirkel (zirkel)
 * 
 */
public class CommonVariableExpression extends CommonExpression implements
		VariableExpression {

	Variable variable;

	/**
	 * A use of a variable in an expression.
	 * 
	 * @param variable
	 *            The variable.
	 */
	public CommonVariableExpression(CIVLSource source, Variable variable) {
		super(source);
		this.variable = variable;
	}

	/**
	 * @return The variable
	 */
	public Variable variable() {
		return variable;
	}

	/**
	 * @param variable
	 *            The variable.
	 */
	public void setVariable(Variable variable) {
		this.variable = variable;
	}

	@Override
	public String toString() {
		return variable.name().name();
	}

	@Override
	public ExpressionKind expressionKind() {
		return ExpressionKind.VARIABLE;
	}

	@Override
	public void setPurelyLocal(boolean pl) {
		this.variable.setPurelyLocal(pl);
	}

	@Override
	public void purelyLocalAnalysisOfVariables(Scope funcScope) {
		// if(this.variable.type().isPointerType())
		// this.setPurelyLocal(false);
		if (funcScope.isDescendantOf(this.variable.scope()))
			this.setPurelyLocal(false);

	}

	@Override
	public void purelyLocalAnalysis() {
		this.purelyLocal = this.variable.purelyLocal();
	}

	@Override
	public Set<Variable> variableAddressedOf(Scope scope,
			CIVLHeapType heapType, CIVLType commType) {
		return null;
	}

	@Override
	public Set<Variable> variableAddressedOf(CIVLHeapType heapType,
			CIVLType commType) {
		return null;
	}

	@Override
	public Variable variableWritten(Scope scope, CIVLHeapType heapType,
			CIVLType commType) {
		Scope vScope = variable.scope();
		CIVLType vType = variable.type();

		if (vType.equals(heapType))
			return null;
		if (vType.equals(commType))
			return null;
		if (variable.isConst())
			return null;
		if (scope.equals(vScope) || scope.isDescendantOf(vScope))
			return variable;
		return null;
	}

	@Override
	public Variable variableWritten(CIVLHeapType heapType, CIVLType commType) {
		CIVLType vType = variable.type();

		if (vType.equals(heapType))
			return null;
		if (vType.equals(commType))
			return null;
		if (variable.isConst())
			return null;
		return variable;
	}

}
