Skip to content
Snippets Groups Projects
Commit 56be33c4 authored by Johannes Mey's avatar Johannes Mey
Browse files

Merge branch '19-poc-use-mustache-as-template-engine' into 'master'

Resolve "PoC: Use mustache as template engine"

Closes #19

See merge request jastadd/ros2rag!2
parents 52785f37 4c7463c6
Branches
No related tags found
No related merge requests found
Showing
with 403 additions and 251 deletions
......@@ -17,10 +17,9 @@ buildscript {
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-core:2.9.8'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
// api 'org.jastadd:jastadd:2.3.4'
runtime 'org.jastadd:jastadd:2.3.4'
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'
}
......@@ -62,6 +61,7 @@ task relast(type: JavaExec) {
"../libs/relast.jar",
"../relast.preprocessor/src/main/jastadd/RelAst.relast",
"./src/main/jastadd/Ros2Rag.relast",
"./src/main/jastadd/MustacheNodes.relast",
"--listClass=java.util.ArrayList",
"--jastAddList=JastAddList",
"--useJastAddNames",
......@@ -72,11 +72,12 @@ task relast(type: JavaExec) {
inputs.files file("../libs/relast.jar"),
file("../relast.preprocessor/src/main/jastadd/RelAST.relast"),
file("src/main/jastadd/Ros2Rag.relast")
file("./src/main/jastadd/Ros2Rag.relast")
file("./src/main/jastadd/MustacheNodes.relast")
outputs.files file("./src/gen/jastadd/Ros2Rag.ast"),
file("src/gen/jastadd/Ros2Rag.jadd"),
file("src/gen/jastadd/Ros2RagRefResolver.jadd"),
file('src/gen/jastadd/Ros2RagResolverStubs.jrag')
file("./src/gen/jastadd/Ros2Rag.jadd"),
file("./src/gen/jastadd/Ros2RagRefResolver.jadd"),
file('./src/gen/jastadd/Ros2RagResolverStubs.jrag')
}
jastadd {
......
//TypeComponentMustache ;
//rel TypeComponentMustache.TypeComponent -> TypeComponent ;
MRos2Rag ::= ReadDefinition:MReadDefinition* WriteDefinition:MWriteDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*;
abstract MUpdateDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*;
MReadDefinition : MUpdateDefinition;
MWriteDefinition : MUpdateDefinition;
MMappingDefinition;
MInnerMappingDefinition;
MDependencyDefinition;
MTypeComponent;
MTokenComponent;
rel MRos2Rag.Ros2Rag -> Ros2Rag;
rel MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
rel MReadDefinition.ReadFromMqttDefinition -> ReadFromMqttDefinition;
rel MWriteDefinition.WriteToMqttDefinition -> WriteToMqttDefinition;
rel MMappingDefinition.MappingDefinition -> MappingDefinition;
rel MDependencyDefinition.DependencyDefinition -> DependencyDefinition;
rel MTypeComponent.TypeComponent -> TypeComponent;
rel MTokenComponent.TokenComponent -> TokenComponent;
rel MTokenComponent.DependencyDefinition* -> MDependencyDefinition;
......@@ -2,10 +2,12 @@ aspect Navigation {
// --- program ---
eq Ros2Rag.getChild().program() = getProgram();
eq MRos2Rag.getChild().program() = getRos2Rag().program();
// --- ros2rag
// --- ros2rag ---
inh Ros2Rag ASTNode.ros2rag();
eq Ros2Rag.getChild().ros2rag() = this;
eq MRos2Rag.getChild().ros2rag() = getRos2Rag();
// --- containedFile (first equation should be in preprocessor) ---
eq Program.getChild().containedFile() = null;
......@@ -32,6 +34,7 @@ aspect Navigation {
eq GrammarFile.getChild().containedFileName() = getFileName();
eq Ros2Rag.getChild().containedFileName() = getFileName();
eq Program.getChild().containedFileName() = null;
eq MRos2Rag.getChild().containedFileName() = null;
// --- isTokenUpdateDefinition ---
syn boolean UpdateDefinition.isTokenUpdateDefinition() = false;
......@@ -49,6 +52,10 @@ aspect Navigation {
syn WriteToMqttDefinition UpdateDefinition.asWriteToMqttDefinition() = null;
eq WriteToMqttDefinition.asWriteToMqttDefinition() = this;
// --- asReadFromMqttDefinition ---
syn ReadFromMqttDefinition UpdateDefinition.asReadFromMqttDefinition() = null;
eq ReadFromMqttDefinition.asReadFromMqttDefinition() = this;
// --- targetUpdateDefinition ---
syn WriteToMqttDefinition DependencyDefinition.targetUpdateDefinition() {
// resolve definition in here, as we do not need resolveMethod in any other place (yet)
......
......@@ -10,7 +10,6 @@ rel TokenUpdateDefinition.Token -> TokenComponent;
ReadFromMqttDefinition : TokenUpdateDefinition;
WriteToMqttDefinition : TokenUpdateDefinition;
// example: RobotArm._AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1
DependencyDefinition ::= <ID>;
rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
rel DependencyDefinition.Target -> TokenComponent;
......
aspect Configuration {
public static boolean ASTNode.loggingEnabledForReads = false;
public static boolean ASTNode.loggingEnabledForWrites = false;
public static TypeDecl ASTNode.rootNode;
}
This diff is collapsed.
package org.jastadd.ros2rag.compiler;
import java.io.IOException;
import java.io.Writer;
/**
* Writer appending to a StringBuilder.
*
* @author rschoene - Initial contribution
*/
public class AppendableWriter extends Writer {
private final StringBuilder sb;
public AppendableWriter(StringBuilder sb) {
this.sb = sb;
}
@Override
public void write(char[] chars, int off, int len) throws IOException {
sb.append(chars, off, len);
}
@Override
public void write(String str) throws IOException {
sb.append(str);
}
@Override
public void flush() {
}
@Override
public void close() {
}
}
......@@ -37,6 +37,8 @@ public class Compiler {
}
public void run(String[] args) throws CommandLineException, CompilerException {
System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
System.setProperty("mustache.debug", "true");
options = new ArrayList<>();
addOptions();
commandLine = new CommandLine(options);
......
public void {{targetParentTypeName}}.{{dependencyMethod}}({{sourceParentTypeName}} source) {
add{{internalRelationPrefix}}Source(source);
}
{{lastDefinitionToType}} {{resultVarPrefix}}{{lastDefinitionName}};
try {
{{#InnerMappingDefinitions}}
{{^last}}{{ToType}} {{/last}}{{resultVarPrefix}}{{methodName}} = {{methodName}}({{inputVarName}});{{!inputVarName has to be computed beforehand}}
{{/InnerMappingDefinitions}}
} catch (Exception e) {
e.printStackTrace();
{{preemptiveReturn}}
}
{{^alwaysApply}}
if ({{{condition}}}) {
{{preemptiveReturn}}
}
{{/alwaysApply}}
protected static {{toType}} ASTNode.{{methodName}}({{fromType}} {{fromVariableName}}) throws Exception {
{{{content}}}{{!maybe print line by line to get better indentation}}
}
aspect MQTT {
private MqttUpdater {{rootNodeName}}.{{mqttUpdaterField}} = new MqttUpdater();
public void {{rootNodeName}}.{{mqttSetHostMethod}}(String host) throws java.io.IOException {
{{mqttUpdaterField}}.setHost(host);
}
public void {{rootNodeName}}.{{mqttSetHostMethod}}(String host, int port) throws java.io.IOException {
{{mqttUpdaterField}}.setHost(host, port);
}
public boolean {{rootNodeName}}.{{mqttWaitUntilReadyMethod}}(long time, java.util.concurrent.TimeUnit unit) {
return {{mqttUpdaterField}}.waitUntilReady(time, unit);
}
public void {{rootNodeName}}.{{mqttCloseMethod}}() {
{{mqttUpdaterField}}.close();
}
inh MqttUpdater ASTNode.{{mqttUpdaterAttribute}}();
{{#getRootTypeComponents}}
eq {{rootNodeName}}.get{{name}}().{{mqttUpdaterAttribute}}() = {{mqttUpdaterField}};
{{/getRootTypeComponents}}
}
public void {{parentTypeName}}.{{connectMethod}}(String topic) {
{{mqttUpdaterAttribute}}().newConnection(topic, message -> {
{{> mappingApplication}}
{{#loggingEnabledForReads}}
System.out.println("[Read] " + topic + " -> {{tokenName}} = " + {{lastResult}});{{!lastResult has to be a new attribute}}
{{/loggingEnabledForReads}}
set{{tokenName}}({{lastResult}});
});
}
{{> mqtt}}
aspect ROS2RAG {
{{#ReadDefinitions}}
{{> readDefinition}}
{{/ReadDefinitions}}
{{#WriteDefinitions}}
{{> writeDefinition}}
{{/WriteDefinitions}}
{{#MappingDefinitions}}
{{> mappingDefinition}}
{{/MappingDefinitions}}
{{#DependencyDefinitions}}
{{> dependencyDefinition}}
{{/DependencyDefinitions}}
{{#TokenComponents}}
{{> tokenComponent}}
{{/TokenComponents}}
}
public {{parentTypeName}} {{parentTypeName}}.set{{name}}({{javaType}} value) {
set{{internalName}}(value);
{{#DependencyDefinitions}}
for ({{targetParentTypeName}} target : get{{internalRelationPrefix}}TargetList()) {
{{#targetUpdateDefinition}}
if (target.{{updateMethod}}()) {
target.{{writeMethod}}();
}
{{/targetUpdateDefinition}}
}
{{/DependencyDefinitions}}
return this;
}
public {{javaType}} {{parentTypeName}}.get{{name}}() {
return get{{internalName}}();
}
private String {{parentTypeName}}.{{writeTopic}} = null;
private byte[] {{parentTypeName}}.{{lastValue}} = null;
public void {{parentTypeName}}.{{connectMethod}}(String topic, boolean writeCurrentValue) {
{{writeTopic}} = topic;
{{updateMethod}}();
if (writeCurrentValue) {
{{writeMethod}}();
}
}
protected boolean {{parentTypeName}}.{{updateMethod}}() {
{{tokenResetMethod}}();
{{> mappingApplication}}
{{lastValue}} = {{lastResult}};
return true;
}
protected void {{parentTypeName}}.{{writeMethod}}() {
{{#loggingEnabledForWrites}}
System.out.println("[Write] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{writeTopic}});
{{/loggingEnabledForWrites}}
{{mqttUpdaterAttribute}}().publish({{writeTopic}}, {{lastValue}});
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment