Skip to content
Snippets Groups Projects
Commit e118f631 authored by René Schöne's avatar René Schöne
Browse files

Make order of children configurable.

- let user activate children ordering
parent 5f40f8c3
No related branches found
No related tags found
2 merge requests!60.3.6,!4Resolve "Keep order of children"
Pipeline #12732 passed
......@@ -6,16 +6,16 @@ TypePatternCollectionMapping ::= <TypeRegex> PatternCollection ;
PatternCollection ::= <TokenPattern> <ChildPattern> <RelationPattern> <AttributePattern> <NonterminalAttributePattern> ;
StyleInformation ::= <NameMethod:StyleMethod> <BackgroundColorMethod:StyleMethod> <TextColorMethod:StyleMethod>;
PrintConfig ::= <Scale:double> <Version> Header* ;
PrintConfig ::= <Scale:double> <Version> <OrderChildren:boolean> Header* ;
Header ::= <Value> ;
DumpNode ::= <Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> DumpChildNode* DumpToken* DumpRelation* /InvisiblePath/ ;
InnerDumpNode ;
rel InnerDumpNode.DumpNode -> DumpNode ;
rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner ;
abstract DumpChildNode ::= <Name> <Computed:boolean> ;
DumpNormalChildNode : DumpChildNode ;
rel DumpNormalChildNode.DumpNode -> DumpNode ;
rel DumpNormalChildNode.DumpNode <-> DumpNode.ContainerOfNormalChild ;
DumpListChildNode : DumpChildNode ::= InnerDumpNode* ;
abstract DumpToken ::= <Name> <Computed:boolean> ;
......
......@@ -453,6 +453,7 @@ aspect GenerationBackend {
return result;
}
// --- labelAndTextColor ---
syn String DumpNode.labelAndTextColor() {
if (getTextColor().isEmpty()) {
return getLabel();
......@@ -461,35 +462,41 @@ aspect GenerationBackend {
}
}
// --- myChildren ---
syn java.util.List<DumpNode> DumpNode.myChildren() {
java.util.List<DumpNode> result = new java.util.ArrayList<>();
for (DumpChildNode childNode : getDumpChildNodeList()) {
for (DumpNode inner : childNode.innerNodes(true)) {
result.add(inner);
}
}
return result;
}
// --- successor ---
syn DumpNode DumpNode.successor() {
if (container() == null) {
// not contained
return null;
}
java.util.List<DumpNode> siblingsAndMe = container().myChildren();
int indexOfMe = siblingsAndMe.indexOf(this);
if (indexOfMe == siblingsAndMe.size() - 1) {
// last child
return null;
}
return siblingsAndMe.get(indexOfMe + 1);
}
// --- hasSuccessor ---
syn boolean DumpNode.hasSuccessor() = successor() != null;
class TransformationTransferInformation {
java.util.Map<Object, DumpNode> transformed = new java.util.HashMap<>();
java.util.Map<DumpNode, Boolean> relationTargetsUnprocessed = new java.util.HashMap<>();
}
syn String DumpAst.toPlantUml() {
StringBuilder sb = new StringBuilder();
com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() {
@Override
public com.github.mustachejava.Binding createBinding(String name, final com.github.mustachejava.TemplateContext tc, com.github.mustachejava.Code code) {
return new com.github.mustachejava.reflect.GuardedBinding(this, name, tc, code) {
@Override
protected synchronized com.github.mustachejava.util.Wrapper getWrapper(String name, java.util.List<Object> scopes) {
com.github.mustachejava.util.Wrapper wrapper = super.getWrapper(name, scopes);
if (wrapper instanceof com.github.mustachejava.reflect.MissingWrapper) {
throw new com.github.mustachejava.MustacheException(name + " not found in " + tc);
}
return wrapper;
}
};
}
};
com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
mf.setObjectHandler(roh);
com.github.mustachejava.Mustache m = mf.compile("dumpAst.mustache");
m.execute(new java.io.PrintWriter(new AppendableWriter(sb)), this);
return sb.toString();
}
syn String DumpAst.toYaml(boolean prependCreationComment) {
Document doc = new Document();
doc.setRootElement(getRootNode().toYaml());
......
......@@ -342,6 +342,11 @@ public class DumpBuilder {
return this;
}
public DumpBuilder orderChildren() {
printConfig.setOrderChildren(true);
return this;
}
private String readVersion() {
try {
java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("dumpAstVersion");
......
aspect GenerationMustache {
syn String DumpAst.toPlantUml() {
StringBuilder sb = new StringBuilder();
com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() {
@Override
public com.github.mustachejava.Binding createBinding(String name, final com.github.mustachejava.TemplateContext tc, com.github.mustachejava.Code code) {
return new com.github.mustachejava.reflect.GuardedBinding(this, name, tc, code) {
@Override
protected synchronized com.github.mustachejava.util.Wrapper getWrapper(String name, java.util.List<Object> scopes) {
com.github.mustachejava.util.Wrapper wrapper = super.getWrapper(name, scopes);
if (wrapper instanceof com.github.mustachejava.reflect.MissingWrapper) {
throw new com.github.mustachejava.MustacheException(name + " not found in " + tc);
}
return wrapper;
}
};
}
};
com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
mf.setObjectHandler(roh);
com.github.mustachejava.Mustache m = mf.compile("dumpAst.mustache");
m.execute(new java.io.PrintWriter(new AppendableWriter(sb)), this);
return sb.toString();
}
}
......@@ -33,6 +33,17 @@ aspect Navigation {
eq DumpNode.getDumpRelation().containingDumpNode() = this;
eq DumpNode.getInvisiblePath().containingDumpNode() = this;
// --- container ---
syn DumpNode DumpNode.container() {
if (getContainerOfNormalChild() != null) {
return getContainerOfNormalChild().containingDumpNode();
}
if (getContainerOfInner() != null) {
return getContainerOfInner().containingDumpNode();
}
return null;
}
// --- innerVisibleNodes ---
syn java.util.List<DumpNode> DumpChildNode.innerVisibleNodes() = innerNodes(true);
syn java.util.List<DumpNode> DumpRelation.innerVisibleNodes() = innerNodes(true);
......
......@@ -63,6 +63,13 @@ object "{{{labelAndTextColor}}}" as {{name}} {{#backgroundColor}}#{{{backgroundC
{{/InnerDumpNodes}}
{{/InvisiblePath}}
{{/Invisible}}
{{#PrintConfig}}{{#orderChildren}}
{{#myChildren}}
{{#hasSuccessor}}
{{name}} -[hidden]right-> {{#successor}}{{name}}{{/successor}}
{{/hasSuccessor}}
{{/myChildren}}
{{/orderChildren}}{{/PrintConfig}}
{{/DumpNodes}}
{{#BuildConfig}}
{{#Debug}}
......
package de.tudresden.inf.st.jastadd.testDumper;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpAst;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode;
import org.jastadd.testDumper.ast.A;
import org.jastadd.testDumper.ast.B;
import org.jastadd.testDumper.ast.C;
import org.jastadd.testDumper.ast.Root;
import java.util.stream.Collectors;
public class TestDumperMain {
public static void main(String[] args) {
Root root = new Root();
......@@ -29,14 +33,20 @@ public class TestDumperMain {
TestUtils.ExposingDumpBuilder builder = new TestUtils.ExposingDumpBuilder(root);
builder.includeAttributes("simpleAttr")
.includeNonterminalAttributes("getCalculated");
builder.setNameMethod(n -> n.getClass().getSimpleName());
.orderChildren()
.includeNonterminalAttributes("getCalculated")
.setNameMethod(n -> n.getClass().getSimpleName());
System.out.println(">> PlantUml");
System.out.println(builder.build().toPlantUml());
DumpAst dumpAst = builder.build();
System.out.println(dumpAst.toPlantUml());
DumpNode node = dumpAst.getDumpNode(0);
System.out.println(node.getName());
System.out.println(node.myChildren().stream().map(DumpNode::getName).collect(Collectors.joining(", ")));
System.out.println(">> YAML begin");
System.out.println(builder.build().toYaml(true));
System.out.println(">> YAML end");
// System.out.println(">> YAML begin");
// System.out.println(builder.build().toYaml(true));
// System.out.println(">> YAML end");
}
}
package de.tudresden.inf.st.jastadd.testDumper;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpAst;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpBuilder;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode;
import org.jastadd.testDumper.ast.*;
import org.junit.jupiter.api.Test;
......@@ -60,6 +62,22 @@ public class TestSimple {
assertThatMapOf(listChildren(actualRoot), "B").containsExactlyInAnyOrder(B1_NAME, B2_NAME, B3_NAME);
}
@Test
public void testOrderedListChildren() {
Root root = createRoot(null, null, createB(B1_NAME), createB(B2_NAME), createB(B3_NAME));
List<DumpNode> nodes = TestUtils.dumpModel(root, DumpBuilder::orderChildren);
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, B1_NAME, B2_NAME, B3_NAME);
DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
// in grammar: DumpAst ::= [...] DumpNode* [...];
// use getParent() twice as first returns JastAddList for DumpNode list
assertTrue(((DumpAst) actualRoot.getParent().getParent()).getPrintConfig().getOrderChildren());
List<DumpNode> children = actualRoot.myChildren();
assertThat(children).extracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(B1_NAME, B2_NAME, B3_NAME);
}
@Test
public void testOneOptChild() {
Root root = createRoot(null, createC(C_NAME));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment