]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / TForAll.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java
new file mode 100644 (file)
index 0000000..a22a4b2
--- /dev/null
@@ -0,0 +1,153 @@
+package org.simantics.scl.compiler.types;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+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.TForAllAst;
+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 TForAll extends Type {
+    public final TVar var;
+    public final Type type;
+    
+    TForAll(TVar var, Type type) {
+        if(NULL_CHECKS) {
+            if(var == null || type == null)
+                throw new NullPointerException();
+        }
+        this.var = var;
+        this.type = type;
+    }
+    
+    private TForAll create(Type type) {
+        if(type == this.type)
+            return this;
+        else
+            return new TForAll(var, type);
+    }
+
+    @Override
+    public TForAll replace(TVar var, Type replacement) {
+        if(var == this.var) {
+            if(replacement instanceof TVar) {
+               return new TForAll((TVar)replacement, type.replace(var, replacement));
+            }
+            else
+                throw new IllegalStateException("Tried to replace a variable that is not free in the type.");
+        }
+        else
+            return create(type.replace(var, replacement));
+    }
+
+    @Override
+    public TypeAst toTypeAst(TypeUnparsingContext context) {
+        ArrayList<String> vars = new ArrayList<String>();
+        vars.add(context.getName(var));
+        Type cur = Types.canonical(type);
+        while(cur instanceof TForAll) {
+            TForAll forAll = (TForAll)cur;
+            vars.add(context.getName(forAll.var));
+            cur = Types.canonical(forAll.type);
+        }
+        return new TForAllAst(
+                vars.toArray(new String[vars.size()]), 
+                cur.toTypeAst(context));
+    }
+    
+    @Override
+    public void updateHashCode(TypeHashCodeContext context) {
+        context.append(TypeHashCodeContext.FORALL);
+        TObjectIntHashMap<TVar> varHashCode = context.createVarHashCode();
+        varHashCode.put(var, varHashCode.size());
+        type.updateHashCode(context);
+        varHashCode.remove(var);
+    }
+
+    @Override
+    public void collectFreeVars(ArrayList<TVar> vars) {
+        type.collectFreeVars(vars);
+        vars.remove(var);
+    }
+    
+    @Override
+    public void collectMetaVars(ArrayList<TMetaVar> vars) {
+        type.collectMetaVars(vars);
+    }
+    
+    @Override
+    public void collectMetaVars(THashSet<TMetaVar> vars) {
+        type.collectMetaVars(vars);
+    }
+    
+    @Override
+    public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
+        type.collectEffectMetaVars(vars);
+    }
+    
+    @Override
+    public boolean contains(TMetaVar other) {
+        return type.contains(other);
+    }
+    
+    @Override
+    public Type convertMetaVarsToVars() {
+        Type newType = type.convertMetaVarsToVars();
+        if(newType == type)
+            return this;
+        else
+            return new TForAll(var, type);
+    }
+
+    @Override
+    public boolean isGround() {
+        return false; // The method is usually not called for quantified types
+                      // so it is unclear what it should do here.
+    }
+
+       public Kind inferKind(Environment context) throws KindUnificationException {
+        type.checkKind(context, Kinds.STAR);
+        return Kinds.STAR;
+    }
+
+    @Override
+    public boolean containsMetaVars() {
+        return type.containsMetaVars();
+    }
+
+    @Override
+    public void toName(TypeUnparsingContext context, StringBuilder b) {
+        type.toName(context, b);
+    }
+    
+    @Override
+    public int getClassId() {
+        return FORALL_ID;
+    }
+
+    @Override
+    public void addPolarity(Polarity polarity) {
+        type.addPolarity(polarity);
+    }
+
+    @Override
+    public Type head() {
+        return this;
+    }
+
+    @Override
+    public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
+        // Should never get here
+        return new TMetaVar(Kinds.STAR);
+    }
+}