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

WIP dumpAst 0.3.1

- ignored types still leave "path to ancestors objects"
parent b50b459e
No related branches found
No related tags found
No related merge requests found
Pipeline #7863 passed
......@@ -2,7 +2,7 @@ DumpAst ::= DumpNode* <PackageName> BuildConfig PrintConfig ;
BuildConfig ::= <TypeIgnore> <TokenIgnore> <ChildIgnore> <AttributeIgnore> <RelationIgnore> <IncludeEmptyString:boolean> <Debug:boolean> ;
PrintConfig ::= <Scale:double> <Version> Header* ;
Header ::= <Value> ;
DumpNode ::= <Name> <Label> <Object:Object> DumpChildNode* DumpToken* DumpRelation* ;
DumpNode ::= <Name> <Label> <Object:Object> <Invisible:boolean> DumpChildNode* DumpToken* DumpRelation* /InvisiblePath/ ;
InnerDumpNode ;
rel InnerDumpNode.DumpNode -> DumpNode ;
......@@ -20,3 +20,6 @@ abstract DumpRelation ::= <Name> <Bidirectional:boolean> ;
DumpNormalRelation : DumpRelation ;
rel DumpNormalRelation.DumpNode -> DumpNode ;
DumpListRelation : DumpRelation ::= InnerDumpNode* ;
// type of NTA
InvisiblePath ::= InnerDumpNode* ;
......@@ -54,6 +54,7 @@ import java.lang.String;aspect GenerationFrontend {
/**
* Exclude object with types matching at least one of the given regex strings.
* Exlcuding object won't be included in any output. However, their children are still processed.
* @param regexes patterns to match type names
* @return this
* @see java.util.regex.Pattern#compile(java.lang.String)
......@@ -166,16 +167,17 @@ aspect GenerationBackend {
if (tti.transformed.containsKey(obj)) {
return tti.transformed.get(obj);
}
if (matches(getBuildConfig().typeIgnorePattern(), obj.getClass().getSimpleName())) {
tti.transformed.put(obj, null);
return null;
}
// tti.transformed.put(obj, null);
// return null;
DumpNode node = new DumpNode();
node.setObject(obj);
node.setLabel(obj.getClass().getSimpleName() + "@" + obj.hashCode());
node.setName("node" + tti.transformed.size());
tti.transformed.put(obj, node);
this.addDumpNode(node);
if (matches(getBuildConfig().typeIgnorePattern(), obj.getClass().getSimpleName())) {
node.setInvisible(true);
}
if (node.isAstNode()) {
// only caching node.analyseClass does not help, since we want to do this only once per class of a node
final ClassAnalysisResult car;
......@@ -370,6 +372,7 @@ aspect GenerationBackend {
return (String) annotation.annotationType().getMethod("name").invoke(annotation);
}
// --- isAstNode ---
syn boolean DumpNode.isAstNode() {
Class<?> clazz = getObject().getClass();
for (java.lang.reflect.Constructor<?> constructor : clazz.getConstructors()) {
......@@ -383,9 +386,34 @@ aspect GenerationBackend {
return false;
}
// --- astNodeAnnotationPrefix ---
inh String DumpNode.astNodeAnnotationPrefix();
eq DumpAst.getDumpNode().astNodeAnnotationPrefix() = getPackageName() + ".ASTNodeAnnotation";
// --- NTA: InvisiblePath ---
syn InvisiblePath DumpNode.getInvisiblePath() {
InvisiblePath result = new InvisiblePath();
for (DumpNode successor : reachableThroughInvisible()) {
result.addInnerDumpNode(new InnerDumpNode(successor));
}
return result;
}
// --- reachableThroughInvisible ---
syn java.util.List<DumpNode> DumpNode.reachableThroughInvisible() {
java.util.List<DumpNode> result = new java.util.ArrayList<>();
for (DumpChildNode childNode : getDumpChildNodeList()) {
for (DumpNode inner : childNode.innerNodes(false)) {
if (inner.getInvisible()) {
result.addAll(inner.reachableThroughInvisible());
} else if (this.getInvisible()) {
result.add(inner);
}
}
}
return result;
}
class TransformationTransferInformation {
java.util.Map<Object, DumpNode> transformed = new java.util.HashMap<>();
java.util.Map<Class<?>, ClassAnalysisResult> classAnalysisResults = new java.util.HashMap<>();
......
......@@ -20,4 +20,50 @@ aspect Navigation {
// --- printConfig ---
inh PrintConfig BuildConfig.printConfig();
eq DumpAst.getChild().printConfig() = getPrintConfig();
// --- containingDumpNode ---
inh DumpNode InnerDumpNode.containingDumpNode();
inh DumpNode DumpChildNode.containingDumpNode();
inh DumpNode DumpRelation.containingDumpNode();
eq DumpNode.getDumpChildNode().containingDumpNode() = this;
eq DumpNode.getDumpRelation().containingDumpNode() = this;
eq DumpNode.getInvisiblePath().containingDumpNode() = this;
// --- innerVisibleNodes ---
syn java.util.List<DumpNode> DumpChildNode.innerVisibleNodes() = innerNodes(true);
syn java.util.List<DumpNode> DumpRelation.innerVisibleNodes() = innerNodes(true);
// --- innerNodes ---
syn java.util.List<DumpNode> DumpChildNode.innerNodes(boolean onlyVisible);
eq DumpNormalChildNode.innerNodes(boolean onlyVisible) = onlyVisible && (containingDumpNode().getInvisible() || getDumpNode().getInvisible()) ?
java.util.Collections.emptyList() :
java.util.Collections.singletonList(getDumpNode());
eq DumpListChildNode.innerNodes(boolean onlyVisible) {
if (onlyVisible && containingDumpNode().getInvisible()) {
return java.util.Collections.emptyList();
}
java.util.List<DumpNode> result = new java.util.ArrayList<>();
getInnerDumpNodeList().forEach(inner -> {
if (!onlyVisible || !inner.getDumpNode().getInvisible()) {
result.add(inner.getDumpNode());
}
});
return result;
}
syn java.util.List<DumpNode> DumpRelation.innerNodes(boolean onlyVisible);
eq DumpNormalRelation.innerNodes(boolean onlyVisible) = onlyVisible && (containingDumpNode().getInvisible() || getDumpNode().getInvisible()) ?
java.util.Collections.emptyList() :
java.util.Collections.singletonList(getDumpNode());
eq DumpListRelation.innerNodes(boolean onlyVisible) {
if (onlyVisible && containingDumpNode().getInvisible()) {
return java.util.Collections.emptyList();
}
java.util.List<DumpNode> result = new java.util.ArrayList<>();
getInnerDumpNodeList().forEach(inner -> {
if (!onlyVisible || !inner.getDumpNode().getInvisible()) {
result.add(inner.getDumpNode());
}
});
return result;
}
}
......@@ -20,4 +20,9 @@ aspect Printing {
syn String DumpRelation.label() = getName();
syn String DumpToken.label() = getName();
syn String DumpNode.label() = getLabel();
// --- bothVisible ---
syn boolean InnerDumpNode.bothVisible() = !containingDumpNode().getInvisible() && !getDumpNode().getInvisible();
syn boolean DumpNormalChildNode.bothVisible() = !containingDumpNode().getInvisible() && !getDumpNode().getInvisible();
syn boolean DumpNormalRelation.bothVisible() = !containingDumpNode().getInvisible() && !getDumpNode().getInvisible();
}
......@@ -8,6 +8,7 @@ scale {{Scale}}
{{#DumpNodes}}
{{#isAstNode}}
{{^Invisible}}
object "{{label}}" as {{name}} {
{{#DumpTokens}}
{{#isDumpValueToken}}
......@@ -15,35 +16,53 @@ object "{{label}}" as {{name}} {
{{/isDumpValueToken}}
{{/DumpTokens}}
}
{{/Invisible}}
{{/isAstNode}}
{{/DumpNodes}}
{{#DumpNodes}}
{{#DumpTokens}}
{{^Invisible}}
{{^isDumpValueToken}}
{{outerNodeName}} ..> {{innerNodeName}} : {{label}}
{{/isDumpValueToken}}
{{/Invisible}}
{{/DumpTokens}}
{{#DumpChildNodes}}
{{#isList}}
{{#InnerDumpNodes}}
{{#bothVisible}}
{{outerNodeName}} *-- {{innerNodeName}} : {{label}}
{{/bothVisible}}
{{/InnerDumpNodes}}
{{/isList}}
{{^isList}}
{{#bothVisible}}
{{outerNodeName}} *-- {{innerNodeName}} : {{label}}
{{/bothVisible}}
{{/isList}}
{{/DumpChildNodes}}
{{#DumpRelations}}
{{#isList}}
{{#InnerDumpNodes}}
{{#bothVisible}}
{{outerNodeName}} {{#Bidirectional}}<{{/Bidirectional}}--> {{innerNodeName}} : {{label}}
{{/bothVisible}}
{{/InnerDumpNodes}}
{{/isList}}
{{^isList}}
{{#bothVisible}}
{{outerNodeName}} {{#Bidirectional}}<{{/Bidirectional}}--> {{innerNodeName}} : {{label}}
{{/bothVisible}}
{{/isList}}
{{/DumpRelations}}
{{^Invisible}}
{{#InvisiblePath}}
{{#InnerDumpNodes}}
{{outerNodeName}} o.. {{innerNodeName}}
{{/InnerDumpNodes}}
{{/InvisiblePath}}
{{/Invisible}}
{{/DumpNodes}}
{{#BuildConfig}}
{{#Debug}}
......
......@@ -2,9 +2,13 @@ package de.tudresden.inf.st.jastadd.testDumper;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpBuilder;
import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode;
import de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper;
import org.jastadd.testDumper.ast.A;
import org.jastadd.testDumper.ast.Root;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import static de.tudresden.inf.st.jastadd.testDumper.TestUtils.*;
......@@ -65,11 +69,11 @@ public class TestExcluded {
Root root = setupTypes();
List<DumpNode> nodes = TestUtils.dumpModel(root);
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
assertTypeDefaultMatches(nodes);
}
private void assertTypeDefaultMatches(List<DumpNode> nodes) {
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
// A
assertThatMapOf(normalRelationChildren(findByName(nodes, A_NAME))).containsExactlyInAnyOrder(
tuple("BiC1", C_NAME), tuple("BiC2", C_NAME), tuple("BiC3", C_NAME));
......@@ -89,6 +93,7 @@ public class TestExcluded {
Root root = setupTypes();
List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.excludeTypes("NonExistingType"));
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
assertTypeDefaultMatches(nodes);
}
......@@ -97,6 +102,7 @@ public class TestExcluded {
Root root = setupTypes();
List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.excludeTypes("Nameable"));
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
assertTypeDefaultMatches(nodes);
}
......@@ -135,6 +141,44 @@ public class TestExcluded {
assertThatMapOf(normalRelationChildren(findByName(nodes, B_NAME))).isEmpty();
}
@Test
public void testTypesExcludeRegex() {
Root root = setupTypes();
List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.excludeTypes("Ro*t"));
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(A_NAME, B_NAME, C_NAME);
assertTypeDefaultMatches(nodes);
}
@Test
public void testTypesInvisiblePath() throws IOException {
final String A2_Name = "a2";
final String A3_Name = "a3";
final String C2_Name = "c2";
A mostInnerA = createA(A3_Name);
mostInnerA.setB(createB(B_NAME));
Root root = createRoot(createA(A_NAME,
createC(C_NAME,
createA(A2_Name,
createC(C2_Name, mostInnerA)))),
null);
List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.excludeTypes("A", "C"));
Dumper.read(root).excludeTypes("A", "C").dumpAsPNG(Paths.get("test.png"));
DumpNode actualRoot = findByName(nodes, ROOT_NAME);
assertThat(invisiblePath(actualRoot)).flatExtracting(NAME_EXTRACTOR).containsExactly(B_NAME);
}
@Test
public void testTokenDefault() {
}
@Test
public void testTokenExclude() {
}
// --- copy from below here ---
@Test
......
......@@ -14,7 +14,7 @@ import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import static org.assertj.core.api.Assertions.tuple;
import static org.junit.jupiter.api.Assertions.assertFalse;
public class TestUtils {
public static final Random rand = new Random();
......@@ -50,6 +50,13 @@ public class TestUtils {
return result;
}
public static A createA(String name, C myC) {
A result = new A();
result.setName(name);
result.setMyC(myC);
return result;
}
public static B createB(String name) {
B result = new B();
result.setName(name);
......@@ -69,8 +76,15 @@ public class TestUtils {
return result;
}
public static final Function<DumpNode, String> NAME_EXTRACTOR = dp -> {
for (DumpToken dumpToken : dp.getDumpTokenList()) {
public static C createC(String name, A optA) {
C result = new C();
result.setName(name);
result.setA(optA);
return result;
}
public static final Function<DumpNode, String> NAME_EXTRACTOR = node -> {
for (DumpToken dumpToken : node.getDumpTokenList()) {
if (dumpToken.getName().equals("Name")) {
return dumpToken.asDumpValueToken().getValue().toString();
}
......@@ -99,9 +113,11 @@ public class TestUtils {
ExposingDumpBuilder builder = new ExposingDumpBuilder(target);
options.accept(builder);
DumpAst dumpAst = builder.build();
// let mustache run, but ignore result
dumpAst.toPlantUml();
List<DumpNode> result = new ArrayList<>();
for (DumpNode dumpNode : dumpAst.getDumpNodeList()) {
if (dumpNode.isAstNode()) {
if (dumpNode.isAstNode() && !dumpNode.getInvisible()) {
result.add(dumpNode);
}
}
......@@ -124,7 +140,10 @@ public class TestUtils {
for (DumpChildNode dumpChildNode : node.getDumpChildNodeList()) {
if (!dumpChildNode.isList()) {
// then it is a DumpNormalChildNode
result.put(dumpChildNode.label(), ((DumpNormalChildNode) dumpChildNode).getDumpNode());
DumpNode target = ((DumpNormalChildNode) dumpChildNode).getDumpNode();
if (!target.getInvisible()) {
result.put(dumpChildNode.label(), target);
}
}
}
return result;
......@@ -135,8 +154,11 @@ public class TestUtils {
for (DumpChildNode dumpChildNode : node.getDumpChildNodeList()) {
if (dumpChildNode.isList()) {
// then it is a DumpListChildNode
((DumpListChildNode) dumpChildNode).getInnerDumpNodeList().forEach(inner ->
result.computeIfAbsent(dumpChildNode.label(), key -> new ArrayList<>()).add(inner.getDumpNode()));
((DumpListChildNode) dumpChildNode).getInnerDumpNodeList().forEach(inner -> {
if (!inner.getDumpNode().getInvisible()) {
result.computeIfAbsent(dumpChildNode.label(), key -> new ArrayList<>()).add(inner.getDumpNode());
}
});
}
}
return result;
......@@ -147,7 +169,10 @@ public class TestUtils {
for (DumpRelation dumpRelation : node.getDumpRelationList()) {
if (!dumpRelation.isList()) {
// then it is a DumpNormalRelation
result.put(dumpRelation.label(), ((DumpNormalRelation) dumpRelation).getDumpNode());
DumpNode target = ((DumpNormalRelation) dumpRelation).getDumpNode();
if (!target.getInvisible()) {
result.put(dumpRelation.label(), target);
}
}
}
return result;
......@@ -158,8 +183,11 @@ public class TestUtils {
for (DumpRelation dumpRelation : node.getDumpRelationList()) {
if (dumpRelation.isList()) {
// then it is a DumpListRelation
((DumpListRelation) dumpRelation).getInnerDumpNodeList().forEach(
inner -> result.computeIfAbsent(dumpRelation.label(), key -> new ArrayList<>()).add(inner.getDumpNode()));
((DumpListRelation) dumpRelation).getInnerDumpNodeList().forEach(inner -> {
if (!inner.getDumpNode().getInvisible()) {
result.computeIfAbsent(dumpRelation.label(), key -> new ArrayList<>()).add(inner.getDumpNode());
}
});
}
}
return result;
......@@ -170,7 +198,10 @@ public class TestUtils {
for (DumpToken dumpToken : node.getDumpTokenList()) {
if (!dumpToken.isDumpValueToken()) {
// then it is a DumpReferenceToken
result.put(dumpToken.label(), ((DumpReferenceToken) dumpToken).getValue());
DumpNode target = ((DumpReferenceToken) dumpToken).getValue();
if (!target.getInvisible()) {
result.put(dumpToken.label(), target);
}
}
}
return result;
......@@ -188,6 +219,16 @@ public class TestUtils {
return result;
}
public static List<DumpNode> invisiblePath(DumpNode node) {
List<DumpNode> result = new ArrayList<>();
for (InnerDumpNode inner : node.getInvisiblePath().getInnerDumpNodeList()) {
DumpNode target = inner.getDumpNode();
assertFalse(target.getInvisible());
result.add(target);
}
return result;
}
static class ExposingDumpBuilder extends DumpBuilder {
protected ExposingDumpBuilder(Object target) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment