diff --git a/dumpAst/src/main/jastadd/DumpAst.relast b/dumpAst/src/main/jastadd/DumpAst.relast index 3d76a4b0c5fb31fd428b970c8248da607f3126a8..e847a08ffc41780bfe91ed568cca77d094685cd9 100644 --- a/dumpAst/src/main/jastadd/DumpAst.relast +++ b/dumpAst/src/main/jastadd/DumpAst.relast @@ -4,8 +4,11 @@ rel DumpAst.RootNode? -> DumpNode ; DumpNode ::= DumpChildNode* DumpToken* DumpRelation* <Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> <Computed:boolean> <ManualStereotypes> /InvisiblePath/ ; + InnerDumpNode ; rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner ; +InnerRelationDumpNode; +rel InnerRelationDumpNode.DumpNode -> DumpNode ; // .ContainerOfInner* abstract DumpChildNode ::= <Name> <Computed:boolean> ; DumpNormalChildNode : DumpChildNode ; @@ -15,15 +18,16 @@ DumpListChildNode : DumpChildNode ::= InnerDumpNode* ; abstract DumpToken ::= <Name> <Computed:boolean> ; DumpReferenceToken : DumpToken ; rel DumpReferenceToken.Value -> DumpNode ; +DumpReferenceListToken : DumpToken ::= InnerRelationDumpNode* ; DumpValueToken : DumpToken ::= <Value:Object> ; abstract DumpRelation ::= <Name> <Bidirectional:boolean> ; DumpNormalRelation : DumpRelation ; rel DumpNormalRelation.DumpNode -> DumpNode ; -DumpListRelation : DumpRelation ::= InnerDumpNode* ; +DumpListRelation : DumpRelation ::= InnerRelationDumpNode* ; // type of NTA -InvisiblePath ::= InnerDumpNode* ; +InvisiblePath ::= InnerRelationDumpNode* ; ClassAnalysisResult ::= ContainmentMethod:AnalysedMethod* OtherMethod:AnalysedMethod* ; abstract AnalysedMethod ::= <Method:java.lang.reflect.Method> <Name> ; diff --git a/dumpAst/src/main/jastadd/GenerationBackend.jadd b/dumpAst/src/main/jastadd/GenerationBackend.jadd index fa8b0df9677e79d2ffa8f2553eb0acb9d38bf8e8..dace5302a2590a03acf86d82f867d88df0ba049f 100644 --- a/dumpAst/src/main/jastadd/GenerationBackend.jadd +++ b/dumpAst/src/main/jastadd/GenerationBackend.jadd @@ -11,7 +11,7 @@ aspect GenerationBackend { public boolean computed; public TransformationOptions asRelation() { - return fromSource(Source.RELATION, false); + return fromSource(Source.RELATION, false).allowNullObjectsOnce(); } public TransformationOptions asRoot() { @@ -192,7 +192,7 @@ aspect GenerationBackend { // -- singleRelation -- Object target = otherMethod.getMethod().invoke(obj); DumpNode targetNode = transform(tti, target, options.asRelation()); - if (target != null && targetNode != null) { + if (targetNode != null) { DumpNormalRelation normalRelation = new DumpNormalRelation(); normalRelation.setName(otherMethod.getName()); normalRelation.setDumpNode(targetNode); @@ -206,27 +206,52 @@ aspect GenerationBackend { for (Object target : targetList) { DumpNode targetNode = transform(tti, target, options.asRelation()); if (target != null && targetNode != null) { - listRelation.addInnerDumpNode(new InnerDumpNode(targetNode)); + listRelation.addInnerRelationDumpNode(new InnerRelationDumpNode(targetNode)); } } - if (listRelation.getNumInnerDumpNode() > 0) { + if (listRelation.getNumInnerRelationDumpNode() > 0) { node.addDumpRelation(listRelation); } } else if (otherMethod.isTokenMethod()) { // -- token -- Object target = otherMethod.getMethod().invoke(obj); +// java.util.function.Consumer<DumpToken> handleToken = token -> { +// token.setName(otherMethod.getName()); +// token.setComputed(otherMethod.asTokenMethod().isAttributeMethod()); +// node.addDumpToken(token); +// }; if (target != null) { - DumpNode targetNode = transform(tti, target, options.asRelation()); DumpToken token = null; - // TODO check, if Iterable.isAssignableFrom(target.getClass()). - // if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's - if (targetNode != null && targetNode.isAstNode()) { - token = new DumpReferenceToken().setValue(targetNode); - } else { - if (target != null && (getBuildConfig().getIncludeEmptyString() || !target.toString().isEmpty())) { - DumpValueToken valueToken = new DumpValueToken(); - valueToken.setValue(target); - token = valueToken; + boolean atLeastOneASTNode = false; + if (Iterable.class.isAssignableFrom(target.getClass())) { + java.util.List<DumpNode> nodes = new java.util.ArrayList<>(); + Iterable iterable = (Iterable) target; + for (Object element : iterable) { + // TODO check if isAstNode for first non-null. if yes, use DumpReferenceListToken, other DumpValueToken + DumpNode nodeForElement = transform(tti, element, options.asRelation()); + nodes.add(nodeForElement); + if (nodeForElement != null && nodeForElement.isAstNode()) { + atLeastOneASTNode = true; + } + } + if (atLeastOneASTNode) { + DumpReferenceListToken listToken = new DumpReferenceListToken(); + nodes.forEach(element -> { + listToken.addInnerRelationDumpNode(new InnerRelationDumpNode().setDumpNode(element)); + }); + token = listToken; + } + } + if (!atLeastOneASTNode) { + DumpNode targetNode = transform(tti, target, options.asRelation()); + if (targetNode != null && targetNode.isAstNode()) { + token = new DumpReferenceToken().setValue(targetNode); + } else { + if (getBuildConfig().getIncludeEmptyString() || !target.toString().isEmpty()) { + DumpValueToken valueToken = new DumpValueToken(); + valueToken.setValue(target); + token = valueToken; + } } } if (token != null) { @@ -584,7 +609,7 @@ aspect GenerationBackend { syn InvisiblePath DumpNode.getInvisiblePath() { InvisiblePath result = new InvisiblePath(); for (DumpNode successor : reachableThroughInvisible()) { - result.addInnerDumpNode(new InnerDumpNode(successor)); + result.addInnerRelationDumpNode(new InnerRelationDumpNode(successor)); } return result; } diff --git a/dumpAst/src/main/jastadd/GenerationToYaml.jrag b/dumpAst/src/main/jastadd/GenerationToYaml.jrag index 30a093c9f2495e68f4b552cedf9ce16d77e7ed06..a1dd78cc1444455a1e19bfc38af273722c55c0ce 100644 --- a/dumpAst/src/main/jastadd/GenerationToYaml.jrag +++ b/dumpAst/src/main/jastadd/GenerationToYaml.jrag @@ -26,14 +26,6 @@ aspect GenerationToYaml { return result; } - static void ASTNode.addYamledList(MappingElement base, String key, Iterable<? extends ASTNode<?>> iterable, boolean fromRelation) { - ListElement innerList = new ListElement(); - for (ASTNode node : iterable) { - innerList.add(safeToYaml(node, fromRelation)); - } - base.put(key, innerList); - } - syn MappingElement PrintConfig.toYaml(boolean fromRelation) { MappingElement result = new MappingElement(); // children @@ -128,6 +120,7 @@ aspect GenerationToYaml { result.put("name", getName()); result.put("computed", getComputed()); // attributes + result.put("isList", isList()); result.put("label", label()); result.put("isDumpValueToken", isDumpValueToken()); return result; @@ -142,12 +135,23 @@ aspect GenerationToYaml { syn MappingElement DumpReferenceToken.toYaml(boolean fromRelation) { MappingElement result = super.toYaml(fromRelation); - // tokens + // attributes result.put("innerNodeName", innerNodeName()); result.put("outerNodeName", outerNodeName()); return result; } + syn MappingElement DumpReferenceListToken.toYaml(boolean fromRelation) { + MappingElement result = super.toYaml(fromRelation); + + // children + addYamledList(result, "InnerRelationDumpNode", getInnerRelationDumpNodeList(), fromRelation); + + // attributes + result.put("outerNodeName", outerNodeName()); + return result; + } + syn MappingElement DumpRelation.toYaml(boolean fromRelation) { MappingElement result = new MappingElement(); // tokens @@ -171,7 +175,7 @@ aspect GenerationToYaml { syn MappingElement DumpListRelation.toYaml(boolean fromRelation) { MappingElement result = super.toYaml(fromRelation); // children - addYamledList(result, "InnerDumpNodes", getInnerDumpNodeList(), fromRelation); + addYamledList(result, "InnerRelationDumpNode", getInnerRelationDumpNodeList(), fromRelation); return result; } @@ -185,13 +189,31 @@ aspect GenerationToYaml { return result; } + syn MappingElement InnerRelationDumpNode.toYaml(boolean fromRelation) { + MappingElement result = new MappingElement(); + // attributes + result.put("bothVisible", bothVisible()); + result.put("innerNodeName", innerNodeName()); + result.put("outerNodeName", outerNodeName()); + result.put("label", label()); + return result; + } + syn MappingElement InvisiblePath.toYaml(boolean fromRelation) { MappingElement result = super.toYaml(fromRelation); // children - addYamledList(result, "InnerDumpNodes", getInnerDumpNodeList(), fromRelation); + addYamledList(result, "InnerRelationDumpNode", getInnerRelationDumpNodeList(), fromRelation); return result; } + static void ASTNode.addYamledList(MappingElement base, String key, Iterable<? extends ASTNode<?>> iterable, boolean fromRelation) { + ListElement innerList = new ListElement(); + for (ASTNode node : iterable) { + innerList.add(safeToYaml(node, fromRelation)); + } + base.put(key, innerList); + } + // extension for mustache public static ValueElement ValueElement.of(double value) { return new ValueElement(false, String.valueOf(value)); diff --git a/dumpAst/src/main/jastadd/Navigation.jrag b/dumpAst/src/main/jastadd/Navigation.jrag index c69141d3208bc5f99ee866d6417b043daaac9a03..656556f4f495fab814ed2c34e265341467d87746 100644 --- a/dumpAst/src/main/jastadd/Navigation.jrag +++ b/dumpAst/src/main/jastadd/Navigation.jrag @@ -4,6 +4,8 @@ aspect Navigation { eq DumpListChildNode.isList() = true; syn boolean DumpRelation.isList() = false; eq DumpListRelation.isList() = true; + syn boolean DumpToken.isList() = false; + eq DumpReferenceListToken.isList() = true; // --- buildConfig --- inh BuildConfig DumpNode.buildConfig(); @@ -16,10 +18,12 @@ aspect Navigation { // --- containingDumpNode --- inh DumpNode InnerDumpNode.containingDumpNode(); + inh DumpNode InnerRelationDumpNode.containingDumpNode(); inh DumpNode DumpChildNode.containingDumpNode(); inh DumpNode DumpRelation.containingDumpNode(); eq DumpNode.getDumpChildNode().containingDumpNode() = this; eq DumpNode.getDumpRelation().containingDumpNode() = this; + eq DumpNode.getDumpToken().containingDumpNode() = this; eq DumpNode.getInvisiblePath().containingDumpNode() = this; // --- container --- @@ -69,7 +73,7 @@ aspect Navigation { return java.util.Collections.emptyList(); } java.util.List<DumpNode> result = new java.util.ArrayList<>(); - getInnerDumpNodeList().forEach(inner -> { + getInnerRelationDumpNodeList().forEach(inner -> { if (!onlyVisible || !inner.getDumpNode().getInvisible()) { result.add(inner.getDumpNode()); } diff --git a/dumpAst/src/main/jastadd/Printing.jrag b/dumpAst/src/main/jastadd/Printing.jrag index 8fdcc8ee044699fabfbbdcd940c6f751cbad9f4b..6ae0af30b8273ed64d20e486035ef03b912f4844 100644 --- a/dumpAst/src/main/jastadd/Printing.jrag +++ b/dumpAst/src/main/jastadd/Printing.jrag @@ -1,13 +1,16 @@ aspect Printing { // --- outerNodeName --- inh String InnerDumpNode.outerNodeName(); + inh String InnerRelationDumpNode.outerNodeName(); inh String DumpChildNode.outerNodeName(); inh String DumpRelation.outerNodeName(); + inh String DumpToken.outerNodeName(); inh String DumpReferenceToken.outerNodeName(); eq DumpNode.getChild().outerNodeName() = name(); // --- innerNodeName --- syn String InnerDumpNode.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null; + syn String InnerRelationDumpNode.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null; syn String DumpNormalChildNode.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null; syn String DumpNormalRelation.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null; syn String DumpReferenceToken.innerNodeName() = getValue().name(); @@ -21,15 +24,18 @@ aspect Printing { syn String DumpToken.label() = getName() + (getComputed() ? "()" : ""); syn String DumpNode.label() = getLabel(); inh String InnerDumpNode.label(); + inh String InnerRelationDumpNode.label(); eq DumpListChildNode.getInnerDumpNode(int index).label() = label() + "[" + index + "]"; - eq DumpListRelation.getInnerDumpNode(int index).label() = label() + "[" + index + "]"; - eq InvisiblePath.getInnerDumpNode(int index).label() = null; + eq DumpListRelation.getInnerRelationDumpNode(int index).label() = label() + "[" + index + "]"; + eq DumpReferenceListToken.getInnerRelationDumpNode(int index).label() = label() + "[" + index + "]"; + eq InvisiblePath.getInnerRelationDumpNode(int index).label() = null; // --- bothVisible --- boolean ASTNode.bothVisible(DumpNode one, DumpNode two) { return one != null && two != null && !one.getInvisible() && !two.getInvisible(); } syn boolean InnerDumpNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode()); + syn boolean InnerRelationDumpNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode()); syn boolean DumpNormalChildNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode()); syn boolean DumpNormalRelation.bothVisible() = bothVisible(containingDumpNode(), getDumpNode()); } diff --git a/dumpAst/src/main/resources/dumpAst.mustache b/dumpAst/src/main/resources/dumpAst.mustache index a4c15afde2619529e104c4288b5d5fe80cf9244e..051cd8c7aa42b40c95aad024a87966aeb955f76d 100644 --- a/dumpAst/src/main/resources/dumpAst.mustache +++ b/dumpAst/src/main/resources/dumpAst.mustache @@ -37,9 +37,18 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun {{#DumpNodes}} {{#DumpTokens}} {{^invisible}} - {{^isDumpValueToken}} + {{#isList}} + {{#InnerRelationDumpNode}} + {{#bothVisible}} {{{outerNodeName}}} .{{#computed}}[#{{{computedColor}}}]{{/computed}}.> {{{innerNodeName}}} : {{{label}}} - {{/isDumpValueToken}} + {{/bothVisible}} + {{/InnerRelationDumpNode}} + {{/isList}} + {{^isList}} + {{^isDumpValueToken}} +{{{outerNodeName}}} .{{#computed}}[#{{{computedColor}}}]{{/computed}}.> {{{innerNodeName}}} : {{{label}}} + {{/isDumpValueToken}} + {{/isList}} {{/invisible}} {{/DumpTokens}} {{#DumpChildNodes}} @@ -58,11 +67,11 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun {{/DumpChildNodes}} {{#DumpRelations}} {{#isList}} - {{#InnerDumpNodes}} + {{#InnerRelationDumpNode}} {{#bothVisible}} {{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}--> {{{innerNodeName}}} : {{{label}}} {{/bothVisible}} - {{/InnerDumpNodes}} + {{/InnerRelationDumpNode}} {{/isList}} {{^isList}} {{#bothVisible}} @@ -72,9 +81,9 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun {{/DumpRelations}} {{^invisible}} {{#InvisiblePath}} - {{#InnerDumpNodes}} + {{#InnerRelationDumpNode}} {{{outerNodeName}}} o.. {{{innerNodeName}}} - {{/InnerDumpNodes}} + {{/InnerRelationDumpNode}} {{/InvisiblePath}} {{/invisible}} {{#PrintConfig}}{{#orderChildren}} diff --git a/dumpAst/src/main/resources/dumpAstVersion.properties b/dumpAst/src/main/resources/dumpAstVersion.properties index 6e2bce737359ddcd9a0a3f7bc29e7d8813e12751..bdaf3608801384e2c166884daa6df52e0dee9922 100644 --- a/dumpAst/src/main/resources/dumpAstVersion.properties +++ b/dumpAst/src/main/resources/dumpAstVersion.properties @@ -1,2 +1,2 @@ -#Mon May 16 18:32:38 CEST 2022 -version=1.0.2 +#Mon Jun 13 18:33:49 CEST 2022 +version=1.0.3 diff --git a/featureTest/build.gradle b/featureTest/build.gradle index e773bca511a3bab75e10e50ab30aa3074cbb9d40..21ca23ab47a643426503e7d188a03ac2add312b9 100644 --- a/featureTest/build.gradle +++ b/featureTest/build.gradle @@ -32,6 +32,7 @@ configurations { dependencies { implementation project(":dumpAst") + jastadd2 group: 'org.jastadd', name: 'jastadd2', version: '2.3.5-dresden' relast group: 'org.jastadd', name: 'relast', version: "${relast_version}" implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' diff --git a/featureTest/src/main/jastadd/featureTest.jrag b/featureTest/src/main/jastadd/featureTest.jrag index 4001126135dcb55faee01ca8edfc8c8f959f019f..9a158c1b6d03df5db880aa7ab63b373bc798e6a4 100644 --- a/featureTest/src/main/jastadd/featureTest.jrag +++ b/featureTest/src/main/jastadd/featureTest.jrag @@ -2,6 +2,7 @@ aspect GrammarGlobal { syn A C.getCalculated() { A result = new A(); result.setName("Calculated-" + getName()); + result.setB(new B().setName("B" + getName())); D innerD = new D(); result.setD(innerD); return result; @@ -18,6 +19,7 @@ aspect GrammarGlobal { syn nta A C.getCalculatedNewSyntax() { A result = new A(); result.setName("Calculated-" + getName()); + result.setB(new B().setName("B" + getName())); return result; } @@ -34,6 +36,11 @@ aspect GrammarGlobal { syn boolean ASTNode.isA() = false; eq A.isA() = true; + + coll java.util.Set<B> Root.collectBs() [new java.util.HashSet<>()] root Root ; + B contributes this to Root.collectBs(); + C contributes nta getAlsoCalculatedList() to Root.collectBs(); + C contributes nta getAlsoCalculatedListNewSyntax() to Root.collectBs(); } aspect GrammarTypeLevel { diff --git a/featureTest/src/main/jastadd/featureTest.relast b/featureTest/src/main/jastadd/featureTest.relast index 7b66cc96e3e0af88dd7c124928fca2ae86fa5e53..fa1c50ee8d1848f9aaa64306bc75ef70c89f8587 100644 --- a/featureTest/src/main/jastadd/featureTest.relast +++ b/featureTest/src/main/jastadd/featureTest.relast @@ -1,7 +1,7 @@ // testcases with global inclusion/exclusion Nameable ::= <Name> ; Root : Nameable ::= A B* [C]; -A : Nameable ::= B MyC:C D; +A : Nameable ::= B [MyC:C] [D]; B : Nameable ::= <OtherValue> ; C : Nameable ::= [A] <Unwanted:int> <RawReference:A> /Calculated:A/ /AlsoCalculated:B*/ ; SubC : C ::= <RawReference:A> <Unwanted:int> [A] /Calculated:A/ /AlsoCalculated:B*/ ; diff --git a/featureTest/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java b/featureTest/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java index 298298c64c1ce5ff4f1a646c9aaacc2c465cf70f..1a8177de6d48e67885d1ed73f0e879018d7289c5 100644 --- a/featureTest/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java +++ b/featureTest/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java @@ -8,6 +8,8 @@ import org.jastadd.featureTest.ast.*; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.function.Consumer; +import java.util.function.Function; /** * Main class of feature test. @@ -19,18 +21,17 @@ public class FeatureTestMain { public static void main(String[] args) throws IOException { Root root = new Root(); root.setName("Root1"); - A a = new A(); - a.setName("A2"); - B b1 = new B(); - b1.setName("B3"); - C c = new C(); - c.setName("C4"); + A a = new A().setName("A2"); + a.setB(new B().setName("B2.1")); + a.setMyC(new C().setName("C2.1")); + B b1 = new B().setName("B3"); + C c = new C().setName("C4"); + c.setA(new A().setName("A4.1").setB(new B().setName("B4.1.1"))); c.setRawReference(a); b1.setOneA(a); - B b2 = new B(); - b2.setName("B5"); - C myC = new C(); - myC.setName("C6"); + B b2 = new B().setName("B5"); + C myC = new C().setName("C6"); + c.setA(new A().setName("A6.1").setB(new B().setName("B6.1.1"))); a.setMyC(myC); root.setA(a); root.addB(b1); @@ -45,7 +46,9 @@ public class FeatureTestMain { .read(root) // .customPreamble("hide empty members") .skinParam(SkinParamBooleanSetting.Shadowing, false) - .includeAttributes("referenceAttr") + .includeAttributes("referenceAttr" + , "collectBs" + ) .includeNonterminalAttributes("Calculated") .includeNonterminalAttributes("AlsoCalculatedListNewSyntax") .dumpAsYaml(pathToYaml, true) diff --git a/testDumper/src/main/jastadd/testDumper.jrag b/testDumper/src/main/jastadd/testDumper.jrag index 4cedce8cfa75749d2fb90adcb0ef5766e36e0ca1..a4e17a122827b1b54a814ddd453014a9b8beda0f 100644 --- a/testDumper/src/main/jastadd/testDumper.jrag +++ b/testDumper/src/main/jastadd/testDumper.jrag @@ -32,6 +32,12 @@ aspect GrammarGlobal { syn boolean ASTNode.isA() = false; eq A.isA() = true; + + syn Object Root.setOfBs() { + java.util.Set<B> result = new java.util.HashSet<>(); + getBList().forEach(result::add); + return result; + } } aspect GrammarTypeLevel { diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestIncluded.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestIncluded.java index cd6e5c83fc191d797b0b3cb8901749f28c840773..0d5dce44733c11890fa8d345c310c3fcbe1ead61 100644 --- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestIncluded.java +++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestIncluded.java @@ -31,6 +31,18 @@ public class TestIncluded { assertThat(valueTokens(actualRoot)).containsOnly(entry("Name", ROOT_NAME), entry("simpleAttr", 42)); } + @Test + public void testReferenceListAttributeIncluded() { + Root root = createRoot(null, null, createB(B1_NAME), createB(B2_NAME), createB(B3_NAME)); + + List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.includeAttributes("setOfBs")); + assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME, B1_NAME, B2_NAME, B3_NAME); + + DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME); + assertThatMapOf(referenceListTokens(actualRoot), "setOfBs").containsOnly( + B1_NAME, B2_NAME, B3_NAME); + } + @Test public void testReferenceAttributeDefault() { Root root = createRoot(createA(A_NAME), null); diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java index ec0037e8f3fc280319a172fe49467c7447251868..8a10b40c290454c154ea0c1ab9d978d279e96952 100644 --- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java +++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java @@ -74,14 +74,24 @@ public class TestSimple { List<DumpNode> nodes = TestUtils.dumpModel(root, DumpBuilder::includeNullNodes); assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder( - ROOT_NAME, A_NAME, null, null, null, null); + ROOT_NAME, A_NAME, + null, // C in Root + null, // B in A + null, // MyC in A + null, // D in A + null, // BiC2 in A + null, // BiC1 in A + null // BiC3 in A + ); DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME); assertEquals(1, actualRoot.getNumDumpToken()); assertEquals(2, actualRoot.getNumDumpChildNode()); assertEquals(0, actualRoot.getNumDumpRelation()); DumpNode actualA = TestUtils.findByName(nodes, A_NAME); + assertEquals(1, actualA.getNumDumpToken()); assertEquals(3, actualA.getNumDumpChildNode()); + assertEquals(3, actualA.getNumDumpRelation()); } @Test diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java index b3e8fa92d7ddfcefc0331facc0d27e228f6363b8..9d76fca579ef4856ee7279949de341c7a48a4afc 100644 --- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java +++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java @@ -229,7 +229,7 @@ public class TestUtils { for (DumpRelation dumpRelation : node.getDumpRelationList()) { if (dumpRelation.isList()) { // then it is a DumpListRelation - ((DumpListRelation) dumpRelation).getInnerDumpNodeList().forEach(inner -> { + ((DumpListRelation) dumpRelation).getInnerRelationDumpNodeList().forEach(inner -> { if (!inner.getDumpNode().getInvisible()) { result.computeIfAbsent(dumpRelation.getName(), key -> new ArrayList<>()).add(inner.getDumpNode()); } @@ -242,7 +242,7 @@ public class TestUtils { public static Map<String, DumpNode> referenceTokens(DumpNode node) { Map<String, DumpNode> result = new HashMap<>(); for (DumpToken dumpToken : node.getDumpTokenList()) { - if (!dumpToken.isDumpValueToken()) { + if (!dumpToken.isDumpValueToken() && !dumpToken.isList()) { // then it is a DumpReferenceToken DumpNode target = ((DumpReferenceToken) dumpToken).getValue(); if (!target.getInvisible()) { @@ -253,6 +253,21 @@ public class TestUtils { return result; } + public static Map<String, List<DumpNode>> referenceListTokens(DumpNode node) { + Map<String, List<DumpNode>> result = new HashMap<>(); + for (DumpToken dumpToken : node.getDumpTokenList()) { + if (!dumpToken.isDumpValueToken() && dumpToken.isList()) { + // then it is a DumpReferenceListToken + ((DumpReferenceListToken) dumpToken).getInnerRelationDumpNodeList().forEach(inner -> { + if (!inner.getDumpNode().getInvisible()) { + result.computeIfAbsent(dumpToken.getName(), key -> new ArrayList<>()).add(inner.getDumpNode()); + } + }); + } + } + return result; + } + public static Map<String, Object> valueTokens(DumpNode node) { Map<String, Object> result = new HashMap<>(); for (DumpToken dumpToken : node.getDumpTokenList()) { @@ -267,7 +282,7 @@ public class TestUtils { public static List<DumpNode> invisiblePath(DumpNode node) { List<DumpNode> result = new ArrayList<>(); - for (InnerDumpNode inner : node.getInvisiblePath().getInnerDumpNodeList()) { + for (InnerRelationDumpNode inner : node.getInvisiblePath().getInnerRelationDumpNodeList()) { DumpNode target = inner.getDumpNode(); assertFalse(target.getInvisible()); result.add(target);