//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// THIS CLASS WAS ADDED WITHOUT THE CONSENT OF THE SYSTEM'S AUTHOR. IT IS \\
// NOT PART OF THE ORIGINAL DESIGN AND IT IS POLLUTING IT !!!        -HAK \\
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

package ilog.language.design.types;

import ilog.language.design.kernel.Expression;
import ilog.language.design.kernel.Sanitizer;
import ilog.language.design.kernel.ParameterStack;

import java.util.HashMap;

/**
 * An object of this class is of the form <tt>SameType(expr)</tt> and stands for "<i>the type
 * of the expression <tt>expr</tt></i>." It is used as a temporary reference to the actual
 * type of an expression <tt>expr</tt> when that type is not known at the time of the
 * construction of a type expression; <i>e.g.</i>, because of dependencies with variables
 * that may not have been declared yet. Note that <tt>SameType(expr)</tt> is simply a type
 * <i>proto-</i>expression and not exactly a type <i>expression</i> because it does not
 * implement any of the methods of <a href="Type.html"><tt>Type</tt></a> except for
 * <tt>sanitizeTypeReferences(ParameterStack,ClassTypeHandle)</tt> which "evaluates" [<i>perhaps
 * "dereferences" might be a better word? -hak</i>] the type of <tt>expr</tt> in the context
 * provided (<i>i.e</i>, a <a href="../kernel/ParameterStack.html"><tt>ParameterStack</tt></a>
 * and a <a href="ClassTypeHandle.html"><tt>ClassTypeHandle</tt></a>), and returns the
 * corresponding actual type expression. This mechanism of forward referencing (a type, in
 * this case) is the same as that used for referencing an actual (global or local) symbol
 * expression from a name occurrence in an expression (using a <a href="../kernel/Dummy.html">
 * <tt>Dummy</tt></a>).
 *
 *  @author      <a href="mailto:pviry@ilog.fr">Patrick Viry</a>
 *  @copyright &copy; 2000-2002 <a href="http://www.ilog.fr/">ILOG, S.A.</a>
 */

public class SameType extends ProtoType
{
//     static int nextID = 1;
//     int ID = nextID++;
//     static boolean debug = false;

  Expression _expr;
  private static Sanitizer sanitizer = new Sanitizer();

  public final int numberOfTypeComponents ()
    {
      return 0;
    }

  public final Type typeRefComponent (int n) throws NoSuchTypeComponentException
    {
      throw new NoSuchTypeComponentException(this,n);
    }

  public final void setTypeRefComponent (int n, Type type) throws NoSuchTypeComponentException
    {
      throw new NoSuchTypeComponentException(this,n);
    }

  public SameType(Expression expr)
    {
        _expr = expr;
    }

  public Type sanitizeTypeReferences (ParameterStack parameters, ClassTypeHandle handle)
    {
      Type t = _expr.checkedType();
      Type result;

      if (t != null) {
        result = t.sanitizeTypeReferences();
      }
      else
        {
          _expr = _expr.sanitizeNames(parameters, handle);

          try {
              _expr.typeCheck(new TypeChecker());
          } catch (TypingErrorException error) {
              throw new java.lang.Error("SameType(t==null): cannot find a type for " + _expr./*toTypedString*/toString());
          }

          // ensure that the type is ground
          if(_expr.type().isPolymorphic())
              throw new java.lang.Error("NonGroundType"); //        ???? -hak
          
          result = _expr.type().sanitizeTypeReferences();
        }
      return result;
    }

  public String toString ()
    {
//         return "SameType#" + ID + "(" + _expr./*toTypedString*/toString() + ")";
        return "SameType(" + _expr./*toTypedString*/toString() + ")";
    }    

}

