diff --git a/ast/JaddCodeGen.jrag b/ast/JaddCodeGen.jrag index 7501a79acb51220eb6c12d909c2b3c138c831c08..48c0b9ba6efb363c4c24705b1088a0813848e164 100644 --- a/ast/JaddCodeGen.jrag +++ b/ast/JaddCodeGen.jrag @@ -1101,6 +1101,9 @@ aspect JaddCodeGen { // ES_2011-09-20: Code generation for incremental evaluation, modifying tree, set child 4 public void ASTDecl.jjtGenIncrementalASTChangeSetChild4(PrintWriter stream) { if (ASTNode.incrementalLevelParam) { + stream.println(ind(2) + "if (getChild_handler[i] == null) {"); + stream.println(ind(3) + "getChild_handler[i] = new ASTNode$DepGraphNode(this, \"getChild\", new Integer(i));"); + stream.println(ind(2) + "}"); stream.println(ind(2) + "if (!state().IN_REWRITE_EVAL && !childIsNTA(i)) {"); stream.println(ind(3) + "for (int k = 0; k < children.length; k++) {"); stream.println(ind(4) + "if (getChild_handler[k] != null && !childIsNTA(k)) {"); @@ -2101,8 +2104,8 @@ aspect JaddCodeGen { if (ASTNode.incrementalLevelParam) { stream.println(" getParent_handler.notifyDependencies();"); stream.println(" numChildren_handler.notifyDependencies();"); - stream.println(" for (int i = 0; i < getNumChildNoTransform(); i++) {"); - stream.println(" if (getChild_handler[i].hasDependants()) {"); + stream.println(" for (int i = 0; i < numChildren; i++) {"); + stream.println(" if (!childIsNTA(i) && getChild_handler[i].hasDependants()) {"); stream.println(" getChildNoTransform(i).notifyForRemove();"); stream.println(" getChild_handler[i].notifyDependencies();"); stream.println(" }"); diff --git a/doc/incremental.txt b/doc/incremental.txt index bb7607e7b7fcd1e1891fa649d38036f8e202a3d8..5dbf1692c3aa7dc245ff35f2d2eba239edf43033 100644 --- a/doc/incremental.txt +++ b/doc/incremental.txt @@ -74,3 +74,7 @@ tracking during rewrites. The implementation of "clearDepsInTree" should not inv For this reason, the looping over child nodes uses the "numChildren" attribute directly to circumvent a call to "getNumChild" or "getNumChildNoTransform". +There is a default rewrite on List included to allow for the "rewrite A in B" construct allowing rewrites affecting siblings +in a list. The typical (only?) example is the rewrite of "int x,y;" to "int x; int y;", or similar. + + diff --git a/test/Test123.result b/test/Test123.result index 917a5958e6b564c1cc8cc3492d2bf4c81c62470b..a4c82b5a0103d7c046d70a46be23b5ddc6f8b31e 100644 --- a/test/Test123.result +++ b/test/Test123.result @@ -1,14 +1,20 @@ Dependencies after b1.decl: -dep(A/List[0]/B[0]:decl -> A:getChild[0]) -dep(A/List[0]/B[0]:decl -> A/List[0]:getParent) -dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[0]) -dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[1]) +dep(A:getChild[0] -> A/List[0]:getChild[0]) +dep(A:getChild[0] -> A/List[0]:getChild[1]) dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getName) -dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getUse) dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getParent) +dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getUse) dep(A/List[0]/B[0]:decl -> A/List[0]/B[1]:getName) +dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[0]) +dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[1]) +dep(A/List[0]/B[0]:decl -> A/List[0]:getParent) +dep(A/List[0]/B[0]:decl -> A:getChild[0]) Cached values after b1.decl: +A/List[0] rewritten from A/List value(A/List[0]/B[0]:decl, A/List[0]/B[1]) Dependencies after b2.setName: +dep(A:getChild[0] -> A/List[0]:getChild[0]) +dep(A:getChild[0] -> A/List[0]:getChild[1]) Cached values after b2.setName: +A/List[0] rewritten from A/List diff --git a/test/Test124.result b/test/Test124.result index 05a52f11cbc34262d4b6e36ff03d84ed174812bd..b6307a8874292432ebd8962aad434812099e685a 100644 --- a/test/Test124.result +++ b/test/Test124.result @@ -1,21 +1,25 @@ Dependencies/Cache after b1.decl and b2.decl: -dep(A/List[0]/B[0]:decl -> A:getChild[0]) -dep(A/List[0]/B[1]:decl -> A:getChild[0]) -dep(A/List[0]/B[0]:decl -> A/List[0]:getParent) -dep(A/List[0]/B[1]:decl -> A/List[0]:getParent) -dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[0]) -dep(A/List[0]/B[1]:decl -> A/List[0]:getChild[0]) -dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[1]) -dep(A/List[0]/B[1]:decl -> A/List[0]:getChild[1]) +dep(A:getChild[0] -> A/List[0]:getChild[0]) +dep(A:getChild[0] -> A/List[0]:getChild[1]) dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getName) -dep(A/List[0]/B[1]:decl -> A/List[0]/B[0]:getName) -dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getUse) dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getParent) +dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getUse) dep(A/List[0]/B[0]:decl -> A/List[0]/B[1]:getName) -dep(A/List[0]/B[1]:decl -> A/List[0]/B[1]:getUse) +dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[0]) +dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[1]) +dep(A/List[0]/B[0]:decl -> A/List[0]:getParent) +dep(A/List[0]/B[0]:decl -> A:getChild[0]) +dep(A/List[0]/B[1]:decl -> A/List[0]/B[0]:getName) dep(A/List[0]/B[1]:decl -> A/List[0]/B[1]:getParent) +dep(A/List[0]/B[1]:decl -> A/List[0]/B[1]:getUse) +dep(A/List[0]/B[1]:decl -> A/List[0]:getChild[0]) +dep(A/List[0]/B[1]:decl -> A/List[0]:getChild[1]) +dep(A/List[0]/B[1]:decl -> A/List[0]:getParent) +dep(A/List[0]/B[1]:decl -> A:getChild[0]) +A/List[0] rewritten from A/List value(A/List[0]/B[0]:decl, A/List[0]/B[1]) value(A/List[0]/B[1]:decl, A/List[0]/B[0]) Dependencies/Cache after a.setChild(1): +A/List[0] rewritten from A/List Dependencies/Cache in replaced child: diff --git a/test/Test125.class b/test/Test125.class index 80fbbd3110b61369fd0338ef802e6bde5cbda4f1..eb39beffab671037eef2f359a7d0b8c186b1207f 100644 Binary files a/test/Test125.class and b/test/Test125.class differ diff --git a/test/Test125.java b/test/Test125.java index 0614c1c7df0d841b3df827da47b1ce300d125f04..036dfc2aae8e236289e0a260401763b88cb1aaa5 100644 --- a/test/Test125.java +++ b/test/Test125.java @@ -8,15 +8,13 @@ public class Test125 { B b1 = new B("b", "a"); B b2 = new B("a", "b"); - A a = new A(new test.ast.List().add(b1).add(b2)); - b1 = a.getB(0); b2 = a.getB(1); - b1.decl(); b2.decl(); + System.out.println("Dependencies/Cache after b1.decl and b2.decl:"); a.dumpDependencies(); a.getChild(0).dumpDependencies(); @@ -27,7 +25,6 @@ public class Test125 { b1.dumpCachedValues(); b2.dumpCachedValues(); - B b3 = new B("c", "b"); a.getChild(0).addChild(b3); diff --git a/test/Test125.result b/test/Test125.result index 10aae3b81eac0e667e5a083a00b374d8e7c11f70..be66789e27ec5dea4e0b2a9dffde25fe305c52d5 100644 --- a/test/Test125.result +++ b/test/Test125.result @@ -1,23 +1,26 @@ Dependencies/Cache after b1.decl and b2.decl: -dep(A/List[0]/B[0]:decl -> A:getChild[0]) -dep(A/List[0]/B[1]:decl -> A:getChild[0]) -dep(A/List[0]/B[0]:decl -> A/List[0]:getParent) -dep(A/List[0]/B[1]:decl -> A/List[0]:getParent) -dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[0]) -dep(A/List[0]/B[1]:decl -> A/List[0]:getChild[0]) -dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[1]) -dep(A/List[0]/B[1]:decl -> A/List[0]:getChild[1]) -dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getName) -dep(A/List[0]/B[1]:decl -> A/List[0]/B[0]:getName) -dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getUse) +dep(A:getChild[0] -> A/List[0]:getChild[0]) +dep(A:getChild[0] -> A/List[0]:getChild[1]) dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:a) -dep(A/List[0]/B[0]:a -> A/List[0]/B[0]:b) +dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getName) dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getParent) +dep(A/List[0]/B[0]:decl -> A/List[0]/B[0]:getUse) dep(A/List[0]/B[0]:decl -> A/List[0]/B[1]:getName) -dep(A/List[0]/B[1]:decl -> A/List[0]/B[1]:getUse) +dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[0]) +dep(A/List[0]/B[0]:decl -> A/List[0]:getChild[1]) +dep(A/List[0]/B[0]:decl -> A/List[0]:getParent) +dep(A/List[0]/B[0]:decl -> A:getChild[0]) +dep(A/List[0]/B[0]:a -> A/List[0]/B[0]:b) +dep(A/List[0]/B[1]:decl -> A/List[0]/B[0]:getName) dep(A/List[0]/B[1]:decl -> A/List[0]/B[1]:a) -dep(A/List[0]/B[1]:a -> A/List[0]/B[1]:b) dep(A/List[0]/B[1]:decl -> A/List[0]/B[1]:getParent) +dep(A/List[0]/B[1]:decl -> A/List[0]/B[1]:getUse) +dep(A/List[0]/B[1]:decl -> A/List[0]:getChild[0]) +dep(A/List[0]/B[1]:decl -> A/List[0]:getChild[1]) +dep(A/List[0]/B[1]:decl -> A/List[0]:getParent) +dep(A/List[0]/B[1]:decl -> A:getChild[0]) +dep(A/List[0]/B[1]:a -> A/List[0]/B[1]:b) +A/List[0] rewritten from A/List value(A/List[0]/B[0]:decl, A/List[0]/B[1]) value(A/List[0]/B[0]:a, false) value(A/List[0]/B[0]:b, false) @@ -25,10 +28,11 @@ value(A/List[0]/B[1]:decl, A/List[0]/B[0]) value(A/List[0]/B[1]:a, false) value(A/List[0]/B[1]:b, false) Dependencies/Cache after a.addChild(): -dep(A/List[0]/B[0]:a -> A/List[0]/B[0]:b) -dep(A/List[0]/B[1]:a -> A/List[0]/B[1]:b) -value(A/List[0]/B[0]:a, false) -value(A/List[0]/B[0]:b, false) -value(A/List[0]/B[1]:a, false) -value(A/List[0]/B[1]:b, false) +dep(A/List/B[0]:a -> A/List/B[0]:b) +dep(A/List/B[1]:a -> A/List/B[1]:b) +A/List[0] rewritten from A/List +value(A/List/B[0]:a, false) +value(A/List/B[0]:b, false) +value(A/List/B[1]:a, false) +value(A/List/B[1]:b, false)