template.ast.Collections.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-2019, 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.
CollDecl.findRoot [[
$if(#implicitRoot)
$ASTNode node = this;
while (node.getParent() != null) {
node = node.getParent();
}
$else
$ASTNode node = this;
while (node != null && !(node instanceof #rootType)) {
node = node.getParent();
}
$endif
$include(CollDecl.collDebugCheck)
#rootType root = (#rootType) node;
]]
CollDecl.collDebugCheck [[
$if(DebugMode)
if (node == null) {
throw new RuntimeException(
"Trying to evaluate collection attribute #getTarget.#getName() in subtree not attached to main tree.");
}
$endif
]]
CollDecl.computeMethod:onePhase [[
/** @apilevel internal */
private #getType #(name)_compute() {
$include(CollDecl.findRoot)
root.survey_#collectionId();
if (#(signature)_value == null) {
#(signature)_value = $BottomValue;
}
return #(signature)_value;
}
]]
CollDecl.computeMethod:twoPhase [[
/** @apilevel internal */
private #getType #(name)_compute() {
$include(CollDecl.findRoot)
root.survey_#collectionId();
#getType _computedValue = $BottomValue;
$include(CollDecl.collectContributions)
return _computedValue;
}
]]
CollDecl.collectContributions [[
if (root.contributorMap_#collectionId.containsKey(this)) {
for ($ASTNode contributor : (java.util.Set<$ASTNode>) root.contributorMap_#collectionId.get(this)) {
contributor.contributeTo_#(signature)(_computedValue);
}
}
]]
CollEq.collectContributors:onePhase [[
// #declaredat
$if(HasCondition)
if (#getCondition) {
$include(CollEq.contribution:onePhase)
}
$else
$include(CollEq.contribution:onePhase)
$endif
]]
CollEq.contribution:onePhase [[
$if(#iterableTarget)
for (#getTargetName target : (Iterable extends #getTargetName>) (#getReference)) {
$include(CollEq.targetDebugCheck)
if (target.#(signature)_value == null) {
target.#(signature)_value = $BottomValue;
}
#getType collection = target.#(signature)_value;
$include(CollEq.addValueToCollection)
}
$else
{
$if(#implicitTarget)
if (_root.#(signature)_value == null) {
_root.#(signature)_value = $BottomValue;
}
#getType collection = _root.#(signature)_value;
$include(CollEq.addValueToCollection)
$else
#getTargetName target = #getReference;
$include(CollEq.targetDebugCheck)
if (target.#(signature)_value == null) {
target.#(signature)_value = $BottomValue;
}
#getType collection = target.#(signature)_value;
$include(CollEq.addValueToCollection)
$endif
}
$endif
]]
CollEq.collectContributors:twoPhase [[
// #declaredat
$if(HasCondition)
if (#getCondition) {
$include(CollEq.contribution:twoPhase)
}
$else
$include(CollEq.contribution:twoPhase)
$endif
]]
CollEq.contribution:twoPhase [[
$if(#iterableTarget)
for (#getTargetName target : (Iterable extends #getTargetName>) (#getReference)) {
$include(CollEq.targetDebugCheck)
java.util.Set<$ASTNode> contributors = _map.get(target);
if (contributors == null) {
contributors = new java.util.LinkedHashSet<$ASTNode>();
_map.put(($ASTNode) target, contributors);
}
contributors.add(this);
}
$else
{
$if(#implicitTarget)
java.util.Set<$ASTNode> contributors = _map.get(_root);
if (contributors == null) {
contributors = new java.util.LinkedHashSet<$ASTNode>();
_map.put(($ASTNode) _root, contributors);
}
contributors.add(this);
$else
#getTargetName target = (#getTargetName) (#getReference);
$include(CollEq.targetDebugCheck)
java.util.Set<$ASTNode> contributors = _map.get(target);
if (contributors == null) {
contributors = new java.util.LinkedHashSet<$ASTNode>();
_map.put(($ASTNode) target, contributors);
}
contributors.add(this);
$endif
}
$endif
]]
CollEq.targetDebugCheck [[
$if(DebugMode)
ASTNode _targetRoot = target;
ASTNode _targetParent = target;
while (_targetParent != null) {
_targetParent = _targetParent.getParent();
if (_targetParent instanceof #rootType) {
_targetRoot = _targetParent;
}
}
ASTNode _sourceRoot = _root;
ASTNode _sourceParent = _root;
while (_sourceParent != null) {
_sourceParent = _sourceParent.getParent();
if (_sourceParent instanceof #rootType) {
_sourceRoot = _sourceParent;
}
}
if (_targetRoot != _sourceRoot) {
throw new RuntimeException("Contribution source and target do not share a common collection "
+ "root node for collection attribute #getTargetName.#getTargetAttributeName().");
}
$endif
]]
CollDecl.collectContributors:header [[
$if(#onePhase)
/** @apilevel internal */
protected void collect_contributors_#collectionId(#rootType _root) {
$else
/** @apilevel internal */
protected void collect_contributors_#collectionId(#rootType _root, java.util.Map<$ASTNode, java.util.Set<$ASTNode>> _map) {
$endif
]]
CollDecl.collectContributors:default [[
for (int i = 0; i < getNumChild(); i++) {
getChild(i).collect_contributors_#collectionId(_root$if(!#onePhase), _map$endif);
}
}
]]
CollDecl.collectContributors:end [[
$if(#onePhase)
super.collect_contributors_#collectionId(_root);
$else
super.collect_contributors_#collectionId(_root, _map);
$endif
}
]]
CollDecl.contributeTo:default [[
/** @apilevel internal */
protected void contributeTo_#(signature)(#getType collection) {
}
]]
CollDecl.contributeTo:header [[
/** @apilevel internal */
protected void contributeTo_#(signature)(#getType collection) {
$if(!IsAstNode)
super.contributeTo_#(signature)(collection);
$endif
]]
CollEq.contributeStatement [[
$if(#hasCondition)
if (#getCondition) {
$include(CollEq.addValueToCollection)
}
$else
$include(CollEq.addValueToCollection)
$endif
]]
CollEq.addValueToCollection [[
$if(#iterableValue)
for (#elementType value : #getValue) {
collection.$CombOp(value);
}
$else
collection.$CombOp(#getValue);
$endif
]]
# The method to start the survey phase (collecting contributors).
CollDecl.surveyMethod [[
$if(#onePhase)
/** @apilevel internal */
private boolean collect_contributors_#collectionId = false;
$else
/** @apilevel internal */
protected java.util.Map<$ASTNode, java.util.Set<$ASTNode>> contributorMap_#collectionId = null;
$endif
$include(CollDecl.incSurveyHandlerDecl)
$if(#isCircular)
/** @apilevel internal */
protected boolean collecting_contributors_#collectionId = false;
$endif
/** @apilevel internal */
protected void survey_#collectionId() {
$include(CollDecl.incHookCollectionSurveyHandler)
$if(#onePhase)
if (!collect_contributors_#collectionId) {
collect_contributors_#collectionId = true;
$else
if (contributorMap_#collectionId == null) {
contributorMap_#collectionId = new java.util.IdentityHashMap<$ASTNode, java.util.Set<$ASTNode>>();
$endif
$include(CollDecl.incHookCollectionSurveyStart)
$if(#isCircular)
collecting_contributors_#collectionId = true;
$endif
$if(#onePhase)
collect_contributors_#collectionId(this);
$else
collect_contributors_#collectionId(this, contributorMap_#collectionId);
$endif
$if(#isCircular)
collecting_contributors_#collectionId = false;
$endif
$include(CollDecl.incHookCollectionSurveyEnd)
}
}
]]
Collection.flush [[
$if(#onePhase)
collect_contributors_#collectionId = false;
$else
contributorMap_#collectionId = null;
$endif
$if(#circularCollection)
collecting_contributors_#collectionId = false;
$endif
]]