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

Merge branch 'dev' into 'main'

1.1.0

See merge request jastadd/relast2uml!11
parents 469f5036 f9d17e5f
No related branches found
No related tags found
1 merge request!111.1.0
Pipeline #13991 failed
Showing
with 1148 additions and 667 deletions
variables:
GIT_SUBMODULE_STRATEGY: recursive
before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle
cache:
paths:
- .gradle/wrapper
- .gradle/caches
stages:
- build
- test
......
[submodule "relast.preprocessor"]
path = relast.preprocessor
url = ../relast-preprocessor.git
[submodule "dumpAst/src/main/jastadd/mustache"]
path = dumpAst/src/main/jastadd/mustache
url = ../mustache
plugins {
id 'com.github.ben-manes.versions' version '0.36.0'
id 'java'
}
java.toolchain.languageVersion = JavaLanguageVersion.of(11)
if (JavaVersion.current().isJava8Compatible()) {
allprojects {
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
}
}
}
// --- Buildscripts (must be at the top) ---
buildscript {
repositories.mavenLocal()
repositories.mavenCentral()
dependencies {
classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3'
......@@ -9,23 +8,30 @@ buildscript {
// --- Plugin definitions ---
plugins {
id 'com.github.ben-manes.versions'
id 'java'
id 'idea'
id 'com.github.ben-manes.versions'
id 'org.jastadd'
id 'java-library'
id 'maven-publish'
}
apply plugin: 'jastadd'
// --- Dependencies ---
repositories {
mavenCentral()
maven {
name 'gitlab-maven'
url 'https://git-st.inf.tu-dresden.de/api/v4/groups/jastadd/-/packages/maven'
}
}
configurations {
relast
}
dependencies {
jastadd2 "org.jastadd:jastadd:2.3.5"
// https://mvnrepository.com/artifact/net.sourceforge.plantuml/plantuml
relast group: 'org.jastadd', name: 'relast', version: "${relast_version}"
implementation group: 'net.sourceforge.plantuml', name: 'plantuml', version: '1.2022.2'
api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: "0.9.10"
......@@ -42,18 +48,15 @@ File mustacheGrammar = file('./src/main/jastadd/mustache/Mustache.relast')
task relast(type: JavaExec) {
group = 'Build'
main = "-jar"
classpath = configurations.relast
mainClass = 'org.jastadd.relast.compiler.Compiler'
doFirst {
delete "src/gen/jastadd/*.ast"
delete "src/gen/jastadd/DumpAst.jadd"
delete "src/gen/jastadd/DumpAstRefResolver.jadd"
delete "src/gen/jastadd/DumpAstResolverStubs.jrag"
delete "src/gen/jastadd/*"
mkdir "src/gen/jastadd/"
}
args = [
"../libs/relast.jar",
dumpAstGrammar,
mustacheGrammar,
"--listClass=java.util.ArrayList",
......@@ -63,14 +66,6 @@ task relast(type: JavaExec) {
"--resolverHelper",
"--grammarName=./src/gen/jastadd/DumpAst"
]
inputs.files(file("../libs/relast.jar"),
dumpAstGrammar,
mustacheGrammar)
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 ---
......@@ -121,6 +116,16 @@ jastadd {
// --- Versioning and Publishing ---
group = 'de.tudresden.inf.st'
task fatJar(type: Jar) {
dependsOn jar
group = "build"
archiveAppendix = "fatjar"
from sourceSets.main.output
from {
configurations.runtimeClasspath.collect {it.isDirectory() ? it : zipTree(it) }
}
}
def versionFile = "src/main/resources/${project.getName()}Version.properties"
try {
......@@ -154,6 +159,11 @@ task setDevVersionForCI() {
}
}
java {
withJavadocJar()
withSourcesJar()
}
publishing {
publications {
maven(MavenPublication) {
......
......@@ -4,8 +4,11 @@ rel DumpAst.RootNode? -> DumpNode ;
DumpNode ::= DumpChildNode* DumpToken* DumpRelation*
<Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> <Computed:boolean> <ManualStereotypes>
/InvisiblePath/ ;
InnerDumpNode ;
rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner ;
InnerRelationDumpNode;
rel InnerRelationDumpNode.DumpNode -> DumpNode ; // .ContainerOfInner*
abstract DumpChildNode ::= <Name> <Computed:boolean> ;
DumpNormalChildNode : DumpChildNode ;
......@@ -15,15 +18,16 @@ DumpListChildNode : DumpChildNode ::= InnerDumpNode* ;
abstract DumpToken ::= <Name> <Computed:boolean> ;
DumpReferenceToken : DumpToken ;
rel DumpReferenceToken.Value -> DumpNode ;
DumpReferenceListToken : DumpToken ::= InnerRelationDumpNode* ;
DumpValueToken : DumpToken ::= <Value:Object> ;
abstract DumpRelation ::= <Name> <Bidirectional:boolean> ;
DumpNormalRelation : DumpRelation ;
rel DumpNormalRelation.DumpNode -> DumpNode ;
DumpListRelation : DumpRelation ::= InnerDumpNode* ;
DumpListRelation : DumpRelation ::= InnerRelationDumpNode* ;
// type of NTA
InvisiblePath ::= InnerDumpNode* ;
InvisiblePath ::= InnerRelationDumpNode* ;
ClassAnalysisResult ::= ContainmentMethod:AnalysedMethod* OtherMethod:AnalysedMethod* ;
abstract AnalysedMethod ::= <Method:java.lang.reflect.Method> <Name> ;
......@@ -47,6 +51,10 @@ BuildConfig ::= StyleInformation
GlobalPatternCollection:PatternCollection
ExcludeTypePattern:TypePatternCollectionMapping*
IncludeTypePattern:TypePatternCollectionMapping*
<IncludeRelationMethod:IncludeRelationMethod>
<IncludeChildMethod:IncludeChildMethod>
<IncludeAttributeMethod:IncludeAttributeMethod>
<IncludeTokenMethod:IncludeTokenMethod>
<TypeIgnorePattern>
<IncludeEmptyString:boolean>
<ExcludeNullNodes:boolean>
......@@ -58,5 +66,6 @@ StyleInformation ::= <NameMethod:StyleMethod> <BackgroundColorMethod:StyleMethod
PrintConfig ::= Header*
<Scale:double>
<Version>
<RelationWithRank:boolean>
<OrderChildren:boolean> ;
Header ::= <Value> ;
This diff is collapsed.
aspect GenerationFrontend {
public class Dumper {
/**
* Prepare to read in the given object. Use the <code>dump*</code> methods to actually dump its content.
* @param obj the object to dump
* @return a builder to adjust dump options
*/
public static DumpBuilder read(Object obj) {
return new DumpBuilder(obj);
}
}
public enum SkinParamBooleanSetting {
/** Print in grayscale? */
Monochrome,
/** Use shadows? */
Shadowing,
/** Use handwritten style? */
Handwritten
}
public enum SkinParamStringSetting {
/** Set color of background */
backgroundColor
}
/**
* Building a dump.
* <p>
*
* <h3>Inclusion and Exclusion of Types</h3>
* Types can be only be disabled, see {@link #disableTypes(String[])}.
*
* <h3>Inclusion and Exclusion of Childrens, tokens and relations</h3>
* Childrens, tokens and relations are included by default.
* This can be changed using exclusions and inclusion, both in general and per-type.
* They are applied in the following order making later conditions take precedence over the first ones.
* <ol>
* <li>Include everything as default.
* <li>Exclude general.
* <li>Include per type.
* <li>Exclude per type.
* </ol>
*
* <h3>Inclusion and Exclusion of Attributes</h3>
* Attributes are excluded by default, i.e., not shown.
* This can be changed using inclusions and exclusions, both in general and per-type.
* They are applied in the following order making later conditions take precedence over the first ones.
* <ol>
* <li> Exclude everything as default.
* <li> Include general.
* <li> Exclude per type.
* <li> Include per type
* </ol>
*/
public class DumpBuilder {
private final Object target;
private String packageName;
private DumpAst result;
private final BuildConfig buildConfig;
private final PrintConfig printConfig;
protected DumpBuilder(Object target) {
this.target = target;
buildConfig = new BuildConfig();
buildConfig.setGlobalPatternCollection(new PatternCollection());
buildConfig.setStyleInformation(StyleInformation.createDefault());
printConfig = new PrintConfig();
printConfig.setScale(1);
printConfig.setVersion(readVersion());
}
/**
* Add debug information in dumped content, mainly version numbers.
* @return this
*/
public DumpBuilder enableDebug() {
buildConfig.setDebug(true);
return this;
}
/**
* Include empty strings for all tokens
* @return this
*/
public DumpBuilder includeEmptyStringsOnTokens() {
buildConfig.setIncludeEmptyString(true);
return this;
}
/**
* Disable all objects with types matching at least one of the given regex strings.
* Disabled objects won't be included in any output. However, their children are still processed.
* <p>
* See {@link DumpBuilder} for details on inclusion and exclusion precedence.
* @param regexes patterns to match type names
* @return this
* @see java.util.regex.Pattern#compile(java.lang.String)
*/
public DumpBuilder disableTypes(String regex, String... moreRegexes) {
updateRegexes(() -> buildConfig.getTypeIgnorePattern(),
s -> buildConfig.setTypeIgnorePattern(s),
regex, moreRegexes);
return this;
}
/**
* Exclude tokens and their value if the token name matches at least one of the given regex strings.
* <p>
* See {@link DumpBuilder} for details on inclusion and exclusion precedence.
* @param regexes regex patterns to match token names
* @return this
* @see java.util.regex.Pattern#compile(java.lang.String)
*/
public DumpBuilder excludeTokens(String regex, String... moreRegexes) {
updateRegexes(() -> buildConfig.getGlobalPatternCollection().getTokenPattern(),
s -> buildConfig.getGlobalPatternCollection().setTokenPattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder excludeTokensFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateExcludePatternCollection(typeRegex);
updateRegexes(() -> collection.getTokenPattern(),
s -> collection.setTokenPattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder excludeChildrenFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateExcludePatternCollection(typeRegex);
updateRegexes(() -> collection.getChildPattern(),
s -> collection.setChildPattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder excludeRelationsFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateExcludePatternCollection(typeRegex);
updateRegexes(() -> collection.getRelationPattern(),
s -> collection.setRelationPattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder excludeAttributesFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateExcludePatternCollection(typeRegex);
updateRegexes(() -> collection.getAttributePattern(),
s -> collection.setAttributePattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder excludeNonterminalAttributesFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateExcludePatternCollection(typeRegex);
updateRegexes(() -> collection.getNonterminalAttributePattern(),
s -> collection.setNonterminalAttributePattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder includeTokensFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateIncludePatternCollection(typeRegex);
updateRegexes(() -> collection.getTokenPattern(),
s -> collection.setTokenPattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder includeChildrenFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateIncludePatternCollection(typeRegex);
updateRegexes(() -> collection.getChildPattern(),
s -> collection.setChildPattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder includeRelationsFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateIncludePatternCollection(typeRegex);
updateRegexes(() -> collection.getRelationPattern(),
s -> collection.setRelationPattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder includeAttributesFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateIncludePatternCollection(typeRegex);
updateRegexes(() -> collection.getAttributePattern(),
s -> collection.setAttributePattern(s),
regex, moreRegexes);
return this;
}
/** TODO: document, implement, sort */
public DumpBuilder includeNonterminalAttributesFor(String typeRegex, String regex, String... moreRegexes) {
PatternCollection collection = findOrCreateIncludePatternCollection(typeRegex);
updateRegexes(() -> collection.getNonterminalAttributePattern(),
s -> collection.setNonterminalAttributePattern(s),
regex, moreRegexes);
return this;
}
/**
* Include attributes (as tokens) and their value if the attribute name matches at least on of the given regex strings.
* <p>
* See {@link DumpBuilder} for details on inclusion and exclusion precedence.
* @param regexes regex patterns to match token names
* @return this
* @see java.util.regex.Pattern#compile(java.lang.String)
*/
public DumpBuilder includeAttributes(String regex, String... moreRegexes) {
updateRegexes(() -> buildConfig.getGlobalPatternCollection().getAttributePattern(),
s -> buildConfig.getGlobalPatternCollection().setAttributePattern(s),
regex, moreRegexes);
return this;
}
/**
* Includes nonterminal-attributes (as children) and their values if
* their attribute name matches at least on of the given regex strings.
* <br>
* <b>Note</b>: A leading "get" and a trailing "List" in the name will be removed prior to matching.
* Thus, it should not be contained in the regex either.
* <p>
* See {@link DumpBuilder} for details on inclusion and exclusion precedence.
* @param regexes regex patterns to match token names
* @return this
* @see java.util.regex.Pattern#compile(java.lang.String)
*/
public DumpBuilder includeNonterminalAttributes(String regex, String... moreRegexes) {
updateRegexes(() -> buildConfig.getGlobalPatternCollection().getNonterminalAttributePattern(),
s -> buildConfig.getGlobalPatternCollection().setNonterminalAttributePattern(s),
regex, moreRegexes);
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.
* <p>
* See {@link DumpBuilder} for details on inclusion and exclusion precedence.
* @param regexes regex patterns to match child names
* @return this
* @see java.util.regex.Pattern#compile(java.lang.String)
*/
public DumpBuilder excludeChildren(String regex, String... moreRegexes) {
updateRegexes(() -> buildConfig.getGlobalPatternCollection().getChildPattern(),
s -> buildConfig.getGlobalPatternCollection().setChildPattern(s),
regex, moreRegexes);
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
* object(s) are not shown unless they are reachable by another relation or by containment.
* <p>
* See {@link DumpBuilder} for details on inclusion and exclusion precedence.
* @param regexes regex patterns to match child names
* @return this
* @see java.util.regex.Pattern#compile(java.lang.String)
*/
public DumpBuilder excludeRelations(String regex, String... moreRegexes) {
updateRegexes(() -> buildConfig.getGlobalPatternCollection().getRelationPattern(),
s -> buildConfig.getGlobalPatternCollection().setRelationPattern(s),
regex, moreRegexes);
return this;
}
private PatternCollection findOrCreateIncludePatternCollection(String typeRegex) {
PatternCollection result = buildConfig.findIncludePatternCollection(typeRegex);
if (result == null) {
TypePatternCollectionMapping mapping = new TypePatternCollectionMapping();
mapping.setTypeRegex(typeRegex);
result = new PatternCollection();
mapping.setPatternCollection(result);
buildConfig.addIncludeTypePattern(mapping);
}
return result;
}
private PatternCollection findOrCreateExcludePatternCollection(String typeRegex) {
PatternCollection result = buildConfig.findExcludePatternCollection(typeRegex);
if (result == null) {
TypePatternCollectionMapping mapping = new TypePatternCollectionMapping();
mapping.setTypeRegex(typeRegex);
result = new PatternCollection();
mapping.setPatternCollection(result);
buildConfig.addExcludeTypePattern(mapping);
}
return result;
}
private void updateRegexes(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter, String regex, String... moreRegexes) {
if (getter.get().isEmpty()) {
setter.accept(regex);
} else {
setter.accept(getter.get() + "|" + regex);
}
for (String value : moreRegexes) {
setter.accept(getter.get() + "|" + value);
}
}
public DumpBuilder excludeNullNodes() {
buildConfig.setExcludeNullNodes(true);
return this;
}
public DumpBuilder includeNullNodes() {
buildConfig.setExcludeNullNodes(false);
return this;
}
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;
}
public <ASTNODE> DumpBuilder setNameMethod(StyleMethod<ASTNODE> nameMethod) {
buildConfig.getStyleInformation().setNameMethod(nameMethod);
return this;
}
public <ASTNODE> DumpBuilder setBackgroundColorMethod(StyleMethod<ASTNODE> colorMethod) {
buildConfig.getStyleInformation().setBackgroundColorMethod(colorMethod);
return this;
}
public <ASTNODE> DumpBuilder setTextColorMethod(StyleMethod<ASTNODE> colorMethod) {
buildConfig.getStyleInformation().setTextColorMethod(colorMethod);
return this;
}
public <ASTNODE> DumpBuilder setStereotypeMethod(StyleMethod<ASTNODE> stereotypeMethod) {
buildConfig.getStyleInformation().setStereotypeMethod(stereotypeMethod);
return this;
}
public DumpBuilder setComputedColor(String color) {
buildConfig.getStyleInformation().setComputedColor(color);
return this;
}
public DumpBuilder setScale(double value) {
printConfig.setScale(value);
return this;
}
public DumpBuilder orderChildren() {
printConfig.setOrderChildren(true);
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() {
if (result == null) {
result = new DumpAst();
final String packageNameToUse;
if (this.packageName != null) {
packageNameToUse = this.packageName;
} else {
if (this.target == null) {
packageNameToUse = null;
} else {
packageNameToUse = this.target.getClass().getPackage().getName();
}
}
result.setPackageName(packageNameToUse);
result.setBuildConfig(this.buildConfig);
result.setPrintConfig(this.printConfig);
try {
result.transform(new TransformationTransferInformation(), this.target);
} catch (java.lang.reflect.InvocationTargetException e) {
throw new RuntimeException("Could not transform :(", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Could not transform :(", e);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Could not transform :(", e);
}
}
return result;
}
/**
* Write out content as plantuml source code.
* @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 dumpAsSource(java.nio.file.Path destination) throws java.io.IOException {
String content = build().toPlantUml();
try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
writer.write(content);
}
return this;
}
public DumpBuilder dumpAsYaml(java.nio.file.Path destination, boolean prependCreationComment) throws java.io.IOException {
String content = build().printYaml(prependCreationComment);
try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
writer.write(content);
}
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));
return this;
}
}
}
......@@ -26,14 +26,6 @@ aspect GenerationToYaml {
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) {
MappingElement result = new MappingElement();
// children
......@@ -128,6 +120,7 @@ aspect GenerationToYaml {
result.put("name", getName());
result.put("computed", getComputed());
// attributes
result.put("isList", isList());
result.put("label", label());
result.put("isDumpValueToken", isDumpValueToken());
return result;
......@@ -142,8 +135,20 @@ aspect GenerationToYaml {
syn MappingElement DumpReferenceToken.toYaml(boolean fromRelation) {
MappingElement result = super.toYaml(fromRelation);
// tokens
// attributes
result.put("innerNodeName", innerNodeName());
result.put("innerNotNull", innerNotNull());
result.put("outerNodeName", outerNodeName());
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;
}
......@@ -165,13 +170,14 @@ aspect GenerationToYaml {
// attributes
result.put("bothVisible", bothVisible());
result.put("innerNodeName", innerNodeName());
result.put("innerNotNull", innerNotNull());
return result;
}
syn MappingElement DumpListRelation.toYaml(boolean fromRelation) {
MappingElement result = super.toYaml(fromRelation);
// children
addYamledList(result, "InnerDumpNodes", getInnerDumpNodeList(), fromRelation);
addYamledList(result, "InnerRelationDumpNode", getInnerRelationDumpNodeList(), fromRelation);
return result;
}
......@@ -185,13 +191,32 @@ aspect GenerationToYaml {
return result;
}
syn MappingElement InnerRelationDumpNode.toYaml(boolean fromRelation) {
MappingElement result = new MappingElement();
// attributes
result.put("bothVisible", bothVisible());
result.put("innerNodeName", innerNodeName());
result.put("innerNotNull", innerNotNull());
result.put("outerNodeName", outerNodeName());
result.put("label", label());
return result;
}
syn MappingElement InvisiblePath.toYaml(boolean fromRelation) {
MappingElement result = super.toYaml(fromRelation);
// children
addYamledList(result, "InnerDumpNodes", getInnerDumpNodeList(), fromRelation);
addYamledList(result, "InnerRelationDumpNode", getInnerRelationDumpNodeList(), fromRelation);
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
public static ValueElement ValueElement.of(double value) {
return new ValueElement(false, String.valueOf(value));
......
......@@ -4,6 +4,8 @@ aspect Navigation {
eq DumpListChildNode.isList() = true;
syn boolean DumpRelation.isList() = false;
eq DumpListRelation.isList() = true;
syn boolean DumpToken.isList() = false;
eq DumpReferenceListToken.isList() = true;
// --- buildConfig ---
inh BuildConfig DumpNode.buildConfig();
......@@ -12,14 +14,20 @@ aspect Navigation {
// --- printConfig ---
inh PrintConfig BuildConfig.printConfig();
inh PrintConfig DumpNode.printConfig();
inh PrintConfig DumpNormalRelation.printConfig();
inh PrintConfig InnerRelationDumpNode.printConfig();
inh PrintConfig DumpReferenceToken.printConfig();
eq DumpAst.getChild().printConfig() = getPrintConfig();
// --- containingDumpNode ---
inh DumpNode InnerDumpNode.containingDumpNode();
inh DumpNode InnerRelationDumpNode.containingDumpNode();
inh DumpNode DumpChildNode.containingDumpNode();
inh DumpNode DumpRelation.containingDumpNode();
eq DumpNode.getDumpChildNode().containingDumpNode() = this;
eq DumpNode.getDumpRelation().containingDumpNode() = this;
eq DumpNode.getDumpToken().containingDumpNode() = this;
eq DumpNode.getInvisiblePath().containingDumpNode() = this;
// --- container ---
......@@ -69,7 +77,7 @@ aspect Navigation {
return java.util.Collections.emptyList();
}
java.util.List<DumpNode> result = new java.util.ArrayList<>();
getInnerDumpNodeList().forEach(inner -> {
getInnerRelationDumpNodeList().forEach(inner -> {
if (!onlyVisible || !inner.getDumpNode().getInvisible()) {
result.add(inner.getDumpNode());
}
......@@ -77,6 +85,11 @@ aspect Navigation {
return result;
}
// --- innerNotNull ---
syn boolean DumpNormalRelation.innerNotNull() = !printConfig().getRelationWithRank() && getDumpNode() != null && getDumpNode().getObject() != null;
syn boolean DumpReferenceToken.innerNotNull() = !printConfig().getRelationWithRank() && getValue() != null && getValue().getObject() != null;
syn boolean InnerRelationDumpNode.innerNotNull() = !printConfig().getRelationWithRank() && getDumpNode() != null && getDumpNode().getObject() != null;
// === Method naviagtion ===
coll java.util.List<SingleChildMethod> ClassAnalysisResult.singleChildMethods() [new java.util.ArrayList<>()] root ClassAnalysisResult;
SingleChildMethod contributes this to ClassAnalysisResult.singleChildMethods();
......
aspect Printing {
// --- outerNodeName ---
inh String InnerDumpNode.outerNodeName();
inh String InnerRelationDumpNode.outerNodeName();
inh String DumpChildNode.outerNodeName();
inh String DumpRelation.outerNodeName();
inh String DumpToken.outerNodeName();
inh String DumpReferenceToken.outerNodeName();
eq DumpNode.getChild().outerNodeName() = name();
// --- innerNodeName ---
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 DumpNormalRelation.innerNodeName() = getDumpNode() != null ? getDumpNode().name() : null;
syn String DumpReferenceToken.innerNodeName() = getValue().name();
......@@ -21,15 +24,46 @@ aspect Printing {
syn String DumpToken.label() = getName() + (getComputed() ? "()" : "");
syn String DumpNode.label() = getLabel();
inh String InnerDumpNode.label();
inh String InnerRelationDumpNode.label();
eq DumpListChildNode.getInnerDumpNode(int index).label() = label() + "[" + index + "]";
eq DumpListRelation.getInnerDumpNode(int index).label() = label() + "[" + index + "]";
eq InvisiblePath.getInnerDumpNode(int index).label() = null;
eq DumpListRelation.getInnerRelationDumpNode(int index).label() = label() + "[" + index + "]";
eq DumpReferenceListToken.getInnerRelationDumpNode(int index).label() = label() + "[" + index + "]";
eq InvisiblePath.getInnerRelationDumpNode(int index).label() = null;
// --- bothVisible ---
boolean ASTNode.bothVisible(DumpNode one, DumpNode two) {
return one != null && two != null && !one.getInvisible() && !two.getInvisible();
}
syn boolean InnerDumpNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
syn boolean InnerRelationDumpNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
syn boolean DumpNormalChildNode.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
syn boolean DumpNormalRelation.bothVisible() = bothVisible(containingDumpNode(), getDumpNode());
}
aspect Debugging {
syn String ClassAnalysisResult.prettyPrint() {
StringBuilder sb = new StringBuilder();
sb.append("ContainmentMethods:");
for (AnalysedMethod method : getContainmentMethodList()) {
sb.append(method.prettyPrint()).append(",");
}
if (getNumContainmentMethod() == 0) {
sb.append("none. ");
}
sb.append("other methods:");
for (AnalysedMethod method : getOtherMethodList()) {
sb.append(method.prettyPrint()).append(",");
}
if (getNumOtherMethod() == 0) {
sb.append("none.");
}
return sb.toString();
}
syn String AnalysedMethod.prettyPrint() {
String methodString = "?";
try {
methodString = getMethod().toString();
} catch (Exception ignore) {}
return this.getClass().getSimpleName() + "[Method: " + methodString + ", Name: " + getName() + "]";
}
}
package de.tudresden.inf.st.jastadd.dumpAst.ast;
/**
* Entrypoint for dumpAst.
*
* @author rschoene - Initial contribution
*/
public class Dumper {
/**
* Prepare to read in the given object. Use the <code>dump*</code> methods to actually dump its content.
* @param obj the object to dump
* @return a builder to adjust dump options
*/
public static DumpBuilder read(Object obj) {
return new DumpBuilder(obj);
}
}
package de.tudresden.inf.st.jastadd.dumpAst.ast;
public enum SkinParamBooleanSetting {
/**
* Print in grayscale?
*/
Monochrome,
/**
* Use shadows?
*/
Shadowing,
/**
* Use handwritten style?
*/
Handwritten
}
package de.tudresden.inf.st.jastadd.dumpAst.ast;
public enum SkinParamStringSetting {
/**
* Set color of background
*/
backgroundColor
}
......@@ -37,9 +37,18 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun
{{#DumpNodes}}
{{#DumpTokens}}
{{^invisible}}
{{^isDumpValueToken}}
{{{outerNodeName}}} .{{#computed}}[#{{{computedColor}}}]{{/computed}}.> {{{innerNodeName}}} : {{{label}}}
{{/isDumpValueToken}}
{{#isList}}
{{#InnerRelationDumpNode}}
{{#bothVisible}}
{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNull}},norank{{/innerNotNull}}].> {{{innerNodeName}}} : {{{label}}}
{{/bothVisible}}
{{/InnerRelationDumpNode}}
{{/isList}}
{{^isList}}
{{^isDumpValueToken}}
{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNull}},norank{{/innerNotNull}}].> {{{innerNodeName}}} : {{{label}}}
{{/isDumpValueToken}}
{{/isList}}
{{/invisible}}
{{/DumpTokens}}
{{#DumpChildNodes}}
......@@ -58,23 +67,23 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun
{{/DumpChildNodes}}
{{#DumpRelations}}
{{#isList}}
{{#InnerDumpNodes}}
{{#InnerRelationDumpNode}}
{{#bothVisible}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}--> {{{innerNodeName}}} : {{{label}}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNull}}[norank]{{/innerNotNull}}-> {{{innerNodeName}}} : {{{label}}}
{{/bothVisible}}
{{/InnerDumpNodes}}
{{/InnerRelationDumpNode}}
{{/isList}}
{{^isList}}
{{#bothVisible}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}--> {{{innerNodeName}}} : {{{label}}}
{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNull}}[norank]{{/innerNotNull}}-> {{{innerNodeName}}} : {{{label}}}
{{/bothVisible}}
{{/isList}}
{{/DumpRelations}}
{{^invisible}}
{{#InvisiblePath}}
{{#InnerDumpNodes}}
{{#InnerRelationDumpNode}}
{{{outerNodeName}}} o.. {{{innerNodeName}}}
{{/InnerDumpNodes}}
{{/InnerRelationDumpNode}}
{{/InvisiblePath}}
{{/invisible}}
{{#PrintConfig}}{{#orderChildren}}
......
#Fri Mar 11 12:41:31 CET 2022
version=1.0.0
#Thu Jun 23 16:13:20 CEST 2022
version=1.1.0
......@@ -5,3 +5,4 @@ out/
*.class
/featureTest.png
/featureTest.yml
/featureTest.puml
......@@ -20,16 +20,22 @@ apply plugin: 'jastadd'
// --- Dependencies ---
repositories {
mavenCentral()
maven {
name 'gitlab-maven'
url 'https://git-st.inf.tu-dresden.de/api/v4/groups/jastadd/-/packages/maven'
}
}
configurations {
relast
}
dependencies {
implementation project(":dumpAst")
jastadd2 group: 'org.jastadd', name: 'jastadd2', version: '2.3.5-dresden'
relast group: 'org.jastadd', name: 'relast', version: "${relast_version}"
api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: "${jupiter_version}"
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.18.1'
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: "${jupiter_version}"
implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
}
// --- Preprocessors ---
......@@ -41,20 +47,16 @@ File testingGrammar = file('./src/main/jastadd/featureTest.relast')
task relast(type: JavaExec) {
group = 'Build'
main = "-jar"
classpath = configurations.relast
mainClass = 'org.jastadd.relast.compiler.Compiler'
doFirst {
delete "src/gen/jastadd/*.ast"
delete "src/gen/jastadd/featureTest.jadd"
delete "src/gen/jastadd/featureTestRefResolver.jadd"
delete "src/gen/jastadd/featureTestResolverStubs.jrag"
delete "src/gen/jastadd/*"
mkdir "src/gen/jastadd/"
}
args = [
"../libs/relast.jar",
testingGrammar,
// "./src/main/jastadd/MustacheNodes.relast",
"--listClass=java.util.ArrayList",
"--jastAddList=JastAddList",
"--useJastAddNames",
......@@ -62,13 +64,6 @@ task relast(type: JavaExec) {
"--resolverHelper",
"--grammarName=./src/gen/jastadd/featureTest"
]
inputs.files(file("../libs/relast.jar"),
testingGrammar)
outputs.files(file("./src/gen/jastadd/featureTest.ast"),
file("./src/gen/jastadd/featureTest.jadd"),
file("./src/gen/jastadd/featureTestRefResolver.jadd"),
file('./src/gen/jastadd/featureTestResolverStubs.jrag'))
}
// --- JastAdd ---
......@@ -102,7 +97,6 @@ jastadd {
}
// --- Tests ---
test.useJUnitPlatform()
// --- Versioning and Publishing ---
mainClassName = 'de.tudresden.inf.st.jastadd.featureTest.FeatureTestMain'
......
......@@ -2,6 +2,7 @@ aspect GrammarGlobal {
syn A C.getCalculated() {
A result = new A();
result.setName("Calculated-" + getName());
result.setB(new B().setName("B" + getName()));
D innerD = new D();
result.setD(innerD);
return result;
......@@ -18,6 +19,7 @@ aspect GrammarGlobal {
syn nta A C.getCalculatedNewSyntax() {
A result = new A();
result.setName("Calculated-" + getName());
result.setB(new B().setName("B" + getName()));
return result;
}
......@@ -34,6 +36,11 @@ aspect GrammarGlobal {
syn boolean ASTNode.isA() = false;
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 {
......
// testcases with global inclusion/exclusion
Nameable ::= <Name> ;
Root : Nameable ::= A B* [C];
A : Nameable ::= B MyC:C D;
A : Nameable ::= B [MyC:C] [D];
B : Nameable ::= <OtherValue> ;
C : Nameable ::= [A] <Unwanted:int> <RawReference:A> /Calculated:A/ /AlsoCalculated:B*/ ;
SubC : C ::= <RawReference:A> <Unwanted:int> [A] /Calculated:A/ /AlsoCalculated:B*/ ;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment