From cfc5dc3958bf68912d30771276638784538c84f6 Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Sat, 26 Sep 2020 11:25:24 +0200
Subject: [PATCH] WIP dumpAst 0.3.2

- split into version w/ and w/out plantuml included
- begin with dumping yaml
- removing unnecessary dependencies
---
 build.gradle                                  |   2 -
 dumpAst/build.gradle                          |  22 +-
 dumpAst/src/main/jastadd/Generation.jadd      |  33 +-
 .../inf/st/jastadd/dumpAst/SimpleMain.java    | 311 ------------------
 .../main/resources/dumpAstVersion.properties  |   4 +-
 dumpAstWithPlantuml/.gitignore                |   5 +
 dumpAstWithPlantuml/build.gradle              | 134 ++++++++
 .../src/main/jastadd/Generation.jadd          |  29 ++
 .../{SimpleMain.java => Grammar2UmlMain.java} |  17 +-
 settings.gradle                               |   1 +
 10 files changed, 192 insertions(+), 366 deletions(-)
 delete mode 100644 dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/SimpleMain.java
 create mode 100644 dumpAstWithPlantuml/.gitignore
 create mode 100644 dumpAstWithPlantuml/build.gradle
 create mode 100644 dumpAstWithPlantuml/src/main/jastadd/Generation.jadd
 rename grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/{SimpleMain.java => Grammar2UmlMain.java} (83%)

diff --git a/build.gradle b/build.gradle
index 1e6f7df..2ea7c13 100644
--- a/build.gradle
+++ b/build.gradle
@@ -38,8 +38,6 @@ subprojects {
     }
 
     dependencies {
-        implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.2'
-        implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.2'
         testImplementation group: 'org.hamcrest', name: 'hamcrest-junit', version: '2.0.0.0'
     }
 
diff --git a/dumpAst/build.gradle b/dumpAst/build.gradle
index 0c1159e..9580ac1 100644
--- a/dumpAst/build.gradle
+++ b/dumpAst/build.gradle
@@ -1,11 +1,8 @@
 apply plugin: 'jastadd'
-apply plugin: 'application'
 apply plugin: 'idea'
 
 sourceCompatibility = 1.8
 
-mainClassName = 'de.tudresden.inf.st.jastadd.dumpAst.compiler.Compiler'
-
 repositories {
     jcenter()
 }
@@ -18,13 +15,7 @@ buildscript {
 }
 
 dependencies {
-    implementation project(':grammar2uml')  // just to test SimpleMain
-    implementation fileTree(include: ['plantuml.jar'], dir: '../libs')
-//    implementation project(':relast.preprocessor')
-
     implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: '0.9.6'
-    implementation group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.11.2'
-    runtime group: 'org.jastadd', name: 'jastadd', version: '2.3.4'
     api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
 
     testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0'
@@ -52,16 +43,11 @@ task newVersion() {
 }
 
 jar {
-    manifest {
-        attributes "Main-Class": mainClassName
-    }
-
     from {
         configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
-        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
     }
 
-    archiveBaseName = 'dumpAst2uml'
+    archiveBaseName = 'dumpAst'
 }
 
 File genSrc = file("src/gen/java")
@@ -115,9 +101,9 @@ jastadd {
         module("DumpAst") {
 
             java {
-                basedir ".."
-                include "dumpAst/src/main/**/*.java"
-                include "dumpAst/src/gen/**/*.java"
+                basedir "."
+                include "src/main/**/*.java"
+                include "src/gen/**/*.java"
             }
 
             jastadd {
diff --git a/dumpAst/src/main/jastadd/Generation.jadd b/dumpAst/src/main/jastadd/Generation.jadd
index c1d0245..111d767 100644
--- a/dumpAst/src/main/jastadd/Generation.jadd
+++ b/dumpAst/src/main/jastadd/Generation.jadd
@@ -180,30 +180,11 @@ import java.lang.String;aspect GenerationFrontend {
       return this;
     }
 
-    /**
-     * Write out content as PNG image generated by plantuml.
-     * @param destination path of destination file
-     * @return this
-     * @throws java.io.IOException if an I/O error happend during opening or writing in that file
-     */
-    public DumpBuilder dumpAsPNG(java.nio.file.Path destination) throws java.io.IOException {
-      String content = build().toPlantUml();
-      net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
-      reader.outputImage(java.nio.file.Files.newOutputStream(destination));
-      return this;
-    }
-
-    /**
-     * Write out content as SVG image generated by plantuml.
-     * @param destination path of destination file
-     * @return this
-     * @throws java.io.IOException if an I/O error happend during opening or writing in that file
-     */
-    public DumpBuilder dumpAsSVG(java.nio.file.Path destination) throws java.io.IOException {
-      String content = build().toPlantUml();
-      net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
-      reader.outputImage(java.nio.file.Files.newOutputStream(destination),
-          new net.sourceforge.plantuml.FileFormatOption(net.sourceforge.plantuml.FileFormat.SVG));
+    public DumpBuilder dumpAsYaml(java.nio.file.Path destination) throws java.io.IOException {
+      String content = build().toYaml();
+      try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
+        writer.write(content);
+      }
       return this;
     }
   }
@@ -557,6 +538,10 @@ aspect GenerationBackend {
     return sb.toString();
   }
 
+  syn String DumpAst.toYaml() {
+    return "TODO :)";
+  }
+
   public class AppendableWriter extends java.io.Writer {
     private final StringBuilder sb;
 
diff --git a/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/SimpleMain.java b/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/SimpleMain.java
deleted file mode 100644
index 2ff16f1..0000000
--- a/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/SimpleMain.java
+++ /dev/null
@@ -1,311 +0,0 @@
-package de.tudresden.inf.st.jastadd.dumpAst;
-
-import beaver.Parser;
-import de.tudresden.inf.st.jastadd.dumpAst.ast.*;
-import de.tudresden.inf.st.jastadd.dumpAst.ast.ASTNode;
-import de.tudresden.inf.st.jastadd.dumpAst.ast.JastAddList;
-import de.tudresden.inf.st.jastadd.grammar2uml.ast.*;
-import de.tudresden.inf.st.jastadd.grammar2uml.parser.Grammar2UmlParser;
-import de.tudresden.inf.st.jastadd.grammar2uml.scanner.Grammar2UmlScanner;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static de.tudresden.inf.st.jastadd.dumpAst.SimpleMain.Kind.*;
-
-/**
- * Testing Relast2Uml without parser.
- *
- * @author rschoene - Initial contribution
- */
-@SuppressWarnings("unused")
-public class SimpleMain {
-
-  public static void main(String[] args) throws Exception {
-    printing();
-//    createManualAST();
-//    small();
-  }
-
-  private static void createManualAST() {
-    DumpAst dumpAst = new DumpAst();
-    dumpAst.setPackageName("foo");
-    DumpNode a = new DumpNode();
-    a.setName("a");
-    dumpAst.addDumpNode(a);
-    DumpNode b = new DumpNode();
-    b.setName("b");
-    dumpAst.addDumpNode(b);
-    DumpNode c = new DumpNode();
-    c.setName("c");
-    dumpAst.addDumpNode(c);
-    DumpNode d = new DumpNode();
-    d.setName("d");
-    dumpAst.addDumpNode(d);
-    DumpNode e = new DumpNode();
-    e.setName("e");
-    dumpAst.addDumpNode(e);
-    DumpNode f = new DumpNode();
-    f.setName("f");
-    dumpAst.addDumpNode(f);
-    DumpNode g = new DumpNode();
-    g.setName("g");
-    dumpAst.addDumpNode(g);
-    DumpNode h = new DumpNode();
-    h.setName("h");
-    dumpAst.addDumpNode(h);
-
-    DumpListChildNode listNode = new DumpListChildNode();
-    listNode.setName("list");
-    listNode.addInnerDumpNode(new InnerDumpNode(b));
-    listNode.addInnerDumpNode(new InnerDumpNode(c));
-    a.addDumpChildNode(listNode);
-    a.addDumpChildNode(new DumpNormalChildNode("opt", d));
-    a.addDumpChildNode(new DumpNormalChildNode("normal", e));
-
-    DumpListRelation listRelation = new DumpListRelation();
-    listRelation.setName("listRel");
-    listRelation.addInnerDumpNode(new InnerDumpNode(f));
-    listRelation.addInnerDumpNode(new InnerDumpNode(g));
-    b.addDumpRelation(listRelation);
-
-    c.addDumpRelation(new DumpNormalRelation("relOpt", false, g));
-    c.addDumpRelation(new DumpNormalRelation("biRelOpt", true, h));
-
-    d.addDumpRelation(new DumpNormalRelation("relNormal", false, c));
-
-    e.addDumpToken(new DumpReferenceToken("ref", h));
-
-    h.addDumpToken(new DumpValueToken("intValue", 4));
-    DumpListRelation biListRelation = new DumpListRelation();
-    biListRelation.setName("biRelList");
-    biListRelation.setBidirectional(true);
-    biListRelation.addInnerDumpNode(new InnerDumpNode(f));
-    biListRelation.addInnerDumpNode(new InnerDumpNode(g));
-    h.addDumpRelation(biListRelation);
-
-    String content = dumpAst.toPlantUml();
-    System.out.println(content);
-  }
-
-  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("mustache.debug", "true");
-    Grammar2Uml model = new Grammar2Uml();
-    Path path = Paths.get("grammar2uml", "src", "test", "resources", "Example.relast");
-    System.out.println("path.toFile().getAbsolutePath() = " + path.toFile().getAbsolutePath());
-    Program program = parseProgram(path);
-    model.setProgram(program);
-
-    Folder folder1 = new Folder();
-    folder1.setName("Folder1");
-    folder1.addType(program.resolveTypeDecl("Wert"));
-    folder1.addType(program.resolveTypeDecl("Quelle"));
-    model.addFolder(folder1);
-
-    model.treeResolveAll();
-//    traverseInitial(model.toMustache());
-    Dumper.read(model.toMustache())
-        .skinParam(SkinParamBooleanSetting.Monochrome, true)
-        .enableDebug()
-        .disableTypes(".*Comment")
-        .dumpAsSource(Paths.get("temp.plantuml"))
-        .dumpAsSVG(Paths.get("temp.svg"));
-    System.out.println(Iterable.class.getMethods()[0].getReturnType());
-  }
-
-  private static void small() throws IOException {
-    Program program = new Program();
-    GrammarFile grammar = new GrammarFile();
-    grammar.setFileName("foo.relast");
-    program.addGrammarFile(grammar);
-
-    TypeDecl typeDeclA = new TypeDecl();
-    typeDeclA.setName("A");
-    grammar.addDeclaration(typeDeclA);
-
-    TypeDecl typeDeclB = new TypeDecl();
-    typeDeclB.setName("B");
-    grammar.addDeclaration(typeDeclB);
-
-    LeftDirectedRelation relation = new LeftDirectedRelation();
-    relation.setSource(new NormalRole(typeDeclA, "myB"));
-    relation.setTarget(new UnnamedRole(typeDeclB));
-    grammar.addDeclaration(relation);
-    WhitespaceComment comment = new WhitespaceComment("// comment\\n");
-    relation.addComment(comment);
-
-    Dumper.read(program)
-        .excludeTokens("Name")
-//        .ignoreTypes(".*Comment")
-        .dumpAsSource(Paths.get("grammar.plantuml"))
-        .dumpAsSVG(Paths.get("grammar.svg"));
-  }
-
-  static final String MORE_INDENT = "| ";
-  static final String AST_NODE_ANNOTATION = "org.jastadd.grammar2uml.ast" + ".ASTNodeAnnotation";
-
-  private static void traverseInitial(Object obj) {
-    traverse(obj, new HashSet<>(), "");
-  }
-
-  private static void traverse(Object obj, Set<Object> seen, String indent) {
-    if (seen.contains(obj)) {
-      return;
-    }
-    seen.add(obj);
-    System.out.println(indent + "|> " + obj.toString());
-    System.out.println(indent + "| isAstNode(obj) = " + isAstNode(obj));
-    printChildren(obj, seen, indent);
-//    printTokens(obj, seen, indent);
-  }
-
-  private static boolean isAstNode(Object obj) {
-    Class<?> clazz = obj.getClass();
-    for (Constructor<?> constructor : clazz.getConstructors()) {
-      if (hasConstructionAnnotationClass(constructor)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private static boolean hasConstructionAnnotationClass(Constructor<?> constructor) {
-//    ASTNodeAnnotation.Constructor.class;
-    for (Annotation annotation : constructor.getAnnotations()) {
-      String canonicalName = annotation.annotationType().getCanonicalName();
-      if (canonicalName.startsWith(AST_NODE_ANNOTATION) && annotation.annotationType().getSimpleName().equals("Constructor")) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  enum Kind {child, list, opt, tokenOrRelation, token, relation, other}
-  static class NameAndKind {
-    String name;
-    Kind kind;
-    static NameAndKind of(String name, Kind kind) {
-      NameAndKind result = new NameAndKind();
-      result.name = name;
-      result.kind = kind;
-      return result;
-    }
-  }
-
-  private static NameAndKind analyzeMethod(Method method) {
-    for (Annotation annotation : method.getAnnotations()) {
-      String canonicalName = annotation.annotationType().getCanonicalName();
-      if (canonicalName.startsWith(AST_NODE_ANNOTATION)) {
-        String simpleName = annotation.annotationType().getSimpleName();
-        switch (simpleName) {
-          case "Child": return NameAndKind.of(invokeName(annotation), Kind.child);
-          case "ListChild": return NameAndKind.of(invokeName(annotation), Kind.list);
-          case "OptChild": return NameAndKind.of(invokeName(annotation), Kind.opt);
-          case "Token": return NameAndKind.of(invokeName(annotation), tokenOrRelation);
-        }
-      }
-    }
-    return NameAndKind.of(null, Kind.other);
-  }
-
-  private static String invokeName(Annotation annotation) {
-    try {
-      return (String) annotation.annotationType().getMethod("name").invoke(annotation);
-    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
-      return "<error>";
-    }
-  }
-
-  static void printChildren(Object obj, Set<Object> seen, String indent) {
-    Class<?> clazz = obj.getClass();
-    for (Method method : clazz.getMethods()) {
-      NameAndKind nameAndKind = analyzeMethod(method);
-      String name = nameAndKind.name;
-      Kind kind = nameAndKind.kind;
-      Method methodToInvoke = method;
-      if (kind == tokenOrRelation) {
-        // heuristic for relations
-        if (name.startsWith("_impl_")) {
-          try {
-            methodToInvoke = clazz.getMethod("get" + name.substring(6));
-            name = name.substring(6);
-            kind = relation;
-          } catch (NoSuchMethodException e) {
-            // this is probably not a relation
-          }
-        }
-        if (kind == tokenOrRelation) {
-          kind = token;
-        }
-      }
-      if (kind != other) {
-        try {
-          Object child = methodToInvoke.invoke(obj);
-          System.out.println(indent + "| " + kind + " child (" + name + ") = " + child);
-          traverse(child, seen, indent + MORE_INDENT);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-          e.printStackTrace();
-        }
-      }
-    }
-  }
-
-//  static void printTokens(Object obj, Set<Object> seen, String indent) {
-//    Class<?> clazz = obj.getClass();
-//    for (Method method : clazz.getMethods()) {
-//      if (method.isAnnotationPresent(ASTNodeAnnotation.Token.class)) {
-//        Method methodToInvoke = null;
-//        String name = method.getAnnotation(ASTNodeAnnotation.Token.class).name();
-//        // heuristic for relations
-//        if (name.startsWith("_impl_")) {
-//          try {
-//            methodToInvoke = clazz.getMethod("get" + name.substring(6));
-//            name = name.substring(6);
-//          } catch (NoSuchMethodException e) {
-//            // this is probably not a relation
-//          }
-//        }
-//        final String kind;
-//        if (methodToInvoke == null) {
-//          methodToInvoke = method;
-//          kind = "token";
-//        } else {
-//          kind = "relation";
-//        }
-//        try {
-//          Object value = methodToInvoke.invoke(obj);
-//          System.out.println(indent + "| " + kind + " (" + name + ") = " + value);
-//          traverse(value, seen, indent + MORE_INDENT);
-//        } catch (IllegalAccessException | InvocationTargetException e) {
-//          e.printStackTrace();
-//        }
-//      }
-//    }
-//  }
-
-  private static Program parseProgram(Path path) {
-    try (BufferedReader reader = Files.newBufferedReader(path)) {
-      Grammar2UmlScanner scanner = new Grammar2UmlScanner(reader);
-      Grammar2UmlParser parser = new Grammar2UmlParser();
-      GrammarFile grammarFile = (GrammarFile) parser.parse(scanner);
-      Program program = new Program();
-      program.addGrammarFile(grammarFile);
-      return program;
-    } catch (IOException | Parser.Exception e) {
-      e.printStackTrace();
-    }
-    return null;
-  }
-}
diff --git a/dumpAst/src/main/resources/dumpAstVersion.properties b/dumpAst/src/main/resources/dumpAstVersion.properties
index ea4c6af..6ce4cb9 100644
--- a/dumpAst/src/main/resources/dumpAstVersion.properties
+++ b/dumpAst/src/main/resources/dumpAstVersion.properties
@@ -1,2 +1,2 @@
-#Fri Sep 11 23:37:05 CEST 2020
-version=0.3.1
+#Sat Sep 26 11:23:37 CEST 2020
+version=0.3.2
diff --git a/dumpAstWithPlantuml/.gitignore b/dumpAstWithPlantuml/.gitignore
new file mode 100644
index 0000000..87b4cdd
--- /dev/null
+++ b/dumpAstWithPlantuml/.gitignore
@@ -0,0 +1,5 @@
+build
+src/gen-res/
+src/gen/
+out/
+*.class
diff --git a/dumpAstWithPlantuml/build.gradle b/dumpAstWithPlantuml/build.gradle
new file mode 100644
index 0000000..8742ea8
--- /dev/null
+++ b/dumpAstWithPlantuml/build.gradle
@@ -0,0 +1,134 @@
+apply plugin: 'jastadd'
+apply plugin: 'idea'
+
+sourceCompatibility = 1.8
+
+repositories {
+    jcenter()
+}
+
+buildscript {
+    repositories.jcenter()
+    dependencies {
+        classpath 'org.jastadd:jastaddgradle:1.13.3'
+    }
+}
+
+dependencies {
+    implementation fileTree(include: ['plantuml.jar'], dir: '../libs')
+
+    implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: '0.9.6'
+    api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
+
+    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0'
+    testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.0'
+    testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.12.1'
+}
+
+def versionFile = '../dumpAst/src/main/resources/dumpAstVersion.properties'
+def oldProps = new Properties()
+
+try {
+    file(versionFile).withInputStream { stream -> oldProps.load(stream) }
+    version = oldProps['version']
+} catch (e) {
+    // this happens, if either the properties file is not present, or cannot be read from
+    throw new GradleException("File ${versionFile} not found or unreadable. Aborting.", e)
+}
+
+jar {
+    from {
+        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
+    }
+
+    archiveBaseName = 'dumpAst-plantuml'
+}
+
+File genSrc = file("src/gen/java")
+sourceSets.main.java.srcDir genSrc
+idea.module.generatedSourceDirs += genSrc
+
+test {
+    useJUnitPlatform()
+
+    maxHeapSize = '1G'
+}
+
+File dumpAstGrammar = file('../dumpAst/src/main/jastadd/DumpAst.relast')
+
+task relast(type: JavaExec) {
+    group = 'Build'
+    main = "-jar"
+
+    doFirst {
+        delete "src/gen/jastadd/*.ast"
+        delete "src/gen/jastadd/DumpAst.jadd"
+        delete "src/gen/jastadd/DumpAstRefResolver.jadd"
+        delete "src/gen/jastadd/DumpAstResolverStubs.jrag"
+        mkdir  "src/gen/jastadd/"
+    }
+
+    args = [
+            "../libs/relast.jar",
+            dumpAstGrammar,
+//            "./src/main/jastadd/MustacheNodes.relast",
+            "--listClass=java.util.ArrayList",
+            "--jastAddList=JastAddList",
+            "--useJastAddNames",
+            "--file",
+            "--resolverHelper",
+            "--grammarName=./src/gen/jastadd/DumpAst"
+    ]
+
+    inputs.files(file("../libs/relast.jar"),
+            dumpAstGrammar)
+    outputs.files(file("./src/gen/jastadd/DumpAst.ast"),
+            file("./src/gen/jastadd/DumpAst.jadd"),
+            file("./src/gen/jastadd/DumpAstRefResolver.jadd"),
+            file('./src/gen/jastadd/DumpAstResolverStubs.jrag'))
+}
+
+jastadd {
+    configureModuleBuild()
+    modules {
+        //noinspection GroovyAssignabilityCheck
+        module("DumpAstWithPlantuml") {
+
+            java {
+                basedir "."
+                include "src/main/**/*.java"
+                include "src/gen/**/*.java"
+            }
+
+            jastadd {
+                basedir ".."
+                include "dumpAst/src/main/jastadd/**/*.ast"
+                include "dumpAst/src/main/jastadd/**/*.jadd"
+                include "dumpAst/src/main/jastadd/**/*.jrag"
+                include "dumpAstWithPlantuml/src/main/jastadd/**/*.jadd"
+                include "dumpAst/src/gen/jastadd/**/*.ast"
+                include "dumpAst/src/gen/jastadd/**/*.jadd"
+                include "dumpAst/src/gen/jastadd/**/*.jrag"
+            }
+        }
+    }
+
+    cleanGen.doFirst {
+        delete "src/gen/java/de"
+        delete "src/gen-res/BuildInfo.properties"
+    }
+
+    preprocessParser.doFirst {
+
+        args += ["--no-beaver-symbol"]
+
+    }
+
+    module = "DumpAstWithPlantuml"
+    astPackage = 'de.tudresden.inf.st.jastadd.dumpAst.ast'
+    genDir = 'src/gen/java'
+    buildInfoDir = 'src/gen-res'
+    jastaddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"]
+}
+
+generateAst.dependsOn relast
diff --git a/dumpAstWithPlantuml/src/main/jastadd/Generation.jadd b/dumpAstWithPlantuml/src/main/jastadd/Generation.jadd
new file mode 100644
index 0000000..35905af
--- /dev/null
+++ b/dumpAstWithPlantuml/src/main/jastadd/Generation.jadd
@@ -0,0 +1,29 @@
+aspect Generation {
+
+    /**
+     * Write out content as PNG image generated by plantuml.
+     * @param destination path of destination file
+     * @return this
+     * @throws java.io.IOException if an I/O error happend during opening or writing in that file
+     */
+    public DumpBuilder DumpBuilder.dumpAsPNG(java.nio.file.Path destination) throws java.io.IOException {
+      String content = build().toPlantUml();
+      net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
+      reader.outputImage(java.nio.file.Files.newOutputStream(destination));
+      return this;
+    }
+
+    /**
+     * Write out content as SVG image generated by plantuml.
+     * @param destination path of destination file
+     * @return this
+     * @throws java.io.IOException if an I/O error happend during opening or writing in that file
+     */
+    public DumpBuilder DumpBuilder.dumpAsSVG(java.nio.file.Path destination) throws java.io.IOException {
+      String content = build().toPlantUml();
+      net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
+      reader.outputImage(java.nio.file.Files.newOutputStream(destination),
+          new net.sourceforge.plantuml.FileFormatOption(net.sourceforge.plantuml.FileFormat.SVG));
+      return this;
+    }
+}
\ No newline at end of file
diff --git a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/SimpleMain.java b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlMain.java
similarity index 83%
rename from grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/SimpleMain.java
rename to grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlMain.java
index b8313b8..e552d55 100644
--- a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/SimpleMain.java
+++ b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlMain.java
@@ -10,23 +10,20 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * Testing Grammar2Uml without parser.
  *
  * @author rschoene - Initial contribution
  */
-public class SimpleMain {
+public class Grammar2UmlMain {
 
   public static void main(String[] args) {
 //    testing();
-    createManualAST();
+    processManualAST();
   }
 
-  private static void createManualAST() {
+  public static Grammar2Uml createManualAST() {
     System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
     System.setProperty("mustache.debug", "true");
     Grammar2Uml model = new Grammar2Uml();
@@ -41,9 +38,11 @@ public class SimpleMain {
     folder1.addType(program.resolveTypeDecl("Quelle"));
     model.addFolder(folder1);
 
-    ArrayList t = new ArrayList();
-    List<TypeDecl> list = ((ArrayList<Object>) t).stream().map(x -> TypeDecl.createRef((String) x)).collect(Collectors.toList());
+    return model;
+  }
 
+  private static void processManualAST() {
+    Grammar2Uml model = createManualAST();
     model.treeResolveAll();
     for (Folder f : model.getFolderList()) {
       System.out.println(f.getName() + ":");
@@ -55,7 +54,7 @@ public class SimpleMain {
     System.out.println(model.generateAspect());
   }
 
-  private static Program parseProgram(Path path) {
+  public static Program parseProgram(Path path) {
     try (BufferedReader reader = Files.newBufferedReader(path)) {
       Grammar2UmlScanner scanner = new Grammar2UmlScanner(reader);
       Grammar2UmlParser parser = new Grammar2UmlParser();
diff --git a/settings.gradle b/settings.gradle
index 5f2b84d..ddebe30 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,4 +3,5 @@ rootProject.name = 'relast2uml'
 include 'relast.preprocessor'
 include 'grammar2uml'
 include 'dumpAst'
+include 'dumpAstWithPlantuml'
 include 'testDumper'
-- 
GitLab