//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// PLEASE DO NOT EDIT WITHOUT THE EXPLICIT CONSENT OF THE AUTHOR! \\
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

package ilog.language.design.kernel;

/**
 * @version     Last modified on Fri Oct 18 17:51:45 2002 by hak
 * @version          modified on Wed Jul 24 12:19:13 2002 by pviry
 * @author      <a href="mailto:hak@ilog.fr">Hassan A&iuml;t-Kaci</a>
 * @copyright   &copy; 2002 <a href="http://www.ilog.fr/">ILOG, S.A.</a>
 */

import ilog.language.design.types.*;

/**
 * This kernel expression is used on an expression whose type is a defined opaque type.
 * Its semantics consists simply in "opening" the expression's opaque type; <i>i.e.</i>,
 * its value is that of the expression seen as having the hidden type. The inverse operation,
 * which consists in hiding an expression's type into a given defined opaque type having
 * that type as definition, is <a href="HideType.html"><tt>HideType</tt></a>.
 */
public class OpenType extends ProtoExpression
{
  private Expression _expression;

  public OpenType (Expression expression)
    {
      _expression = expression;
    }

  public final Expression expression ()
    {
      return _expression;
    }

  public final int numberOfSubexpressions ()
    {
      return 1;
    }

  public final Expression subexpression (int n) throws NoSuchSubexpressionException
    {
      if (n == 0)
        return _expression;

      throw new NoSuchSubexpressionException(this,n);
    }

  public final void setCheckedType ()
    {
      if (isSetCheckedType()) return;
      setCheckedType(type().copy());
      _expression.setCheckedType();
    }

  public final Expression sanitizeNames (ParameterStack parameters, ClassTypeHandle handle)
    {
      _expression = _expression.sanitizeNames(parameters,handle);
      return this;
    }

  public final void sanitizeSorts (Enclosure enclosure)
    {
      _expression.sanitizeSorts(enclosure);
    }

  public final Expression shiftOffsets (int intShift, int realShift, int objectShift,
                                       int intDepth, int realDepth, int objectDepth)
    {
      _expression = _expression.shiftOffsets(intShift,realShift,objectShift,
                                             intDepth,realDepth,objectDepth);
      return this;
    }

  public final void typeCheck (TypeChecker typeChecker) throws TypingErrorException
    {
      if (typeCheckLocked()) return;

      _expression.typeCheck(typeChecker);

      if (_expression.type().kind() != Type.DEFINED)
        typeChecker.error(locate(new TypingErrorException("can't open a non-opaque type: "
                                                          +_expression.type())));

      typeChecker.unify(_type,((DefinedType)_expression.type()).definition(),this);
    }

  public final void compile (Compiler compiler)
    {
      _expression.compile(compiler);
    }

  public final String toString ()
    {
      return "OpenType("+_expression+")";
    }

  // Added by PV
  public final String toTypedString ()
    {
        return typed("OpenType("+_expression.toTypedString()+")");
    }
}
