ArrayElementReferenceValue.java

package edu.udel.cis.vsl.tass.dynamic.impl.value;

import edu.udel.cis.vsl.tass.dynamic.IF.type.ReferenceValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ArrayElementReferenceValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ReferenceValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.VariableReferenceValueIF;
import edu.udel.cis.vsl.tass.dynamic.impl.type.ValueTypeFactory;
import edu.udel.cis.vsl.tass.morph.Morphic;

public class ArrayElementReferenceValue extends ReferenceValue implements
		ArrayElementReferenceValueIF {

	private static int classHashCode = ArrayElementReferenceValue.class
			.hashCode();

	private ValueIF index;

	/**
	 * Redundant information, as this can be obtained by repeated calls to
	 * parent(), but provided for efficiency.
	 */
	private VariableReferenceValueIF variableReference;

	public ArrayElementReferenceValue(ReferenceValueIF parent, ValueIF index,
			ReferenceValueTypeIF valueType) {
		super(parent, valueType);
		this.index = index;
		variableReference = parent.variableReference();
	}

	@Override
	protected int computeHashCode() {
		return super.computeHashCode() + classHashCode + index.hashCode();
	}

	@Override
	public ValueIF index() {
		return index;
	}

	@Override
	public String toString() {
		return parent() + "[" + index + "]";
	}

	@Override
	public VariableReferenceValueIF variableReference() {
		return variableReference;
	}

	@Override
	protected boolean computeEquals(Morphic component) {
		if (!super.computeEquals(component))
			return false;
		if (component instanceof ArrayElementReferenceValue) {
			ArrayElementReferenceValue that = (ArrayElementReferenceValue) component;

			return index.equals(that.index);
		}
		return false;
	}

	@Override
	public boolean isNull() {
		return false;
	}

	@Override
	protected void commitChildren() {
		super.commitChildren();
		index.commit();
	}

	@Override
	protected void canonicalizeChildren(ValueFactory valueFactory,
			ValueTypeFactory typeFactory) {
		super.canonicalizeChildren(valueFactory, typeFactory);
		if (!variableReference.isCanonic())
			variableReference = parent().variableReference();
		index = valueFactory.canonic(index);
	}
}