Commit 76111d20 authored by René Schöne's avatar René Schöne
Browse files

Tests are working again!

- added fail-fast behaviour to mustache (if a name/method can not be resolved)
- enabled logging of mustache (using log4j)
parent c086c962
......@@ -20,6 +20,7 @@ dependencies {
implementation 'com.fasterxml.jackson.core:jackson-core:2.9.8'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
implementation 'com.github.spullara.mustache.java:compiler:0.9.6'
implementation group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.11.2'
// api 'org.jastadd:jastadd:2.3.4'
runtime 'org.jastadd:jastadd:2.3.4'
api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
......
//TypeComponentMustache ;
//rel TypeComponentMustache.TypeComponent -> TypeComponent ;
MRos2Rag ::= ReadDefinition:MReadDefinition* WriteDefinition:MWriteDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeChildren:MTypeComponent* TokenComponent:MTokenComponent*;
MRos2Rag ::= ReadDefinition:MReadDefinition* WriteDefinition:MWriteDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*;
abstract MUpdateDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*;
MReadDefinition : MUpdateDefinition;
MWriteDefinition : MUpdateDefinition;
......
......@@ -27,6 +27,14 @@ aspect GenerationUtils {
aspect AttributesForMustache {
// --- MRos2Rag ---
eq MRos2Rag.getChild().mqttUpdaterAttribute() = mqttUpdaterAttribute();
eq MRos2Rag.getChild().mqttUpdaterField() = mqttUpdaterField();
syn String MRos2Rag.mqttUpdaterAttribute() = getRos2Rag().mqttUpdaterAttribute();
syn String MRos2Rag.mqttUpdaterField() = getRos2Rag().mqttUpdaterField();
syn String MRos2Rag.mqttSetHostMethod() = getRos2Rag().mqttSetHostMethod();
syn String MRos2Rag.mqttWaitUntilReadyMethod() = getRos2Rag().mqttWaitUntilReadyMethod();
syn String MRos2Rag.mqttCloseMethod() = getRos2Rag().mqttCloseMethod();
// --- MUpdateDefinition ---
syn String MUpdateDefinition.preemptiveExpectedValue();
......@@ -34,12 +42,12 @@ aspect AttributesForMustache {
syn TokenUpdateDefinition MUpdateDefinition.updateDef();
syn String MUpdateDefinition.firstInputVarName();
eq MUpdateDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition();
eq MUpdateDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1;
eq MUpdateDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix();
eq MUpdateDefinition.getInnerMappingDefinition(int i).inputVarName() = i == 0 ? firstInputVarName() : resultVarPrefix() + getInnerMappingDefinition(i - 1).getMappingDefinition().methodName();
eq MRos2Rag.getChild().mqttUpdaterField() = getRos2Rag().mqttUpdaterField();
syn String MUpdateDefinition.mqttUpdaterAttribute() = updateDef().mqttUpdaterAttribute();
inh String MUpdateDefinition.mqttUpdaterAttribute();
syn String MUpdateDefinition.connectMethod() = updateDef().connectMethod();
syn TokenComponent MUpdateDefinition.token() = updateDef().getToken();
syn boolean MUpdateDefinition.alwaysApply() = updateDef().getAlwaysApply();
......@@ -47,7 +55,7 @@ aspect AttributesForMustache {
syn String MUpdateDefinition.parentTypeName() = token().containingTypeDecl().getName();
syn String MUpdateDefinition.tokenName() = token().getName();
syn MInnerMappingDefinition MUpdateDefinition.lastDefinition() = getInnerMappingDefinition(getNumInnerMappingDefinition() - 1);
syn String MUpdateDefinition.lastDefinitionType() = lastDefinition().ToType();
syn String MUpdateDefinition.lastDefinitionToType() = lastDefinition().ToType();
syn String MUpdateDefinition.lastDefinitionName() = lastDefinition().methodName();
syn String MUpdateDefinition.lastResult() = resultVarPrefix() + lastDefinitionName();
syn String MUpdateDefinition.condition() {
......@@ -133,11 +141,13 @@ aspect AttributesForMustache {
result.addDependencyDefinition(def.toMustache());
}
for (TokenComponent token : getProgram().allTokenComponents()) {
result.addTokenComponent(token.toMustache());
if (!token.getDependencySourceDefinitionList().isEmpty()) {
result.addTokenComponent(token.toMustache());
}
}
for (Component child : rootNode.getComponentList()) {
if (child.isTypeComponent()) {
result.addRootTypeChildren(child.asTypeComponent().toMustache());
result.addRootTypeComponent(child.asTypeComponent().toMustache());
}
}
return result;
......@@ -220,242 +230,37 @@ aspect AspectGeneration {
inh String DependencyDefinition.mqttUpdaterAttribute();
eq Ros2Rag.getChild().mqttUpdaterAttribute() = mqttUpdaterAttribute();
// --- mqttUpdaterField ---
// --- rootNodeName ---
syn String ASTNode.rootNodeName() = rootNode.getName();
// mustache specific nodes
// syn nta TypeComponentMustache TypeComponent.mustache() {
// TypeComponentMustache result = new TypeComponentMustache();
// result.setTypeComponent(this);
// return result;
// }
// syn String TypeComponentMustache.name() = getTypeComponent().getName();
// inh String TypeComponentMustache.mqttUpdaterAttribute();
// inh String TypeComponentMustache.mqttUpdaterField();
//
// // mustache specific attributes
// syn java.util.List<TypeComponentMustache> Ros2Rag.rootTypeChildren() {
// java.util.List<TypeComponentMustache> result = new java.util.ArrayList<>();
// for (Component child : rootNode.getComponentList()) {
// if (child.isTypeComponent()){
// result.add(child.asTypeComponent().mustache());
// }
// }
// return result;
// }
public String Ros2Rag.generateAspect(String rootNodeName) {
StringBuilder sb = new StringBuilder();
rootNode = getProgram().resolveTypeDecl(rootNodeName);
com.github.mustachejava.MustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
return toMustache().generateAspect();
}
public String MRos2Rag.generateAspect() {
StringBuilder sb = new StringBuilder();
com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() {
@Override
public com.github.mustachejava.Binding createBinding(String name, final com.github.mustachejava.TemplateContext tc, com.github.mustachejava.Code code) {
return new com.github.mustachejava.reflect.GuardedBinding(this, name, tc, code) {
@Override
protected synchronized com.github.mustachejava.util.Wrapper getWrapper(String name, java.util.List<Object> scopes) {
com.github.mustachejava.util.Wrapper wrapper = super.getWrapper(name, scopes);
if (wrapper instanceof com.github.mustachejava.reflect.MissingWrapper) {
throw new com.github.mustachejava.MustacheException(name + " not found in " + tc);
}
return wrapper;
}
};
}
};
com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
mf.setObjectHandler(roh);
com.github.mustachejava.Mustache m = mf.compile("ros2rag.mustache");
m.execute(new java.io.PrintWriter(new org.jastadd.ros2rag.compiler.AppendableWriter(sb)), this);
// generateMqttAspect(sb);
// generateGrammarExtension(sb);
return sb.toString();
}
//
// public void Ros2Rag.generateMqttAspect(StringBuilder sb) {
// String rootNodeName = rootNode.getName();
// com.github.mustachejava.MustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
// com.github.mustachejava.Mustache m = mf.compile("mqtt.mustache");
// m.execute(new java.io.PrintWriter(new org.jastadd.ros2rag.compiler.AppendableWriter(sb)), this);
// }
//
// public void Ros2Rag.generateGrammarExtension(StringBuilder sb) {
// sb.append("aspect ROS2RAG {\n");
//
// for (UpdateDefinition def : getUpdateDefinitionList()) {
// def.generateAspect(sb);
// }
// for (MappingDefinition def : allMappingDefinitions()) {
// def.generateAspect(sb);
// }
// for (DependencyDefinition def : getDependencyDefinitionList()) {
// def.generateAspect(sb);
// }
// for (TokenComponent token : getProgram().allTokenComponents()) {
// token.generateAspect(sb);
// }
//
// sb.append("}\n");
// }
//
// abstract void UpdateDefinition.generateAspect(StringBuilder sb);
//
// String TokenUpdateDefinition.generateMappingApplication(StringBuilder sb, int indent,
// String initialInputVariableName) {
// final String resultVariablePrefix = "result"; // we do not need "_" here, because methodName begins with one
// String inputVariableName = initialInputVariableName;
// // last variable need to be declared before begin of try
// MappingDefinition lastDefinition = effectiveMappings().get(effectiveMappings().size() - 1);
// sb.append(ind(indent)).append(lastDefinition.getToType().prettyPrint()).append(" ")
// .append(resultVariablePrefix).append(lastDefinition.methodName()).append(";\n");
// sb.append(ind(indent)).append("try {\n");
// for (MappingDefinition mappingDefinition : effectiveMappings()) {
// String resultVariableName = resultVariablePrefix + mappingDefinition.methodName();
// sb.append(ind(indent + 1));
// if (mappingDefinition != lastDefinition) {
// sb.append(mappingDefinition.getToType().prettyPrint()).append(" ");
// }
// sb.append(resultVariablePrefix).append(mappingDefinition.methodName())
// .append(" = ").append(mappingDefinition.methodName()).append("(")
// .append(inputVariableName).append(");\n");
// inputVariableName = resultVariableName;
// }
// sb.append(ind(indent)).append("} catch (Exception e) {\n");
// sb.append(ind(indent + 1)).append("e.printStackTrace();\n");
// sb.append(ind(indent + 1)).append(preemptiveReturnStatement()).append("\n");
// sb.append(ind(indent)).append("}\n");
// if (!getAlwaysApply()) {
// MappingDefinition lastMapping = effectiveMappings().get(effectiveMappings().size() - 1);
// sb.append(ind(indent)).append("if (");
// if (lastMapping.getToType().isArray()) {
// sb.append("java.util.Arrays.equals(").append(preemptiveExpectedValue())
// .append(", ").append(inputVariableName).append(")");
// } else {
// sb.append(preemptiveExpectedValue());
// if (getToken().isPrimitiveType() && lastMapping.getToType().isPrimitiveType()) {
// sb.append(" == ").append(inputVariableName);
// } else if (lastMapping.isDefaultMappingDefinition()) {
// sb.append(" != null && ").append(preemptiveExpectedValue()).append(".equals(")
// .append(inputVariableName).append(")");
// } else {
// sb.append(" != null ? ").append(preemptiveExpectedValue()).append(".equals(")
// .append(inputVariableName).append(")").append(" : ")
// .append(inputVariableName).append(" == null");
// }
// }
// sb.append(") { ").append(preemptiveReturnStatement()).append(" }\n");
// }
// return inputVariableName;
// }
//
// syn String TokenUpdateDefinition.preemptiveExpectedValue();
// eq ReadFromMqttDefinition.preemptiveExpectedValue() = "get" + getToken().getName() + "()";
// eq WriteToMqttDefinition.preemptiveExpectedValue() = lastValue();
//
// syn String TokenUpdateDefinition.preemptiveReturnStatement();
// eq ReadFromMqttDefinition.preemptiveReturnStatement() = "return;";
// eq WriteToMqttDefinition.preemptiveReturnStatement() = "return false;";
//
// @Override
// void ReadFromMqttDefinition.generateAspect(StringBuilder sb) {
// sb.append(ind(1)).append("public void ").append(getToken().containingTypeDecl().getName()).append(".")
// .append(connectMethod()).append("(String topic) {\n");
// sb.append(ind(2)).append(mqttUpdaterAttribute()).append("().newConnection(topic, message -> {\n");
// String lastResult = generateMappingApplication(sb, 3, "message");
// if (loggingEnabledForReads) {
// sb.append(ind(3)).append("System.out.println(\"[Read] \" + topic + \" -> ")
// .append(getToken().getName()).append(" = \" + ").append(lastResult)
// .append(");\n");
// }
// sb.append(ind(3)).append("set").append(getToken().getName()).append("(").append(lastResult).append(");\n");
// sb.append(ind(2)).append("});\n");
// sb.append(ind(1)).append("}\n\n");
// }
//
// @Override
// void WriteToMqttDefinition.generateAspect(StringBuilder sb) {
// String parentTypeName = getToken().containingTypeDecl().getName();
// // fields
// sb.append(ind(1)).append("private String ").append(parentTypeName).append(".")
// .append(writeTopic()).append(" = null;\n");
// sb.append(ind(1)).append("private byte[] ").append(parentTypeName).append(".")
// .append(lastValue()).append(" = null;\n");
//
// // connect method
// sb.append(ind(1)).append("public void ").append(parentTypeName).append(".")
// .append(connectMethod()).append("(String topic, boolean writeCurrentValue) {\n");
// sb.append(ind(2)).append(writeTopic()).append(" = topic;\n");
// sb.append(ind(2)).append(updateMethod()).append("();\n");
// sb.append(ind(2)).append("if (writeCurrentValue) {\n");
// sb.append(ind(3)).append(writeMethod()).append("();\n");
// sb.append(ind(2)).append("}\n");
// sb.append(ind(1)).append("}\n\n");
//
// // update method
// sb.append(ind(1)).append("protected boolean ").append(parentTypeName).append(".")
// .append(updateMethod()).append("() {\n");
// sb.append(ind(2)).append(tokenResetMethod()).append("();\n");
// String lastResult = generateMappingApplication(sb, 2, "get" + getToken().getName() + "()");
// sb.append(ind(2)).append(lastValue()).append(" = ").append(lastResult).append(";\n");
// sb.append(ind(2)).append("return true;\n");
// sb.append(ind(1)).append("}\n\n");
//
// // write method
// sb.append(ind(1)).append("protected void ").append(parentTypeName).append(".")
// .append(writeMethod()).append("() {\n");
// if (loggingEnabledForWrites) {
// sb.append(ind(2)).append("System.out.println(\"[Write] ").append(getToken().getName())
// .append(" = \" + ")
// .append("get").append(getToken().getName()).append("() + \" -> \" + ")
// .append(writeTopic()).append(");\n");
// }
// // _mqttUpdater().publish(${writeTopic()}, ${lastValue()});
// sb.append(ind(2)).append(mqttUpdaterAttribute()).append("().publish(")
// .append(writeTopic()).append(", ").append(lastValue()).append(");\n");
// sb.append(ind(1)).append("}\n\n");
// }
//
// void MappingDefinition.generateAspect(StringBuilder sb) {
// sb.append(ind(1)).append("protected static ").append(getToType().prettyPrint())
// .append(" ASTNode.").append(methodName()).append("(")
// .append(getFromType().prettyPrint()).append(" ").append(getFromVariableName())
// .append(") throws Exception {\n");
// for (String line : getContent().split("\n")) {
// if (!line.trim().isEmpty()) {
// sb.append(ind(2)).append(line).append("\n");
// }
// }
// sb.append(ind(1)).append("}\n\n");
// }
//
// void DependencyDefinition.generateAspect(StringBuilder sb) {
// String targetParentTypeName = getTarget().containingTypeDecl().getName();
// String sourceParentTypeName = getSource().containingTypeDecl().getName();
//
// // dependency method
// sb.append(ind(1)).append("public void ").append(targetParentTypeName).append(".")
// .append(dependencyMethod()).append("(").append(sourceParentTypeName).append(" source) {\n");
// sb.append(ind(2)).append("add").append(internalRelationPrefix()).append("Source(source);\n");
// sb.append(ind(1)).append("}\n\n");
// }
//
// void TokenComponent.generateAspect(StringBuilder sb) {
// if (getDependencySourceDefinitionList().isEmpty()) { return; }
//
// String parentTypeName = containingTypeDecl().getName();
// // virtual setter
// sb.append(ind(1)).append("public ").append(parentTypeName).append(" ")
// .append(parentTypeName).append(".set").append(getName()).append("(")
// .append(getJavaTypeUse().prettyPrint()).append(" value) {\n");
// sb.append(ind(2)).append("set").append(internalName()).append("(value);\n");
//
// for (DependencyDefinition dependencyDefinition : getDependencySourceDefinitionList()) {
// String targetParentTypeName = dependencyDefinition.getTarget().containingTypeDecl().getName();
// sb.append(ind(2)).append("for (").append(targetParentTypeName).append(" target : get")
// .append(dependencyDefinition.internalRelationPrefix()).append("TargetList()) {\n");
// sb.append(ind(3)).append("if (target.")
// .append(dependencyDefinition.targetUpdateDefinition().updateMethod())
// .append("()) {\n");
// sb.append(ind(4)).append("target.")
// .append(dependencyDefinition.targetUpdateDefinition().writeMethod())
// .append("();\n");
// sb.append(ind(3)).append("}\n");
// sb.append(ind(2)).append("}\n");
// }
// sb.append(ind(2)).append("return this;\n");
// sb.append(ind(1)).append("}\n\n");
//
// // virtual getter
// sb.append(ind(1)).append("public ").append(getJavaTypeUse().prettyPrint())
// .append(" ").append(parentTypeName).append(".get").append(getName()).append("() {\n");
// sb.append(ind(2)).append("return get").append(internalName()).append("();\n");
// sb.append(ind(1)).append("}\n\n");
// }
}
aspect RelationGeneration {
......
......@@ -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);
......
{{lastDefinitionToType}} {{resultVarPrefix}}{{lastDefinitionName}};
try {
{{#InnerMappingDefinitions}}
{{^isLast}}{{ToType}} {{/isLast}}{{resultVarPrefix}}{{methodName}} = {{methodName}}({{inputVarName}});{{!inputVarName has to be computed beforehand}}
{{^last}}{{ToType}} {{/last}}{{resultVarPrefix}}{{methodName}} = {{methodName}}({{inputVarName}});{{!inputVarName has to be computed beforehand}}
{{/InnerMappingDefinitions}}
} catch (Exception e) {
e.printStackTrace();
{{preemptiveReturn}}
}
{{^alwaysApply}}
if ({{condition}}) {
if ({{{condition}}}) {
{{preemptiveReturn}}
}
{{/alwaysApply}}
protected static {{toType}} ASTNode.{{methodName}}({{fromType}} {{fromVariableName}}) throws Exception {
{{content}}{{!maybe print line by line to get better indentation}}
{{{content}}}{{!maybe print line by line to get better indentation}}
}
......@@ -16,7 +16,7 @@ aspect MQTT {
}
inh MqttUpdater ASTNode.{{mqttUpdaterAttribute}}();
{{#RootTypeChildren}}
{{#getRootTypeComponents}}
eq {{rootNodeName}}.get{{name}}().{{mqttUpdaterAttribute}}() = {{mqttUpdaterField}};
{{/RootTypeChildren}}
{{/getRootTypeComponents}}
}
public {{parentTypeName}} {{parentTypeName}}.set{{name}}({{javaType}} value) {
set{{internalName}}(value);
{{#DependencyDefinitions}}
for ({{targetParentType}} target : get{{internalRelationPrefix}}TargetList) {
for ({{targetParentTypeName}} target : get{{internalRelationPrefix}}TargetList()) {
{{#targetUpdateDefinition}}
if (target.{{updateMethod}}()) {
target.{{writeMethod}}();
......
......@@ -18,7 +18,7 @@
protected void {{parentTypeName}}.{{writeMethod}}() {
{{#loggingEnabledForWrites}}
System.out.println("[Write] {{tokenName}} = " + get{{tokenName}}() + " -> {{writeTopic}});
System.out.println("[Write] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{writeTopic}});
{{/loggingEnabledForWrites}}
{{mqttUpdateAttribute}}().publish({{writeTopic}}, {{lastValue}});
{{mqttUpdaterAttribute}}().publish({{writeTopic}}, {{lastValue}});
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment