template.incremental.DDGNode.tt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jastadd Show documentation
Show all versions of jastadd Show documentation
A metacompilation framework for Java using attribute grammars.
# 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
]]