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

Merge branch 'dev' into 'master'

0.4.0

Closes #27

See merge request !20
parents 2dffc2f1 699ebb7a
Pipeline #12984 passed with stages
in 1 minute and 55 seconds
......@@ -13,4 +13,3 @@ src/test/jastadd/*/*.ast
src/test/jastadd/*/*.jadd
src/test/jastadd/*/*ResolverStubs.jrag
!src/test/jastadd/*/MyRefResolver.jadd
/gradle.properties
stages:
- build
- test
- jar
- deploy
before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle
cache:
paths:
- .gradle/wrapper
- .gradle/caches
build:
image: openjdk:8
stage: build
script:
- ./gradlew --console=plain --build-cache assemble
cache:
key: "$CI_COMMIT_REF_NAME"
policy: push
- ./gradlew --console=plain --no-daemon assemble fatJar
artifacts:
paths:
- build
- .gradle
- "/builds/jastadd/relational-rags/build/libs/relast-*.jar"
test:
image: openjdk:8
stage: test
script:
- ./gradlew --continue --console=plain --info check
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
paths:
- build
- .gradle
jar:
image: openjdk:8
stage: jar
script:
- ./gradlew --continue --console=plain --info jar
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
paths:
- build
- .gradle
artifacts:
paths:
- "/builds/jastadd/*/build/libs/*relast*.jar"
- ./gradlew --console=plain --no-daemon --info test
pages:
image: python:3.7-alpine
......@@ -53,4 +36,28 @@ pages:
paths:
- public
only:
- master
- master
- main
publish:
image: openjdk:8
stage: deploy
needs:
- test
script:
- "./gradlew publish"
only:
- master
- main
publish_dev:
image: openjdk:8
stage: deploy
needs:
- test
script:
- "./gradlew setDevVersionForCI"
- "./gradlew publish"
except:
- master
- main
......@@ -23,33 +23,27 @@ This location can be [configured](#build-configuration).
## Build configuration
Currently, the test setup is configured within `build.gradle` using a specialized Gradle task `RelastTest`.
Currently, the test setup is configured within `build.gradle` using a specialized Gradle task `RelastTest` provided by the [preprocessor testing Gradle plugin][preprocessor-testing].
An example configuration might look like:
```groovy
task compileMultipleTest(type: RelastTest) {
relastFiles 'src/test/jastadd/multiple/Part1.relast',
'src/test/jastadd/multiple/Part2.relast',
'src/test/jastadd/multiple/Part3.relast'
grammarName = 'src/test/jastadd/multiple/Multiple'
useJastAddNames = true
packageName = 'multiple.ast'
moreInputFiles 'src/test/jastadd/Utils.jadd'
relast {
inputFiles = [file('src/test/jastadd/multiple/Part1.relast'),
file('src/test/jastadd/multiple/Part2.relast'),
file('src/test/jastadd/multiple/Part3.relast')]
grammarName = 'src/test/jastadd/multiple/Multiple'
useJastAddNames = true
noResolverHelper = true
}
jastadd {
packageName = 'multiple.ast'
inputFiles = [file('src/test/jastadd/Utils.jadd')]
}
}
```
The following options are supported, similar to the [command-line options](/../#supported-command-line-options):
| Name | Description | Required | Default |
|-------------------|--------------------------------------------------------------------------------------------------------|--------------------|---------------------|
| `relastFiles` | Input grammar(s). Either one or multiple files separated by comma. | Yes | _none_ |
| `grammarName` | Directory and file prefix for the generated grammar and jrag created by RelAST. | Yes | _none_ |
| `useJastAddNames` | Set to `true` to use accessor names for relations matching JastAdd naming convention. | No | `false` |
| `packageName` | Name of the package for the Java files generated by JastAdd. | Yes (not enforced) | The empty package |
| `moreInputFiles` | Additional files as input for JastAdd. | No | No additional files |
| `resolverHelper` | Set to `true` to generate means for lazy resolving. | No | `false` |
| `jastAddList` | Alternative name for `List` nodes. Will be passed to both RelAST and JastAdd. | No | `List` |
| `serializer` | Name of supported serializer. One of {`jackson`, `jackson-json-pointer`, `jackson-manual-references`}. | No | No serializer |
Please see the [documentation of the plugin][preprocessor-testing] for all options.
## Test files
......@@ -106,3 +100,4 @@ The workflow:
[semantic-versioning]: https://semver.org/
[create-release]: /../-/tags/new
[create-issue]: https://git-st.inf.tu-dresden.de/jastadd/relational-rags/issues/new
[preprocessor-testing]: https://jastadd.pages.st.inf.tu-dresden.de/testing/
......@@ -2,7 +2,7 @@
![RelAST process](relast-process.png)
See [releases page](/../../releases) for the latest version.
See [releases page](/../../releases) for the latest version and <https://jastadd.pages.st.inf.tu-dresden.de/relational-rags/> for more documentation.
The RelAST preprocessor takes a `.relast` file as input comprising AST rules and relations. It produces files that afterwards are processed by JastAdd to generated Java code.
To use it in your project, build the JAR file running
......@@ -52,21 +52,23 @@ Note that you may have to change
## Supported relations
// Directed relations
A.b -> B;
A.b? -> B;
A.bs* -> B;
B <- A.b ;
B <- A.b? ;
B <- A.bs*;
```
// Directed relations
A.b -> B;
A.b? -> B;
A.bs* -> B;
B <- A.b ;
B <- A.b? ;
B <- A.bs*;
// Bidirectional relations
A.b <-> B.a;
A.b <-> B.a?;
A.b <-> B.as*;
A.b? <-> B.a;
A.b? <-> B.a?;
A.b? <-> B.as*;
A.bs* <-> B.a;
A.bs* <-> B.a?;
A.bs* <-> B.as*;
// Bidirectional relations
A.b <-> B.a;
A.b <-> B.a?;
A.b <-> B.as*;
A.b? <-> B.a;
A.b? <-> B.a?;
A.b? <-> B.as*;
A.bs* <-> B.a;
A.bs* <-> B.a?;
A.bs* <-> B.as*;
```
This diff is collapsed.
package org.jastadd.relast.plugin;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.tasks.TaskCollection;
import java.util.Set;
/**
* Plugin for RelAst-Test.
*
* @author rschoene - Initial contribution
*/
public class RelastPlugin implements Plugin<Project> {
private Task testTask;
@Override
public void apply(Project project) {
Set<Task> tasks = project.getTasksByName("test", false);
// there should be only one task "test"
testTask = tasks.iterator().next();
TaskCollection<RelastTest> relastTests = project.getTasks().withType(RelastTest.class);
relastTests.forEach(this::setupRelastTest);
relastTests.whenTaskAdded(this::setupRelastTest);
}
private void setupRelastTest(RelastTest relastTest) {
testTask.dependsOn(relastTest);
relastTest.setGroup("verification");
}
}
package org.jastadd.relast.plugin;
import org.gradle.api.DefaultTask;
import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskAction;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* RelAst Test Task
*
* @author rschoene - Initial contribution
*/
@SuppressWarnings({"unused", "WeakerAccess"})
public class RelastTest extends DefaultTask {
// general options
private boolean verbose = false;
// pre-process options
private List<String> relastFiles = new ArrayList<>();
private boolean useJastAddNames;
private boolean resolverHelper;
private boolean writeToFile = true;
private String grammarName;
private String listClass;
private String jastAddList;
private String serializer;
// compile options
private boolean runJastAdd = true;
private String outputDir = "src/test/java-gen/";
private String packageName;
private List<String> moreInputFiles = new ArrayList<>();
public boolean isVerbose() {
return verbose;
}
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
// pre-process options
public List<String> getRelastFiles() {
return relastFiles;
}
public void relastFiles(String relastFile) {
this.relastFiles.add(relastFile);
}
public void relastFiles(String[] relastFilesArray) {
this.relastFiles = Arrays.asList(relastFilesArray);
}
public boolean isUseJastAddNames() {
return useJastAddNames;
}
public void setUseJastAddNames(boolean useJastAddNames) {
this.useJastAddNames = useJastAddNames;
}
public boolean isResolverHelper() {
return resolverHelper;
}
public void setResolverHelper(boolean resolverHelper) {
this.resolverHelper = resolverHelper;
}
public boolean isWriteToFile() {
return writeToFile;
}
public void setWriteToFile(boolean writeToFile) {
this.writeToFile = writeToFile;
}
public String getGrammarName() {
return grammarName;
}
public void setGrammarName(String grammarName) {
this.grammarName = grammarName;
}
public String getListClass() {
return listClass;
}
public void setListClass(String listClass) {
this.listClass = listClass;
}
public String getJastAddList() {
return jastAddList;
}
public void setJastAddList(String jastAddList) {
this.jastAddList = jastAddList;
}
public String getSerializer() {
return serializer;
}
public void setSerializer(String serializer) {
this.serializer = serializer;
}
// compile options
public boolean isRunJastAdd() {
return runJastAdd;
}
public void setRunJastAdd(boolean runJastAdd) {
this.runJastAdd = runJastAdd;
}
public String getOutputDir() {
return outputDir;
}
public void setOutputDir(String outputDir) {
this.outputDir = outputDir;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public List<String> getMoreInputFiles() {
return moreInputFiles;
}
public void moreInputFiles(String f) {
this.moreInputFiles.add(f);
}
public void moreInputFiles(String[] fileArray) {
this.moreInputFiles.addAll(Arrays.asList(fileArray));
}
private boolean isSet(String option) {
return option != null && !option.isEmpty();
}
private String[] genSuffixes = {".ast", ".jadd", "RefResolver.jadd", "ResolverStubs.jrag", "Serializer.jadd"};
@TaskAction
void runTest() {
setGroup("verification");
setDescription("Runs a relast test");
Project project = getProject();
if (isVerbose()) {
System.out.println("Running relast test");
System.out.println("relast files: " + getRelastFiles());
System.out.println("Deleting files");
}
// first, delete generated files
List<String> genFiles = new ArrayList<>();
for (String suffix : genSuffixes) {
genFiles.add(getGrammarName() + suffix);
}
if (isVerbose()) {
System.out.println("gen files: " + genFiles);
}
project.delete(deleteSpec -> {
deleteSpec.delete(genFiles);
if (isSet(getPackageName())) {
deleteSpec.delete(Paths.get(getOutputDir(), getPackageName()));
}
});
if (isVerbose()) {
System.out.println("Pre processing, running relast");
}
// then, run relast pre processing
project.getPlugins().withType(JavaPlugin.class, javaPlugin -> {
SourceSetContainer sourceSets = (SourceSetContainer) project.getProperties().get("sourceSets");
FileCollection runtimeClasspath = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath();
project.javaexec(javaExecSpec -> {
javaExecSpec.setClasspath(runtimeClasspath);
javaExecSpec.setMain("org.jastadd.relast.compiler.Compiler");
List<Object> args = new ArrayList<>(getRelastFiles());
args.add("--quiet");
if (isWriteToFile()) {
args.add("--file");
}
if (isUseJastAddNames()) {
args.add("--useJastAddNames");
}
if (isResolverHelper()) {
args.add("--resolverHelper");
}
if (isSet(getJastAddList())) {
args.add("--jastAddList=" + getJastAddList());
}
if (isSet(getListClass())) {
args.add("--listClass=" + getListClass());
}
if (isSet(getSerializer())) {
args.add("--serializer=" + getSerializer());
}
args.add("--grammarName=" + getGrammarName());
if (isVerbose()) {
System.out.println("Start relast with args: " + args);
}
javaExecSpec.args(args);
});
});
if (isRunJastAdd()) {
if (isVerbose()) {
System.out.println("Compile with JastAdd");
}
// check which files were actually generated
genFiles.removeIf(s -> !Paths.get(s).toFile().exists());
// finally, compile generated files
project.getPlugins().withType(JavaPlugin.class, javaPlugin -> {
SourceSetContainer sourceSets = (SourceSetContainer) project.getProperties().get("sourceSets");
FileCollection runtimeClasspath = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath();
project.javaexec(javaExecSpec -> {
javaExecSpec.setClasspath(runtimeClasspath);
javaExecSpec.setMain("org.jastadd.JastAdd");
List<Object> args = new ArrayList<>();
args.add("--o=" + getOutputDir());
args.add("--package=" + getPackageName());
if (isSet(getJastAddList())) {
args.add("--List=" + getJastAddList());
}
args.addAll(genFiles);
args.addAll(getMoreInputFiles());
if (isVerbose()) {
System.out.println("Start JastAdd with args: " + args);
}
javaExecSpec.args(args);
});
});
}
}
}
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
......@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
......@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
......@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
......@@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
......@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.