Skip to content
Snippets Groups Projects
Commit 9ddf1fc1 authored by Jesper's avatar Jesper
Browse files

Add collection attribute runtime debug check

Added a runtime debug check for collection attributes, checking that a
contribution contributes to a target node that is under a common collection
root node with the source node.

Removed target null check in collection attribute code - the target of a
contribution should always be non null.

see #251 (bitbucket)
parent 9430332b
Branches
No related tags found
No related merge requests found
......@@ -36,8 +36,12 @@ aspect CollectionAttributes {
eq CollDecl.isCollection() = true;
/** @return the type name of the collection root node */
syn String CollDecl.rootType() = root().name();
/** @return the type name of the collection root node */
syn String CollEq.rootType() = decl().rootType();
/** @return the return type of the collection attribute */
syn String CollEq.getType() = decl().getType();
......@@ -117,6 +121,7 @@ aspect CollectionAttributes {
}
syn TypeDecl AttrDecl.root() = grammar().root();
eq CollDecl.root() = root != null ? grammar().lookup(root) : super.root();
// Only used by circular collection attributes.
......
......@@ -220,17 +220,16 @@ aspect JragCodeGen {
if (config().lazyMaps()) {
if (!isCircular()) {
if (getNumParameter() != 0 && config().visitCheckEnabled() && config().rewriteEnabled()) {
sb.append("if (" + signature() + "_visited == null) " + signature()
+ "_visited = " + config().createDefaultMap() + ";\n");
}
else if (getNumParameter() != 0 && config().visitCheckEnabled()) {
sb.append("if (" + signature() + "_visited == null) " + signature()
+ "_visited = " + config().createDefaultSet() + ";\n");
sb.append(String.format("if (%s_visited == null) %s_visited = %s;\n",
signature(), signature(), config().createDefaultMap()));
} else if (getNumParameter() != 0 && config().visitCheckEnabled()) {
sb.append(String.format("if (%s_visited == null) %s_visited = %s;\n",
signature(), signature(), config().createDefaultSet()));
}
}
if (getNumParameter() != 0 && (isLazy() || isCircular())) {
sb.append("if (" + signature() + "_values == null) " + signature()
+ "_values = " + config().createDefaultMap() + ";\n");
sb.append(String.format("if (%s_values == null) %s_values = %s;\n",
signature(), signature(), config().createDefaultMap()));
}
}
return sb.toString();
......@@ -257,7 +256,9 @@ aspect JragCodeGen {
* @return {@code true} if the attribute is declared as NTA in the aspect file
*/
syn boolean AttrDecl.declaredNTA() = false;
eq SynDecl.declaredNTA() = getNTA();
eq InhDecl.declaredNTA() = getNTA();
public static String ASTNode.boxedType(String type) {
......@@ -663,7 +664,7 @@ aspect JragCodeGen {
+ " was affected by a bug causing the equation value to be discarded! "
+ "(fixed since version 2.1.11)");
}
String attrName = getName().substring(3); // remove get
String attrName = getName().substring(3);
if (comp.name().equals(attrName) && comp instanceof AggregateComponentNTA
|| attrName.equals(comp.name() + "Opt") && comp instanceof OptionalComponentNTA
|| attrName.equals(comp.name() + "List") && comp instanceof ListComponentNTA) {
......
......@@ -45,7 +45,7 @@ $if(#isCollection)
while (_node != null && !(_node instanceof #rootType)) {
_node = _node.getParent();
}
$include(collDebugCheck)
$include(CollDecl.collDebugCheck)
#rootType root = (#rootType) _node;
if (root.collecting_contributors_#collectionId) {
throw new RuntimeException("Circularity during survey phase");
......
......@@ -25,11 +25,11 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
collDebugCheck [[
CollDecl.collDebugCheck [[
$if(DebugMode)
if (node == null) {
throw new RuntimeException(
"Trying to evaluate collection attribute in subtree not attached to main tree");
"Trying to evaluate collection attribute #getTarget.#getName() in subtree not attached to main tree.");
}
$endif
]]
......@@ -41,7 +41,7 @@ CollDecl.computeMethod:onePhase [[
while (node != null && !(node instanceof #rootType)) {
node = node.getParent();
}
$include(collDebugCheck)
$include(CollDecl.collDebugCheck)
#rootType root = (#rootType) node;
root.survey_#collectionId();
if (#(signature)_value == null) {
......@@ -58,7 +58,7 @@ CollDecl.computeMethod:twoPhase [[
while (node != null && !(node instanceof #rootType)) {
node = node.getParent();
}
$include(collDebugCheck)
$include(CollDecl.collDebugCheck)
#rootType root = (#rootType) node;
root.survey_#collectionId();
#getType _computedValue = $BottomValue;
......@@ -71,7 +71,7 @@ CollDecl.computeMethod:twoPhase [[
}
]]
CollEq.collectContributors:onePhase = [[
CollEq.collectContributors:onePhase [[
// #declaredat
$if(HasCondition)
if (#getCondition) {
......@@ -85,14 +85,13 @@ $endif
CollEq.contribution:onePhase [[
$if(#iterableTarget)
for (#getTargetName target : (Iterable<? extends #getTargetName>) (#getReference)) {
if (target != null) {
$include(CollEq.targetDebugCheck)
if (target.#(signature)_value == null) {
target.#(signature)_value = $BottomValue;
}
#getType collection = target.#(signature)_value;
$include(CollEq.addValueToCollection)
}
}
$else
{
$if(#implicitTarget)
......@@ -103,19 +102,18 @@ $if(#implicitTarget)
$include(CollEq.addValueToCollection)
$else
#getTargetName target = #getReference;
if (target != null) {
$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 = [[
CollEq.collectContributors:twoPhase [[
// #declaredat
$if(HasCondition)
if (#getCondition) {
......@@ -129,7 +127,7 @@ $endif
CollEq.contribution:twoPhase [[
$if(#iterableTarget)
for (#getTargetName target : (Iterable<? extends #getTargetName>) (#getReference)) {
if (target != null) {
$include(CollEq.targetDebugCheck)
java.util.Set<$ASTNode> contributors = _map.get(target);
if (contributors == null) {
contributors = new java.util.HashSet<$ASTNode>();
......@@ -137,29 +135,50 @@ for (#getTargetName target : (Iterable<? extends #getTargetName>) (#getReference
}
contributors.add(this);
}
}
$else
{
$if(#implicitTarget)
if (_root != null) {
java.util.Set<$ASTNode> contributors = _map.get(_root);
if (contributors == null) {
contributors = new java.util.HashSet<$ASTNode>();
_map.put(($ASTNode) _root, contributors);
}
contributors.add(this);
}
$else
#getTargetName target = (#getTargetName) (#getReference);
if (target != null) {
$include(CollEq.targetDebugCheck)
java.util.Set<$ASTNode> contributors = _map.get(target);
if (contributors == null) {
contributors = new java.util.HashSet<$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
]]
......@@ -188,7 +207,7 @@ $endif
}
]]
CollDecl.contributeTo:default = [[
CollDecl.contributeTo:default [[
protected void contributeTo_#(signature)(#getType collection) {
}
]]
......@@ -255,7 +274,7 @@ $endif
}
]]
Collection.flush = [[
Collection.flush [[
$if(#onePhase)
collect_contributors_#collectionId = false;
$else
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment