Select Git revision
Generation.jadd
-
René Schöne authored
- changed semantics of ViaTest slightly (setting same value for inputBoth does not change to newly send value as the "FromMqtt-" and "FromRest-" part is not prepended, and therefore it stays the same)
René Schöne authored- changed semantics of ViaTest slightly (setting same value for inputBoth does not change to newly send value as the "FromMqtt-" and "FromRest-" part is not prepended, and therefore it stays the same)
Generation.jadd 14.56 KiB
aspect GenerationUtils {
public static final String ASTNode.aspectIndent = " ";
public String ASTNode.ind(int n) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < n; i++) {
s.append(aspectIndent);
}
return s.toString();
}
// --- prettyPrint ---
syn String MappingDefinitionType.prettyPrint();
eq JavaMappingDefinitionType.prettyPrint() = getType().getName();
eq JavaArrayMappingDefinitionType.prettyPrint() = getType().getName() + "[]";
syn String JavaTypeUse.prettyPrint() {
StringBuilder sb = new StringBuilder();
generateAbstractGrammar(sb);
return sb.toString();
}
}
/* Open questions
- Should all string constants be defined on the normal AST, or on the special mustache AST?
Design considerations
- InnerMappingDefinition needed for iteration attribute (first, last) - not easily possible with list-relation
*/
aspect AttributesForMustache {
// --- MRagConnect ---
eq MRagConnect.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
eq MRagConnect.getChild().restHandlerAttribute() = restHandlerAttribute();
eq MRagConnect.getChild().mqttHandlerField() = mqttHandlerField();
eq MRagConnect.getRootTypeComponent(int i).isFirst() = i == 0;
syn String MRagConnect.closeMethod() = "ragconnectCloseConnections";
// syn boolean MRagConnect.usesMqtt() = getRagConnect().usesMqtt();
syn String MRagConnect.mqttHandlerAttribute() = "_mqttHandler";
syn String MRagConnect.mqttHandlerField() = "_mqttHandler";
// syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost";
syn String MRagConnect.mqttSetupWaitUntilReadyMethod() = "ragconnectSetupMqttWaitUntilReady";
// syn boolean MRagConnect.usesRest() = getRagConnect().usesRest();
syn String MRagConnect.restHandlerAttribute() = "_restHandler";
syn String MRagConnect.restHandlerField() = "_restHandler";
// syn String MRagConnect.restSetPortMethod() = "RestSetPort";
// --- MEndpointDefinition ---
syn String MEndpointDefinition.preemptiveExpectedValue();
syn String MEndpointDefinition.preemptiveReturn();
syn TokenEndpointDefinition MEndpointDefinition.endpointDef();
syn String MEndpointDefinition.firstInputVarName();
// syn String MEndpointDefinition.newConnectionMethod();
eq MEndpointDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1;
eq MEndpointDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix();
eq MEndpointDefinition.getInnerMappingDefinition(int i).inputVarName() = i == 0 ? firstInputVarName() : resultVarPrefix() + getInnerMappingDefinition(i - 1).methodName();
inh String MEndpointDefinition.mqttHandlerAttribute();
inh String MEndpointDefinition.restHandlerAttribute();
syn String MEndpointDefinition.connectParameterName() = "uriString";
// switch (endpointDef().protocol()) {
// case "mqtt": return "topic";
// case "rest": return "path";
// default: return null;
// }
// }
// syn String MEndpointDefinition.handlerAttribute() {
// switch (endpointDef().protocol()) {
// case "mqtt": return mqttHandlerAttribute();
// case "rest": return restHandlerAttribute();
// default: return null;
// }
// }
syn String MEndpointDefinition.connectMethod() = "connect" + tokenName();
syn TokenComponent MEndpointDefinition.token() = endpointDef().getToken();
syn boolean MEndpointDefinition.alwaysApply() = endpointDef().getAlwaysApply();
syn String MEndpointDefinition.resultVarPrefix() = "result"; // we do not need "_" here, because methodName begins with one
syn String MEndpointDefinition.parentTypeName() = token().containingTypeDecl().getName();
syn String MEndpointDefinition.tokenName() = token().getName();
syn MInnerMappingDefinition MEndpointDefinition.lastDefinition() = getInnerMappingDefinition(getNumInnerMappingDefinition() - 1);
syn String MEndpointDefinition.lastDefinitionToType() = lastDefinition().toType();
syn String MEndpointDefinition.lastDefinitionName() = lastDefinition().methodName();
syn String MEndpointDefinition.lastResult() = resultVarPrefix() + lastDefinitionName();
syn String MEndpointDefinition.condition() {
if (lastDefinition().mappingDef().getToType().isArray()) {
return "java.util.Arrays.equals(" + preemptiveExpectedValue() + ", " + lastResult() + ")";
}
if (token().isPrimitiveType() && lastDefinition().mappingDef().getToType().isPrimitiveType()) {
return preemptiveExpectedValue() + " == " + lastResult();
}
if (lastDefinition().mappingDef().isDefaultMappingDefinition()) {
return preemptiveExpectedValue() + " != null && " + preemptiveExpectedValue() + ".equals(" + lastResult() + ")";
}
return preemptiveExpectedValue() + " != null ? " + preemptiveExpectedValue() + ".equals(" + lastResult() + ") : " + lastResult() + " == null";
}
// --- MInnerMappingDefinition ---
inh boolean MInnerMappingDefinition.isLast();
inh String MInnerMappingDefinition.resultVarPrefix();
inh String MInnerMappingDefinition.inputVarName();
syn String MInnerMappingDefinition.toType() = mappingDef().getToType().prettyPrint();
syn String MInnerMappingDefinition.methodName() = getMMappingDefinition().methodName();
syn MappingDefinition MInnerMappingDefinition.mappingDef() = getMMappingDefinition().getMappingDefinition();
// --- MReceiveDefinition ---
eq MReceiveDefinition.preemptiveExpectedValue() = "get" + tokenName() + "()";
eq MReceiveDefinition.preemptiveReturn() = "return;";
eq MReceiveDefinition.endpointDef() = getReceiveTokenEndpointDefinition();
eq MReceiveDefinition.firstInputVarName() = "message";
// syn String MReceiveDefinition.newConnectionMethod() {
// switch (endpointDef().protocol()) {
// case "mqtt": return "newConnection";
// case "rest": return "newPUTConnection";
// default: return null;
// }
// }
// --- MSendDefinition ---
eq MSendDefinition.preemptiveExpectedValue() = lastValue();
eq MSendDefinition.preemptiveReturn() = "return false;";
// switch (endpointDef().protocol()) {
// case "mqtt": return "return false;";
// case "rest": return "throw e;"; // e is Exception variable
// default: return null;
// }
// }
eq MSendDefinition.endpointDef() = getSendTokenEndpointDefinition();
eq MSendDefinition.firstInputVarName() = "get" + tokenName() + "()";
syn String MSendDefinition.sender() = "_sender_" + tokenName();
syn String MSendDefinition.lastValue() = "_lastValue" + tokenName();
syn String MSendDefinition.updateMethod() = "_update_" + tokenName();
syn String MSendDefinition.writeMethod() = "_writeLastValue_" + tokenName();
syn String MSendDefinition.tokenResetMethod() = "get" + tokenName() + "_reset";
// syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush();
// syn String MSendDefinition.newConnectionMethod() {
// switch (endpointDef().protocol()) {
// case "mqtt": return null;
// case "rest": return "newGETConnection";
// default: return null;
// }
// }
// --- MMappingDefinition ---
syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint();
syn String MMappingDefinition.methodName() = "_apply_" + getMappingDefinition().getID();
syn String MMappingDefinition.fromType() = getMappingDefinition().getFromType().prettyPrint();
syn String MMappingDefinition.fromVariableName() = getMappingDefinition().getFromVariableName();
syn String MMappingDefinition.content() = getMappingDefinition().getContent();
// --- MDependencyDefinition ---
syn String MDependencyDefinition.targetParentTypeName() = getDependencyDefinition().getTarget().containingTypeDecl().getName();
syn String MDependencyDefinition.dependencyMethod() = "add" + capitalize(getDependencyDefinition().getID());
syn String MDependencyDefinition.sourceParentTypeName() = getDependencyDefinition().getSource().containingTypeDecl().getName();
syn String MDependencyDefinition.internalRelationPrefix() = "_internal_" + getDependencyDefinition().getID();
syn nta MSendDefinition MDependencyDefinition.targetEndpointDefinition() {
return getDependencyDefinition().targetEndpointDefinition().toMustache();
}
// --- MTypeComponent ---
syn String MTypeComponent.name() = getTypeComponent().getName();
inh String MTypeComponent.mqttHandlerAttribute();
inh String MTypeComponent.mqttHandlerField();
inh boolean MTypeComponent.isFirst();
// --- MTokenComponent ---
syn String MTokenComponent.parentTypeName() = getTokenComponent().containingTypeDecl().getName();
syn String MTokenComponent.name() = getTokenComponent().getName();
syn String MTokenComponent.javaType() = getTokenComponent().effectiveJavaTypeUse().prettyPrint();
syn String MTokenComponent.internalName() = getTokenComponent().getDependencySourceDefinitionList().isEmpty() ? externalName() : "_internal_" + name();
syn String MTokenComponent.externalName() = name();
// --- toMustache ---
syn lazy MRagConnect RagConnect.toMustache() {
MRagConnect result = new MRagConnect();
result.setRagConnect(this);
for (EndpointDefinition def : getEndpointDefinitionList()) {
if (def.isSendTokenEndpointDefinition()) {
SendTokenEndpointDefinition sendDef = def.asSendTokenEndpointDefinition();
result.addSendDefinition(sendDef.toMustache());
} else {
result.addReceiveDefinition(def.asReceiveTokenEndpointDefinition().toMustache());
}
}
for (MappingDefinition def : allMappingDefinitions()) {
result.addMappingDefinition(def.toMustache());
}
for (DependencyDefinition def : getDependencyDefinitionList()) {
result.addDependencyDefinition(def.toMustache());
}
for (TokenComponent token : getProgram().allTokenComponents()) {
if (!token.getDependencySourceDefinitionList().isEmpty()) {
result.addTokenComponent(token.toMustache());
}
}
for (Component child : rootNode.getComponentList()) {
if (child.isTypeComponent()) {
result.addRootTypeComponent(child.asTypeComponent().toMustache());
}
}
return result;
}
//MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
protected void MEndpointDefinition.addInnerMappings() {
for (MappingDefinition def : endpointDef().effectiveMappings()) {
MInnerMappingDefinition inner = new MInnerMappingDefinition();
inner.setMMappingDefinition(def.toMustache());
addInnerMappingDefinition(inner);
}
}
syn lazy MReceiveDefinition ReceiveTokenEndpointDefinition.toMustache() {
MReceiveDefinition result = new MReceiveDefinition();
result.setReceiveTokenEndpointDefinition(this);
result.addInnerMappings();
return result;
}
syn lazy MSendDefinition SendTokenEndpointDefinition.toMustache() {
MSendDefinition result = new MSendDefinition();
result.setSendTokenEndpointDefinition(this);
result.addInnerMappings();
return result;
}
syn lazy MMappingDefinition MappingDefinition.toMustache() {
MMappingDefinition result = new MMappingDefinition();
result.setMappingDefinition(this);
return result;
}
syn lazy MDependencyDefinition DependencyDefinition.toMustache() {
MDependencyDefinition result = new MDependencyDefinition();
result.setDependencyDefinition(this);
return result;
}
syn lazy MTypeComponent TypeComponent.toMustache() {
MTypeComponent result = new MTypeComponent();
result.setTypeComponent(this);
return result;
}
syn lazy MTokenComponent TokenComponent.toMustache() {
MTokenComponent result = new MTokenComponent();
result.setTokenComponent(this);
for (DependencyDefinition def : getDependencySourceDefinitionList()) {
result.addDependencyDefinition(def.toMustache());
}
return result;
}
}
aspect AspectGeneration {
// syn boolean SendTokenEndpointDefinition.isPush();
// eq SendToMqttDefinition.isPush() = true;
// eq SendToRestDefinition.isPush() = false;
// --- rootNodeName ---
syn String ASTNode.rootNodeName() = rootNode.getName();
public String RagConnect.generateAspect(String rootNodeName) {
rootNode = getProgram().resolveTypeDecl(rootNodeName);
return toMustache().generateAspect();
}
public String MRagConnect.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("ragconnect.mustache");
m.execute(new java.io.PrintWriter(new org.jastadd.ragconnect.compiler.AppendableWriter(sb)), this);
return sb.toString();
}
}
aspect RelationGeneration {
syn java.util.List<Relation> RagConnect.additionalRelations() {
java.util.List<Relation> result = new java.util.ArrayList<>();
for (DependencyDefinition dd : getDependencyDefinitionList()) {
result.add(dd.getRelationToCreate());
}
return result;
}
syn nta Relation DependencyDefinition.getRelationToCreate() {
String internalRelationPrefix = toMustache().internalRelationPrefix();
BidirectionalRelation result = new BidirectionalRelation();
NavigableRole left = new ListRole(internalRelationPrefix + "Source");
left.setType(getTarget().containingTypeDecl());
NavigableRole right = new ListRole(internalRelationPrefix + "Target");
right.setType(getSource().containingTypeDecl());
result.setLeft(left);
result.setRight(right);
result.addComment(new WhitespaceComment("\n"));
return result;
}
}
aspect GrammarExtension {
refine BackendAbstractGrammar public void TokenComponent.generateAbstractGrammar(StringBuilder b) {
if (getNTA()) {
b.append("/");
}
b.append("<");
if (!getName().equals("")) {
b.append(toMustache().internalName()).append(":");
}
effectiveJavaTypeUse().generateAbstractGrammar(b);
b.append(">");
if (getNTA()) {
b.append("/");
}
}
}