]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java
migrated to svn revision 33108
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / util / TypeListener.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java
new file mode 100644 (file)
index 0000000..04c9e16
--- /dev/null
@@ -0,0 +1,63 @@
+package org.simantics.scl.compiler.types.util;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.types.Skeletons;
+import org.simantics.scl.compiler.types.TApply;
+import org.simantics.scl.compiler.types.TForAll;
+import org.simantics.scl.compiler.types.TFun;
+import org.simantics.scl.compiler.types.TMetaVar;
+import org.simantics.scl.compiler.types.TMetaVar.TMetaVarListener;
+import org.simantics.scl.compiler.types.TPred;
+import org.simantics.scl.compiler.types.Type;
+
+public abstract class TypeListener {
+    private ArrayList<TMetaVarListener> metaVarListeners = new ArrayList<TMetaVarListener>(2);
+    public abstract void notifyAboutChange();
+    
+    private static class SubListener extends TMetaVarListener {
+        private final TypeListener parent;
+        public SubListener(TypeListener parent) {
+            this.parent = parent;
+        }        @Override
+        public void notifyAboutChange() {
+            for(TMetaVarListener otherListeners : parent.metaVarListeners)
+                otherListeners.remove();
+            parent.notifyAboutChange();
+        }
+    };
+    
+    public void listenSkeleton(Type type) {
+        type = Skeletons.canonicalSkeleton(type);
+        if(type instanceof TMetaVar) {
+            TMetaVar metaVar = (TMetaVar)type;
+            TMetaVarListener latestListener = metaVar.getLatestListener();
+            if(latestListener instanceof SubListener &&
+                    ((SubListener)latestListener).parent == this)
+                return;
+            
+            SubListener subListener = new SubListener(this);
+            metaVarListeners.add(subListener);
+            metaVar.addListener(subListener);
+        }
+        else if(type instanceof TApply) {
+            TApply apply = (TApply)type;
+            listenSkeleton(apply.function);
+            listenSkeleton(apply.parameter);
+        }
+        else if(type instanceof TFun) {
+            TFun fun = (TFun)type;
+            listenSkeleton(fun.domain);
+            listenSkeleton(fun.range);
+        }
+        else if(type instanceof TForAll) {
+            TForAll forAll = (TForAll)type;
+            listenSkeleton(forAll.type);
+        }
+        else if(type instanceof TPred) {
+            TPred pred = (TPred)type;
+            for(Type parameter : pred.parameters)
+                listenSkeleton(parameter);
+        }
+    }
+}