1 package org.simantics.scl.compiler.types;
3 import java.util.ArrayList;
6 import org.simantics.scl.compiler.environment.Environment;
7 import org.simantics.scl.compiler.internal.types.HashCodeUtils;
8 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
9 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
10 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
11 import org.simantics.scl.compiler.types.kinds.KMetaVar;
12 import org.simantics.scl.compiler.types.kinds.Kind;
13 import org.simantics.scl.compiler.types.kinds.Kinds;
14 import org.simantics.scl.compiler.types.util.Polarity;
15 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
17 import gnu.trove.map.hash.THashMap;
18 import gnu.trove.set.hash.THashSet;
23 * This class represents the types of variables and constants in SCL.
24 * It is not meant to be extended outside of this package.
26 * @author Hannu Niemistö
28 public abstract class Type {
30 public static final boolean NULL_CHECKS = true;
31 public static final Type[] EMPTY_ARRAY = new Type[0];
33 public static final int FUN_ID = 0;
34 public static final int APPLY_ID = 1;
35 public static final int CON_ID = 2;
36 public static final int FORALL_ID = 3;
37 public static final int PRED_ID = 4;
38 public static final int METAVAR_ID = 5;
39 public static final int VAR_ID = 6;
40 public static final int UNION_ID = 7;
42 protected static final int APPLY_HASH = HashCodeUtils.preprocessValue(0);
43 protected static final int FORALL_HASH = HashCodeUtils.preprocessValue(1);
44 protected static final int FUN_HASH = HashCodeUtils.preprocessValue(2);
45 protected static final int PRED_HASH = HashCodeUtils.preprocessValue(3);
46 protected static final int UNION_HASH = HashCodeUtils.preprocessValue(4);
47 protected static final int BOUND_VAR_HASH = HashCodeUtils.preprocessValue(5);
50 * This class is not meant to be extended outside of this package.
56 * Recursively replace a type variable with a type in this type expression.
57 * @param var A type variable to be replaced
58 * @param replacement A the replacement type
59 * @return A new type instance, or this, if no changes are necessary
61 public abstract Type replace(TVar var, Type replacement);
63 public Type replace(TVar[] var, Type[] replacement) {
65 for(int i=0;i<var.length;++i)
66 cur = cur.replace(var[i], replacement[i]);
70 public <T extends Type> Type replace(THashMap<TVar, T> substitution) {
72 for(Map.Entry<TVar, T> entry : substitution.entrySet())
73 cur = cur.replace(entry.getKey(), entry.getValue());
77 abstract TypeAst toTypeAst(TypeUnparsingContext context);
80 public String toString() {
81 return toString(new TypeUnparsingContext());
84 public String toString(TypeUnparsingContext context) {
85 return toTypeAst(context).toString();
88 public void toString(TypeUnparsingContext context, StringBuilder b) {
89 toTypeAst(context).toString(b);
92 public void toString(TypeUnparsingContext context, StringBuilder b, int precedence) {
93 toTypeAst(context).toString(b, precedence);
96 public String toName() {
97 TypeUnparsingContext context = new TypeUnparsingContext();
98 StringBuilder b = new StringBuilder();
103 public abstract void toName(TypeUnparsingContext context, StringBuilder b);
106 public boolean equals(Object obj) {
109 if(obj == null || !(obj instanceof Type))
111 return Types.equals(this, (Type)obj);
115 public int hashCode() {
116 return hashCode(HashCodeUtils.SEED);
119 public abstract void updateHashCode(TypeHashCodeContext context);
120 public abstract int hashCode(int hash);
121 public abstract int hashCode(int hash, TVar[] boundVars);
123 public int skeletonHashCode() {
124 return skeletonHashCode(HashCodeUtils.SEED);
127 public abstract int skeletonHashCode(int hash);
128 public abstract int skeletonHashCode(int hash, TVar[] boundVars);
130 public abstract void collectFreeVars(ArrayList<TVar> vars);
132 public abstract void collectMetaVars(ArrayList<TMetaVar> vars);
133 public abstract void collectMetaVars(THashSet<TMetaVar> vars);
134 public abstract void collectEffectMetaVars(ArrayList<TMetaVar> vars);
136 public abstract boolean contains(TMetaVar other);
138 public abstract Type convertMetaVarsToVars();
140 public abstract boolean isGround();
142 public Kind inferKind(Environment context) throws KindUnificationException {
143 KMetaVar var = Kinds.metaVar();
144 checkKind(context, var);
145 return Kinds.canonical(var);
148 public void checkKind(Environment context, Kind requiredKind) throws KindUnificationException {
149 Kind kind = inferKind(context);
150 Kinds.unify(kind, requiredKind);
153 public abstract boolean containsMetaVars();
155 public abstract int getClassId();
157 public boolean isMinimal() {
161 public boolean isMaximal() {
165 public abstract void addPolarity(Polarity polarity);
167 public void collectConcreteEffects(ArrayList<TCon> concreteEffects) {
170 public abstract Type head();
173 * Creates an independent copy of the type, but replaces all effects by metavars
175 public abstract Type copySkeleton(THashMap<TMetaVar,TMetaVar> metaVarMap);
177 public abstract boolean equalsCanonical(Type other);
179 public Type canonical() {
183 public abstract Kind getKind(Environment context);
185 public abstract Type[] skeletonCanonicalChildren();