diff --git a/dumpAst.base/build.gradle b/dumpAst.base/build.gradle index c813e63f6966f638e106498364ffb4498ff60f4f..88ccfde78f90ad7ccb280fab03e417a534ccced3 100644 --- a/dumpAst.base/build.gradle +++ b/dumpAst.base/build.gradle @@ -179,6 +179,15 @@ publishing { } } +// --- Misc --- +task ensureNoTrainlingNewlineForRelationStyleMustache() { + doFirst { + def text = project.file("src/main/resources/RelationStyle.mustache").text + project.file("src/main/resources/RelationStyle.mustache").write(text.strip()) + } +} + // --- Task order --- +compileJava.dependsOn ensureNoTrainlingNewlineForRelationStyleMustache generateAst.dependsOn relast publish.dependsOn jar diff --git a/dumpAst.base/src/main/jastadd/DumpAst.relast b/dumpAst.base/src/main/jastadd/DumpAst.relast index f66e04b7aca3b740004a7fc24dea2584a19945f9..5abf5872ff94270d670b9d1acd747019560d025f 100644 --- a/dumpAst.base/src/main/jastadd/DumpAst.relast +++ b/dumpAst.base/src/main/jastadd/DumpAst.relast @@ -5,24 +5,24 @@ DumpNode ::= DumpChildNode* DumpToken* DumpRelation* <Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> <Computed:boolean> <ManualStereotypes> /InvisiblePath/ ; -InnerDumpNode ::= <OriginalIndex:int> <Label> <TextColor> ; +InnerDumpNode ::= <OriginalIndex:int> <Label> <LineColor> <TextColor> ; rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner? ; -InnerRelationDumpNode ::= <OriginalIndex:int> <Label> <TextColor> ; +InnerRelationDumpNode ::= <OriginalIndex:int> <Label> <LineColor> <TextColor> ; rel InnerRelationDumpNode.DumpNode <-> DumpNode.ContainerOfRelationInner* ; -abstract DumpChildNode ::= <Name> <Computed:boolean> ; -DumpNormalChildNode : DumpChildNode ::= <TextColor> ; +abstract DumpChildNode ::= <Label> <Computed:boolean> ; +DumpNormalChildNode : DumpChildNode ::= <LineColor> <TextColor> ; rel DumpNormalChildNode.DumpNode <-> DumpNode.ContainerOfNormalChild? ; DumpListChildNode : DumpChildNode ::= InnerDumpNode* ; -abstract DumpToken ::= <Name> <Computed:boolean> ; +abstract DumpToken ::= <Label> <Computed:boolean> ; DumpReferenceToken : DumpToken ; rel DumpReferenceToken.Value -> DumpNode ; DumpReferenceListToken : DumpToken ::= InnerRelationDumpNode* ; DumpValueToken : DumpToken ::= <Value:Object> ; -abstract DumpRelation ::= <Name> <Bidirectional:boolean> ; -DumpNormalRelation : DumpRelation ::= <TextColor> ; +abstract DumpRelation ::= <Label> <Bidirectional:boolean> ; +DumpNormalRelation : DumpRelation ::= <LineColor> <TextColor> ; rel DumpNormalRelation.DumpNode -> DumpNode ; DumpListRelation : DumpRelation ::= InnerRelationDumpNode* ; @@ -74,4 +74,4 @@ PrintConfig ::= Header* Header ::= <Value> ; NodeStyle ::= <Label> <BackgroundColor> <TextColor> <StereoTypes> ; -RelationStyle ::= <Label> <TextColor> ; +RelationStyle ::= <Label> <LineColor> <TextColor> ; diff --git a/dumpAst.base/src/main/jastadd/Frontend.jrag b/dumpAst.base/src/main/jastadd/Frontend.jrag index 86f36a3f6e537553bb68ea6ccce519ff38992897..41319aa812239c1a3e8b273e7aaf6740065912ec 100644 --- a/dumpAst.base/src/main/jastadd/Frontend.jrag +++ b/dumpAst.base/src/main/jastadd/Frontend.jrag @@ -12,7 +12,7 @@ aspect Frontend { @FunctionalInterface public interface RelationStyleDefinition<ASTNODE> { - void style(ASTNODE source, ASTNODE target, String context, RelationStyle style); + void style(ASTNODE source, ASTNODE target, RelationStyle style); } public void NodeStyle.useSimpleLabel() { diff --git a/dumpAst.base/src/main/jastadd/Printing.jrag b/dumpAst.base/src/main/jastadd/Printing.jrag index eb16c8074de6935e485db0ad0d0d089fd3d97b41..6325c9da6411abefd31a5b8df62631c4d18ff8bd 100644 --- a/dumpAst.base/src/main/jastadd/Printing.jrag +++ b/dumpAst.base/src/main/jastadd/Printing.jrag @@ -19,9 +19,9 @@ aspect Printing { syn String DumpNode.name() = getName(); // might change in the future // --- label --- - syn String DumpChildNode.label() = getName() + (getComputed() ? "()" : ""); - syn String DumpRelation.label() = getName(); - syn String DumpToken.label() = getName() + (getComputed() ? "()" : ""); + syn String DumpChildNode.label() = getLabel() + (getComputed() ? "()" : ""); + syn String DumpRelation.label() = getLabel(); + syn String DumpToken.label() = getLabel() + (getComputed() ? "()" : ""); syn String DumpNode.label() = getLabel(); inh String InnerDumpNode.label(); inh String InnerRelationDumpNode.label(); diff --git a/dumpAst.base/src/main/jastadd/TemplateContext.jrag b/dumpAst.base/src/main/jastadd/TemplateContext.jrag index a559311c3c6fb8ae58a93cf19ea72a1b81ba5936..0f313732f5d521d08a2b8b29d1f5331137638bb3 100644 --- a/dumpAst.base/src/main/jastadd/TemplateContext.jrag +++ b/dumpAst.base/src/main/jastadd/TemplateContext.jrag @@ -60,6 +60,12 @@ aspect TemplateContext { } } + // --- hasLineColor --- + syn boolean InnerDumpNode.needRelationStyling() = !getLineColor().isEmpty() || !getTextColor().isEmpty(); + syn boolean InnerRelationDumpNode.needRelationStyling() = !getLineColor().isEmpty() || !getTextColor().isEmpty(); + syn boolean DumpNormalChildNode.needRelationStyling() = !getLineColor().isEmpty() || !getTextColor().isEmpty(); + syn boolean DumpNormalRelation.needRelationStyling() = !getLineColor().isEmpty() || !getTextColor().isEmpty(); + // --- stereotypeList --- syn String DumpNode.stereotypeList() { StringBuilder sb = new StringBuilder(getManualStereotypes()); diff --git a/dumpAst.base/src/main/jastadd/ToYaml.jrag b/dumpAst.base/src/main/jastadd/ToYaml.jrag index ba9c7e8b72bde8a6112ee63a2c374176ef664fa6..51f5eee938fd792a6b1d027b8c4bd307dfe8acc2 100644 --- a/dumpAst.base/src/main/jastadd/ToYaml.jrag +++ b/dumpAst.base/src/main/jastadd/ToYaml.jrag @@ -32,9 +32,9 @@ aspect ToYaml { addYamledList(result, "Headers", getHeaderList(), fromRelation); // tokens - result.put("scale", getScale()); - result.put("version", getVersion()); - result.put("orderChildren", getOrderChildren()); + result.put("Scale", getScale()); + result.put("Version", getVersion()); + result.put("OrderChildren", getOrderChildren()); // attributes result.put("debug", debug()); @@ -44,7 +44,7 @@ aspect ToYaml { syn MappingElement Header.toYaml(boolean fromRelation) { MappingElement result = new MappingElement(); // tokens - result.put("value", getValue()); + result.put("Value", getValue()); return result; } @@ -59,13 +59,13 @@ aspect ToYaml { } // tokens - result.put("name", getName()); + result.put("Name", getName()); if (!fromRelation) { - result.put("computed", getComputed()); - result.put("label", getLabel()); - result.put("backgroundColor", getBackgroundColor()); - result.put("textColor", getTextColor()); - result.put("invisible", getInvisible()); + result.put("Computed", getComputed()); + result.put("Label", getLabel()); + result.put("BackgroundColor", getBackgroundColor()); + result.put("TextColor", getTextColor()); + result.put("Invisible", getInvisible()); } // attributes @@ -90,8 +90,8 @@ aspect ToYaml { syn MappingElement DumpChildNode.toYaml(boolean fromRelation) { MappingElement result = new MappingElement(); // tokens - result.put("name", getName()); - result.put("computed", getComputed()); + result.put("Label", getLabel()); + result.put("Computed", getComputed()); // attributes result.put("label", label()); result.put("isList", isList()); @@ -102,9 +102,13 @@ aspect ToYaml { syn MappingElement DumpNormalChildNode.toYaml(boolean fromRelation) { MappingElement result = super.toYaml(fromRelation); + // tokens + result.put("LineColor", getLineColor()); + result.put("TextColor", getTextColor()); // attributes result.put("bothVisible", bothVisible()); result.put("innerNodeName", innerNodeName()); + result.put("needRelationStyling", needRelationStyling()); return result; } @@ -118,8 +122,8 @@ aspect ToYaml { syn MappingElement DumpToken.toYaml(boolean fromRelation) { MappingElement result = new MappingElement(); // tokens - result.put("name", getName()); - result.put("computed", getComputed()); + result.put("Label", getLabel()); + result.put("Computed", getComputed()); // attributes result.put("isList", isList()); result.put("label", label()); @@ -130,7 +134,7 @@ aspect ToYaml { syn MappingElement DumpValueToken.toYaml(boolean fromRelation) { MappingElement result = super.toYaml(fromRelation); // tokens - result.put("value", getValue().toString()); + result.put("Value", getValue().toString()); return result; } @@ -157,8 +161,8 @@ aspect ToYaml { syn MappingElement DumpRelation.toYaml(boolean fromRelation) { MappingElement result = new MappingElement(); // tokens - result.put("name", getName()); - result.put("bidirectional", getBidirectional()); + result.put("Label", getLabel()); + result.put("Bidirectional", getBidirectional()); // attributes result.put("isList", isList()); result.put("label", label()); @@ -168,10 +172,14 @@ aspect ToYaml { syn MappingElement DumpNormalRelation.toYaml(boolean fromRelation) { MappingElement result = super.toYaml(fromRelation); + // tokens + result.put("LineColor", getLineColor()); + result.put("TextColor", getTextColor()); // attributes result.put("bothVisible", bothVisible()); result.put("innerNodeName", innerNodeName()); result.put("innerNotNullOrEmpty", innerNotNullOrEmpty()); + result.put("needRelationStyling", needRelationStyling()); return result; } @@ -184,22 +192,30 @@ aspect ToYaml { syn MappingElement InnerDumpNode.toYaml(boolean fromRelation) { MappingElement result = new MappingElement(); + // tokens + result.put("LineColor", getLineColor()); + result.put("TextColor", getTextColor()); // attributes result.put("bothVisible", bothVisible()); result.put("innerNodeName", innerNodeName()); result.put("outerNodeName", outerNodeName()); result.put("label", label()); + result.put("needRelationStyling", needRelationStyling()); return result; } syn MappingElement InnerRelationDumpNode.toYaml(boolean fromRelation) { MappingElement result = new MappingElement(); + // tokens + result.put("LineColor", getLineColor()); + result.put("TextColor", getTextColor()); // attributes result.put("bothVisible", bothVisible()); result.put("innerNodeName", innerNodeName()); result.put("innerNotNullOrEmpty", innerNotNullOrEmpty()); result.put("outerNodeName", outerNodeName()); result.put("label", label()); + result.put("needRelationStyling", needRelationStyling()); return result; } diff --git a/dumpAst.base/src/main/jastadd/Transform.jadd b/dumpAst.base/src/main/jastadd/Transform.jadd index c30ecbc9a4e9eb328f39ad7aa5cb5701eb31bc8f..f0468843188d59aa1c03112690c6e1b31a2c1637 100644 --- a/dumpAst.base/src/main/jastadd/Transform.jadd +++ b/dumpAst.base/src/main/jastadd/Transform.jadd @@ -172,7 +172,7 @@ aspect Transform { DumpNode targetNode = transform(tti, target, options.asNormal(false).allowNullObjectsOnce()); if (targetNode != null) { DumpNormalChildNode normalChild = new DumpNormalChildNode(); - normalChild.setName(childName + (containmentMethod.isOptChildMethod() ? "?" : "")); + normalChild.setLabel(childName + (containmentMethod.isOptChildMethod() ? "?" : "")); normalChild.setDumpNode(targetNode); normalChild.setComputed(false); node.addDumpChildNode(normalChild); @@ -189,7 +189,7 @@ aspect Transform { DumpListChildNode listChild = new DumpListChildNode(); listChild.setComputed(false); String childName = containmentMethod.getName(); - listChild.setName(childName); + listChild.setLabel(childName); node.addDumpChildNode(listChild); int index = -1; @@ -229,7 +229,7 @@ aspect Transform { DumpNode targetNode = transform(tti, otherMethod.getMethod().invoke(obj), options.asNormal(false).computed(computed).allowNullObjectsOnce()); if (targetNode != null) { DumpNormalChildNode normalChild = new DumpNormalChildNode(); - normalChild.setName(childName); + normalChild.setLabel(childName); normalChild.setDumpNode(targetNode); normalChild.setComputed(computed); node.addDumpChildNode(normalChild); @@ -251,7 +251,7 @@ aspect Transform { DumpListChildNode listChild = new DumpListChildNode(); boolean computed = otherMethod.asListChildMethod().isNTAListChildMethod(); listChild.setComputed(computed); - listChild.setName(childName); + listChild.setLabel(childName); boolean notAddedYet = true; for (Object target : targetList) { DumpNode targetNode = transform(tti, target, options.asNormal(false).computed(computed)); @@ -280,7 +280,7 @@ aspect Transform { DumpNode targetNode = transform(tti, target, options.asRelation()); if (targetNode != null) { DumpNormalRelation normalRelation = new DumpNormalRelation(); - normalRelation.setName(otherMethod.getName() + + normalRelation.setLabel(otherMethod.getName() + (otherMethod.asSingleRelationMethod().isOptRelationMethod() ? "?" : "")); normalRelation.setDumpNode(targetNode); node.addDumpRelation(normalRelation); @@ -295,7 +295,7 @@ aspect Transform { // -- listRelation -- Iterable<?> targetList = (Iterable<?>) otherMethod.getMethod().invoke(obj); DumpListRelation listRelation = new DumpListRelation(); - listRelation.setName(otherMethod.getName()); + listRelation.setLabel(otherMethod.getName()); node.addDumpRelation(listRelation); int index = -1; @@ -367,7 +367,7 @@ aspect Transform { } } if (token != null) { - token.setName(otherMethod.getName()); + token.setLabel(otherMethod.getName()); token.setComputed(otherMethod.asTokenMethod().isAttributeMethod()); node.addDumpToken(token); } @@ -405,52 +405,38 @@ aspect Transform { } // === RelationStyle === - RelationStyle DumpNormalChildNode.createDefaultStyle() { - return new RelationStyle().setLabel(getName()); + interface RelationStylable<SELF> { + default RelationStyle createDefaultStyle() { + return new RelationStyle().setLabel(initialLabel()); + } + default void applyStyle(RelationStyleDefinition relationStyleDefinition) { + RelationStyle style = createDefaultStyle(); + relationStyleDefinition.style(containingDumpNode().getObject(), getDumpNode().getObject(), style); + setLabel(style.getLabel()); + setTextColor(style.getTextColor()); + setLineColor(style.getLineColor()); + } + String initialLabel(); + DumpNode containingDumpNode(); + DumpNode getDumpNode(); + SELF setLabel(String name); + SELF setTextColor(String textColor); + SELF setLineColor(String lineColor); } + DumpNormalChildNode implements RelationStylable<DumpNormalChildNode>; + syn String DumpNormalChildNode.initialLabel() = getLabel(); - RelationStyle InnerDumpNode.createDefaultStyle() { - return new RelationStyle().setLabel(containingDumpListChildNode().getName()); - } + InnerDumpNode implements RelationStylable<InnerDumpNode>; + syn String InnerDumpNode.initialLabel() = containingDumpListChildNode().getLabel(); - RelationStyle DumpNormalRelation.createDefaultStyle() { - return new RelationStyle().setLabel(getName()); - } + DumpNormalRelation implements RelationStylable<DumpNormalRelation>; + syn String DumpNormalRelation.initialLabel() = getLabel(); - RelationStyle InnerRelationDumpNode.createDefaultStyle() { - return new RelationStyle().setLabel(containingDumpListRelation().getName()); - } + InnerRelationDumpNode implements RelationStylable<InnerRelationDumpNode>; + syn String InnerRelationDumpNode.initialLabel() = containingDumpListRelation().getLabel(); - private void DumpAst.applyStyle(DumpNormalChildNode node) { - RelationStyle style = node.createDefaultStyle(); - getPrintConfig().getRelationStyleDefinition().style(node.containingDumpNode().getObject(), - node.getDumpNode().getObject(), node.getName(), style); - node.setName(style.getLabel()); - node.setTextColor(style.getTextColor()); - } - - private void DumpAst.applyStyle(InnerDumpNode node) { - RelationStyle style = node.createDefaultStyle(); - getPrintConfig().getRelationStyleDefinition().style(node.containingDumpNode().getObject(), - node.getDumpNode().getObject(), node.containingDumpListChildNode().getName(), style); - node.setLabel(style.getLabel()); - node.setTextColor(style.getTextColor()); - } - - private void DumpAst.applyStyle(DumpNormalRelation node) { - RelationStyle style = node.createDefaultStyle(); - getPrintConfig().getRelationStyleDefinition().style(node.containingDumpNode().getObject(), - node.getDumpNode().getObject(), node.getName(), style); - node.setName(style.getLabel()); - node.setTextColor(style.getTextColor()); - } - - private void DumpAst.applyStyle(InnerRelationDumpNode node) { - RelationStyle style = node.createDefaultStyle(); - getPrintConfig().getRelationStyleDefinition().style(node.containingDumpNode().getObject(), - node.getDumpNode().getObject(), node.containingDumpListRelation().getName(), style); - node.setLabel(style.getLabel()); - node.setTextColor(style.getTextColor()); + private void DumpAst.applyStyle(RelationStylable<?> stylable) { + stylable.applyStyle(getPrintConfig().getRelationStyleDefinition()); } // --- isTypeEnabled --- diff --git a/dumpAst.base/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java b/dumpAst.base/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java index e3a7265fb4948038735661681fab2edc67a8fd31..89d8cf4057224d9385fc48f656d5bbfe2890a4ab 100644 --- a/dumpAst.base/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java +++ b/dumpAst.base/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java @@ -39,7 +39,7 @@ public class DumpBuilder { dumpAst.getPrintConfig().setScale(1); dumpAst.getPrintConfig().setVersion(readVersion()); dumpAst.getPrintConfig().setNodeStyleDefinition((node, style) -> {}); - dumpAst.getPrintConfig().setRelationStyleDefinition((sourceNode, targetNode, context, style) -> {}); + dumpAst.getPrintConfig().setRelationStyleDefinition((sourceNode, targetNode, style) -> {}); } private DumpBuilder thisWithResetBuilt() { diff --git a/dumpAst.base/src/main/resources/RelationStyle.mustache b/dumpAst.base/src/main/resources/RelationStyle.mustache new file mode 100644 index 0000000000000000000000000000000000000000..b48a25121e6fa8e4d31d1eaecbb29bb5874e444f --- /dev/null +++ b/dumpAst.base/src/main/resources/RelationStyle.mustache @@ -0,0 +1 @@ +{{#TextColor}}#text:{{{TextColor}}}{{/TextColor}}{{#LineColor}}{{#TextColor}};{{/TextColor}}{{^TextColor}}#{{/TextColor}}line:{{{LineColor}}}{{/LineColor}} \ No newline at end of file diff --git a/dumpAst.base/src/main/resources/dumpAst.mustache b/dumpAst.base/src/main/resources/dumpAst.mustache index 80010c0882ada38aafc77e43b4f2a2f79dd091ce..350e26a5047cfb25d60fae4bb654b5790da62473 100644 --- a/dumpAst.base/src/main/resources/dumpAst.mustache +++ b/dumpAst.base/src/main/resources/dumpAst.mustache @@ -11,60 +11,60 @@ skinparam object<<NTA>> { hide <<NTA>> stereotype {{#PrintConfig}} -scale {{{scale}}} +scale {{{Scale}}} {{#Headers}} -{{{value}}} +{{{Value}}} {{/Headers}} {{/PrintConfig}} {{#DumpNodes}} - {{^invisible}} + {{^Invisible}} {{#isNull}} -object "null" as {{{name}}}<<null>> +object "null" as {{{Name}}}<<null>> {{/isNull}} {{#isEmpty}} -object "[]" as {{{name}}}<<null>> +object "[]" as {{{Name}}}<<null>> {{/isEmpty}} {{#isAstNode}} -object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroundColor}}#{{{backgroundColor}}}{{/backgroundColor}} { +object "{{{labelAndTextColor}}}" as {{{Name}}} {{{stereotypeList}}} {{#BackgroundColor}}#{{{BackgroundColor}}}{{/BackgroundColor}} { {{#DumpTokens}} {{#isDumpValueToken}} - {{{label}}} = {{{value}}} + {{{label}}} = {{{Value}}} {{/isDumpValueToken}} {{/DumpTokens}} } {{/isAstNode}} - {{/invisible}} + {{/Invisible}} {{/DumpNodes}} {{#DumpNodes}} {{#DumpTokens}} - {{^invisible}} + {{^Invisible}} {{#isList}} {{#InnerRelationDumpNode}} {{#bothVisible}} -{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} : {{{label}}} +{{{outerNodeName}}} .[#black{{#Computed}},#{{{computedColor}}}{{/Computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}} {{/bothVisible}} {{/InnerRelationDumpNode}} {{/isList}} {{^isList}} {{^isDumpValueToken}} -{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} : {{{label}}} +{{{outerNodeName}}} .[#black{{#Computed}},#{{{computedColor}}}{{/Computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} : {{{label}}} {{/isDumpValueToken}} {{/isList}} - {{/invisible}} + {{/Invisible}} {{/DumpTokens}} {{#DumpChildNodes}} {{#isList}} {{#InnerDumpNodes}} {{#bothVisible}} -{{{outerNodeName}}} *-{{#computed}}[#{{{computedColor}}}]{{/computed}}- {{{innerNodeName}}} : {{{label}}} +{{{outerNodeName}}} *-{{#Computed}}[#{{{computedColor}}}]{{/Computed}}- {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}} {{/bothVisible}} {{/InnerDumpNodes}} {{/isList}} {{^isList}} {{#bothVisible}} -{{{outerNodeName}}} *-{{#computed}}[#{{{computedColor}}}]{{/computed}}- {{{innerNodeName}}} : {{{label}}} +{{{outerNodeName}}} *-{{#Computed}}[#{{{computedColor}}}]{{/Computed}}- {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}} {{/bothVisible}} {{/isList}} {{/DumpChildNodes}} @@ -72,36 +72,36 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun {{#isList}} {{#InnerRelationDumpNode}} {{#bothVisible}} -{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} : {{{label}}} +{{{outerNodeName}}} {{#Bidirectional}}<{{/Bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}} {{/bothVisible}} {{/InnerRelationDumpNode}} {{/isList}} {{^isList}} {{#bothVisible}} -{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} : {{{label}}} +{{{outerNodeName}}} {{#Bidirectional}}<{{/Bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}} {{/bothVisible}} {{/isList}} {{/DumpRelations}} - {{^invisible}} + {{^Invisible}} {{#InvisiblePath}} {{#InnerRelationDumpNode}} {{{outerNodeName}}} o.. {{{innerNodeName}}} {{/InnerRelationDumpNode}} {{/InvisiblePath}} - {{/invisible}} - {{#PrintConfig}}{{#orderChildren}} + {{/Invisible}} + {{#PrintConfig}}{{#OrderChildren}} {{#myChildren}} {{#hasSuccessor}} -{{{name}}} -[hidden]right-> {{#successor}}{{{name}}}{{/successor}} +{{{Name}}} -[hidden]right-> {{#successor}}{{{Name}}}{{/successor}} {{/hasSuccessor}} {{/myChildren}} - {{/orderChildren}}{{/PrintConfig}} + {{/OrderChildren}}{{/PrintConfig}} {{/DumpNodes}} {{#PrintConfig}} {{#debug}} legend right %date() - dumpAst: {{{version}}} + dumpAst: {{{Version}}} plantuml: %version() endlegend {{/debug}} diff --git a/dumpAst.prototyping/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java b/dumpAst.prototyping/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java index 10e3f6afd2bd043499bd9788f4168cceb98803b7..cf3ce5b068a919cafe5604cc3a816dcb609901d1 100644 --- a/dumpAst.prototyping/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java +++ b/dumpAst.prototyping/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java @@ -22,6 +22,7 @@ public class FeatureTestMain { root.setName("Root1"); A a = new A().setName("A2"); a.setB(new B().setName("B2.1")); + a.setD(new D()); // a.setMyC(new C().setName("C2.1")); B b1 = new B().setName("B3").setOtherValue("some long text"); // C c = new C().setName("C4"); @@ -48,9 +49,9 @@ public class FeatureTestMain { .enableDebug() .customPreamble("title My fancy title") .includeChild((parentNode, childNode, contextName) -> { - if (parentNode instanceof A && ((A) parentNode).getName().equals("A2")) { - return false; - } +// if (parentNode instanceof A && ((A) parentNode).getName().equals("A2")) { +// return false; +// } if (parentNode instanceof Root && childNode instanceof B) { return !"B3".equals(((B) childNode).getName()); } @@ -72,11 +73,12 @@ public class FeatureTestMain { } }) .skinParam(SkinParamBooleanSetting.Shadowing, false) - .relationStyle((source, target, context, style) -> { - if (context.equals("ManyA")) { + .relationStyle((source, target, style) -> { + if (style.getLabel().equals("ManyA")) { style.setLabel("ManyA of " + ((Nameable) source).getName()); - } else if (context.equals("OneA") || context.equals("MaybeC")) { + } else if (style.getLabel().equals("OneA") || style.getLabel().equals("MaybeC?")) { style.setTextColor("red"); + style.setLineColor("green"); } }) .<ASTNode<?>>nodeStyle((node, style) -> { diff --git a/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestComplex.java b/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestRegression.java similarity index 62% rename from dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestComplex.java rename to dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestRegression.java index 574ec066d9d04d22bfc0f3662058f0960c516d20..a7a35cdf0200dd9726bb4f8f79e7ecda1c544a30 100644 --- a/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestComplex.java +++ b/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestRegression.java @@ -6,22 +6,28 @@ import org.jastadd.testDumper.ast.DropOffLocation; import org.jastadd.testDumper.ast.Orientation; import org.jastadd.testDumper.ast.Position; import org.jastadd.testDumper.ast.Size; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import static de.tudresden.inf.st.jastadd.testDumper.TestUtils.*; import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; /** - * More complex test cases. + * Regression test cases. * * @author rschoene - Initial contribution */ -public class TestComplex { +public class TestRegression { @Test - public void testRegressionIssue16() throws TransformationException { + public void regressionIssue16() throws TransformationException { DropOffLocation location = new DropOffLocation(); location.setName(ROOT_NAME); location.setPosition(new Position(T1_NAME, 1, 2, 3)); @@ -35,4 +41,11 @@ public class TestComplex { entry("Y", 2.0), entry("Z", 3.0)); } + + @Test + public void regressionNoNewlineForRelationStyleMustache() throws IOException { + Path path = Paths.get("..", "dumpAst.base", "src", "main", "resources", "RelationStyle.mustache"); + List<String> lines = Files.readAllLines(path); + assertEquals(1, lines.size(), "Ensure no trailing newline in RelationStyle.mustache"); + } } diff --git a/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java b/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java index 9bd634b20ca1c3d231194c3801595678a00a9333..5246c9f332a82b94326598bbf27cc92bb1f65b42 100644 --- a/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java +++ b/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java @@ -93,7 +93,7 @@ public class TestUtils { public static final Function<DumpNode, String> NAME_EXTRACTOR = node -> { for (DumpToken dumpToken : node.getDumpTokenList()) { - if (dumpToken.getName().equals("Name")) { + if (dumpToken.getLabel().equals("Name")) { return dumpToken.asDumpValueToken().getValue().toString(); } } @@ -156,7 +156,7 @@ public class TestUtils { // then it is a DumpNormalChildNode DumpNode target = ((DumpNormalChildNode) dumpChildNode).getDumpNode(); if (target != null && !target.getInvisible()) { - result.put(dumpChildNode.getName(), target); + result.put(dumpChildNode.getLabel(), target); } } } @@ -170,7 +170,7 @@ public class TestUtils { // then it is a DumpListChildNode ((DumpListChildNode) dumpChildNode).getInnerDumpNodeList().forEach(inner -> { if (inner.getDumpNode() != null && !inner.getDumpNode().getInvisible()) { - result.computeIfAbsent(dumpChildNode.getName(), key -> new ArrayList<>()).add(inner.getDumpNode()); + result.computeIfAbsent(dumpChildNode.getLabel(), key -> new ArrayList<>()).add(inner.getDumpNode()); } }); } @@ -185,7 +185,7 @@ public class TestUtils { // then it is a DumpNormalRelation DumpNode target = ((DumpNormalRelation) dumpRelation).getDumpNode(); if (!target.getInvisible()) { - result.put(dumpRelation.getName(), target); + result.put(dumpRelation.getLabel(), target); } } } @@ -199,7 +199,7 @@ public class TestUtils { // then it is a DumpListRelation ((DumpListRelation) dumpRelation).getInnerRelationDumpNodeList().forEach(inner -> { if (!inner.getDumpNode().getInvisible()) { - result.computeIfAbsent(dumpRelation.getName(), key -> new ArrayList<>()).add(inner.getDumpNode()); + result.computeIfAbsent(dumpRelation.getLabel(), key -> new ArrayList<>()).add(inner.getDumpNode()); } }); } @@ -214,7 +214,7 @@ public class TestUtils { // then it is a DumpReferenceToken DumpNode target = ((DumpReferenceToken) dumpToken).getValue(); if (!target.getInvisible()) { - result.put(dumpToken.getName(), target); + result.put(dumpToken.getLabel(), target); } } } @@ -228,7 +228,7 @@ public class TestUtils { // then it is a DumpReferenceListToken ((DumpReferenceListToken) dumpToken).getInnerRelationDumpNodeList().forEach(inner -> { if (!inner.getDumpNode().getInvisible()) { - result.computeIfAbsent(dumpToken.getName(), key -> new ArrayList<>()).add(inner.getDumpNode()); + result.computeIfAbsent(dumpToken.getLabel(), key -> new ArrayList<>()).add(inner.getDumpNode()); } }); } @@ -242,7 +242,7 @@ public class TestUtils { if (dumpToken.isDumpValueToken()) { // then it is a DumpValueToken DumpValueToken dumpValueToken = (DumpValueToken) dumpToken; - result.put(dumpValueToken.getName(), dumpValueToken.getValue()); + result.put(dumpValueToken.getLabel(), dumpValueToken.getValue()); } } return result; diff --git a/pages/docs/using.md b/pages/docs/using.md index 04472f13a6818e4b67fb26fad4bd6df36d10c6b0..26cd6c0c6c3c60d6bb7e08084f945e97b7c93290 100644 --- a/pages/docs/using.md +++ b/pages/docs/using.md @@ -27,15 +27,20 @@ public class Main { } return !contextName.equals("EndEffector"); }) - .style((node, style) -> { + .nodeStyle((node, style) -> { style.useSimpleName(); // (4) style.setBackgroundColor(node.size() > 30 ? "blue" : "white"); // (5) }) - .skinParam(SkinParamBooleanSetting.Shadowing, false); // (6) - builder.dumpAsPng(Paths.get("featureTest.png")); // (7) - builder.dumpAsSVG(Paths.get("featureTest.svg")); // (8) + .relationStyle((source, target, style) -> { + if (style.getLabel().equals("EndEffector")) { + style.setLabel(""); // (6) + } + }) + .skinParam(SkinParamBooleanSetting.Shadowing, false); // (7) + builder.dumpAsPng(Paths.get("featureTest.png")); // (8) + builder.dumpAsSVG(Paths.get("featureTest.svg")); // (9) OutputStream os = getMyOutputStream(); - builder.dumpAsPNG(os); // (9) + builder.dumpAsPNG(os); // (10) } } ``` @@ -51,9 +56,10 @@ The steps in detail: - (1) In the beginning, your model is somehow constructed and changed. This is indicated with the method `createModel`. - (2) The first call is always `Dumper.read()` to which the (part of the) AST is provided as an argument. It returns an object of type [DumpBuilder](../ragdoc/#/type/DumpBuilder). With this object, the output can be changed. - (3) [Optional] You can only include nodes of certain types by using `includeChild` and passing a lambda function, which is called for every node and should return `true` if the `childNode` shall be included in the output. It defaults to returning `true` for every node. Here, all children of a `Robot` node (except if the name of the robot is `"Robot2"`) and all children of the context named `"EndEffector"` are excluded. -- (4) and (5) [Optional] To style a node, the `style` is used. It accepts a lambda function, in which the style of every node can be customized by calling methods on the given `Style` object, e.g. setting the name (5) or background color (6). The default name is to use the class name along with the hashcode of the object (`node == null ? "null" : node.getClass().getSimpleName() + "@" + Integer.toHexString(node.hashCode())`). -- (6) [Optional] There are a few ways to style the output in general through [SkinParam](https://plantuml.com/de/skinparam). Not all of those parameters are supported; see `SkinParamBooleanSetting` and `SkinParamStringSetting`. -- (7), (8) and (9) To create an output image, use `dumpAsPng` for PNG (`dumpAsSVG` for SVG). Those methods do not return the builder object, as they produce an output. They potentially throw two kinds of exception: `IOException` (when the file could not be written) and `TransformationException` (when the AST could not be processed). As shown here, the builder object must be stored in a variable to create multiple outputs. Alternatively to a file, the result can be written to a given `OutputStream` (9). +- (4) and (5) [Optional] To style a node, the method `nodeStyle` is used. It accepts a lambda function, in which the style of every node can be customized by calling methods on the given `Style` object, e.g. setting the name (5) or background color (6). The default name is to use the class name along with the hashcode of the object (`node == null ? "null" : node.getClass().getSimpleName() + "@" + Integer.toHexString(node.hashCode())`). +- (6) [Optional] To style a relation, the method `relationStyle` is used. It is used similar to `nodeStyle`, but is called with source and target node of a relation (containment and non-containment). Note, that (a) the default label can be retrieved with `style.getLabel()` and (b) indices are always appended to the set label. +- (7) [Optional] There are a few ways to style the output in general through [SkinParam](https://plantuml.com/de/skinparam). Not all of those parameters are supported; see `SkinParamBooleanSetting` and `SkinParamStringSetting`. +- (8), (9) and (10) To create an output image, use `dumpAsPng` for PNG (`dumpAsSVG` for SVG). Those methods do not return the builder object, as they produce an output. They potentially throw two kinds of exception: `IOException` (when the file could not be written) and `TransformationException` (when the AST could not be processed). As shown here, the builder object must be stored in a variable to create multiple outputs. Alternatively to a file, the result can be written to a given `OutputStream` (10). To summarise the required steps: Specify the AST to read in, configure the output, and write ("dump") the output. For more configuration options, please consult the [API Docs of DumpBuilder](../ragdoc/#/type/DumpBuilder).