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

Merge branch 'release-1.0.0' into 'master'

1.0.0

See merge request jastadd/relast2uml!10
parents ec2ab792 fb67ef02
Pipeline #12961 passed with stages
in 3 minutes and 13 seconds
......@@ -45,6 +45,7 @@ publish_master:
script:
- "./gradlew publish"
only:
- main
- master
ragdoc_build:
......@@ -55,7 +56,7 @@ ragdoc_build:
needs:
- build
script:
- JAVA_FILES=$(find dumpAstWithPlantuml/src/ -name '*.java')
- JAVA_FILES=$(find dumpAst/src/ -name '*.java')
- /ragdoc-builder/start-builder.sh -excludeGenerated -d data/ $JAVA_FILES
artifacts:
paths:
......@@ -77,6 +78,7 @@ ragdoc_view:
only:
- dev
- main
- master
artifacts:
paths:
- "pages/docs/ragdoc"
......@@ -96,3 +98,4 @@ pages:
- public/
only:
- main
- master
# DumpAst
For documentation, please see https://jastadd.pages.st.inf.tu-dresden.de/relast2uml/
plugins {
id 'relast2uml.java-common-conventions'
id 'application'
}
plugins {
id 'java'
id 'idea'
id 'com.github.ben-manes.versions'
}
repositories {
mavenCentral()
}
dependencies {
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}"
}
tasks.named('test') {
useJUnitPlatform()
}
plugins {
id 'relast2uml.java-common-conventions'
id 'java-library'
}
dependencies {
api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
}
File genSrc = file("src/gen/java")
sourceSets.main.java.srcDir genSrc
idea.module.generatedSourceDirs += genSrc
plugins {
id 'java'
id 'idea'
id 'com.github.ben-manes.versions'
id 'maven-publish'
}
repositories {
mavenCentral()
}
dependencies {
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}"
}
jar {
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
def versionFile = "src/main/resources/${project.getName()}Version.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)
}
task printVersion() {
doLast {
println(version)
}
}
task newVersion() {
doFirst {
def props = new Properties()
props['version'] = value
props.store(file(versionFile).newWriter(), null)
}
}
task setDevVersionForCI() {
doFirst {
def props = new Properties()
props['version'] = version + "-$System.env.CI_PIPELINE_IID"
props.store(file(versionFile).newWriter(), null)
}
}
//679
publishing {
publications {
maven(MavenPublication) {
groupId = 'de.tudresden.inf.st'
// from components.java
artifact("build/libs/${project.getName()}-${project.getVersion()}.jar") {
extension 'jar'
}
}
}
repositories {
maven {
url "https://git-st.inf.tu-dresden.de/api/v4/projects/679/packages/maven"
// Uncomment the following lines to publish manually (and comment out the other credentials section)
// credentials(HttpHeaderCredentials) {
// name = "Private-Token"
// value = gitLabPrivateToken // the variable resides in ~/.gradle/gradle.properties
// }
credentials(HttpHeaderCredentials) {
name = 'Job-Token'
value = System.getenv("CI_JOB_TOKEN")
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
}
publish.dependsOn jar
// --- Buildscripts (must be at the top) ---
buildscript {
repositories.mavenLocal()
repositories.mavenCentral()
......@@ -6,18 +7,35 @@ buildscript {
}
}
// --- Plugin definitions ---
plugins {
id 'relast2uml.java-jastadd-conventions'
id 'relast2uml.java-publishing-conventions'
id 'java'
id 'idea'
id 'com.github.ben-manes.versions'
id 'java-library'
id 'maven-publish'
}
apply plugin: 'jastadd'
// --- Dependencies ---
repositories {
mavenCentral()
}
dependencies {
jastadd2 "org.jastadd:jastadd:2.3.4"
implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: "${mustache_java_version}"
jastadd2 "org.jastadd:jastadd:2.3.5"
implementation fileTree(include: ['plantuml.jar'], dir: '../libs')
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"
implementation group: 'org.yaml', name: 'snakeyaml', version: '1.27'
}
// --- Preprocessors ---
File genSrc = file("src/gen/java")
sourceSets.main.java.srcDir genSrc
idea.module.generatedSourceDirs += genSrc
File dumpAstGrammar = file('./src/main/jastadd/DumpAst.relast')
File mustacheGrammar = file('./src/main/jastadd/mustache/Mustache.relast')
......@@ -54,6 +72,7 @@ task relast(type: JavaExec) {
file('./src/gen/jastadd/DumpAstResolverStubs.jrag'))
}
// --- JastAdd ---
jastadd {
configureModuleBuild()
modules {
......@@ -96,4 +115,70 @@ jastadd {
jastaddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"]
}
// --- Tests ---
// --- Versioning and Publishing ---
group = 'de.tudresden.inf.st'
jar {
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
def versionFile = "src/main/resources/${project.getName()}Version.properties"
try {
def oldProps = new Properties()
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)
}
task printVersion() {
doLast {
println(version)
}
}
task newVersion() {
doFirst {
def props = new Properties()
props['version'] = value
props.store(file(versionFile).newWriter(), null)
}
}
task setDevVersionForCI() {
doFirst {
def props = new Properties()
props['version'] = version + "-$System.env.CI_PIPELINE_IID"
props.store(file(versionFile).newWriter(), null)
}
}
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
repositories {
maven {
url "https://git-st.inf.tu-dresden.de/api/v4/projects/$System.env.CI_PROJECT_ID/packages/maven"
credentials(HttpHeaderCredentials) {
name = 'Job-Token'
value = System.getenv("CI_JOB_TOKEN")
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
}
// --- Task order ---
generateAst.dependsOn relast
publish.dependsOn jar
DumpAst ::= DumpNode* <PackageName> BuildConfig PrintConfig ;
rel DumpAst.RootNode -> DumpNode ;
BuildConfig ::= StyleInformation GlobalPatternCollection:PatternCollection
ExcludeTypePattern:TypePatternCollectionMapping* IncludeTypePattern:TypePatternCollectionMapping*
<TypeIgnorePattern> <IncludeEmptyString:boolean> <ExcludeNullNodes:boolean> <Debug:boolean>;
TypePatternCollectionMapping ::= <TypeRegex> PatternCollection ;
PatternCollection ::= <TokenPattern> <ChildPattern> <RelationPattern> <AttributePattern> <NonterminalAttributePattern> ;
StyleInformation ::= <NameMethod:StyleMethod> <BackgroundColorMethod:StyleMethod> <TextColorMethod:StyleMethod>;
PrintConfig ::= <Scale:double> <Version> <OrderChildren:boolean> Header* ;
Header ::= <Value> ;
rel DumpAst.RootNode? -> DumpNode ;
DumpNode ::= DumpChildNode* DumpToken* DumpRelation*
<Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean>
<Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> <Computed:boolean> <ManualStereotypes>
/InvisiblePath/ ;
InnerDumpNode ;
rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner ;
......@@ -35,7 +25,7 @@ DumpListRelation : DumpRelation ::= InnerDumpNode* ;
// type of NTA
InvisiblePath ::= InnerDumpNode* ;
ClassAnalysisResult ::= AnalysedMethod* ;
ClassAnalysisResult ::= ContainmentMethod:AnalysedMethod* OtherMethod:AnalysedMethod* ;
abstract AnalysedMethod ::= <Method:java.lang.reflect.Method> <Name> ;
abstract SingleChildMethod : AnalysedMethod ;
......@@ -52,3 +42,21 @@ ListRelationMethod : AnalysedMethod ;
abstract TokenMethod : AnalysedMethod ;
IntrinsicTokenMethod : TokenMethod ;
AttributeMethod : TokenMethod ;
BuildConfig ::= StyleInformation
GlobalPatternCollection:PatternCollection
ExcludeTypePattern:TypePatternCollectionMapping*
IncludeTypePattern:TypePatternCollectionMapping*
<TypeIgnorePattern>
<IncludeEmptyString:boolean>
<ExcludeNullNodes:boolean>
<Debug:boolean>;
TypePatternCollectionMapping ::= <TypeRegex> PatternCollection ;
PatternCollection ::= <TokenPattern> <ChildPattern> <RelationPattern> <AttributePattern> <NonterminalAttributePattern> ;
StyleInformation ::= <NameMethod:StyleMethod> <BackgroundColorMethod:StyleMethod> <TextColorMethod:StyleMethod> <StereotypeMethod:StyleMethod> <ComputedColor>;
PrintConfig ::= Header*
<Scale:double>
<Version>
<OrderChildren:boolean> ;
Header ::= <Value> ;
aspect Navigation {
/** Tests if TokenMethod is a IntrinsicTokenMethod.
* @return 'true' if this is a IntrinsicTokenMethod, otherwise 'false'
*/
syn boolean TokenMethod.isIntrinsicTokenMethod() = false;
eq IntrinsicTokenMethod.isIntrinsicTokenMethod() = true;
/** Tests if TokenMethod is a AttributeMethod.
* @return 'true' if this is a AttributeMethod, otherwise 'false'
*/
syn boolean TokenMethod.isAttributeMethod() = false;
eq AttributeMethod.isAttributeMethod() = true;
/** Tests if AnalysedMethod is a SingleChildMethod.
* @return 'true' if this is a SingleChildMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isSingleChildMethod() = false;
eq SingleChildMethod.isSingleChildMethod() = true;
/** Tests if AnalysedMethod is a ListChildMethod.
* @return 'true' if this is a ListChildMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isListChildMethod() = false;
eq ListChildMethod.isListChildMethod() = true;
/** Tests if AnalysedMethod is a SingleRelationMethod.
* @return 'true' if this is a SingleRelationMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isSingleRelationMethod() = false;
eq SingleRelationMethod.isSingleRelationMethod() = true;
/** Tests if AnalysedMethod is a ListRelationMethod.
* @return 'true' if this is a ListRelationMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isListRelationMethod() = false;
eq ListRelationMethod.isListRelationMethod() = true;
/** Tests if AnalysedMethod is a TokenMethod.
* @return 'true' if this is a TokenMethod, otherwise 'false'
*/
syn boolean AnalysedMethod.isTokenMethod() = false;
eq TokenMethod.isTokenMethod() = true;
/** Tests if DumpRelation is a DumpNormalRelation.
* @return 'true' if this is a DumpNormalRelation, otherwise 'false'
*/
syn boolean DumpRelation.isDumpNormalRelation() = false;
eq DumpNormalRelation.isDumpNormalRelation() = true;
/** Tests if DumpRelation is a DumpListRelation.
* @return 'true' if this is a DumpListRelation, otherwise 'false'
*/
syn boolean DumpRelation.isDumpListRelation() = false;
eq DumpListRelation.isDumpListRelation() = true;
/** Tests if DumpChildNode is a DumpNormalChildNode.
* @return 'true' if this is a DumpNormalChildNode, otherwise 'false'
*/
syn boolean DumpChildNode.isDumpNormalChildNode() = false;
eq DumpNormalChildNode.isDumpNormalChildNode() = true;
/** Tests if DumpChildNode is a DumpListChildNode.
* @return 'true' if this is a DumpListChildNode, otherwise 'false'
*/
syn boolean DumpChildNode.isDumpListChildNode() = false;
eq DumpListChildNode.isDumpListChildNode() = true;
/** Tests if ListChildMethod is a NormalListChildMethod.
* @return 'true' if this is a NormalListChildMethod, otherwise 'false'
*/
syn boolean ListChildMethod.isNormalListChildMethod() = false;
eq NormalListChildMethod.isNormalListChildMethod() = true;
/** Tests if ListChildMethod is a NTAListChildMethod.
* @return 'true' if this is a NTAListChildMethod, otherwise 'false'
*/
syn boolean ListChildMethod.isNTAListChildMethod() = false;
eq NTAListChildMethod.isNTAListChildMethod() = true;
/** Tests if SingleChildMethod is a NormalSingleChildMethod.
* @return 'true' if this is a NormalSingleChildMethod, otherwise 'false'
*/
syn boolean SingleChildMethod.isNormalSingleChildMethod() = false;
eq NormalSingleChildMethod.isNormalSingleChildMethod() = true;
/** Tests if SingleChildMethod is a NTASingleChildMethod.
* @return 'true' if this is a NTASingleChildMethod, otherwise 'false'
*/
syn boolean SingleChildMethod.isNTASingleChildMethod() = false;
eq NTASingleChildMethod.isNTASingleChildMethod() = true;
/** Tests if DumpToken is a DumpReferenceToken.
* @return 'true' if this is a DumpReferenceToken, otherwise 'false'
*/
syn boolean DumpToken.isDumpReferenceToken() = false;
eq DumpReferenceToken.isDumpReferenceToken() = true;
/** Tests if DumpToken is a DumpValueToken.
* @return 'true' if this is a DumpValueToken, otherwise 'false'
*/
syn boolean DumpToken.isDumpValueToken() = false;
eq DumpValueToken.isDumpValueToken() = true;
/** casts a TokenMethod into a IntrinsicTokenMethod if possible.
* @return 'this' cast to a IntrinsicTokenMethod or 'null'
*/
syn IntrinsicTokenMethod TokenMethod.asIntrinsicTokenMethod();
eq TokenMethod.asIntrinsicTokenMethod() = null;
eq IntrinsicTokenMethod.asIntrinsicTokenMethod() = this;
/** casts a TokenMethod into a AttributeMethod if possible.
* @return 'this' cast to a AttributeMethod or 'null'
*/
syn AttributeMethod TokenMethod.asAttributeMethod();
eq TokenMethod.asAttributeMethod() = null;
eq AttributeMethod.asAttributeMethod() = this;
/** casts a AnalysedMethod into a SingleChildMethod if possible.
* @return 'this' cast to a SingleChildMethod or 'null'
*/
syn SingleChildMethod AnalysedMethod.asSingleChildMethod();
eq AnalysedMethod.asSingleChildMethod() = null;
eq SingleChildMethod.asSingleChildMethod() = this;
/** casts a AnalysedMethod into a ListChildMethod if possible.
* @return 'this' cast to a ListChildMethod or 'null'
*/
syn ListChildMethod AnalysedMethod.asListChildMethod();
eq AnalysedMethod.asListChildMethod() = null;
eq ListChildMethod.asListChildMethod() = this;
/** casts a AnalysedMethod into a SingleRelationMethod if possible.
* @return 'this' cast to a SingleRelationMethod or 'null'
*/
syn SingleRelationMethod AnalysedMethod.asSingleRelationMethod();
eq AnalysedMethod.asSingleRelationMethod() = null;
eq SingleRelationMethod.asSingleRelationMethod() = this;
/** casts a AnalysedMethod into a ListRelationMethod if possible.
* @return 'this' cast to a ListRelationMethod or 'null'
*/
syn ListRelationMethod AnalysedMethod.asListRelationMethod();
eq AnalysedMethod.asListRelationMethod() = null;
eq ListRelationMethod.asListRelationMethod() = this;
/** casts a AnalysedMethod into a TokenMethod if possible.
* @return 'this' cast to a TokenMethod or 'null'
*/
syn TokenMethod AnalysedMethod.asTokenMethod();
eq AnalysedMethod.asTokenMethod() = null;
eq TokenMethod.asTokenMethod() = this;
/** casts a DumpRelation into a DumpNormalRelation if possible.
* @return 'this' cast to a DumpNormalRelation or 'null'
*/
syn DumpNormalRelation DumpRelation.asDumpNormalRelation();
eq DumpRelation.asDumpNormalRelation() = null;
eq DumpNormalRelation.asDumpNormalRelation() = this;
/** casts a DumpRelation into a DumpListRelation if possible.
* @return 'this' cast to a DumpListRelation or 'null'
*/
syn DumpListRelation DumpRelation.asDumpListRelation();
eq DumpRelation.asDumpListRelation() = null;
eq DumpListRelation.asDumpListRelation() = this;
/** casts a DumpChildNode into a DumpNormalChildNode if possible.
* @return 'this' cast to a DumpNormalChildNode or 'null'
*/
syn DumpNormalChildNode DumpChildNode.asDumpNormalChildNode();
eq DumpChildNode.asDumpNormalChildNode() = null;
eq DumpNormalChildNode.asDumpNormalChildNode() = this;
/** casts a DumpChildNode into a DumpListChildNode if possible.
* @return 'this' cast to a DumpListChildNode or 'null'
*/
syn DumpListChildNode DumpChildNode.asDumpListChildNode();
eq DumpChildNode.asDumpListChildNode() = null;
eq DumpListChildNode.asDumpListChildNode() = this;
/** casts a ListChildMethod into a NormalListChildMethod if possible.
* @return 'this' cast to a NormalListChildMethod or 'null'
*/
syn NormalListChildMethod ListChildMethod.asNormalListChildMethod();
eq ListChildMethod.asNormalListChildMethod() = null;
eq NormalListChildMethod.asNormalListChildMethod() = this;
/** casts a ListChildMethod into a NTAListChildMethod if possible.
* @return 'this' cast to a NTAListChildMethod or 'null'
*/
syn NTAListChildMethod ListChildMethod.asNTAListChildMethod();
eq ListChildMethod.asNTAListChildMethod() = null;
eq NTAListChildMethod.asNTAListChildMethod() = this;
/** casts a SingleChildMethod into a NormalSingleChildMethod if possible.
* @return 'this' cast to a NormalSingleChildMethod or 'null'
*/
syn NormalSingleChildMethod SingleChildMethod.asNormalSingleChildMethod();
eq SingleChildMethod.asNormalSingleChildMethod() = null;
eq NormalSingleChildMethod.asNormalSingleChildMethod() = this;
/** casts a SingleChildMethod into a NTASingleChildMethod if possible.
* @return 'this' cast to a NTASingleChildMethod or 'null'
*/
syn NTASingleChildMethod SingleChildMethod.asNTASingleChildMethod();
eq SingleChildMethod.asNTASingleChildMethod() = null;
eq NTASingleChildMethod.asNTASingleChildMethod() = this;
/** casts a DumpToken into a DumpReferenceToken if possible.
* @return 'this' cast to a DumpReferenceToken or 'null'
*/
syn DumpReferenceToken DumpToken.asDumpReferenceToken();
eq DumpToken.asDumpReferenceToken() = null;
eq DumpReferenceToken.asDumpReferenceToken() = this;
/** casts a DumpToken into a DumpValueToken if possible.
* @return 'this' cast to a DumpValueToken or 'null'
*/
syn DumpValueToken DumpToken.asDumpValueToken();
eq DumpToken.asDumpValueToken() = null;
eq DumpValueToken.asDumpValueToken() = this;
}
......@@ -347,6 +347,16 @@ public class DumpBuilder {
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;
......@@ -369,7 +379,17 @@ public class DumpBuilder {
protected DumpAst build() {
if (result == null) {
result = new DumpAst();
result.setPackageName(this.packageName == null ? this.target.getClass().getPackage().getName() : this.packageName);
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 {
......@@ -400,11 +420,38 @@ public class DumpBuilder {
}
public DumpBuilder dumpAsYaml(java.nio.file.Path destination, boolean prependCreationComment) throws java.io.IOException {
String content = build().toYaml(prependCreationComment);
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);