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

WIP dumpAst 0.3

parent 99c0fbe1
No related branches found
No related tags found
No related merge requests found
Pipeline #7845 passed
...@@ -32,7 +32,7 @@ dependencies { ...@@ -32,7 +32,7 @@ dependencies {
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.12.1' testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.12.1'
} }
def versionFile = 'src/main/resources/dumpAst2umlVersion.properties' def versionFile = 'src/main/resources/dumpAstVersion.properties'
def oldProps = new Properties() def oldProps = new Properties()
try { try {
......
DumpAst ::= DumpNode* <PackageName> <Scale:double> ; DumpAst ::= DumpNode* <PackageName> BuildConfig PrintConfig ;
BuildConfig ::= <TypeIgnore> <TokenIgnore> <ChildIgnore> <AttributeIgnore> <RelationIgnore> <IgnoreEmptyString:boolean> <Debug:boolean> ;
PrintConfig ::= <Scale:double> <Version> Header* ;
Header ::= <Value> ;
DumpNode ::= <Name> <Label> <Object:Object> DumpChildNode* DumpToken* DumpRelation* ; DumpNode ::= <Name> <Label> <Object:Object> DumpChildNode* DumpToken* DumpRelation* ;
InnerDumpNode ; InnerDumpNode ;
rel InnerDumpNode.DumpNode -> DumpNode ; rel InnerDumpNode.DumpNode -> DumpNode ;
......
...@@ -4,27 +4,96 @@ aspect Generation { ...@@ -4,27 +4,96 @@ aspect Generation {
return new DumpBuilder(obj); return new DumpBuilder(obj);
} }
} }
public enum SkinParamBooleanSetting {
Monochrome, Shadowing, Handwritten
}
public enum SkinParamStringSetting {
backgroundColor
}
public class DumpBuilder { public class DumpBuilder {
private Object target; private Object target;
private String packageName; private String packageName;
private DumpAst result; private DumpAst result;
private java.util.List<String> header = new java.util.ArrayList<>(); private BuildConfig buildConfig = new BuildConfig();
private PrintConfig printConfig = new PrintConfig();
protected DumpBuilder(Object target) { protected DumpBuilder(Object target) {
this.target = target; this.target = target;
printConfig.setScale(1);
printConfig.setVersion(readVersion());
ignoreEmptyStrings(true);
}
public DumpBuilder setDebug(boolean debug) {
buildConfig.setDebug(debug);
return this;
}
public DumpBuilder ignoreEmptyStrings(boolean ignoreThem) {
buildConfig.setIgnoreEmptyString(ignoreThem);
return this;
} }
public DumpBuilder ignoreTypes(String... regexes) { public DumpBuilder ignoreTypes(String... regexes) {
// TODO updateIgnored(() -> buildConfig.getTypeIgnore(), s -> buildConfig.setTypeIgnore(s), regexes);
return this;
}
public DumpBuilder ignoreTokens(String... regexes) {
updateIgnored(() -> buildConfig.getTokenIgnore(), s -> buildConfig.setTokenIgnore(s), regexes);
return this;
}
public DumpBuilder ignoreAttributes(String... regexes) {
updateIgnored(() -> buildConfig.getAttributeIgnore(), s -> buildConfig.setAttributeIgnore(s), regexes);
return this;
}
public DumpBuilder ignoreChildren(String... regexes) {
updateIgnored(() -> buildConfig.getChildIgnore(), s -> buildConfig.setChildIgnore(s), regexes);
return this;
}
public DumpBuilder ignoreRelations(String... regexes) {
updateIgnored(() -> buildConfig.getRelationIgnore(), s -> buildConfig.setRelationIgnore(s), regexes);
return this;
}
private void updateIgnored(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter, String... values) {
for (String value : values) {
if (getter.get().isEmpty()) {
setter.accept(value);
} else {
setter.accept(getter.get() + "|" + value);
}
}
}
public DumpBuilder customPreamble(String option) {
printConfig.addHeader(new Header(option));
return this;
}
public DumpBuilder skinParam(SkinParamStringSetting setting, String value) {
customPreamble("skinparam " + setting.toString() + " " + value);
return this;
}
public DumpBuilder skinParam(SkinParamBooleanSetting setting, boolean value) {
customPreamble("skinparam " + setting.toString() + " " + value);
return this; return this;
} }
public DumpBuilder skinParam(String option) { public DumpBuilder setScale(double value) {
// TODO printConfig.setScale(value);
return this; return this;
} }
private String readVersion() {
try {
java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("dumpAstVersion");
return resources.getString("version");
} catch (java.util.MissingResourceException e) {
return "version ?";
}
}
protected DumpAst build() { protected DumpAst build() {
if (result == null) { if (result == null) {
result = new DumpAst(); result = new DumpAst();
result.setPackageName(this.packageName == null ? this.target.getClass().getPackage().getName() : this.packageName); result.setPackageName(this.packageName == null ? this.target.getClass().getPackage().getName() : this.packageName);
result.setBuildConfig(this.buildConfig);
result.setPrintConfig(this.printConfig);
try { try {
result.transform(new TransformationTransferInformation(), this.target); result.transform(new TransformationTransferInformation(), this.target);
} catch (java.lang.reflect.InvocationTargetException e) { } catch (java.lang.reflect.InvocationTargetException e) {
...@@ -38,7 +107,6 @@ aspect Generation { ...@@ -38,7 +107,6 @@ aspect Generation {
return result; return result;
} }
public DumpBuilder dumpAsSource(java.nio.file.Path destination) throws java.io.IOException { public DumpBuilder dumpAsSource(java.nio.file.Path destination) throws java.io.IOException {
build().setScale(0.1);
String content = build().toPlantUml(); String content = build().toPlantUml();
try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) { try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
writer.write(content); writer.write(content);
...@@ -46,14 +114,12 @@ aspect Generation { ...@@ -46,14 +114,12 @@ aspect Generation {
return this; return this;
} }
public DumpBuilder dumpAsPNG(java.nio.file.Path destination) throws java.io.IOException { public DumpBuilder dumpAsPNG(java.nio.file.Path destination) throws java.io.IOException {
build().setScale(0.1);
String content = build().toPlantUml(); String content = build().toPlantUml();
net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content); net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
reader.outputImage(java.nio.file.Files.newOutputStream(destination)); reader.outputImage(java.nio.file.Files.newOutputStream(destination));
return this; return this;
} }
public DumpBuilder dumpAsSVG(java.nio.file.Path destination) throws java.io.IOException { public DumpBuilder dumpAsSVG(java.nio.file.Path destination) throws java.io.IOException {
build().setScale(1);
String content = build().toPlantUml(); String content = build().toPlantUml();
net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content); net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
reader.outputImage(java.nio.file.Files.newOutputStream(destination), reader.outputImage(java.nio.file.Files.newOutputStream(destination),
...@@ -71,6 +137,10 @@ aspect Generation { ...@@ -71,6 +137,10 @@ aspect Generation {
if (tti.transformed.containsKey(obj)) { if (tti.transformed.containsKey(obj)) {
return tti.transformed.get(obj); return tti.transformed.get(obj);
} }
if (matches(getBuildConfig().typeIgnorePattern(), obj.getClass().getSimpleName())) {
tti.transformed.put(obj, null);
return null;
}
DumpNode node = new DumpNode(); DumpNode node = new DumpNode();
node.setObject(obj); node.setObject(obj);
node.setLabel(obj.getClass().getSimpleName() + "@" + obj.hashCode()); node.setLabel(obj.getClass().getSimpleName() + "@" + obj.hashCode());
...@@ -90,10 +160,11 @@ aspect Generation { ...@@ -90,10 +160,11 @@ aspect Generation {
// -- singleChild -- // -- singleChild --
for (java.lang.reflect.Method method : car.singleChildMethods) { for (java.lang.reflect.Method method : car.singleChildMethods) {
Object target = method.invoke(obj); Object target = method.invoke(obj);
if (target != null) { DumpNode targetNode = transform(tti, target);
if (target != null && targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode(); DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(car.names.get(method)); normalChild.setName(car.names.get(method));
normalChild.setDumpNode(transform(tti, target)); normalChild.setDumpNode(targetNode);
node.addDumpChildNode(normalChild); node.addDumpChildNode(normalChild);
} }
} }
...@@ -103,8 +174,9 @@ aspect Generation { ...@@ -103,8 +174,9 @@ aspect Generation {
DumpListChildNode listChild = new DumpListChildNode(); DumpListChildNode listChild = new DumpListChildNode();
listChild.setName(car.names.get(method)); listChild.setName(car.names.get(method));
for (Object target : targetList) { for (Object target : targetList) {
if (target != null) { DumpNode targetNode = transform(tti, target);
listChild.addInnerDumpNode(new InnerDumpNode(transform(tti, target))); if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode(targetNode));
} }
} }
node.addDumpChildNode(listChild); node.addDumpChildNode(listChild);
...@@ -112,10 +184,11 @@ aspect Generation { ...@@ -112,10 +184,11 @@ aspect Generation {
// -- singleRelation -- // -- singleRelation --
for (java.lang.reflect.Method method : car.singleRelationMethods) { for (java.lang.reflect.Method method : car.singleRelationMethods) {
Object target = method.invoke(obj); Object target = method.invoke(obj);
if (target != null) { DumpNode targetNode = transform(tti, target);
if (target != null && targetNode != null) {
DumpNormalRelation normalRelation = new DumpNormalRelation(); DumpNormalRelation normalRelation = new DumpNormalRelation();
normalRelation.setName(car.names.get(method)); normalRelation.setName(car.names.get(method));
normalRelation.setDumpNode(transform(tti, target)); normalRelation.setDumpNode(targetNode);
node.addDumpRelation(normalRelation); node.addDumpRelation(normalRelation);
} }
} }
...@@ -125,8 +198,9 @@ aspect Generation { ...@@ -125,8 +198,9 @@ aspect Generation {
DumpListRelation listRelation = new DumpListRelation(); DumpListRelation listRelation = new DumpListRelation();
listRelation.setName(car.names.get(method)); listRelation.setName(car.names.get(method));
for (Object target : targetList) { for (Object target : targetList) {
if (target != null) { DumpNode targetNode = transform(tti, target);
listRelation.addInnerDumpNode(new InnerDumpNode(transform(tti, target))); if (target != null && targetNode != null) {
listRelation.addInnerDumpNode(new InnerDumpNode(targetNode));
} }
} }
node.addDumpRelation(listRelation); node.addDumpRelation(listRelation);
...@@ -136,20 +210,23 @@ aspect Generation { ...@@ -136,20 +210,23 @@ aspect Generation {
Object target = method.invoke(obj); Object target = method.invoke(obj);
if (target != null) { if (target != null) {
DumpNode targetNode = transform(tti, target); DumpNode targetNode = transform(tti, target);
DumpToken token; DumpToken token = null;
if (targetNode.isAstNode()) { if (targetNode != null && targetNode.isAstNode()) {
token = new DumpReferenceToken().setValue(targetNode); token = new DumpReferenceToken().setValue(targetNode);
} else { } else {
// maybe ignore empty string values here if (target != null && (!getBuildConfig().getIgnoreEmptyString() || !target.toString().isEmpty())) {
DumpValueToken valueToken = new DumpValueToken(); DumpValueToken valueToken = new DumpValueToken();
valueToken.setValue(target); valueToken.setValue(target);
token = valueToken; token = valueToken;
} }
}
if (token != null) {
token.setName(car.names.get(method)); token.setName(car.names.get(method));
node.addDumpToken(token); node.addDumpToken(token);
} }
} }
} }
}
return node; return node;
} }
...@@ -165,10 +242,18 @@ aspect Generation { ...@@ -165,10 +242,18 @@ aspect Generation {
switch (simpleName) { switch (simpleName) {
case "Child": case "Child":
case "OptChild": case "OptChild":
String singleChildName = invokeName(annotation);
if (!matches(buildConfig().childIgnorePattern(), singleChildName)) {
result.singleChildMethods.add(method); result.singleChildMethods.add(method);
result.names.put(method, singleChildName);
}
break; break;
case "ListChild": case "ListChild":
String listChildName = invokeName(annotation);
if (!matches(buildConfig().childIgnorePattern(), listChildName)) {
result.listChildMethods.add(method); result.listChildMethods.add(method);
result.names.put(method, listChildName);
}
break; break;
case "Token": case "Token":
// heuristic for relations // heuristic for relations
...@@ -178,8 +263,10 @@ aspect Generation { ...@@ -178,8 +263,10 @@ aspect Generation {
try { try {
java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName); java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName);
// normal get + token-name -> singleRelation // normal get + token-name -> singleRelation
if (!matches(buildConfig().relationIgnorePattern(), relationName)) {
result.singleRelationMethods.add(relationMethod); result.singleRelationMethods.add(relationMethod);
result.names.put(relationMethod, relationName); result.names.put(relationMethod, relationName);
}
continue; continue;
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
// ignore, but we know this is probably not a single relation // ignore, but we know this is probably not a single relation
...@@ -188,25 +275,39 @@ aspect Generation { ...@@ -188,25 +275,39 @@ aspect Generation {
try { try {
java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName + "List"); java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName + "List");
// normal get + token-name + "List" -> listRelation // normal get + token-name + "List" -> listRelation
if (!matches(buildConfig().relationIgnorePattern(), relationName)) {
result.listRelationMethods.add(relationMethod); result.listRelationMethods.add(relationMethod);
result.names.put(relationMethod, relationName); result.names.put(relationMethod, relationName);
}
continue; continue;
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
// ignore, but we know this is probably not a relation at all // ignore, but we know this is probably not a relation at all
} }
} }
if (!matches(buildConfig().tokenIgnorePattern(), tokenName)) {
result.tokenMethods.add(method); result.tokenMethods.add(method);
result.names.put(method, tokenName);
}
break; break;
default:
continue;
} }
result.names.put(method, invokeName(annotation));
} }
} }
} }
return result; return result;
} }
syn java.util.regex.Pattern BuildConfig.typeIgnorePattern() = java.util.regex.Pattern.compile(getTypeIgnore());
syn java.util.regex.Pattern BuildConfig.childIgnorePattern() = java.util.regex.Pattern.compile(getChildIgnore());
syn java.util.regex.Pattern BuildConfig.tokenIgnorePattern() = java.util.regex.Pattern.compile(getTokenIgnore());
syn java.util.regex.Pattern BuildConfig.attributeIgnorePattern() = java.util.regex.Pattern.compile(getAttributeIgnore());
syn java.util.regex.Pattern BuildConfig.relationIgnorePattern() = java.util.regex.Pattern.compile(getRelationIgnore());
static boolean ASTNode.matches(java.util.regex.Pattern p, String input) {
return p.matcher(input).matches();
}
// --- version --- (mustache has buildConfig as context)
syn String BuildConfig.version() = printConfig().getVersion();
private static String DumpNode.invokeName(java.lang.annotation.Annotation annotation) private static String DumpNode.invokeName(java.lang.annotation.Annotation annotation)
throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException { throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException {
return (String) annotation.annotationType().getMethod("name").invoke(annotation); return (String) annotation.annotationType().getMethod("name").invoke(annotation);
......
...@@ -8,4 +8,10 @@ aspect Navigation { ...@@ -8,4 +8,10 @@ aspect Navigation {
// --- isDumpValueToken --- // --- isDumpValueToken ---
syn boolean DumpToken.isDumpValueToken() = false; syn boolean DumpToken.isDumpValueToken() = false;
eq DumpValueToken.isDumpValueToken() = true; eq DumpValueToken.isDumpValueToken() = true;
inh BuildConfig DumpNode.buildConfig();
eq DumpAst.getChild().buildConfig() = getBuildConfig();
inh PrintConfig BuildConfig.printConfig();
eq DumpAst.getChild().printConfig() = getPrintConfig();
} }
...@@ -17,6 +17,7 @@ import java.nio.file.Paths; ...@@ -17,6 +17,7 @@ import java.nio.file.Paths;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import static org.jastadd.dumpAst2uml.compiler.SimpleMain.Kind.*; import static org.jastadd.dumpAst2uml.compiler.SimpleMain.Kind.*;
...@@ -96,6 +97,7 @@ public class SimpleMain { ...@@ -96,6 +97,7 @@ public class SimpleMain {
} }
private static void printing() throws IOException { private static void printing() throws IOException {
// java.util.regex.Pattern p;p.pattern()
System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager"); System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
System.setProperty("mustache.debug", "true"); System.setProperty("mustache.debug", "true");
Grammar2Uml model = new Grammar2Uml(); Grammar2Uml model = new Grammar2Uml();
...@@ -113,6 +115,9 @@ public class SimpleMain { ...@@ -113,6 +115,9 @@ public class SimpleMain {
model.treeResolveAll(); model.treeResolveAll();
// traverseInitial(model.toMustache()); // traverseInitial(model.toMustache());
Dumper.read(model.toMustache()) Dumper.read(model.toMustache())
.skinParam(SkinParamBooleanSetting.Monochrome, true)
.setDebug(true)
.ignoreTypes(".*Comment")
.dumpAsSource(Paths.get("temp.plantuml")) .dumpAsSource(Paths.get("temp.plantuml"))
.dumpAsSVG(Paths.get("temp.svg")); .dumpAsSVG(Paths.get("temp.svg"));
} }
...@@ -135,8 +140,12 @@ public class SimpleMain { ...@@ -135,8 +140,12 @@ public class SimpleMain {
relation.setSource(new NormalRole(typeDeclA, "myB")); relation.setSource(new NormalRole(typeDeclA, "myB"));
relation.setTarget(new UnnamedRole(typeDeclB)); relation.setTarget(new UnnamedRole(typeDeclB));
grammar.addDeclaration(relation); grammar.addDeclaration(relation);
WhitespaceComment comment = new WhitespaceComment("// comment\\n");
relation.addComment(comment);
Dumper.read(program) Dumper.read(program)
.ignoreTokens("Name")
// .ignoreTypes(".*Comment")
.dumpAsSource(Paths.get("grammar.plantuml")) .dumpAsSource(Paths.get("grammar.plantuml"))
.dumpAsSVG(Paths.get("grammar.svg")); .dumpAsSVG(Paths.get("grammar.svg"));
} }
......
@startuml @startuml
{{#PrintConfig}}
scale {{Scale}} scale {{Scale}}
{{#Headers}}
{{Value}}
{{/Headers}}
{{/PrintConfig}}
{{#DumpNodes}} {{#DumpNodes}}
{{#isAstNode}} {{#isAstNode}}
object "{{label}}" as {{name}} { object "{{label}}" as {{name}} {
...@@ -39,4 +45,13 @@ object "{{label}}" as {{name}} { ...@@ -39,4 +45,13 @@ object "{{label}}" as {{name}} {
{{/isList}} {{/isList}}
{{/DumpRelations}} {{/DumpRelations}}
{{/DumpNodes}} {{/DumpNodes}}
{{#BuildConfig}}
{{#Debug}}
legend right
%date()
dumpAst: {{version}}
plantuml: %version()
endlegend
{{/Debug}}
{{/BuildConfig}}
@enduml @enduml
#Sat Sep 05 18:50:58 CEST 2020
version=0.2
#Sat Sep 05 23:54:45 CEST 2020
version=0.3
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment