From 254fb7f99cef0fd6588fca70a4a4f0a67da07894 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emma=20S=C3=B6derberg?= <emma.m.soderberg@gmail.com>
Date: Fri, 25 May 2018 23:13:58 +0200
Subject: [PATCH] Updates handler states and dumping of listeners.

- Adds inc_EMPTY: for handlers of decached values
- Adds inc_COMPUTED: for handlers of cached values
- Adds inc_AST: for handlers of editable AST values
- Changes the dependency dump to show listeners and handler state
- Removes the changeState method from the handler class
- Adds the attribute handler directly on the evaluation stack for plain lazy attributes

Note that all changes are focused on the incremental/param configuration and changes
may not be complete for other incremental configurations.

Tested on incremental/param/Test120-121.
---
 src/jastadd/incremental/IncrementalState.jadd |  8 +-
 src/template/incremental/ASTChange.tt         |  6 +-
 src/template/incremental/DDGNode.tt           | 81 +++++++++++++------
 src/template/incremental/DDGNodeCopy.tt       | 10 +--
 src/template/incremental/State.tt             |  8 +-
 src/template/incremental/Tracking.tt          | 45 +++++++----
 6 files changed, 104 insertions(+), 54 deletions(-)

diff --git a/src/jastadd/incremental/IncrementalState.jadd b/src/jastadd/incremental/IncrementalState.jadd
index d0dc5328..8ffb36a3 100644
--- a/src/jastadd/incremental/IncrementalState.jadd
+++ b/src/jastadd/incremental/IncrementalState.jadd
@@ -33,9 +33,9 @@ aspect IncrementalState {
 
 	tt.expand("ASTDecl.incStateFields", out);
 
-	tt.bind("ChangeStateTokens", emitChangeStateTokensString());
-	tt.bind("ChangeStateAttributes", emitChangeStateAttributesString());
-	tt.expand("ASTDecl.incChangeStateMethod", out);
+	//tt.bind("ChangeStateTokens", emitChangeStateTokensString());
+	//tt.bind("ChangeStateAttributes", emitChangeStateAttributesString());
+	//tt.expand("ASTDecl.incChangeStateMethod", out);
 
 	tt.bind("ThrowAwayTokens", emitThrowAwayTokensString());
 	tt.bind("ThrowAwayAttributes", emitThrowAwayAttributesString());
@@ -43,6 +43,7 @@ aspect IncrementalState {
 
   }
 
+/*
   public String ASTDecl.emitChangeStateTokensString() {
     StringBuffer res = new StringBuffer();
     TemplateContext tt = templateContext();
@@ -69,6 +70,7 @@ aspect IncrementalState {
     }
     return res.toString();
   }
+*/
 
   public String ASTDecl.emitThrowAwayTokensString() {
     StringBuffer res = new StringBuffer();
diff --git a/src/template/incremental/ASTChange.tt b/src/template/incremental/ASTChange.tt
index b8a24849..46091dd6 100644
--- a/src/template/incremental/ASTChange.tt
+++ b/src/template/incremental/ASTChange.tt
@@ -51,11 +51,13 @@ if (!state().IN_CONSTRUCTION && !(state().IN_COMPUTATION > 0)) {
   }
 }
 $endif
+/*
 if (node != null) {
   inc_changeState(node.inc_state);
 } else {
   inc_changeState(inc_GARBAGE);
 }
+*/
 $endif
 ]]
 
@@ -78,7 +80,7 @@ if (!state().IN_CONSTRUCTION && !state().IN_ATTR_STORE_EVAL) {
     if (getChild_handler[i] != null) {
       getChild_handler[i].notifyDependencies();
     } else {
-      getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i));
+      getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i));
     }
   }
 $endif
@@ -241,7 +243,7 @@ $if(IncrementalEnabled)
 
 $if(IncrementalLevelParam)
 getChild_handler = new $DDGNodeName[i + 1];
-getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i));
+getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i));
 $endif
 
 $endif
diff --git a/src/template/incremental/DDGNode.tt b/src/template/incremental/DDGNode.tt
index 8a473f14..94781fe1 100644
--- a/src/template/incremental/DDGNode.tt
+++ b/src/template/incremental/DDGNode.tt
@@ -37,20 +37,35 @@ $if (IncrementalLevelParam)
   public String fAttrID;
   protected Object fParams;
 
-  public $DDGNodeName($ASTNode node, String attrID, Object params) {
+  public static $DDGNodeName createAttrHandler($ASTNode node, String attrID, Object params) {
+    return new $DDGNodeName(node, attrID, params, $ASTNode.inc_EMPTY);
+  }
+
+  public static $DDGNodeName createAttrHandler($DDGNodeName handler, $ASTNode node) {
+    return new $DDGNodeName(handler, node, $ASTNode.inc_EMPTY);
+  }
+
+  public static $DDGNodeName createAstHandler($ASTNode node, String attrID, Object params) {
+    return new $DDGNodeName(node, attrID, params, $ASTNode.inc_AST);
+  }
+
+  public static $DDGNodeName createAstHandler($DDGNodeName handler, $ASTNode node) {
+    return new $DDGNodeName(handler, node, $ASTNode.inc_AST);
+  }
+
+
+  private $DDGNodeName($ASTNode node, String attrID, Object params, int state) {
     fNode = node;
     fAttrID = attrID;
     fParams = params;
-    fState = node.inc_state;
-    //createdHandlers.add(this);
+    fState = state;
   }
 
-  public $DDGNodeName($DDGNodeName handler, $ASTNode node) {
+  private $DDGNodeName($DDGNodeName handler, $ASTNode node, int state) {
     fNode = node;
     fAttrID = handler.fAttrID;
     fParams = handler.fParams;
-    fState = node.inc_state;
-    //createdHandlers.add(this);
+    fState = state;
   }
 
   public void setParams(Object params) {
@@ -260,11 +275,9 @@ $endif
 
   // React to change
 
-  private boolean visitedChange = false;
-
   public void dependencyChanged() {
-    if (!visitedChange) {
-      visitedChange = true;
+    if (isComputed()) {
+      setEmpty();
 $if (IncrementalTrack)
       trackedFlushes++;
       System.out.println("not(" + this + ")");
@@ -305,17 +318,12 @@ $if (IncrementalLevelRegion)
 $endif
 	  }
 $endif
-      visitedChange = false;
     }
   }
 
   // State
 
-  protected int fState = $ASTNode.inc_CREATED;
-
-  public void changeState(int newState) {
-    fState = newState;
-  }
+  protected int fState = $ASTNode.inc_EMPTY;
 
   public void throwAway() {
     fState = $ASTNode.inc_GARBAGE;
@@ -325,6 +333,14 @@ $endif
     fState = $ASTNode.inc_LIVE;
   }
 
+  public void setComputed() {
+    fState = $ASTNode.inc_COMPUTED;
+  }
+
+  public void setEmpty() {
+    fState = $ASTNode.inc_EMPTY;
+  }
+
   public boolean isGarbage() {
     return fState == $ASTNode.inc_GARBAGE;
   }
@@ -341,6 +357,10 @@ $endif
     return fState == $ASTNode.inc_LIVE;
   }
 
+  public boolean isComputed() {
+    return fState == $ASTNode.inc_COMPUTED;
+  }
+
 $if (IncrementalDebug)
   // Debugging
 
@@ -379,8 +399,19 @@ $if (IncrementalDebug)
     for ($DDGNodeName node : fListenerSet) {
       sorted.add(node.toString());
     }
-    for (String s : sorted) {
-      System.out.println("dep(" + s + " -> " + this + ")");
+    System.out.println(this + " listeners: " + sorted);
+  }
+
+  public String state() {
+    switch (fState) {
+      case ASTNode.inc_LIVE: return "LIVE";
+      case ASTNode.inc_COMPUTED: return "COMPUTED";
+      case ASTNode.inc_EMPTY: return "EMPTY";
+      case ASTNode.inc_AST: return "AST";
+      case ASTNode.inc_GARBAGE: return "GARBAGE";
+      case ASTNode.inc_CREATED: return "CREATED";
+      case ASTNode.inc_CLONED: return "CLONED";                
+      default: return "UNKNOWN";
     }
   }
 
@@ -388,7 +419,7 @@ $if (IncrementalDebug)
 $if (IncrementalLevelParam)
     return fNode.relativeNodeID() + ":" + fAttrID + (fParams != null ?
             ("[" + (fParams instanceof $ASTNode ? (($ASTNode) fParams).relativeNodeID() : fParams) + "]")
-            : "");
+            : "") + " (" + state() + ")";
 $endif
 $if (IncrementalLevelAttr)
     return fNode.relativeNodeID() + ":" + fAttrID;
@@ -463,9 +494,9 @@ $if(IncrementalEnabled)
 $if (!#isNTA)
 $if (IncrementalLevelParam)
 $if (IncrementalPropLimit)
-  protected $DDGNodeName $Host.get$(Id)_handler = new $DDGNodeName(this, "get$Id", null, true);
+  protected $DDGNodeName $Host.get$(Id)_handler = $DDGNodeName.createAstHandler(this, "get$Id", null, true);
 $else
-  protected $DDGNodeName $Host.get$(Id)_handler = new $DDGNodeName(this, "get$Id", null);
+  protected $DDGNodeName $Host.get$(Id)_handler = $DDGNodeName.createAstHandler(this, "get$Id", null);
 $endif
 $endif
 $if (IncrementalLevelAttr)
@@ -479,11 +510,11 @@ $endif
 ASTDecl.createASTHandlers = [[
 $if (IncrementalLevelParam)
 $if (IncrementalPropLimit)
-  protected $DDGNodeName $ASTNode.getParent_handler = new $DDGNodeName(this, "getParent", null, true);
-  protected $DDGNodeName $ASTNode.numChildren_handler = new $DDGNodeName(this, "numChildren", null, true);
+  protected $DDGNodeName $ASTNode.getParent_handler = $DDGNodeName.createAstHandler(this, "getParent", null, true);
+  protected $DDGNodeName $ASTNode.numChildren_handler = $DDGNodeName.createAstHandler(this, "numChildren", null, true);
 $else
-  protected $DDGNodeName $ASTNode.getParent_handler = new $DDGNodeName(this, "getParent", null);
-  protected $DDGNodeName $ASTNode.numChildren_handler = new $DDGNodeName(this, "numChildren", null);
+  protected $DDGNodeName $ASTNode.getParent_handler = $DDGNodeName.createAstHandler(this, "getParent", null);
+  protected $DDGNodeName $ASTNode.numChildren_handler = $DDGNodeName.createAstHandler(this, "numChildren", null);
 $endif
   protected $DDGNodeName[] $ASTNode.getChild_handler;
 $endif
diff --git a/src/template/incremental/DDGNodeCopy.tt b/src/template/incremental/DDGNodeCopy.tt
index 1f0c3946..44ce523d 100644
--- a/src/template/incremental/DDGNodeCopy.tt
+++ b/src/template/incremental/DDGNodeCopy.tt
@@ -34,11 +34,11 @@ $if (IncrementalLevelParam)
     if (getChild_handler != null) {
       copy.getChild_handler = ($DDGNodeName[])getChild_handler.clone();
     }
-    copy.numChildren_handler = new $DDGNodeName(numChildren_handler, copy);
-    copy.getParent_handler = new $DDGNodeName(getParent_handler, copy);
+    copy.numChildren_handler = $DDGNodeName.createAstHandler(numChildren_handler, copy);
+    copy.getParent_handler = $DDGNodeName.createAstHandler(getParent_handler, copy);
     for (int i = 0; getChild_handler != null && i < getChild_handler.length; i++) {
       if (getChild_handler[i] != null) {
-        copy.getChild_handler[i] = new $DDGNodeName(getChild_handler[i], copy);
+        copy.getChild_handler[i] = $DDGNodeName.createAttrHandler(getChild_handler[i], copy);
       }
     }
 $endif
@@ -82,7 +82,7 @@ $endif
 # Copy token DDG node
 TokenComponent.copyTokenHandler = [[
     if (get$(Id)_handler != null) {
-      copy.get$(Id)_handler = new $DDGNodeName(get$(Id)_handler, copy);
+      copy.get$(Id)_handler = $DDGNodeName.createAstHandler(get$(Id)_handler, copy);
     }
 ]]
 
@@ -95,7 +95,7 @@ $if (IsParameterized)
     }
 $else
     if ($(AttributeName)_handler != null) {
-      copy.$(AttributeName)_handler = new $DDGNodeName($(AttributeName)_handler, copy);
+      copy.$(AttributeName)_handler = $DDGNodeName.createAttrHandler($(AttributeName)_handler, copy);
     }
 $endif
 $endif
diff --git a/src/template/incremental/State.tt b/src/template/incremental/State.tt
index fbc61249..24913d4f 100644
--- a/src/template/incremental/State.tt
+++ b/src/template/incremental/State.tt
@@ -67,15 +67,16 @@ $if(IncrementalTrack)
 $endif
 //  if (!IN_REWRITE_EVAL) {
     IN_ATTR_STORE_EVAL = true;
-    //System.out.println("attr eval stack enter: " + handler.fAttrID);
+    //System.out.println("attr eval stack enter: " + handler);
     pushHandler(handlerAttrStack, handler);
+    handler.setComputed();
 //  }
   }
 
   public void exitAttrStoreEval($ASTNode$$DepGraphNode handler) {
 //  if (!IN_REWRITE_EVAL) {
     popHandler(handlerAttrStack, handler);
-    //System.out.println("attr eval stack exit: " + handler.fAttrID);
+    //System.out.println("attr eval stack exit: " + handler);
     IN_ATTR_STORE_EVAL = !handlerAttrStack.isEmpty();
 //  }
   }
@@ -380,6 +381,9 @@ public static final int $ASTNode.inc_CREATED = 0;
 public static final int $ASTNode.inc_CLONED = 1;
 public static final int $ASTNode.inc_LIVE = 2;
 public static final int $ASTNode.inc_GARBAGE = 3;
+public static final int $ASTNode.inc_EMPTY = 4;
+public static final int $ASTNode.inc_COMPUTED = 5;
+public static final int $ASTNode.inc_AST = 6;
 public int $ASTNode.inc_state = inc_CREATED;
 $endif
 ]]
diff --git a/src/template/incremental/Tracking.tt b/src/template/incremental/Tracking.tt
index b37e88d1..7d6a9dd4 100644
--- a/src/template/incremental/Tracking.tt
+++ b/src/template/incremental/Tracking.tt
@@ -58,9 +58,9 @@ $if(IncrementalLevelParam)
 int i = getNumChildNoTransform() - 1;
 if (getChild_handler[i] == null) {
 $if(IncrementalPropLimit)
-  getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i), !node.mayHaveRewrite());
+  getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i), !node.mayHaveRewrite());
 $else
-  getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i));
+  getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i));
 $endif
 }
 state().addHandlerDepTo(getChild_handler[i]);
@@ -160,9 +160,9 @@ $if(IncrementalEnabled)
 $if(IncrementalLevelParam)
 if (this.getChild_handler[i] == null) {
   $if(IncrementalPropLimit)
-  this.getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i), !node.mayHaveRewrite());
+  this.getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i), !node.mayHaveRewrite());
   $else
-  this.getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i));
+  this.getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i));
   $endif
 }
 this.state().addHandlerDepTo(this.getChild_handler[i]);
@@ -251,9 +251,9 @@ $if(IncrementalEnabled)
 $if(IncrementalLevelParam)
 if (this.getChild_handler[i] == null) {
   $if(IncrementalPropLimit)
-  this.getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i), !node.mayHaveRewrite());
+  this.getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i), !node.mayHaveRewrite());
   $else
-  this.getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i));
+  this.getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i));
   $endif
 }
 this.state().addHandlerDepTo(this.getChild_handler[i]);
@@ -300,9 +300,9 @@ $if(IncrementalEnabled)
 $if(IncrementalLevelParam)
 if (getChild_handler[i] == null) {
   $if(IncrementalPropLimit)
-  getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i), !child.mayHaveRewrite());
+  getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i), !child.mayHaveRewrite());
   $else
-  getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i));
+  getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i));
   $endif
 }
 state().addHandlerDepTo(getChild_handler[i]);
@@ -335,9 +335,9 @@ $if(IncrementalEnabled)
 $if(IncrementalLevelParam)
 if (getChild_handler[i] == null) {
   $if(IncrementalPropLimit)
-  getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i), !child.mayHaveRewrite());
+  getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i), !child.mayHaveRewrite());
   $else
-  getChild_handler[i] = new $DDGNodeName(this, "getChild", Integer.valueOf(i));
+  getChild_handler[i] = $DDGNodeName.createAttrHandler(this, "getChild", Integer.valueOf(i));
   $endif
 }
 state().addHandlerDepTo(getChild_handler[i]);
@@ -432,12 +432,12 @@ $if(IncrementalEnabled)
 $if(IncrementalLevelParam)
 $if(!#isParameterized)
 if (#(signature)_handler == null) {
-  #(signature)_handler = new $DDGNodeName(this, "#(signature)", null);
+  #(signature)_handler = $DDGNodeName.createAttrHandler(this, "#(signature)", null);
 }
 state().addHandlerDepTo(#(signature)_handler);
 $else
 if (!#(signature)_handler.containsKey(_parameters)) {
-  #(signature)_handler.put(_parameters, new $DDGNodeName(this, "#(signature)", _parameters));
+  #(signature)_handler.put(_parameters, $DDGNodeName.createAttrHandler(this, "#(signature)", _parameters));
 }
 state().addHandlerDepTo(($DDGNodeName)#(signature)_handler.get(_parameters));
 $endif
@@ -487,8 +487,13 @@ $if(IncrementalEnabled)
 $if(#isMemoized)
 
 $if(IncrementalLevelParam)
-$DDGNodeName tmpHandler = new $DDGNodeName(this, "", null);
-state().enterAttrStoreEval(tmpHandler);
+//$DDGNodeName tmpHandler = $DDGNodeName.createAttrHandler(this, "", null);
+//state().enterAttrStoreEval(tmpHandler);
+$if(!#isParameterized)
+state().enterAttrStoreEval(#(signature)_handler);
+$else
+state().enterAttrStoreEval(($DDGNodeName)#(signature)_handler.get(_parameters));
+$endif
 $endif
 
 $if(IncrementalLevelAttr)
@@ -558,7 +563,13 @@ $if(IncrementalEnabled)
 $if(#isMemoized)
 
 $if(IncrementalLevelParam)
-state().exitAttrStoreEval(tmpHandler);
+//state().exitAttrStoreEval(tmpHandler);
+$if(!#isParameterized)
+state().exitAttrStoreEval(#(signature)_handler);
+$else
+state().exitAttrStoreEval(($DDGNodeName)#(signature)_handler.get(_parameters));
+$endif
+
 $endif
 
 $if(IncrementalLevelAttr)
@@ -639,9 +650,9 @@ $if(#isMemoized)
 
 $if(IncrementalLevelParam)
 $if(!#isParameterized)
-#(signature)_handler.transferDependenciesFrom(tmpHandler);
+//#(signature)_handler.transferDependenciesFrom(tmpHandler);
 $else
-(($DDGNodeName)#(signature)_handler.get(_parameters)).transferDependenciesFrom(tmpHandler);
+//(($DDGNodeName)#(signature)_handler.get(_parameters)).transferDependenciesFrom(tmpHandler);
 $endif
 $endif
 
-- 
GitLab