1 package org.simantics.scl.compiler.types;
3 import gnu.trove.map.hash.THashMap;
4 import gnu.trove.set.hash.THashSet;
6 import java.util.ArrayList;
8 import org.simantics.scl.compiler.environment.Environment;
9 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
10 import org.simantics.scl.compiler.internal.types.ast.TVarAst;
11 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
12 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
13 import org.simantics.scl.compiler.types.exceptions.UnificationException;
14 import org.simantics.scl.compiler.types.kinds.KMetaVar;
15 import org.simantics.scl.compiler.types.kinds.Kind;
16 import org.simantics.scl.compiler.types.kinds.Kinds;
17 import org.simantics.scl.compiler.types.util.Polarity;
18 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
23 * A meta-variable, a type that is currently unknown. This class
24 * should occur only during type inference. Method removeMetaVars
25 * can be used to remove all instances of TMetaVar from the type.
27 * @author Hannu Niemistö
29 public class TMetaVar extends Type {
30 public static final TMetaVar[] EMPTY_ARRAY = new TMetaVar[0];
33 Polarity polarity = Polarity.NO_POLARITY;
40 TMetaVar(Kind kind, Polarity polarity) {
42 this.polarity = polarity;
45 public Kind getKind() {
46 if(kind instanceof KMetaVar)
47 kind = Kinds.canonical(kind);
52 public Type replace(TVar var, Type replacement) {
56 Type newRef = ref.replace(var, replacement);
60 // We could also return newRef here, but in this way
61 // we don't have to copy so many parent types.
67 public TypeAst toTypeAst(TypeUnparsingContext context) {
69 return new TVarAst(/*polarity.getSymbol() +*/ context.getName(this));
71 return ref.toTypeAst(context);
75 public int hashCode() {
77 return System.identityHashCode(this);
79 return ref.hashCode();
83 public void updateHashCode(TypeHashCodeContext context) {
85 context.append(System.identityHashCode(this));
87 ref.updateHashCode(context);
91 public void collectFreeVars(ArrayList<TVar> vars) {
93 ref.collectFreeVars(vars);
97 public void collectMetaVars(ArrayList<TMetaVar> vars) {
101 ref.collectMetaVars(vars);
105 public void collectMetaVars(THashSet<TMetaVar> vars) {
109 ref.collectMetaVars(vars);
113 public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
115 ref.collectEffectMetaVars(vars);
118 public void setRef(Type a) throws UnificationException {
119 a = Types.weakCanonical(a);
121 throw new UnificationException(this, a);
123 if(polarity != Polarity.NO_POLARITY)
124 a.addPolarity(polarity);
127 public Type getRef() {
132 public boolean contains(TMetaVar other) {
134 return this == other;
136 return ref.contains(other);
140 public Type convertMetaVarsToVars() {
142 if(kind == Kinds.EFFECT && !polarity.isNegative())
143 ref = Types.NO_EFFECTS;
145 ref = Types.var(getKind());
149 return ref.convertMetaVarsToVars();
153 public boolean isGround() {
157 return ref.isGround();
160 public Kind inferKind(Environment context) throws KindUnificationException {
161 return Kinds.metaVar();
165 public boolean containsMetaVars() {
169 return ref.containsMetaVars();
173 public void toName(TypeUnparsingContext context, StringBuilder b) {
175 ref.toName(context, b);
177 b.append(context.getName(this));
181 public int getClassId() {
186 public boolean isMaximal() {
187 return ref != null && ref.isMaximal();
191 public boolean isMinimal() {
192 return ref != null && ref.isMinimal();
196 public void addPolarity(Polarity polarity) {
198 ref.addPolarity(polarity);
200 this.polarity = this.polarity.add(polarity);
203 public Polarity getPolarity() {
208 public void collectConcreteEffects(ArrayList<TCon> concreteEffects) {
210 ref.collectConcreteEffects(concreteEffects);
222 public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
224 return ref.copySkeleton(metaVarMap);
226 TMetaVar result = metaVarMap.get(this);
228 result = new TMetaVar(kind, polarity);
229 metaVarMap.put(this, result);