All Downloads are FREE. Search and download functionalities are using the official Maven repository.

template.incremental.DDGNode.tt Maven / Gradle / Ivy

There is a newer version: 2.3.6
Show newest version
# Copyright (c) 2013, The JastAdd Team
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Lund University nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Code for DDG node
Grammar.emitDDGNode = [[
/** @apilevel internal */
public class $DDGNodeName {

$if (IncrementalLevelParam)
  // Level: param

  public $ASTNode fNode;
  public String fAttrID;
  protected Object fParams;

  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);
  }


  $DDGNodeName($ASTNode node, String attrID, Object params, int state) {
    fNode = node;
    fAttrID = attrID;
    fParams = params;
    fState = state;
  }

  $DDGNodeName($DDGNodeName handler, $ASTNode node, int state) {
    fNode = node;
    fAttrID = handler.fAttrID;
    fParams = handler.fParams;
    fState = state;
  }

  public void setParams(Object params) {
    fParams = params;
  }

$if (IncrementalPropLimit)
  // Limit change propagation with the use of cache independence

  public boolean cacheInDependent = false;

  public $DDGNodeName($ASTNode node, String attrID, Object params, boolean cacheInDependent) {
    this(node, attrID, params);
    this.cacheInDependent = cacheInDependent;
  }

  public boolean isCacheInDependent() {
    return cacheInDependent;
  }

  public void setCacheInDependent(boolean b) {
    cacheInDependent = b;
  }

  public boolean noCacheRead = true;
$endif

$endif

$if (IncrementalLevelAttr)
  // Level: attr

  public $ASTNode fNode;
  public String fAttrID;

  public $DDGNodeName($ASTNode node, String attrID) {
    fNode = node;
    fAttrID = attrID;
    fState = node.inc_state;
  }

  public $DDGNodeName($DDGNodeName handler, $ASTNode node) {
    fNode = node;
    fAttrID = handler.fAttrID;
    fState = node.inc_state;
  }

  public void flushRegion() {
    // Remove dependencies
    java.util.HashSet<$DDGNodeName> k = fDependencySet;
    fDependencySet = new java.util.HashSet<$DDGNodeName>(4);
    for ($DDGNodeName node : k) {
      node.removeListener(this);
    }
    reactToDependencyChange(fAttrID);
  }
$endif

$if (IncrementalLevelNode)
  // Level: node

  public $ASTNode fNode;

  public $DDGNodeName($ASTNode node) {
    fNode = node;
    fState = node.inc_state;
  }

  public $DDGNodeName($DDGNodeName handler, $ASTNode node) {
    fNode = node;
    fState = node.inc_state;
  }

  public void flushRegion() {
    // Remove dependencies
    java.util.HashSet<$DDGNodeName> k = fDependencySet;
    fDependencySet = new java.util.HashSet<$DDGNodeName>(4);
    for ($DDGNodeName node : k) {
      node.removeListener(this);
    }
    reactToDependencyChange();
  }
$endif

$if (IncrementalLevelRegion)
  // Level: region

  public $ASTNode fNode;

  public $DDGNodeName($ASTNode node) {
    fNode = node;
    fState = node.inc_state;
  }

  public $DDGNodeName($DDGNodeName handler, $ASTNode node) {
    fNode = node;
    fState = node.inc_state;
  }

  public void flushRegion() {
    setEmpty();
    reactToDependencyChange();
  }
$endif

  // Dependency management

  public java.util.HashSet<$DDGNodeName> fListenerSet = new java.util.HashSet<$DDGNodeName>(4);

  public boolean hasListeners() {
    return !fListenerSet.isEmpty();
  }

  public void addListener($DDGNodeName node) {
    fListenerSet.add(node);
$if (IncrementalLevelRegion)
    node.setComputed();
$endif
  }

  public void removeListener($DDGNodeName node) {
    fListenerSet.remove(node);
  }

  public void cleanupListeners() {
    java.util.Iterator<$DDGNodeName> itr = fListenerSet.iterator();
    while (itr.hasNext()) {
      $DDGNodeName node = itr.next();
      if (node.isEmpty() || node.isGarbage()) {
        itr.remove();
      }
    }
  }

  public void clearListeners() {
    fListenerSet.clear();
  }

  // Notification

  private boolean visited = false;

  public void notifyDependencies() {
    // Notify and remove listeners
    if (!visited) {
      visited = true;
      java.util.HashSet<$DDGNodeName> k = fListenerSet;
      fListenerSet = new java.util.HashSet<$DDGNodeName>(4);
      for ($DDGNodeName node : k) {
        if (!node.isGarbage()) {
          node.dependencyChanged();
        }
      }
      visited = false;
    }
  }

  // React to change

  public void dependencyChanged() {
    if (isComputed() || isCreated()) {
      setEmpty();
$if (IncrementalTrack)
      trackedFlushes++;
      System.out.println("not(" + this + ")");
$endif
$if (IncrementalPropLimit)
      if (noCacheRead && !fNode.inc_valueAffected(fAttrID, fParams)) {
      } else {
        reactToDependencyChange();
      }
$else
      reactToDependencyChange();
$endif
    }
  }

  public void reactToDependencyChange() {
$if(IncrementalLevelParam)
    fNode.reactToDependencyChange(fAttrID, fParams);
$endif
$if(IncrementalLevelAttr)
    fNode.reactToDependencyChange(fAttrID);
$endif
$if(IncrementalLevelNode)
    fNode.reactToDependencyChange();
$endif
$if(IncrementalLevelRegion)
    fNode.reactToDependencyChange();
$endif
  }

  // State

  protected int fState = $ASTNode.inc_EMPTY;

  public void throwAway() {
    fState = $ASTNode.inc_GARBAGE;
  }

  public void keepAlive() {
    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;
  }

  public boolean isCreated() {
    return fState == $ASTNode.inc_CREATED;
  }

  public boolean isCloned() {
    return fState == $ASTNode.inc_CLONED;
  }

  public boolean isLive() {
    return fState == $ASTNode.inc_LIVE;
  }

  public boolean isComputed() {
    return fState == $ASTNode.inc_COMPUTED;
  }

  public boolean isEmpty() {
    return fState == $ASTNode.inc_EMPTY;
  }

$if (IncrementalDebug)
  // Debugging

  private int dumpDependents_visited = 0;

  public void dumpDependents(boolean changed, int visited) {
    if (visited != dumpDependents_visited) {
      dumpDependents_visited = visited;
      if (changed) {
        System.out.println("change(" + this + ")");
      } else {
        System.out.println("dep-change(" + this + ")");
      }
      class Entry implements Comparable {
        public String id;
        public $DDGNodeName node;
        public Entry(String id, $DDGNodeName node) {
          this.id = id; this.node = node;
        }
        public int compareTo(Entry e) {
          return id.compareTo(e.id);
        }
      }
      java.util.TreeSet sorted = new java.util.TreeSet();
      for ($DDGNodeName node : fListenerSet) {
        sorted.add(new Entry(node.toString(), node));
      }
      for (Entry e : sorted) {
        e.node.dumpDependents(false, visited);
      }
    }
  }

  public void dumpDeps() {
    java.util.TreeSet sorted = new java.util.TreeSet();
    for ($DDGNodeName node : fListenerSet) {
      sorted.add(node.toString());
    }
    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";
    }
  }

  public String toString() {
$if (IncrementalLevelParam)
    return fNode.relativeNodeID() + ":" + fAttrID + (fParams != null ?
            ("[" + (fParams instanceof $ASTNode ? (($ASTNode) fParams).relativeNodeID() : fParams) + "]")
            : "") + " (" + state() + ")";
$endif
$if (IncrementalLevelAttr)
    return fNode.relativeNodeID() + ":" + fAttrID;
$endif
$if (IncrementalLevelNode)
    return fNode.relativeNodeID();
$endif
$if (IncrementalLevelRegion)
    return fNode.relativeNodeID() + "(" + state() + ")";
$endif
  }
$endif

  // Clean up

  public boolean visitedDuringCleanup = false;
  public static int nbr_cleanup = 0;

  public void cleanUpGarbage() {
    visitedDuringCleanup = true;
    nbr_cleanup++;
    // Clean up garbage
    java.util.Iterator<$DDGNodeName> itr = fListenerSet.iterator();
    while (itr.hasNext()) {
      $DDGNodeName cur = itr.next();
      if (cur.isGarbage()) {
        itr.remove();
      }
    }
  }

$if(IncrementalTrack)
  // Tracking

  public static int trackedReads = 0;
  public static int trackedComputes = 0;
  public static int trackedFlushes = 0;

  public void trackChange() {
    System.out.println("change(" + this + ")");
  }

  public static void resetTrackingCounters() {
    trackedReads = 0;
    trackedComputes = 0;
    trackedFlushes = 0;
  }

  public static String getTrackingResult() {
    return "nbr.reads = " + trackedReads + ", nbr.computes = " + trackedComputes + ", nbr.flushes = " + trackedFlushes;
  }
$endif
}
]]

# Create DDG node for token
TokenComponent.incHookTokenHandler = [[
$if(IncrementalEnabled)
$if (!#isNTA)
$if (IncrementalLevelParam)
$if (IncrementalPropLimit)
  protected $DDGNodeName $Host.get$(Id)_handler = $DDGNodeName.createAstHandler(this, "get$Id", null, true);
$else
  protected $DDGNodeName $Host.get$(Id)_handler = $DDGNodeName.createAstHandler(this, "get$Id", null);
$endif
$endif
$if (IncrementalLevelAttr)
  protected $DDGNodeName $Host.get$(Id)_handler = new $DDGNodeName(this, "get$Id");
$endif
$endif
$endif
]]

# Create DDG nodes for AST
ASTDecl.createASTHandlers = [[
$if (IncrementalLevelParam)
$if (IncrementalPropLimit)
  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 = $DDGNodeName.createAstHandler(this, "getParent", null);
  protected $DDGNodeName $ASTNode.numChildren_handler = $DDGNodeName.createAstHandler(this, "numChildren", null);
$endif
  protected $DDGNodeName[] $ASTNode.getChild_handler;
$endif
$if (IncrementalLevelAttr)
  protected $DDGNodeName $ASTNode.getParent_handler = new $DDGNodeName(this, "getParent");
  protected $DDGNodeName $ASTNode.numChildren_handler = new $DDGNodeName(this, "numChildren");
  protected $DDGNodeName $ASTNode.getChild_handler = new $DDGNodeName(this, "getChild");
$endif
]]

# Create DDG node for AST node
ASTDecl.createNodeHandler = [[
  protected $DDGNodeName #name.handler = new $DDGNodeName(this);
]]

# Create DDG node for rewrite attribute.
ASTDecl.createRewriteAttributeHandler = [[
  protected $DDGNodeName #name.rewrittenNode_handler;
]]

# Create DDG node for attribute
ASTDecl.createAttributeHandler = [[
$if (IncrementalLevelParam)
$if (IsParameterized)
  protected java.util.Map #name.$(AttributeName)_handler = new java.util.HashMap(4);
$else
  protected $DDGNodeName #name.$(AttributeName)_handler;
$endif
$endif
$if (IncrementalLevelAttr)
  protected $DDGNodeName #name.$(AttributeName)_handler;
$endif
]]

# Initialize DDG node for children
ASTDecl.incrementalInitChildHandlers = [[
$if (IncrementalLevelParam)
  getChild_handler = new $DDGNodeName[children.length];
$endif
]]

# Generate code for cleanup listeners method.
ASTDecl.cleanupListenersMethod = [[
private boolean #name.inc_cleanupListeners_visited = false;
public void #name.cleanupListeners() {
  if (inc_cleanupListeners_visited) {
    return;
  }
  inc_cleanupListeners_visited = true;
$if (#isASTNodeDecl)
$if (IncrementalLevelParam)
  getParent_handler.cleanupListeners();
  numChildren_handler.cleanupListeners();
  for (int k = 0; getChild_handler != null && k < getChild_handler.length; k++) {
    if (getChild_handler[k] != null) {
      getChild_handler[k].cleanupListeners();
    }
  }
$endif
$endif
$if (IncrementalLevelRegion)
$if (IsRegionRoot)
  handler.cleanupListeners();
$endif
$endif
  $CleanupTokenListeners
  $CleanupAttributeListeners
$if (!#isASTNodeDecl)
$if (IncrementalLevelRegion)
$if (!IsRegionRoot)
  super.cleanupListeners();
$endif
$else
  super.cleanupListeners();
$endif
$endif
  inc_cleanupListeners_visited = false;
}
]]

# Generate code for checking token handler and cleaning up listeners.
ASTDecl.checkAndCleanupTokenListeners = [[
if (get$(Id)_handler != null) {
  get$(Id)_handler.cleanupListeners();
}
]]

# Generate code for checking attribute handler and cleaning up listeners.
ASTDecl.checkAndCleanupAttributeListeners = [[
$if (IncrementalLevelParam)
$if (IsParameterized)
for (java.util.Iterator itr = $(AttrSign)_handler.values().iterator(); itr.hasNext();) {
  $DDGNodeName handler = ($DDGNodeName)itr.next();
  handler.cleanupListeners();
}
$else
if ($(AttrSign)_handler != null) {
  $(AttrSign)_handler.cleanupListeners();
}
$endif
$if (IsNTA)
$if (IsParameterized)
if ($(AttrSign)_proxy != null) {
  $(AttrSign)_proxy.cleanupListeners();
}
$else
if ($(AttrSign)_computed && ($(AttrSign)_value instanceof $ASTNode)) {
  $(AttrSign)_value.cleanupListeners();
}
$endif
$endif
$endif
]]

# Generate code for method cleanupListenersInTree.
ASTDecl.cleanupListenersInTreeMethod = [[
private boolean #name.inc_cleanupListenersInTree_visited = false;
public void #name.cleanupListenersInTree() {
  if (inc_cleanupListenersInTree_visited) {
    return;
  }
  inc_cleanupListenersInTree_visited = true;
  cleanupListeners();
  for (int i = 0; children != null && i < children.length; i++) {
    $ASTNode child = children[i];
    if (child == null) {
      continue;
    }
    child.cleanupListenersInTree();
  }
  $CleanupListenersInNTAs
  inc_cleanupListenersInTree_visited = false;
}
]]

# Generate string with code for cleaning up listeners in NTAs.
ASTDecl.checkAndCleanupNTAListeners = [[
$if (IsParameterized)
if ($(AttrSign)_proxy != null) {
  $(AttrSign)_proxy.cleanupListenersInTree();
}
$else
if ($(AttrSign)_computed && ($(AttrSign)_value instanceof $ASTNode)) {
  $(AttrSign)_value.cleanupListenersInTree();
}
$endif
]]





© 2015 - 2024 Weber Informatics LLC | Privacy Policy