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

1.0.3

- include null-nodes for single-relation targets
- resolve iterables of ASTNodes in tokens and attributes
parent d0e9a741
No related branches found
No related tags found
1 merge request!111.1.0
Pipeline #13860 passed
Showing
with 179 additions and 55 deletions
...@@ -4,8 +4,11 @@ rel DumpAst.RootNode? -> DumpNode ; ...@@ -4,8 +4,11 @@ rel DumpAst.RootNode? -> DumpNode ;
DumpNode ::= DumpChildNode* DumpToken* DumpRelation* DumpNode ::= DumpChildNode* DumpToken* DumpRelation*
<Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> <Computed:boolean> <ManualStereotypes> <Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> <Computed:boolean> <ManualStereotypes>
/InvisiblePath/ ; /InvisiblePath/ ;
InnerDumpNode ; InnerDumpNode ;
rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner ; rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner ;
InnerRelationDumpNode;
rel InnerRelationDumpNode.DumpNode -> DumpNode ; // .ContainerOfInner*
abstract DumpChildNode ::= <Name> <Computed:boolean> ; abstract DumpChildNode ::= <Name> <Computed:boolean> ;
DumpNormalChildNode : DumpChildNode ; DumpNormalChildNode : DumpChildNode ;
...@@ -15,15 +18,16 @@ DumpListChildNode : DumpChildNode ::= InnerDumpNode* ; ...@@ -15,15 +18,16 @@ DumpListChildNode : DumpChildNode ::= InnerDumpNode* ;
abstract DumpToken ::= <Name> <Computed:boolean> ; abstract DumpToken ::= <Name> <Computed:boolean> ;
DumpReferenceToken : DumpToken ; DumpReferenceToken : DumpToken ;
rel DumpReferenceToken.Value -> DumpNode ; rel DumpReferenceToken.Value -> DumpNode ;
DumpReferenceListToken : DumpToken ::= InnerRelationDumpNode* ;
DumpValueToken : DumpToken ::= <Value:Object> ; DumpValueToken : DumpToken ::= <Value:Object> ;
abstract DumpRelation ::= <Name> <Bidirectional:boolean> ; abstract DumpRelation ::= <Name> <Bidirectional:boolean> ;
DumpNormalRelation : DumpRelation ; DumpNormalRelation : DumpRelation ;
rel DumpNormalRelation.DumpNode -> DumpNode ; rel DumpNormalRelation.DumpNode -> DumpNode ;
DumpListRelation : DumpRelation ::= InnerDumpNode* ; DumpListRelation : DumpRelation ::= InnerRelationDumpNode* ;
// type of NTA // type of NTA
InvisiblePath ::= InnerDumpNode* ; InvisiblePath ::= InnerRelationDumpNode* ;
ClassAnalysisResult ::= ContainmentMethod:AnalysedMethod* OtherMethod:AnalysedMethod* ; ClassAnalysisResult ::= ContainmentMethod:AnalysedMethod* OtherMethod:AnalysedMethod* ;
abstract AnalysedMethod ::= <Method:java.lang.reflect.Method> <Name> ; abstract AnalysedMethod ::= <Method:java.lang.reflect.Method> <Name> ;
......
...@@ -11,7 +11,7 @@ aspect GenerationBackend { ...@@ -11,7 +11,7 @@ aspect GenerationBackend {
public boolean computed; public boolean computed;
public TransformationOptions asRelation() { public TransformationOptions asRelation() {
return fromSource(Source.RELATION, false); return fromSource(Source.RELATION, false).allowNullObjectsOnce();
} }
public TransformationOptions asRoot() { public TransformationOptions asRoot() {
...@@ -192,7 +192,7 @@ aspect GenerationBackend { ...@@ -192,7 +192,7 @@ aspect GenerationBackend {
// -- singleRelation -- // -- singleRelation --
Object target = otherMethod.getMethod().invoke(obj); Object target = otherMethod.getMethod().invoke(obj);
DumpNode targetNode = transform(tti, target, options.asRelation()); DumpNode targetNode = transform(tti, target, options.asRelation());
if (target != null && targetNode != null) { if (targetNode != null) {
DumpNormalRelation normalRelation = new DumpNormalRelation(); DumpNormalRelation normalRelation = new DumpNormalRelation();
normalRelation.setName(otherMethod.getName()); normalRelation.setName(otherMethod.getName());
normalRelation.setDumpNode(targetNode); normalRelation.setDumpNode(targetNode);
...@@ -206,29 +206,54 @@ aspect GenerationBackend { ...@@ -206,29 +206,54 @@ aspect GenerationBackend {
for (Object target : targetList) { for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, options.asRelation()); DumpNode targetNode = transform(tti, target, options.asRelation());
if (target != null && targetNode != null) { 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); node.addDumpRelation(listRelation);
} }
} else if (otherMethod.isTokenMethod()) { } else if (otherMethod.isTokenMethod()) {
// -- token -- // -- token --
Object target = otherMethod.getMethod().invoke(obj); 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) { if (target != null) {
DumpNode targetNode = transform(tti, target, options.asRelation());
DumpToken token = null; DumpToken token = null;
// TODO check, if Iterable.isAssignableFrom(target.getClass()). boolean atLeastOneASTNode = false;
// if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's 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()) { if (targetNode != null && targetNode.isAstNode()) {
token = new DumpReferenceToken().setValue(targetNode); token = new DumpReferenceToken().setValue(targetNode);
} else { } else {
if (target != null && (getBuildConfig().getIncludeEmptyString() || !target.toString().isEmpty())) { if (getBuildConfig().getIncludeEmptyString() || !target.toString().isEmpty()) {
DumpValueToken valueToken = new DumpValueToken(); DumpValueToken valueToken = new DumpValueToken();
valueToken.setValue(target); valueToken.setValue(target);
token = valueToken; token = valueToken;
} }
} }
}
if (token != null) { if (token != null) {
token.setName(otherMethod.getName()); token.setName(otherMethod.getName());
token.setComputed(otherMethod.asTokenMethod().isAttributeMethod()); token.setComputed(otherMethod.asTokenMethod().isAttributeMethod());
...@@ -584,7 +609,7 @@ aspect GenerationBackend { ...@@ -584,7 +609,7 @@ aspect GenerationBackend {
syn InvisiblePath DumpNode.getInvisiblePath() { syn InvisiblePath DumpNode.getInvisiblePath() {
InvisiblePath result = new InvisiblePath(); InvisiblePath result = new InvisiblePath();
for (DumpNode successor : reachableThroughInvisible()) { for (DumpNode successor : reachableThroughInvisible()) {
result.addInnerDumpNode(new InnerDumpNode(successor)); result.addInnerRelationDumpNode(new InnerRelationDumpNode(successor));
} }
return result; return result;
} }
......
...@@ -26,14 +26,6 @@ aspect GenerationToYaml { ...@@ -26,14 +26,6 @@ aspect GenerationToYaml {
return result; 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) { syn MappingElement PrintConfig.toYaml(boolean fromRelation) {
MappingElement result = new MappingElement(); MappingElement result = new MappingElement();
// children // children
...@@ -128,6 +120,7 @@ aspect GenerationToYaml { ...@@ -128,6 +120,7 @@ aspect GenerationToYaml {
result.put("name", getName()); result.put("name", getName());
result.put("computed", getComputed()); result.put("computed", getComputed());
// attributes // attributes
result.put("isList", isList());
result.put("label", label()); result.put("label", label());
result.put("isDumpValueToken", isDumpValueToken()); result.put("isDumpValueToken", isDumpValueToken());
return result; return result;
...@@ -142,12 +135,23 @@ aspect GenerationToYaml { ...@@ -142,12 +135,23 @@ aspect GenerationToYaml {
syn MappingElement DumpReferenceToken.toYaml(boolean fromRelation) { syn MappingElement DumpReferenceToken.toYaml(boolean fromRelation) {
MappingElement result = super.toYaml(fromRelation); MappingElement result = super.toYaml(fromRelation);
// tokens // attributes
result.put("innerNodeName", innerNodeName()); result.put("innerNodeName", innerNodeName());
result.put("outerNodeName", outerNodeName()); result.put("outerNodeName", outerNodeName());
return result; 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) { syn MappingElement DumpRelation.toYaml(boolean fromRelation) {
MappingElement result = new MappingElement(); MappingElement result = new MappingElement();
// tokens // tokens
...@@ -171,7 +175,7 @@ aspect GenerationToYaml { ...@@ -171,7 +175,7 @@ aspect GenerationToYaml {
syn MappingElement DumpListRelation.toYaml(boolean fromRelation) { syn MappingElement DumpListRelation.toYaml(boolean fromRelation) {
MappingElement result = super.toYaml(fromRelation); MappingElement result = super.toYaml(fromRelation);
// children // children
addYamledList(result, "InnerDumpNodes", getInnerDumpNodeList(), fromRelation); addYamledList(result, "InnerRelationDumpNode", getInnerRelationDumpNodeList(), fromRelation);
return result; return result;
} }
...@@ -185,13 +189,31 @@ aspect GenerationToYaml { ...@@ -185,13 +189,31 @@ aspect GenerationToYaml {
return result; 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) { syn MappingElement InvisiblePath.toYaml(boolean fromRelation) {
MappingElement result = super.toYaml(fromRelation); MappingElement result = super.toYaml(fromRelation);
// children // children
addYamledList(result, "InnerDumpNodes", getInnerDumpNodeList(), fromRelation); addYamledList(result, "InnerRelationDumpNode", getInnerRelationDumpNodeList(), fromRelation);
return result; 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 // extension for mustache
public static ValueElement ValueElement.of(double value) { public static ValueElement ValueElement.of(double value) {
return new ValueElement(false, String.valueOf(value)); return new ValueElement(false, String.valueOf(value));
......
...@@ -4,6 +4,8 @@ aspect Navigation { ...@@ -4,6 +4,8 @@ aspect Navigation {
eq DumpListChildNode.isList() = true; eq DumpListChildNode.isList() = true;
syn boolean DumpRelation.isList() = false; syn boolean DumpRelation.isList() = false;
eq DumpListRelation.isList() = true; eq DumpListRelation.isList() = true;
syn boolean DumpToken.isList() = false;
eq DumpReferenceListToken.isList() = true;
// --- buildConfig --- // --- buildConfig ---
inh BuildConfig DumpNode.buildConfig(); inh BuildConfig DumpNode.buildConfig();
...@@ -16,10 +18,12 @@ aspect Navigation { ...@@ -16,10 +18,12 @@ aspect Navigation {
// --- containingDumpNode --- // --- containingDumpNode ---
inh DumpNode InnerDumpNode.containingDumpNode(); inh DumpNode InnerDumpNode.containingDumpNode();
inh DumpNode InnerRelationDumpNode.containingDumpNode();
inh DumpNode DumpChildNode.containingDumpNode(); inh DumpNode DumpChildNode.containingDumpNode();
inh DumpNode DumpRelation.containingDumpNode(); inh DumpNode DumpRelation.containingDumpNode();
eq DumpNode.getDumpChildNode().containingDumpNode() = this; eq DumpNode.getDumpChildNode().containingDumpNode() = this;
eq DumpNode.getDumpRelation().containingDumpNode() = this; eq DumpNode.getDumpRelation().containingDumpNode() = this;
eq DumpNode.getDumpToken().containingDumpNode() = this;
eq DumpNode.getInvisiblePath().containingDumpNode() = this; eq DumpNode.getInvisiblePath().containingDumpNode() = this;
// --- container --- // --- container ---
...@@ -69,7 +73,7 @@ aspect Navigation { ...@@ -69,7 +73,7 @@ aspect Navigation {
return java.util.Collections.emptyList(); return java.util.Collections.emptyList();
} }
java.util.List<DumpNode> result = new java.util.ArrayList<>(); java.util.List<DumpNode> result = new java.util.ArrayList<>();
getInnerDumpNodeList().forEach(inner -> { getInnerRelationDumpNodeList().forEach(inner -> {
if (!onlyVisible || !inner.getDumpNode().getInvisible()) { if (!onlyVisible || !inner.getDumpNode().getInvisible()) {
result.add(inner.getDumpNode()); result.add(inner.getDumpNode());
} }
......
aspect Printing { aspect Printing {
// --- outerNodeName --- // --- outerNodeName ---
inh String InnerDumpNode.outerNodeName(); inh String InnerDumpNode.outerNodeName();
inh String InnerRelationDumpNode.outerNodeName();
inh String DumpChildNode.outerNodeName(); inh String DumpChildNode.outerNodeName();
inh String DumpRelation.outerNodeName(); inh String DumpRelation.outerNodeName();
inh String DumpToken.outerNodeName();
inh String DumpReferenceToken.outerNodeName(); inh String DumpReferenceToken.outerNodeName();
eq DumpNode.getChild().outerNodeName() = name(); eq DumpNode.getChild().outerNodeName() = name();
// --- innerNodeName --- // --- innerNodeName ---
syn String InnerDumpNode.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null; 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 DumpNormalChildNode.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null;
syn String DumpNormalRelation.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null; syn String DumpNormalRelation.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null;
syn String DumpReferenceToken.innerNodeName() = getValue().name(); syn String DumpReferenceToken.innerNodeName() = getValue().name();
...@@ -21,15 +24,18 @@ aspect Printing { ...@@ -21,15 +24,18 @@ aspect Printing {
syn String DumpToken.label() = getName() + (getComputed() ? "()" : ""); syn String DumpToken.label() = getName() + (getComputed() ? "()" : "");
syn String DumpNode.label() = getLabel(); syn String DumpNode.label() = getLabel();
inh String InnerDumpNode.label(); inh String InnerDumpNode.label();
inh String InnerRelationDumpNode.label();
eq DumpListChildNode.getInnerDumpNode(int index).label() = label() + "[" + index + "]"; eq DumpListChildNode.getInnerDumpNode(int index).label() = label() + "[" + index + "]";
eq DumpListRelation.getInnerDumpNode(int index).label() = label() + "[" + index + "]"; eq DumpListRelation.getInnerRelationDumpNode(int index).label() = label() + "[" + index + "]";
eq InvisiblePath.getInnerDumpNode(int index).label() = null; eq DumpReferenceListToken.getInnerRelationDumpNode(int index).label() = label() + "[" + index + "]";
eq InvisiblePath.getInnerRelationDumpNode(int index).label() = null;
// --- bothVisible --- // --- bothVisible ---
boolean ASTNode.bothVisible(DumpNode one, DumpNode two) { boolean ASTNode.bothVisible(DumpNode one, DumpNode two) {
return one != null && two != null && !one.getInvisible() && !two.getInvisible(); return one != null && two != null && !one.getInvisible() && !two.getInvisible();
} }
syn boolean InnerDumpNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode()); syn boolean InnerDumpNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
syn boolean InnerRelationDumpNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
syn boolean DumpNormalChildNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode()); syn boolean DumpNormalChildNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
syn boolean DumpNormalRelation.bothVisible() = bothVisible(containingDumpNode(), getDumpNode()); syn boolean DumpNormalRelation.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
} }
......
...@@ -37,9 +37,18 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun ...@@ -37,9 +37,18 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun
{{#DumpNodes}} {{#DumpNodes}}
{{#DumpTokens}} {{#DumpTokens}}
{{^invisible}} {{^invisible}}
{{#isList}}
{{#InnerRelationDumpNode}}
{{#bothVisible}}
{{{outerNodeName}}} .{{#computed}}[#{{{computedColor}}}]{{/computed}}.> {{{innerNodeName}}} : {{{label}}}
{{/bothVisible}}
{{/InnerRelationDumpNode}}
{{/isList}}
{{^isList}}
{{^isDumpValueToken}} {{^isDumpValueToken}}
{{{outerNodeName}}} .{{#computed}}[#{{{computedColor}}}]{{/computed}}.> {{{innerNodeName}}} : {{{label}}} {{{outerNodeName}}} .{{#computed}}[#{{{computedColor}}}]{{/computed}}.> {{{innerNodeName}}} : {{{label}}}
{{/isDumpValueToken}} {{/isDumpValueToken}}
{{/isList}}
{{/invisible}} {{/invisible}}
{{/DumpTokens}} {{/DumpTokens}}
{{#DumpChildNodes}} {{#DumpChildNodes}}
...@@ -58,11 +67,11 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun ...@@ -58,11 +67,11 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun
{{/DumpChildNodes}} {{/DumpChildNodes}}
{{#DumpRelations}} {{#DumpRelations}}
{{#isList}} {{#isList}}
{{#InnerDumpNodes}} {{#InnerRelationDumpNode}}
{{#bothVisible}} {{#bothVisible}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}--> {{{innerNodeName}}} : {{{label}}} {{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}--> {{{innerNodeName}}} : {{{label}}}
{{/bothVisible}} {{/bothVisible}}
{{/InnerDumpNodes}} {{/InnerRelationDumpNode}}
{{/isList}} {{/isList}}
{{^isList}} {{^isList}}
{{#bothVisible}} {{#bothVisible}}
...@@ -72,9 +81,9 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun ...@@ -72,9 +81,9 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun
{{/DumpRelations}} {{/DumpRelations}}
{{^invisible}} {{^invisible}}
{{#InvisiblePath}} {{#InvisiblePath}}
{{#InnerDumpNodes}} {{#InnerRelationDumpNode}}
{{{outerNodeName}}} o.. {{{innerNodeName}}} {{{outerNodeName}}} o.. {{{innerNodeName}}}
{{/InnerDumpNodes}} {{/InnerRelationDumpNode}}
{{/InvisiblePath}} {{/InvisiblePath}}
{{/invisible}} {{/invisible}}
{{#PrintConfig}}{{#orderChildren}} {{#PrintConfig}}{{#orderChildren}}
......
#Mon May 16 18:32:38 CEST 2022 #Mon Jun 13 18:33:49 CEST 2022
version=1.0.2 version=1.0.3
...@@ -32,6 +32,7 @@ configurations { ...@@ -32,6 +32,7 @@ configurations {
dependencies { dependencies {
implementation project(":dumpAst") implementation project(":dumpAst")
jastadd2 group: 'org.jastadd', name: 'jastadd2', version: '2.3.5-dresden'
relast group: 'org.jastadd', name: 'relast', version: "${relast_version}" relast group: 'org.jastadd', name: 'relast', version: "${relast_version}"
implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
......
...@@ -2,6 +2,7 @@ aspect GrammarGlobal { ...@@ -2,6 +2,7 @@ aspect GrammarGlobal {
syn A C.getCalculated() { syn A C.getCalculated() {
A result = new A(); A result = new A();
result.setName("Calculated-" + getName()); result.setName("Calculated-" + getName());
result.setB(new B().setName("B" + getName()));
D innerD = new D(); D innerD = new D();
result.setD(innerD); result.setD(innerD);
return result; return result;
...@@ -18,6 +19,7 @@ aspect GrammarGlobal { ...@@ -18,6 +19,7 @@ aspect GrammarGlobal {
syn nta A C.getCalculatedNewSyntax() { syn nta A C.getCalculatedNewSyntax() {
A result = new A(); A result = new A();
result.setName("Calculated-" + getName()); result.setName("Calculated-" + getName());
result.setB(new B().setName("B" + getName()));
return result; return result;
} }
...@@ -34,6 +36,11 @@ aspect GrammarGlobal { ...@@ -34,6 +36,11 @@ aspect GrammarGlobal {
syn boolean ASTNode.isA() = false; syn boolean ASTNode.isA() = false;
eq A.isA() = true; 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 { aspect GrammarTypeLevel {
......
// testcases with global inclusion/exclusion // testcases with global inclusion/exclusion
Nameable ::= <Name> ; Nameable ::= <Name> ;
Root : Nameable ::= A B* [C]; Root : Nameable ::= A B* [C];
A : Nameable ::= B MyC:C D; A : Nameable ::= B [MyC:C] [D];
B : Nameable ::= <OtherValue> ; B : Nameable ::= <OtherValue> ;
C : Nameable ::= [A] <Unwanted:int> <RawReference:A> /Calculated:A/ /AlsoCalculated:B*/ ; C : Nameable ::= [A] <Unwanted:int> <RawReference:A> /Calculated:A/ /AlsoCalculated:B*/ ;
SubC : C ::= <RawReference:A> <Unwanted:int> [A] /Calculated:A/ /AlsoCalculated:B*/ ; SubC : C ::= <RawReference:A> <Unwanted:int> [A] /Calculated:A/ /AlsoCalculated:B*/ ;
......
...@@ -8,6 +8,8 @@ import org.jastadd.featureTest.ast.*; ...@@ -8,6 +8,8 @@ import org.jastadd.featureTest.ast.*;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.function.Consumer;
import java.util.function.Function;
/** /**
* Main class of feature test. * Main class of feature test.
...@@ -19,18 +21,17 @@ public class FeatureTestMain { ...@@ -19,18 +21,17 @@ public class FeatureTestMain {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
Root root = new Root(); Root root = new Root();
root.setName("Root1"); root.setName("Root1");
A a = new A(); A a = new A().setName("A2");
a.setName("A2"); a.setB(new B().setName("B2.1"));
B b1 = new B(); a.setMyC(new C().setName("C2.1"));
b1.setName("B3"); B b1 = new B().setName("B3");
C c = new C(); C c = new C().setName("C4");
c.setName("C4"); c.setA(new A().setName("A4.1").setB(new B().setName("B4.1.1")));
c.setRawReference(a); c.setRawReference(a);
b1.setOneA(a); b1.setOneA(a);
B b2 = new B(); B b2 = new B().setName("B5");
b2.setName("B5"); C myC = new C().setName("C6");
C myC = new C(); c.setA(new A().setName("A6.1").setB(new B().setName("B6.1.1")));
myC.setName("C6");
a.setMyC(myC); a.setMyC(myC);
root.setA(a); root.setA(a);
root.addB(b1); root.addB(b1);
...@@ -45,7 +46,9 @@ public class FeatureTestMain { ...@@ -45,7 +46,9 @@ public class FeatureTestMain {
.read(root) .read(root)
// .customPreamble("hide empty members") // .customPreamble("hide empty members")
.skinParam(SkinParamBooleanSetting.Shadowing, false) .skinParam(SkinParamBooleanSetting.Shadowing, false)
.includeAttributes("referenceAttr") .includeAttributes("referenceAttr"
, "collectBs"
)
.includeNonterminalAttributes("Calculated") .includeNonterminalAttributes("Calculated")
.includeNonterminalAttributes("AlsoCalculatedListNewSyntax") .includeNonterminalAttributes("AlsoCalculatedListNewSyntax")
.dumpAsYaml(pathToYaml, true) .dumpAsYaml(pathToYaml, true)
......
...@@ -32,6 +32,12 @@ aspect GrammarGlobal { ...@@ -32,6 +32,12 @@ aspect GrammarGlobal {
syn boolean ASTNode.isA() = false; syn boolean ASTNode.isA() = false;
eq A.isA() = true; 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 { aspect GrammarTypeLevel {
......
...@@ -31,6 +31,18 @@ public class TestIncluded { ...@@ -31,6 +31,18 @@ public class TestIncluded {
assertThat(valueTokens(actualRoot)).containsOnly(entry("Name", ROOT_NAME), entry("simpleAttr", 42)); 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 @Test
public void testReferenceAttributeDefault() { public void testReferenceAttributeDefault() {
Root root = createRoot(createA(A_NAME), null); Root root = createRoot(createA(A_NAME), null);
......
...@@ -74,14 +74,24 @@ public class TestSimple { ...@@ -74,14 +74,24 @@ public class TestSimple {
List<DumpNode> nodes = TestUtils.dumpModel(root, DumpBuilder::includeNullNodes); List<DumpNode> nodes = TestUtils.dumpModel(root, DumpBuilder::includeNullNodes);
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder( 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); DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
assertEquals(1, actualRoot.getNumDumpToken()); assertEquals(1, actualRoot.getNumDumpToken());
assertEquals(2, actualRoot.getNumDumpChildNode()); assertEquals(2, actualRoot.getNumDumpChildNode());
assertEquals(0, actualRoot.getNumDumpRelation()); assertEquals(0, actualRoot.getNumDumpRelation());
DumpNode actualA = TestUtils.findByName(nodes, A_NAME); DumpNode actualA = TestUtils.findByName(nodes, A_NAME);
assertEquals(1, actualA.getNumDumpToken());
assertEquals(3, actualA.getNumDumpChildNode()); assertEquals(3, actualA.getNumDumpChildNode());
assertEquals(3, actualA.getNumDumpRelation());
} }
@Test @Test
......
...@@ -229,7 +229,7 @@ public class TestUtils { ...@@ -229,7 +229,7 @@ public class TestUtils {
for (DumpRelation dumpRelation : node.getDumpRelationList()) { for (DumpRelation dumpRelation : node.getDumpRelationList()) {
if (dumpRelation.isList()) { if (dumpRelation.isList()) {
// then it is a DumpListRelation // then it is a DumpListRelation
((DumpListRelation) dumpRelation).getInnerDumpNodeList().forEach(inner -> { ((DumpListRelation) dumpRelation).getInnerRelationDumpNodeList().forEach(inner -> {
if (!inner.getDumpNode().getInvisible()) { if (!inner.getDumpNode().getInvisible()) {
result.computeIfAbsent(dumpRelation.getName(), key -> new ArrayList<>()).add(inner.getDumpNode()); result.computeIfAbsent(dumpRelation.getName(), key -> new ArrayList<>()).add(inner.getDumpNode());
} }
...@@ -242,7 +242,7 @@ public class TestUtils { ...@@ -242,7 +242,7 @@ public class TestUtils {
public static Map<String, DumpNode> referenceTokens(DumpNode node) { public static Map<String, DumpNode> referenceTokens(DumpNode node) {
Map<String, DumpNode> result = new HashMap<>(); Map<String, DumpNode> result = new HashMap<>();
for (DumpToken dumpToken : node.getDumpTokenList()) { for (DumpToken dumpToken : node.getDumpTokenList()) {
if (!dumpToken.isDumpValueToken()) { if (!dumpToken.isDumpValueToken() && !dumpToken.isList()) {
// then it is a DumpReferenceToken // then it is a DumpReferenceToken
DumpNode target = ((DumpReferenceToken) dumpToken).getValue(); DumpNode target = ((DumpReferenceToken) dumpToken).getValue();
if (!target.getInvisible()) { if (!target.getInvisible()) {
...@@ -253,6 +253,21 @@ public class TestUtils { ...@@ -253,6 +253,21 @@ public class TestUtils {
return result; 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) { public static Map<String, Object> valueTokens(DumpNode node) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
for (DumpToken dumpToken : node.getDumpTokenList()) { for (DumpToken dumpToken : node.getDumpTokenList()) {
...@@ -267,7 +282,7 @@ public class TestUtils { ...@@ -267,7 +282,7 @@ public class TestUtils {
public static List<DumpNode> invisiblePath(DumpNode node) { public static List<DumpNode> invisiblePath(DumpNode node) {
List<DumpNode> result = new ArrayList<>(); List<DumpNode> result = new ArrayList<>();
for (InnerDumpNode inner : node.getInvisiblePath().getInnerDumpNodeList()) { for (InnerRelationDumpNode inner : node.getInvisiblePath().getInnerRelationDumpNodeList()) {
DumpNode target = inner.getDumpNode(); DumpNode target = inner.getDumpNode();
assertFalse(target.getInvisible()); assertFalse(target.getInvisible());
result.add(target); result.add(target);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment