]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java
Merge "Re-enabled Acorn transaction cancellation support for testing"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / TForAll.java
index a22a4b244853406f0ca83dbfaff4d72e5c6ef16e..b4b1af8196486fc14e2209983d425e8279d83edc 100644 (file)
@@ -1,12 +1,10 @@
 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 java.util.Arrays;
 
 import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 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;
@@ -16,10 +14,14 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+
 
 public class TForAll extends Type {
     public final TVar var;
-    public final Type type;
+    public Type type;
     
     TForAll(TVar var, Type type) {
         if(NULL_CHECKS) {
@@ -150,4 +152,131 @@ public class TForAll extends Type {
         // Should never get here
         return new TMetaVar(Kinds.STAR);
     }
+    
+    @Override
+    public int hashCode(int hash) {
+        int count=1;
+        {
+            Type t = Types.canonical(type);
+            while(t instanceof TForAll) {
+                t = Types.canonical( ((TForAll)t).type );
+                ++count;
+            }
+        }
+        TVar[] boundVars = new TVar[count];
+        boundVars[0] = var;
+        TForAll t = this;
+        {
+            for(int i=1;i<count;++i) {
+                t = (TForAll)Types.canonical(t.type);
+                boundVars[i] = t.var;
+            }
+        }
+        
+        for(int i=0;i<count;++i)
+            hash = HashCodeUtils.updateWithPreprocessedValue(hash, FORALL_HASH);
+        return t.type.hashCode(hash, boundVars);
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] oldBoundVars) {
+        int count=1;
+        {
+            Type t = Types.canonical(type);
+            while(t instanceof TForAll) {
+                t = Types.canonical( ((TForAll)t).type );
+                ++count;
+            }
+        }
+        TVar[] boundVars = Arrays.copyOf(oldBoundVars, oldBoundVars.length + count);
+        boundVars[oldBoundVars.length] = var;
+        TForAll t = this;
+        {
+            for(int i=1;i<count;++i) {
+                t = (TForAll)Types.canonical(t.type);
+                boundVars[oldBoundVars.length + i] = t.var;
+            }
+        }
+        
+        for(int i=0;i<count;++i)
+            hash = HashCodeUtils.updateWithPreprocessedValue(hash, FORALL_HASH);
+        return t.type.hashCode(hash, boundVars);
+    }
+    
+    @Override
+    public int skeletonHashCode(int hash) {
+        int count=1;
+        {
+            Type t = Types.canonical(type);
+            while(t instanceof TForAll) {
+                t = Types.canonical( ((TForAll)t).type );
+                ++count;
+            }
+        }
+        TVar[] boundVars = new TVar[count];
+        boundVars[0] = var;
+        TForAll t = this;
+        {
+            for(int i=1;i<count;++i) {
+                t = (TForAll)Types.canonical(t.type);
+                boundVars[i] = t.var;
+            }
+        }
+        
+        for(int i=0;i<count;++i)
+            hash = HashCodeUtils.updateWithPreprocessedValue(hash, FORALL_HASH);
+        return t.type.skeletonHashCode(hash, boundVars);
+    }
+    
+    @Override
+    public int skeletonHashCode(int hash, TVar[] oldBoundVars) {
+        int count=1;
+        {
+            Type t = Types.canonical(type);
+            while(t instanceof TForAll) {
+                t = Types.canonical( ((TForAll)t).type );
+                ++count;
+            }
+        }
+        TVar[] boundVars = Arrays.copyOf(oldBoundVars, oldBoundVars.length + count);
+        boundVars[oldBoundVars.length] = var;
+        TForAll t = this;
+        {
+            for(int i=1;i<count;++i) {
+                t = (TForAll)Types.canonical(t.type);
+                boundVars[oldBoundVars.length + i] = t.var;
+            }
+        }
+        
+        for(int i=0;i<count;++i)
+            hash = HashCodeUtils.updateWithPreprocessedValue(hash, FORALL_HASH);
+        return t.type.skeletonHashCode(hash, boundVars);
+    }
+    
+    public Type getCanonicalType() {
+        if(type instanceof TMetaVar)
+            type = type.canonical();
+        return type;
+    }
+
+    @Override
+    public boolean equalsCanonical(Type other) {
+        if(this == other)
+            return true;
+        if(!other.getClass().equals(TForAll.class))
+            return false;
+        TForAll forAll = (TForAll)other;
+        return getCanonicalType().equalsCanonical(forAll.getCanonicalType().replace(forAll.var, var));
+    }
+
+    @Override
+    public Kind getKind(Environment context) {
+        return Kinds.STAR;
+    }
+
+    @Override
+    public Type[] skeletonCanonicalChildren() {
+        return new Type[] { Skeletons.canonicalSkeleton(type) };
+    } 
+    
 }