--- /dev/null
+package org.simantics.scl.compiler.types;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
+import org.simantics.scl.compiler.internal.types.ast.TypeAst;
+import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
+import org.simantics.scl.compiler.types.kinds.KMetaVar;
+import org.simantics.scl.compiler.types.kinds.Kind;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.compiler.types.util.Polarity;
+import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
+
+
+
+/**
+ * This class represents the types of variables and constants in SCL.
+ * It is not meant to be extended outside of this package.
+ *
+ * @author Hannu Niemistö
+ */
+public abstract class Type {
+
+ public static final boolean NULL_CHECKS = true;
+ public static final Type[] EMPTY_ARRAY = new Type[0];
+
+ public static final int FUN_ID = 0;
+ public static final int APPLY_ID = 1;
+ public static final int CON_ID = 2;
+ public static final int FORALL_ID = 3;
+ public static final int PRED_ID = 4;
+ public static final int METAVAR_ID = 5;
+ public static final int VAR_ID = 6;
+ public static final int UNION_ID = 7;
+ public static final int ALIAS_ID = 8;
+
+
+ /*
+ * This class is not meant to be extended outside of this package.
+ */
+ Type() {
+ }
+
+ /**
+ * Recursively replace a type variable with a type in this type expression.
+ * @param var A type variable to be replaced
+ * @param replacement A the replacement type
+ * @return A new type instance, or this, if no changes are necessary
+ */
+ public abstract Type replace(TVar var, Type replacement);
+
+ public Type replace(TVar[] var, Type[] replacement) {
+ Type cur = this;
+ for(int i=0;i<var.length;++i)
+ cur = cur.replace(var[i], replacement[i]);
+ return cur;
+ }
+
+ public <T extends Type> Type replace(THashMap<TVar, T> substitution) {
+ Type cur = this;
+ for(Map.Entry<TVar, T> entry : substitution.entrySet())
+ cur = cur.replace(entry.getKey(), entry.getValue());
+ return cur;
+ }
+
+ abstract TypeAst toTypeAst(TypeUnparsingContext context);
+
+ @Override
+ public String toString() {
+ return toString(new TypeUnparsingContext());
+ }
+
+ public String toString(TypeUnparsingContext context) {
+ return toTypeAst(context).toString();
+ }
+
+ public void toString(TypeUnparsingContext context, StringBuilder b) {
+ toTypeAst(context).toString(b);
+ }
+
+ public void toString(TypeUnparsingContext context, StringBuilder b, int precedence) {
+ toTypeAst(context).toString(b, precedence);
+ }
+
+ public String toName() {
+ TypeUnparsingContext context = new TypeUnparsingContext();
+ StringBuilder b = new StringBuilder();
+ toName(context, b);
+ return b.toString();
+ }
+
+ public abstract void toName(TypeUnparsingContext context, StringBuilder b);
+
+ @Override
+ public boolean equals(Object obj) {
+ if(this == obj)
+ return true;
+ if(obj == null || !(obj instanceof Type))
+ return false;
+ return Types.equals(this, (Type)obj);
+ }
+
+ @Override
+ public int hashCode() {
+ TypeHashCodeContext context = new TypeHashCodeContext();
+ updateHashCode(context);
+ return context.getResult();
+ }
+
+ public abstract void updateHashCode(TypeHashCodeContext context);
+
+ public abstract void collectFreeVars(ArrayList<TVar> vars);
+
+ public abstract void collectMetaVars(ArrayList<TMetaVar> vars);
+ public abstract void collectMetaVars(THashSet<TMetaVar> vars);
+ public abstract void collectEffectMetaVars(ArrayList<TMetaVar> vars);
+
+ public abstract boolean contains(TMetaVar other);
+
+ public abstract Type convertMetaVarsToVars();
+
+ public abstract boolean isGround();
+
+ public Kind inferKind(Environment context) throws KindUnificationException {
+ KMetaVar var = Kinds.metaVar();
+ checkKind(context, var);
+ return Kinds.canonical(var);
+ }
+
+ public void checkKind(Environment context, Kind requiredKind) throws KindUnificationException {
+ Kind kind = inferKind(context);
+ Kinds.unify(kind, requiredKind);
+ }
+
+ public abstract boolean containsMetaVars();
+
+ public abstract int getClassId();
+
+ public boolean isMinimal() {
+ return true;
+ }
+
+ public boolean isMaximal() {
+ return true;
+ }
+
+ public abstract void addPolarity(Polarity polarity);
+
+ public void collectConcreteEffects(ArrayList<TCon> concreteEffects) {
+ }
+
+ public abstract Type head();
+
+ /**
+ * Creates an independent copy of the type, but replaces all effects by metavars
+ */
+ public abstract Type copySkeleton(THashMap<TMetaVar,TMetaVar> metaVarMap);
+
+}
\ No newline at end of file