+package org.simantics.scl.compiler.types;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
+import org.simantics.scl.compiler.internal.types.ast.TApplyAst;
+import org.simantics.scl.compiler.internal.types.ast.TypeAst;
+import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
+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;
+
+
+
+public class TPred extends Type {
+
+ public static final TPred[] EMPTY_ARRAY = new TPred[0];
+
+ public final TCon typeClass;
+ public final Type[] parameters;
+
+ TPred(TCon typeClass, Type ... parameters) {
+ if(NULL_CHECKS) {
+ if(typeClass == null || parameters == null)
+ throw new NullPointerException();
+ for(Type parameter : parameters)
+ if(parameter == null)
+ throw new NullPointerException();
+ }
+ this.typeClass = typeClass;
+ this.parameters = parameters;
+ }
+
+ @Override
+ public TPred replace(TVar var, Type replacement) {
+ for(int i=0;i<parameters.length;++i) {
+ Type parameter = parameters[i];
+ Type newParameter = parameter.replace(var, replacement);
+ if(parameter != newParameter) {
+ Type[] newParameters = new Type[parameters.length];
+ for(int j=0;j<i;++j)
+ newParameters[j] = parameters[j];
+ newParameters[i] = newParameter;
+ for(int j=i+1;j<parameters.length;++j)
+ newParameters[j] = parameters[j].replace(var, replacement);
+ return new TPred(typeClass, newParameters);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public TypeAst toTypeAst(TypeUnparsingContext context) {
+ TypeAst ast = typeClass.toTypeAst(context);
+ for(Type parameter : parameters)
+ ast = new TApplyAst(ast, parameter.toTypeAst(context));
+ return ast;
+ }
+
+ @Override
+ public void updateHashCode(TypeHashCodeContext context) {
+ typeClass.updateHashCode(context);
+ for(Type parameter : parameters)
+ parameter.updateHashCode(context);
+ }
+
+ @Override
+ public void collectFreeVars(ArrayList<TVar> vars) {
+ for(Type parameter : parameters)
+ parameter.collectFreeVars(vars);
+ }
+
+ @Override
+ public void collectMetaVars(ArrayList<TMetaVar> vars) {
+ for(Type parameter : parameters)
+ parameter.collectMetaVars(vars);
+ }
+
+ @Override
+ public void collectMetaVars(THashSet<TMetaVar> vars) {
+ for(Type parameter : parameters)
+ parameter.collectMetaVars(vars);
+ }
+
+ @Override
+ public boolean contains(TMetaVar other) {
+ for(Type parameter : parameters)
+ if(parameter.contains(other))
+ return true;
+ return false;
+ }
+
+ @Override
+ public Type convertMetaVarsToVars() {
+ for(int i=0;i<parameters.length;++i) {
+ Type parameter = parameters[i];
+ Type temp = parameter.convertMetaVarsToVars();
+ if(temp != parameter) {
+ Type[] newParameters = new Type[parameters.length];
+ for(int j=0;j<i;++j)
+ newParameters[j] = parameters[j];
+ newParameters[i] = temp;
+ for(int j=i+1;j<parameters.length;++j)
+ newParameters[j] = parameters[j].convertMetaVarsToVars();
+ return new TPred(typeClass, parameters);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public boolean isGround() {
+ for(Type parameter : parameters)
+ if(!parameter.isGround())
+ return false;
+ return true;
+ }
+
+
+ public Kind inferKind(Environment context) throws KindUnificationException {
+ return Kinds.STAR;
+ }
+
+ @Override
+ public boolean containsMetaVars() {
+ for(Type parameter : parameters)
+ if(parameter.containsMetaVars())
+ return true;
+ return false;
+ }
+
+ @Override
+ public void toName(TypeUnparsingContext context, StringBuilder b) {
+ typeClass.toName(context, b);
+ for(Type parameter : parameters) {
+ b.append('_');
+ parameter.toName(context, b);
+ }
+ }
+
+ @Override
+ public int getClassId() {
+ return PRED_ID;
+ }
+
+ @Override
+ public void addPolarity(Polarity polarity) {
+ for(Type parameter : parameters)
+ parameter.addPolarity(Polarity.BIPOLAR);
+ }
+
+ @Override
+ public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
+ for(Type parameter : parameters)
+ parameter.collectEffectMetaVars(vars);
+ }
+
+ @Override
+ public Type head() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
+ Type[] newParameters = new Type[parameters.length];
+ for(int i=0;i<parameters.length;++i)
+ newParameters[i] = parameters[i].copySkeleton(metaVarMap);
+ return new TPred(typeClass, parameters);
+ }
+}