]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TUnion.java
migrated to svn revision 33108
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / TUnion.java
index e14ddb3052d5f30a57177753ec32fbc01b078fff..c3d88b00d1c826416e2d6af8144db9cddacde6b6 100644 (file)
@@ -1,17 +1,21 @@
 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.common.exceptions.InternalCompilerError;
+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.TConAst;
 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
+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;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 public class TUnion extends Type {    
     public final Type[] effects;
 
@@ -164,4 +168,64 @@ public class TUnion extends Type {
     public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
         return Types.NO_EFFECTS;
     }
+    
+    @Override
+    public int hashCode(int hash) {
+        int sum = UNION_HASH;
+        for(Type effect : effects)
+            sum += effect.hashCode(HashCodeUtils.SEED);
+        return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        int sum = UNION_HASH;
+        for(Type effect : effects)
+            sum += effect.hashCode(HashCodeUtils.SEED, boundVars);
+        return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
+    }
+    
+    @Override
+    public boolean equalsCanonical(Type other) {
+        if(this == other)
+            return true;
+        if(!other.getClass().equals(TUnion.class))
+            return false;
+        TUnion union = (TUnion)other;
+        int length = effects.length;
+        if(length != union.effects.length)
+            return false;
+        if(length == 0)
+            return true;
+        for(int i=0;i<length;++i) {
+            effects[i] = effects[i].canonical();
+            union.effects[i] = union.effects[i].canonical();
+        }
+        if(length == 2) {
+            if(effects[0].equalsCanonical(union.effects[0]))
+                return effects[1].equalsCanonical(union.effects[1]);
+            else
+                return effects[0].equalsCanonical(union.effects[1]) &&
+                        effects[1].equalsCanonical(union.effects[0]);
+        }
+        loop: for(int i=0;i<length;++i) {
+            Type effect = effects[i]; 
+            for(int j=i;j<length;++j)
+                if(effect.equalsCanonical(union.effects[j])) {
+                    if(j > i) {
+                        effect = union.effects[i];
+                        union.effects[i] = union.effects[j];
+                        union.effects[j] = effect;
+                    }
+                    continue loop;
+                }
+            return false;
+        }
+        return true;
+    }
+    
+    @Override
+    public Kind getKind(Environment context) {
+        return Kinds.EFFECT;
+    }
 }