1 package org.simantics.scl.compiler.types;
3 import java.util.ArrayList;
5 import org.simantics.scl.compiler.environment.Environment;
6 import org.simantics.scl.compiler.internal.types.HashCodeUtils;
7 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
8 import org.simantics.scl.compiler.internal.types.ast.TApplyAst;
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.Kind;
12 import org.simantics.scl.compiler.types.kinds.Kinds;
13 import org.simantics.scl.compiler.types.util.Polarity;
14 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
16 import gnu.trove.map.hash.THashMap;
17 import gnu.trove.set.hash.THashSet;
21 public class TPred extends Type {
23 public static final TPred[] EMPTY_ARRAY = new TPred[0];
25 public final TCon typeClass;
26 public final Type[] parameters;
28 TPred(TCon typeClass, Type ... parameters) {
30 if(typeClass == null || parameters == null)
31 throw new NullPointerException();
32 for(Type parameter : parameters)
34 throw new NullPointerException();
36 this.typeClass = typeClass;
37 this.parameters = parameters;
41 public TPred replace(TVar var, Type replacement) {
42 for(int i=0;i<parameters.length;++i) {
43 Type parameter = parameters[i];
44 Type newParameter = parameter.replace(var, replacement);
45 if(parameter != newParameter) {
46 Type[] newParameters = new Type[parameters.length];
48 newParameters[j] = parameters[j];
49 newParameters[i] = newParameter;
50 for(int j=i+1;j<parameters.length;++j)
51 newParameters[j] = parameters[j].replace(var, replacement);
52 return new TPred(typeClass, newParameters);
59 public TypeAst toTypeAst(TypeUnparsingContext context) {
60 TypeAst ast = typeClass.toTypeAst(context);
61 for(Type parameter : parameters)
62 ast = new TApplyAst(ast, parameter.toTypeAst(context));
67 public void updateHashCode(TypeHashCodeContext context) {
68 typeClass.updateHashCode(context);
69 for(Type parameter : parameters)
70 parameter.updateHashCode(context);
74 public void collectFreeVars(ArrayList<TVar> vars) {
75 for(Type parameter : parameters)
76 parameter.collectFreeVars(vars);
80 public void collectMetaVars(ArrayList<TMetaVar> vars) {
81 for(Type parameter : parameters)
82 parameter.collectMetaVars(vars);
86 public void collectMetaVars(THashSet<TMetaVar> vars) {
87 for(Type parameter : parameters)
88 parameter.collectMetaVars(vars);
92 public boolean contains(TMetaVar other) {
93 for(Type parameter : parameters)
94 if(parameter.contains(other))
100 public Type convertMetaVarsToVars() {
101 for(int i=0;i<parameters.length;++i) {
102 Type parameter = parameters[i];
103 Type temp = parameter.convertMetaVarsToVars();
104 if(temp != parameter) {
105 Type[] newParameters = new Type[parameters.length];
107 newParameters[j] = parameters[j];
108 newParameters[i] = temp;
109 for(int j=i+1;j<parameters.length;++j)
110 newParameters[j] = parameters[j].convertMetaVarsToVars();
111 return new TPred(typeClass, parameters);
118 public boolean isGround() {
119 for(Type parameter : parameters)
120 if(!parameter.isGround())
126 public Kind inferKind(Environment context) throws KindUnificationException {
131 public boolean containsMetaVars() {
132 for(Type parameter : parameters)
133 if(parameter.containsMetaVars())
139 public void toName(TypeUnparsingContext context, StringBuilder b) {
140 typeClass.toName(context, b);
141 for(Type parameter : parameters) {
143 parameter.toName(context, b);
148 public int getClassId() {
153 public void addPolarity(Polarity polarity) {
154 for(Type parameter : parameters)
155 parameter.addPolarity(Polarity.BIPOLAR);
159 public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
160 for(Type parameter : parameters)
161 parameter.collectEffectMetaVars(vars);
166 throw new UnsupportedOperationException();
170 public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
171 Type[] newParameters = new Type[parameters.length];
172 for(int i=0;i<parameters.length;++i)
173 newParameters[i] = parameters[i].copySkeleton(metaVarMap);
174 return new TPred(typeClass, parameters);
178 public int hashCode(int hash) {
179 hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH);
180 hash = typeClass.hashCode(hash);
181 for(Type parameter : parameters)
182 hash = parameter.hashCode(hash);
187 public int hashCode(int hash, TVar[] boundVars) {
188 hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH);
189 hash = typeClass.hashCode(hash, boundVars);
190 for(Type parameter : parameters)
191 hash = parameter.hashCode(hash, boundVars);
196 public int skeletonHashCode(int hash) {
197 hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH);
198 hash = typeClass.skeletonHashCode(hash);
199 for(Type parameter : parameters)
200 hash = parameter.skeletonHashCode(hash);
205 public int skeletonHashCode(int hash, TVar[] boundVars) {
206 hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH);
207 hash = typeClass.skeletonHashCode(hash, boundVars);
208 for(Type parameter : parameters)
209 hash = parameter.skeletonHashCode(hash, boundVars);
214 public boolean equalsCanonical(Type other) {
217 if(!other.getClass().equals(TPred.class))
219 TPred pred = (TPred)other;
220 if(typeClass != pred.typeClass || parameters.length != pred.parameters.length)
222 for(int i=0;i<parameters.length;++i)
223 if(!Types.canonical(parameters[i]).equalsCanonical(Types.canonical(pred.parameters[i])))
229 public Kind getKind(Environment context) {
234 public Type[] skeletonCanonicalChildren() {
235 Type[] result = new Type[parameters.length];
236 for(int i=0;i<parameters.length;++i)
237 result[i] = Skeletons.canonicalSkeleton(parameters[i]);