Commit 61859276 authored by René Schöne's avatar René Schöne
Browse files

1.1.0

- include parts using lambda functions
- children of excluded children are now surveyed as well (previously excluded)
parent 3862eede
Pipeline #13988 failed with stages
in 51 seconds
......@@ -159,6 +159,11 @@ task setDevVersionForCI() {
}
}
java {
withJavadocJar()
withSourcesJar()
}
publishing {
publications {
maven(MavenPublication) {
......
......@@ -51,6 +51,10 @@ BuildConfig ::= StyleInformation
GlobalPatternCollection:PatternCollection
ExcludeTypePattern:TypePatternCollectionMapping*
IncludeTypePattern:TypePatternCollectionMapping*
<IncludeRelationMethod:IncludeRelationMethod>
<IncludeChildMethod:IncludeChildMethod>
<IncludeAttributeMethod:IncludeAttributeMethod>
<IncludeTokenMethod:IncludeTokenMethod>
<TypeIgnorePattern>
<IncludeEmptyString:boolean>
<ExcludeNullNodes:boolean>
......
......@@ -127,7 +127,10 @@ aspect GenerationBackend {
// -- singleChild --
Object target = containmentMethod.getMethod().invoke(obj);
String childName = containmentMethod.getName();
DumpNode targetNode = transform(tti, target, options.asNormal(!isChildEnabled(objClassName, childName)).allowNullObjectsOnce());
if (!getBuildConfig().getIncludeChildMethod().shouldInclude(obj, target, childName)) {
continue;
}
DumpNode targetNode = transform(tti, target, options.asNormal(false).allowNullObjectsOnce());
if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName);
......@@ -141,10 +144,12 @@ aspect GenerationBackend {
DumpListChildNode listChild = new DumpListChildNode();
listChild.setComputed(false);
String childName = containmentMethod.getName();
boolean shouldBeInvisible = !isChildEnabled(objClassName, childName);
listChild.setName(childName);
for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, options.asNormal(shouldBeInvisible));
if (!getBuildConfig().getIncludeChildMethod().shouldInclude(obj, target, childName)) {
continue;
}
DumpNode targetNode = transform(tti, target, options.asNormal(false));
if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode));
}
......@@ -162,7 +167,13 @@ aspect GenerationBackend {
Object target = otherMethod.getMethod().invoke(obj);
String childName = otherMethod.getName();
boolean computed = otherMethod.asSingleChildMethod().isNTASingleChildMethod();
DumpNode targetNode = transform(tti, target, options.asNormal(!isChildEnabled(objClassName, childName)).computed(computed).allowNullObjectsOnce());
boolean shouldInclude = computed ?
getBuildConfig().getIncludeAttributeMethod().shouldInclude(obj, childName, true, () -> catchedInvoke(otherMethod.getMethod(), obj)) :
getBuildConfig().getIncludeChildMethod().shouldInclude(obj, target, childName);
if (!shouldInclude) {
continue;
}
DumpNode targetNode = transform(tti, target, options.asNormal(false).computed(computed).allowNullObjectsOnce());
if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName);
......@@ -177,10 +188,15 @@ aspect GenerationBackend {
boolean computed = otherMethod.asListChildMethod().isNTAListChildMethod();
listChild.setComputed(computed);
String childName = otherMethod.getName();
boolean shouldBeInvisible = !isChildEnabled(objClassName, childName);
listChild.setName(childName);
for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, options.asNormal(shouldBeInvisible).computed(computed));
boolean shouldInclude = computed ?
getBuildConfig().getIncludeAttributeMethod().shouldInclude(obj, childName, true, () -> catchedInvoke(otherMethod.getMethod(), obj)) :
getBuildConfig().getIncludeChildMethod().shouldInclude(obj, target, childName);
if (!shouldInclude) {
continue;
}
DumpNode targetNode = transform(tti, target, options.asNormal(false).computed(computed));
if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode));
}
......@@ -191,6 +207,9 @@ aspect GenerationBackend {
} else if (otherMethod.isSingleRelationMethod()) {
// -- singleRelation --
Object target = otherMethod.getMethod().invoke(obj);
if (!getBuildConfig().getIncludeRelationMethod().shouldInclude(obj, target, otherMethod.getName())) {
continue;
}
DumpNode targetNode = transform(tti, target, options.asRelation());
if (targetNode != null) {
DumpNormalRelation normalRelation = new DumpNormalRelation();
......@@ -204,6 +223,9 @@ aspect GenerationBackend {
DumpListRelation listRelation = new DumpListRelation();
listRelation.setName(otherMethod.getName());
for (Object target : targetList) {
if (!getBuildConfig().getIncludeRelationMethod().shouldInclude(obj, target, otherMethod.getName())) {
continue;
}
DumpNode targetNode = transform(tti, target, options.asRelation());
if (target != null && targetNode != null) {
listRelation.addInnerRelationDumpNode(new InnerRelationDumpNode(targetNode));
......@@ -214,12 +236,14 @@ aspect GenerationBackend {
}
} else if (otherMethod.isTokenMethod()) {
// -- token --
TokenMethod tokenMethod = otherMethod.asTokenMethod();
boolean shouldInclude = tokenMethod.isAttributeMethod() ?
getBuildConfig().getIncludeAttributeMethod().shouldInclude(obj, otherMethod.getName(), false, () -> catchedInvoke(otherMethod.getMethod(), obj)) :
getBuildConfig().getIncludeTokenMethod().shouldInclude(obj, otherMethod.getName(), otherMethod.getMethod().invoke(obj));
if (!shouldInclude) {
continue;
}
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) {
DumpToken token = null;
boolean atLeastOneASTNode = false;
......@@ -267,6 +291,16 @@ aspect GenerationBackend {
return node;
}
private Object DumpAst.catchedInvoke(java.lang.reflect.Method method, Object obj) {
try {
return method.invoke(obj);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
private void DumpAst.applyStyle(DumpNode node) {
Object obj = node.getObject();
node.setLabel(getBuildConfig().getStyleInformation().getNameMethod().get(obj));
......@@ -324,12 +358,10 @@ aspect GenerationBackend {
try {
java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName);
// normal get + token-name -> singleRelation
if (isRelationEnabled(clazzName, relationName)) {
SingleRelationMethod singleRelationMethod = new SingleRelationMethod();
singleRelationMethod.setMethod(relationMethod);
singleRelationMethod.setName(relationName);
result.addOtherMethod(singleRelationMethod);
}
SingleRelationMethod singleRelationMethod = new SingleRelationMethod();
singleRelationMethod.setMethod(relationMethod);
singleRelationMethod.setName(relationName);
result.addOtherMethod(singleRelationMethod);
continue;
} catch (NoSuchMethodException e) {
// ignore, but we know this is probably not a single relation
......@@ -338,23 +370,19 @@ aspect GenerationBackend {
try {
java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName + "List");
// normal get + token-name + "List" -> listRelation
if (isRelationEnabled(clazzName, relationName)) {
ListRelationMethod listRelationMethod = new ListRelationMethod();
listRelationMethod.setMethod(relationMethod);
listRelationMethod.setName(relationName);
result.addOtherMethod(listRelationMethod);
}
ListRelationMethod listRelationMethod = new ListRelationMethod();
listRelationMethod.setMethod(relationMethod);
listRelationMethod.setName(relationName);
result.addOtherMethod(listRelationMethod);
continue;
} catch (NoSuchMethodException e) {
// ignore, but we know this is probably not a relation at all
}
}
if (isTokenEnabled(clazzName, tokenName)) {
IntrinsicTokenMethod tokenMethod = new IntrinsicTokenMethod();
tokenMethod.setMethod(method);
tokenMethod.setName(tokenName);
result.addOtherMethod(tokenMethod);
}
IntrinsicTokenMethod tokenMethod = new IntrinsicTokenMethod();
tokenMethod.setMethod(method);
tokenMethod.setName(tokenName);
result.addOtherMethod(tokenMethod);
break;
case "Attribute":
String attributeName = method.getName();
......@@ -368,20 +396,18 @@ aspect GenerationBackend {
if (attributeName.endsWith("List")) {
attributeName = attributeName.substring(0, attributeName.length() - 4);
}
if (isNonterminalAttributeEnabled(clazzName, attributeName)) {
if (Iterable.class.isAssignableFrom(method.getReturnType())) {
NTAListChildMethod ntaListChildMethod = new NTAListChildMethod();
ntaListChildMethod.setMethod(method);
ntaListChildMethod.setName(attributeName);
result.addOtherMethod(ntaListChildMethod);
} else {
NTASingleChildMethod ntaSingleChildMethod = new NTASingleChildMethod();
ntaSingleChildMethod.setMethod(method);
ntaSingleChildMethod.setName(attributeName);
result.addOtherMethod(ntaSingleChildMethod);
}
if (Iterable.class.isAssignableFrom(method.getReturnType())) {
NTAListChildMethod ntaListChildMethod = new NTAListChildMethod();
ntaListChildMethod.setMethod(method);
ntaListChildMethod.setName(attributeName);
result.addOtherMethod(ntaListChildMethod);
} else {
NTASingleChildMethod ntaSingleChildMethod = new NTASingleChildMethod();
ntaSingleChildMethod.setMethod(method);
ntaSingleChildMethod.setName(attributeName);
result.addOtherMethod(ntaSingleChildMethod);
}
} else if (isAttributeEnabled(clazzName, attributeName)) {
} else {
// normal attribute
AttributeMethod attributeMethod = new AttributeMethod();
attributeMethod.setMethod(method);
......@@ -446,90 +472,6 @@ aspect GenerationBackend {
syn boolean DumpAst.isTypeEnabled(String typeName) {
return !matches(getBuildConfig().typeIgnorePattern(), typeName);
}
// --- isTokenEnabled ---
syn boolean DumpAst.isTokenEnabled(String parentType, String tokenName) {
// level 4: excluded for type? -> return no
PatternCollection excludeOnType = getBuildConfig().matchExcludePatternCollection(parentType);
if (excludeOnType != null && matches(excludeOnType.tokenPattern(), tokenName)) {
return false;
}
// level 3: included for type? -> return yes
PatternCollection includeOnType = getBuildConfig().matchIncludePatternCollection(parentType);
if (includeOnType != null && matches(includeOnType.tokenPattern(), tokenName)) {
return true;
}
// level 2: globally excluded? -> return no
// level 1: otherwise return yes
return !matches(getBuildConfig().getGlobalPatternCollection().tokenPattern(), tokenName);
}
// --- isChildEnabled ---
syn boolean DumpAst.isChildEnabled(String parentType, String childName) {
// level 4: excluded for type? -> return no
PatternCollection excludeOnType = getBuildConfig().matchExcludePatternCollection(parentType);
if (excludeOnType != null && matches(excludeOnType.childPattern(), childName)) {
return false;
}
// level 3: included for type? -> return yes
PatternCollection includeOnType = getBuildConfig().matchIncludePatternCollection(parentType);
if (includeOnType != null && matches(includeOnType.childPattern(), childName)) {
return true;
}
// level 2: globally excluded? -> return no
// level 1: otherwise return yes
return !matches(getBuildConfig().getGlobalPatternCollection().childPattern(), childName);
}
// --- isRelationEnabled ---
syn boolean DumpAst.isRelationEnabled(String parentType, String relationName) {
// level 4: excluded for type? -> return no
PatternCollection excludeOnType = getBuildConfig().matchExcludePatternCollection(parentType);
if (excludeOnType != null && matches(excludeOnType.relationPattern(), relationName)) {
return false;
}
// level 3: included for type? -> return yes
PatternCollection includeOnType = getBuildConfig().matchIncludePatternCollection(parentType);
if (includeOnType != null && matches(includeOnType.relationPattern(), relationName)) {
return true;
}
// level 2: globally excluded? -> return no
// level 1: otherwise return yes
return !matches(getBuildConfig().getGlobalPatternCollection().relationPattern(), relationName);
}
// --- isAttributeEnabled ---
syn boolean DumpAst.isAttributeEnabled(String parentType, String attributeName) {
// level 4: included for type? -> return yes
PatternCollection includeOnType = getBuildConfig().matchIncludePatternCollection(parentType);
if (includeOnType != null && matches(includeOnType.attributePattern(), attributeName)) {
return true;
}
// level 3: excluded for type? -> return no
PatternCollection excludeOnType = getBuildConfig().matchExcludePatternCollection(parentType);
if (excludeOnType != null && matches(excludeOnType.attributePattern(), attributeName)) {
return false;
}
// level 2: globally included? -> return yes
// level 1: otherwise return no
return matches(getBuildConfig().getGlobalPatternCollection().attributePattern(), attributeName);
}
// --- isNonterminalAttributeEnabled ---
syn boolean DumpAst.isNonterminalAttributeEnabled(String parentType, String ntaName) {
// level 4: included for type? -> return yes
PatternCollection includeOnType = getBuildConfig().matchIncludePatternCollection(parentType);
if (includeOnType != null && matches(includeOnType.ntaPattern(), ntaName)) {
return true;
}
// level 3: excluded for type? -> return no
PatternCollection excludeOnType = getBuildConfig().matchExcludePatternCollection(parentType);
if (excludeOnType != null && matches(excludeOnType.ntaPattern(), ntaName)) {
return false;
}
// level 2: globally included? -> return yes
// level 1: otherwise return no
return matches(getBuildConfig().getGlobalPatternCollection().ntaPattern(), ntaName);
}
// --- match{In,Ex}cludePatternCollection ---
syn PatternCollection BuildConfig.matchIncludePatternCollection(String typeName) {
......@@ -714,4 +656,24 @@ aspect GenerationBackend {
public interface StyleMethod<ASTNODE> {
String get(ASTNODE node);
}
@FunctionalInterface
public interface IncludeRelationMethod<ASTNODE> {
boolean shouldInclude(ASTNODE sourceNode, ASTNODE targetNode, String roleName);
}
@FunctionalInterface
public interface IncludeChildMethod<ASTNODE> {
boolean shouldInclude(ASTNODE parentNode, ASTNODE childNode, String contextName);
}
@FunctionalInterface
public interface IncludeAttributeMethod<ASTNODE> {
boolean shouldInclude(ASTNODE node, String attributeName, boolean isNTA, java.util.function.Supplier<Object> value);
}
@FunctionalInterface
public interface IncludeTokenMethod<ASTNODE> {
boolean shouldInclude(ASTNODE node, String tokenName, Object value);
}
}
......@@ -2,6 +2,8 @@ package de.tudresden.inf.st.jastadd.dumpAst.ast;
import java.lang.reflect.InvocationTargetException;
import static de.tudresden.inf.st.jastadd.dumpAst.ast.ASTNode.matches;
/**
* Building a dump.
* <p>
......@@ -42,6 +44,68 @@ public class DumpBuilder {
protected DumpBuilder(Object target) {
this.target = target;
buildConfig = new BuildConfig();
buildConfig.setIncludeChildMethod((parentNode, childNode, contextName) -> {
System.out.printf("child: %s, %s, %s%n", parentNode, childNode, contextName);
// level 4: excluded for type? -> return no
PatternCollection excludeOnType = buildConfig.matchExcludePatternCollection(parentNode.getClass().getSimpleName());
if (excludeOnType != null && matches(excludeOnType.childPattern(), contextName)) {
return false;
}
// level 3: included for type? -> return yes
PatternCollection includeOnType = buildConfig.matchIncludePatternCollection(parentNode.getClass().getSimpleName());
if (includeOnType != null && matches(includeOnType.childPattern(), contextName)) {
return true;
}
// level 2: globally excluded? -> return no
// level 1: otherwise return yes
return !matches(buildConfig.getGlobalPatternCollection().childPattern(), contextName);
});
buildConfig.setIncludeRelationMethod((sourceNode, targetNode, roleName) -> {
// level 4: excluded for type? -> return no
PatternCollection excludeOnType = buildConfig.matchExcludePatternCollection(sourceNode.getClass().getSimpleName());
if (excludeOnType != null && matches(excludeOnType.relationPattern(), roleName)) {
return false;
}
// level 3: included for type? -> return yes
PatternCollection includeOnType = buildConfig.matchIncludePatternCollection(sourceNode.getClass().getSimpleName());
if (includeOnType != null && matches(includeOnType.relationPattern(), roleName)) {
return true;
}
// level 2: globally excluded? -> return no
// level 1: otherwise return yes
return !matches(buildConfig.getGlobalPatternCollection().relationPattern(), roleName);
});
buildConfig.setIncludeTokenMethod((node, tokenName, value) -> {
// level 4: excluded for type? -> return no
PatternCollection excludeOnType = buildConfig.matchExcludePatternCollection(node.getClass().getSimpleName());
if (excludeOnType != null && matches(excludeOnType.tokenPattern(), tokenName)) {
return false;
}
// level 3: included for type? -> return yes
PatternCollection includeOnType = buildConfig.matchIncludePatternCollection(node.getClass().getSimpleName());
if (includeOnType != null && matches(includeOnType.tokenPattern(), tokenName)) {
return true;
}
// level 2: globally excluded? -> return no
// level 1: otherwise return yes
return !matches(buildConfig.getGlobalPatternCollection().tokenPattern(), tokenName);
});
buildConfig.setIncludeAttributeMethod((node, attributeName, isNTA, supplier) -> {
// level 4: included for type? -> return yes
PatternCollection includeOnType = buildConfig.matchIncludePatternCollection(node.getClass().getSimpleName());
if (includeOnType != null && matches(isNTA ? includeOnType.ntaPattern() : includeOnType.attributePattern(), attributeName)) {
return true;
}
// level 3: excluded for type? -> return no
PatternCollection excludeOnType = buildConfig.matchExcludePatternCollection(node.getClass().getSimpleName());
if (excludeOnType != null && matches(isNTA ? excludeOnType.ntaPattern() : excludeOnType.attributePattern(), attributeName)) {
return false;
}
// level 2: globally included? -> return yes
// level 1: otherwise return no
PatternCollection global = buildConfig.getGlobalPatternCollection();
return matches(isNTA ? global.ntaPattern() : global.attributePattern(), attributeName);
});
buildConfig.setGlobalPatternCollection(new PatternCollection());
buildConfig.setStyleInformation(StyleInformation.createDefault());
printConfig = new PrintConfig();
......@@ -111,6 +175,14 @@ public class DumpBuilder {
// --- Tokens ---
public <ASTNODE> DumpBuilder includeTokensWhen(IncludeTokenMethod<ASTNODE> spec) {
buildConfig.setIncludeTokenMethod(spec);
if (!buildConfig.getGlobalPatternCollection().getTokenPattern().isEmpty()) {
System.err.println("Overriding previous filters for tokens");
}
return this;
}
/**
* Exclude tokens and their value if the token name matches at least one of the given regex strings.
* <p>
......@@ -168,6 +240,14 @@ public class DumpBuilder {
// --- Children ---
public <ASTNODE> DumpBuilder includeChildWhen(IncludeChildMethod<ASTNODE> spec) {
buildConfig.setIncludeChildMethod(spec);
if (!buildConfig.getGlobalPatternCollection().getChildPattern().isEmpty()) {
System.err.println("Overriding previous filters for children");
}
return this;
}
/**
* Exclude every child whose name (i.e., context) matches at least on of the given regex strings.
* This means, that the complete object and its (transitive) children will never be included in any output.
......@@ -228,6 +308,14 @@ public class DumpBuilder {
// --- Attributes ---
public <ASTNODE> DumpBuilder includeAttributeWhen(IncludeAttributeMethod<ASTNODE> spec) {
buildConfig.setIncludeAttributeMethod(spec);
if (!buildConfig.getGlobalPatternCollection().getAttributePattern().isEmpty()) {
System.err.println("Overriding previous filters for attributes");
}
return this;
}
/**
* Include attributes (as tokens) and their value if the attribute name matches at least on of the given regex strings.
* <p>
......@@ -354,6 +442,14 @@ public class DumpBuilder {
// --- Relations ---
public <ASTNODE> DumpBuilder includeRelationsWhen(IncludeRelationMethod<ASTNODE> spec) {
buildConfig.setIncludeRelationMethod(spec);
if (!buildConfig.getGlobalPatternCollection().getRelationPattern().isEmpty()) {
System.err.println("Overriding previous filters for relations");
}
return this;
}
/**
* Exclude every relation whose role-name matches at least on of the given regex strings.
* This means two things: a) the relation to any potential target object(s) is never shown, and b) the target
......
#Tue Jun 21 14:31:38 CEST 2022
version=1.0.4
#Thu Jun 23 16:13:20 CEST 2022
version=1.1.0
......@@ -2,14 +2,14 @@ package de.tudresden.inf.st.jastadd.featureTest;
import de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper;
import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamBooleanSetting;
import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamStringSetting;
import org.jastadd.featureTest.ast.*;
import org.jastadd.featureTest.ast.A;
import org.jastadd.featureTest.ast.B;
import org.jastadd.featureTest.ast.C;
import org.jastadd.featureTest.ast.Root;
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.
......@@ -40,26 +40,35 @@ public class FeatureTestMain {
Path pathToYaml = Paths.get("featureTest.yml");
Path pathToPng = Paths.get("featureTest.png");
// Dumper.read(null).dumpAsPNG(pathToPng);
Dumper
// .read(null)
.read(root)
// .customPreamble("hide empty members")
.customPreamble("title My fancy title")
.includeChildWhen((parentNode, childNode, contextName) -> {
if (parentNode instanceof A && ((A) parentNode).getName().equals("A2")) {
return false;
}
return !contextName.equals("MyC");
})
.includeRelationsWhen((sourceNode, targetNode, roleName) ->
!(sourceNode instanceof B) || !((B) sourceNode).getName().equals("B6.1.1"))
.includeAttributeWhen((node, attributeName, isNTA, supplier) -> {
switch (attributeName) {
case "referenceAttr":
case "collectBs":
case "Calculated":
case "AlsoCalculatedListNewSyntax":
return true;
default:
return false;
}
})
.skinParam(SkinParamBooleanSetting.Shadowing, false)
// .enableRelationWithRank()
.includeAttributes("referenceAttr"
, "collectBs"
)
.includeNonterminalAttributes("Calculated")
.includeNonterminalAttributes("AlsoCalculatedListNewSyntax")
.dumpAsYaml(pathToYaml, true)
.dumpAsPNG(pathToPng)
.dumpAsSource(Paths.get("featureTest.puml"))
;
}
private void m() {
//noinspection UnnecessaryReturnStatement
return;
}
}
......@@ -312,7 +312,8 @@ public class TestExcluded {
root.getA().getB().setOneA(root.getA().getMyC().getA());
List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.excludeChildren("MyC"));
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME);
assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(
ROOT_NAME, A_NAME, B_NAME, A2_Name, B2_NAME);
DumpNode actualA = findByName(nodes, A_NAME);
assertThatMapOf(normalChildren(actualA)).containsExactlyInAnyOrder(tuple("B", B_NAME));
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment