From 11229acec4e8498d8f39ed8df30fe89b10270a86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emma=20S=C3=B6derberg?= <emma.m.soderberg@gmail.com>
Date: Mon, 21 May 2018 20:41:48 +0200
Subject: [PATCH] Adds circular check to internal incremental/param methods.

Methods:
- inc_changeState
- inc_flush_subtree
- inc_throwAway

All these methods may be called on rewrittenNode_value which
may have the value this.
---
 src/template/incremental/Notification.tt |  6 ++++++
 src/template/incremental/State.tt        | 12 ++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/src/template/incremental/Notification.tt b/src/template/incremental/Notification.tt
index 55a12673..05fc06d1 100644
--- a/src/template/incremental/Notification.tt
+++ b/src/template/incremental/Notification.tt
@@ -902,8 +902,13 @@ $endif
 $endif
 
 $if(IncrementalLevelParam)
+  private boolean #name.inc_flush_subtree_visited = false;
   /** @apilevel internal */
   protected void #name.inc_flush_subtree($DDGNodeName h) {
+    if (inc_flush_subtree_visited) {
+      return;
+    }
+    inc_flush_subtree_visited = true;
     inc_state = inc_GARBAGE;
     $FlushNtaSubTrees
     $TransferSetsFromAttrTokenHandlers
@@ -923,6 +928,7 @@ $if(#isASTNodeDecl)
 $else
     super.inc_flush_subtree(h);
 $endif
+    inc_flush_subtree_visited = false;
   }
 $endif
 
diff --git a/src/template/incremental/State.tt b/src/template/incremental/State.tt
index 1cf8fce4..fbc61249 100644
--- a/src/template/incremental/State.tt
+++ b/src/template/incremental/State.tt
@@ -156,8 +156,13 @@ $endif
 ]]
 
 ASTDecl.incChangeStateMethod = [[
+private boolean #name.inc_changeState_visited = false;
 /** @apilevel internal */
 public void #name.inc_changeState(int newState) {
+  if (inc_changeState_visited) {
+    return;
+  }
+  inc_changeState_visited = true;
 $if(#isASTNodeDecl)
   inc_state = newState;
 
@@ -214,6 +219,7 @@ $else
 $endif
   $ChangeStateTokens
   $ChangeStateAttributes
+  inc_changeState_visited = false;
 }
 ]]
 
@@ -262,8 +268,13 @@ $endif
 ]]
 
 ASTDecl.incThrowAwayMethod = [[
+private boolean #name.inc_throwAway_visited = false;
 /** @apilevel internal */
 public void #name.inc_throwAway() {
+  if (inc_throwAway_visited) {
+    return;
+  }
+  inc_throwAway_visited = true;
   inc_state = inc_GARBAGE;
 $if(#isASTNodeDecl)
   $if(IncrementalLevelParam)
@@ -315,6 +326,7 @@ $else
 $endif
   $ThrowAwayTokens
   $ThrowAwayAttributes
+  inc_throwAway_visited = false;
 }
 ]]
 
-- 
GitLab