]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TFun.java
(refs #7746) Fixed applications with intermediate effects
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / TFun.java
index 917526dd0bd4494bfa3e4dc73f295f2a0cc3befd..620ef18307421a9bcfeced6410a6ff3045dd4ff9 100644 (file)
@@ -1,11 +1,9 @@
 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.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TEffectAst;
 import org.simantics.scl.compiler.internal.types.ast.TFunctionAst;
@@ -17,10 +15,13 @@ 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 TFun extends Type {
-    public final Type domain;
-    public final Type effect;
-    public final Type range;
+    public Type domain;
+    public Type effect;
+    public Type range;
     
     TFun(Type domain, Type effect, Type range) {
         if(domain == null)
@@ -56,7 +57,7 @@ public class TFun extends Type {
     public TypeAst toTypeAst(TypeUnparsingContext context) {
         TypeAst domainAst = domain.toTypeAst(context);
         TypeAst rangeAst = range.toTypeAst(context);
-        if(Types.canonical(effect) != Types.NO_EFFECTS)
+        if(Types.canonical(effect) != Types.NO_EFFECTS && !context.showSkeletons)
             rangeAst = new TEffectAst(effect.toTypeAst(context), rangeAst);
         Type dom = Types.canonical(domain);
         if(dom instanceof TPred)
@@ -189,4 +190,78 @@ public class TFun extends Type {
         Type newRange = range.copySkeleton(metaVarMap);
         return new TFun(newDomain, newEffect, newRange);
     }
+    
+    @Override
+    public int hashCode(int hash) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, FUN_HASH);
+        hash = domain.hashCode(hash);
+        hash = effect.hashCode(hash);
+        hash = range.hashCode(hash);
+        return hash;
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, FUN_HASH);
+        hash = domain.hashCode(hash, boundVars);
+        hash = effect.hashCode(hash, boundVars);
+        hash = range.hashCode(hash, boundVars);
+        return hash;
+    }
+    
+    @Override
+    public int skeletonHashCode(int hash) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, FUN_HASH);
+        hash = domain.skeletonHashCode(hash);
+        hash = range.skeletonHashCode(hash);
+        return hash;
+    }
+    
+    @Override
+    public int skeletonHashCode(int hash, TVar[] boundVars) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, FUN_HASH);
+        hash = domain.skeletonHashCode(hash, boundVars);
+        hash = range.skeletonHashCode(hash, boundVars);
+        return hash;
+    }
+    
+    public Type getCanonicalDomain() {
+        if(domain instanceof TMetaVar)
+            domain = domain.canonical();
+        return domain;
+    }
+    
+    public Type getCanonicalEffect() {
+        if(effect instanceof TMetaVar)
+            effect = effect.canonical();
+        return effect;
+    }
+    
+    public Type getCanonicalRange() {
+        if(range instanceof TMetaVar)
+            range = range.canonical();
+        return range;
+    }
+
+    @Override
+    public boolean equalsCanonical(Type other) {
+        if(this == other)
+            return true;
+        if(!other.getClass().equals(TFun.class))
+            return false;
+        TFun fun = (TFun)other;
+        return getCanonicalDomain().equalsCanonical(fun.getCanonicalDomain())
+                && getCanonicalEffect().equalsCanonical(fun.getCanonicalEffect())
+                && getCanonicalRange().equalsCanonical(fun.getCanonicalRange());
+    }
+
+    @Override
+    public Kind getKind(Environment context) {
+        return Kinds.STAR;
+    }
+    
+    @Override
+    public Type[] skeletonCanonicalChildren() {
+        return new Type[] {Skeletons.canonicalSkeleton(domain), Skeletons.canonicalSkeleton(range)};
+    }
 }