Generation.jadd 13.7 KB
Newer Older
René Schöne's avatar
René Schöne committed
1
2
3
4
5
6
7
8
9
10
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();
  }
René Schöne's avatar
René Schöne committed
11
12
13
14
15
16
17
18
19
20
21

  // --- 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();
  }
René Schöne's avatar
René Schöne committed
22
23
}

René Schöne's avatar
René Schöne committed
24
25
26
27
28
29
/* Open questions
- Should all string constants be defined on the normal AST, or on the special mustache AST?
*/

aspect AttributesForMustache {
  // --- MRos2Rag ---
30
31
  eq MRos2Rag.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
  eq MRos2Rag.getChild().mqttHandlerField() = mqttHandlerField();
René Schöne's avatar
René Schöne committed
32

33
34
  syn String MRos2Rag.mqttHandlerAttribute() = getRos2Rag().mqttHandlerAttribute();
  syn String MRos2Rag.mqttHandlerField() = getRos2Rag().mqttHandlerField();
René Schöne's avatar
René Schöne committed
35
36
37
  syn String MRos2Rag.mqttSetHostMethod() = getRos2Rag().mqttSetHostMethod();
  syn String MRos2Rag.mqttWaitUntilReadyMethod() = getRos2Rag().mqttWaitUntilReadyMethod();
  syn String MRos2Rag.mqttCloseMethod() = getRos2Rag().mqttCloseMethod();
René Schöne's avatar
René Schöne committed
38
39
40
41

  // --- MUpdateDefinition ---
  syn String MUpdateDefinition.preemptiveExpectedValue();
  syn String MUpdateDefinition.preemptiveReturn();
42
43
  syn TokenUpdateDefinition MUpdateDefinition.updateDef();
  syn String MUpdateDefinition.firstInputVarName();
René Schöne's avatar
René Schöne committed
44

René Schöne's avatar
René Schöne committed
45
  eq MUpdateDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1;
René Schöne's avatar
René Schöne committed
46
  eq MUpdateDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix();
47
  eq MUpdateDefinition.getInnerMappingDefinition(int i).inputVarName() = i == 0 ? firstInputVarName() : resultVarPrefix() + getInnerMappingDefinition(i - 1).getMappingDefinition().methodName();
René Schöne's avatar
René Schöne committed
48

49
  inh String MUpdateDefinition.mqttHandlerAttribute();
René Schöne's avatar
René Schöne committed
50

René Schöne's avatar
René Schöne committed
51
52
53
54
55
  syn String MUpdateDefinition.connectMethod() = updateDef().connectMethod();
  syn TokenComponent MUpdateDefinition.token() = updateDef().getToken();
  syn boolean MUpdateDefinition.alwaysApply() = updateDef().getAlwaysApply();
  syn String MUpdateDefinition.resultVarPrefix() = "result";  // we do not need "_" here, because methodName begins with one
  syn String MUpdateDefinition.parentTypeName() = token().containingTypeDecl().getName();
56
57
  syn String MUpdateDefinition.tokenName() = token().getName();
  syn MInnerMappingDefinition MUpdateDefinition.lastDefinition() = getInnerMappingDefinition(getNumInnerMappingDefinition() - 1);
René Schöne's avatar
René Schöne committed
58
  syn String MUpdateDefinition.lastDefinitionToType() = lastDefinition().ToType();
René Schöne's avatar
René Schöne committed
59
  syn String MUpdateDefinition.lastDefinitionName() = lastDefinition().methodName();
60
  syn String MUpdateDefinition.lastResult() = resultVarPrefix() + lastDefinitionName();
René Schöne's avatar
René Schöne committed
61
62
  syn String MUpdateDefinition.condition() {
    if (lastDefinition().getMappingDefinition().getToType().isArray()) {
63
      return "java.util.Arrays.equals(" + preemptiveExpectedValue() + ", " + lastResult() + ")";
René Schöne's avatar
René Schöne committed
64
65
    }
    if (token().isPrimitiveType() && lastDefinition().getMappingDefinition().getToType().isPrimitiveType()) {
66
      return preemptiveExpectedValue() + " == " + lastResult();
René Schöne's avatar
René Schöne committed
67
68
    }
    if (lastDefinition().getMappingDefinition().isDefaultMappingDefinition()) {
69
      return preemptiveExpectedValue() + " != null && " + preemptiveExpectedValue() + ".equals(" + lastResult() + ")";
René Schöne's avatar
René Schöne committed
70
    }
71
    return preemptiveExpectedValue() + " != null ? " + preemptiveExpectedValue() + ".equals(" + lastResult() + ") : " + lastResult() + " == null";
René Schöne's avatar
René Schöne committed
72
73
74
75
76
77
78
79
80
81
  }

  // --- MInnerMappingDefinition ---
  inh boolean MInnerMappingDefinition.isLast();
  inh String MInnerMappingDefinition.resultVarPrefix();
  syn String MInnerMappingDefinition.ToType() = getMappingDefinition().getToType().prettyPrint();
  syn String MInnerMappingDefinition.methodName() = getMappingDefinition().methodName();
  inh String MInnerMappingDefinition.inputVarName();

  // --- MReadDefinition ---
82
  eq MReadDefinition.preemptiveExpectedValue() = "get" + tokenName() + "()";
René Schöne's avatar
René Schöne committed
83
84
  eq MReadDefinition.preemptiveReturn() = "return;";
  eq MReadDefinition.updateDef() = getReadFromMqttDefinition();
85
  eq MReadDefinition.firstInputVarName() = "message";
René Schöne's avatar
René Schöne committed
86
87
88
89
90

  // --- MWriteDefinition ---
  eq MWriteDefinition.preemptiveExpectedValue() = lastValue();
  eq MWriteDefinition.preemptiveReturn() = "return false;";
  eq MWriteDefinition.updateDef() = getWriteToMqttDefinition();
91
  eq MWriteDefinition.firstInputVarName() = "get" + tokenName() + "()";
René Schöne's avatar
René Schöne committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

  syn String MWriteDefinition.writeTopic() = getWriteToMqttDefinition().writeTopic();
  syn String MWriteDefinition.lastValue() = getWriteToMqttDefinition().lastValue();
  syn String MWriteDefinition.updateMethod() = getWriteToMqttDefinition().updateMethod();
  syn String MWriteDefinition.writeMethod() = getWriteToMqttDefinition().writeMethod();
  syn String MWriteDefinition.tokenResetMethod() = getWriteToMqttDefinition().tokenResetMethod();

  // --- MMappingDefinition ---
  syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint();
  syn String MMappingDefinition.methodName() = getMappingDefinition().methodName();
  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() = getDependencyDefinition().dependencyMethod();
  syn String MDependencyDefinition.sourceParentTypeName() = getDependencyDefinition().getSource().containingTypeDecl().getName();
  syn String MDependencyDefinition.internalRelationPrefix() = getDependencyDefinition().internalRelationPrefix();
  syn nta MUpdateDefinition MDependencyDefinition.targetUpdateDefinition() {
112
    return getDependencyDefinition().targetUpdateDefinition().toMustache();
René Schöne's avatar
René Schöne committed
113
114
115
116
  }

  // --- MTypeComponent ---
  syn String MTypeComponent.name() = getTypeComponent().getName();
117
118
  inh String MTypeComponent.mqttHandlerAttribute();
  inh String MTypeComponent.mqttHandlerField();
119
120
121
122
123
124

  // --- MTokenComponent ---
  syn String MTokenComponent.parentTypeName() = getTokenComponent().containingTypeDecl().getName();
  syn String MTokenComponent.name() = getTokenComponent().getName();
  syn String MTokenComponent.javaType() = getTokenComponent().getJavaTypeUse().prettyPrint();
  syn String MTokenComponent.internalName() = getTokenComponent().internalName();
René Schöne's avatar
René Schöne committed
125

126
127
  // --- toMustache ---
  syn lazy MRos2Rag Ros2Rag.toMustache() {
René Schöne's avatar
René Schöne committed
128
    MRos2Rag result = new MRos2Rag();
129
    result.setRos2Rag(this);
René Schöne's avatar
René Schöne committed
130
131
    for (UpdateDefinition def : getUpdateDefinitionList()) {
      if (def.isWriteToMqttDefinition()) {
132
        result.addWriteDefinition(def.asWriteToMqttDefinition().toMustache());
René Schöne's avatar
René Schöne committed
133
      } else {
134
        result.addReadDefinition(def.asReadFromMqttDefinition().toMustache());
René Schöne's avatar
René Schöne committed
135
136
137
      }
    }
    for (MappingDefinition def : allMappingDefinitions()) {
138
      result.addMappingDefinition(def.toMustache());
René Schöne's avatar
René Schöne committed
139
140
    }
    for (DependencyDefinition def : getDependencyDefinitionList()) {
141
      result.addDependencyDefinition(def.toMustache());
René Schöne's avatar
René Schöne committed
142
143
    }
    for (TokenComponent token : getProgram().allTokenComponents()) {
René Schöne's avatar
René Schöne committed
144
145
146
      if (!token.getDependencySourceDefinitionList().isEmpty()) {
        result.addTokenComponent(token.toMustache());
      }
147
148
149
    }
    for (Component child : rootNode.getComponentList()) {
      if (child.isTypeComponent()) {
René Schöne's avatar
René Schöne committed
150
        result.addRootTypeComponent(child.asTypeComponent().toMustache());
151
      }
René Schöne's avatar
René Schöne committed
152
153
154
    }
    return result;
  }
155

René Schöne's avatar
René Schöne committed
156
//MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
157
158
159
160
161
  protected void MUpdateDefinition.addInnerMappings() {
    for (MappingDefinition def : updateDef().effectiveMappings()) {
      MInnerMappingDefinition inner = new MInnerMappingDefinition();
      inner.setMappingDefinition(def);
      addInnerMappingDefinition(inner);
René Schöne's avatar
René Schöne committed
162
163
    }
  }
164
  syn lazy MReadDefinition ReadFromMqttDefinition.toMustache() {
René Schöne's avatar
René Schöne committed
165
166
167
168
169
    MReadDefinition result = new MReadDefinition();
    result.setReadFromMqttDefinition(this);
    result.addInnerMappings();
    return result;
  }
170
  syn lazy MWriteDefinition WriteToMqttDefinition.toMustache() {
René Schöne's avatar
René Schöne committed
171
172
173
174
175
    MWriteDefinition result = new MWriteDefinition();
    result.setWriteToMqttDefinition(this);
    result.addInnerMappings();
    return result;
  }
176
  syn lazy MMappingDefinition MappingDefinition.toMustache() {
René Schöne's avatar
René Schöne committed
177
178
179
180
    MMappingDefinition result = new MMappingDefinition();
    result.setMappingDefinition(this);
    return result;
  }
181
  syn lazy MDependencyDefinition DependencyDefinition.toMustache() {
René Schöne's avatar
René Schöne committed
182
183
184
185
    MDependencyDefinition result = new MDependencyDefinition();
    result.setDependencyDefinition(this);
    return result;
  }
186
  syn lazy MTypeComponent TypeComponent.toMustache() {
René Schöne's avatar
René Schöne committed
187
188
    MTypeComponent result = new MTypeComponent();
    result.setTypeComponent(this);
189
190
191
192
193
    return result;
  }
  syn lazy MTokenComponent TokenComponent.toMustache() {
    MTokenComponent result = new MTokenComponent();
    result.setTokenComponent(this);
René Schöne's avatar
René Schöne committed
194
    for (DependencyDefinition def : getDependencySourceDefinitionList()) {
195
      result.addDependencyDefinition(def.toMustache());
René Schöne's avatar
René Schöne committed
196
197
198
199
200
    }
    return result;
  }
}

René Schöne's avatar
René Schöne committed
201
aspect AspectGeneration {
René Schöne's avatar
René Schöne committed
202
  // naming convention attributes
203
204
  syn String TokenComponent.internalName() = getDependencySourceDefinitionList().isEmpty() ? externalName() : "_internal_" + getName();
  syn String TokenComponent.externalName() = getName();
René Schöne's avatar
René Schöne committed
205
206
207
208
209
210
211
212
213
214
215
216

  syn String TokenUpdateDefinition.connectMethod() = "connect" + getToken().getName();
  syn String WriteToMqttDefinition.writeTopic() = "_topic_" + getToken().getName();
  syn String WriteToMqttDefinition.lastValue() = "_lastValue" + getToken().getName();
  syn String WriteToMqttDefinition.updateMethod() = "_update_" + getToken().getName();
  syn String WriteToMqttDefinition.writeMethod() = "_writeLastValue_" + getToken().getName();
  syn String WriteToMqttDefinition.tokenResetMethod() = "get" + getToken().getName() + "_reset";
  syn String MappingDefinition.methodName() = "_apply_" + getID();
  syn String DependencyDefinition.dependencyMethod() = "add" +
    Character.toUpperCase(getID().charAt(0)) +
    getID().substring(1);
  syn String DependencyDefinition.internalRelationPrefix() = "_internal_" + getID();
217
  syn String DependencyDefinition.internalTokenName() = getSource().internalName();
René Schöne's avatar
René Schöne committed
218

219
220
  syn String Ros2Rag.mqttHandlerAttribute() = "_mqttHandler";
  syn String Ros2Rag.mqttHandlerField() = "_mqttHandler";
René Schöne's avatar
René Schöne committed
221
222
223
224
225

  syn String Ros2Rag.mqttSetHostMethod() = "MqttSetHost";
  syn String Ros2Rag.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady";
  syn String Ros2Rag.mqttCloseMethod() = "MqttCloseConnections";

René Schöne's avatar
René Schöne committed
226
  // naming copy attributes
227
228
229
230
231
  // --- mqttHandlerAttribute ---
  inh String UpdateDefinition.mqttHandlerAttribute();
  inh String MappingDefinition.mqttHandlerAttribute();
  inh String DependencyDefinition.mqttHandlerAttribute();
  eq Ros2Rag.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
René Schöne's avatar
René Schöne committed
232

René Schöne's avatar
René Schöne committed
233
234
  // --- rootNodeName ---
  syn String ASTNode.rootNodeName() = rootNode.getName();
René Schöne's avatar
René Schöne committed
235

René Schöne's avatar
René Schöne committed
236
237
  public String Ros2Rag.generateAspect(String rootNodeName) {
    rootNode = getProgram().resolveTypeDecl(rootNodeName);
René Schöne's avatar
René Schöne committed
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    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);
260
    com.github.mustachejava.Mustache m = mf.compile("ros2rag.mustache");
René Schöne's avatar
René Schöne committed
261
    m.execute(new java.io.PrintWriter(new org.jastadd.ros2rag.compiler.AppendableWriter(sb)), this);
262
    return sb.toString();
René Schöne's avatar
René Schöne committed
263
264
  }
}
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

aspect RelationGeneration {
  syn java.util.List<Relation> Ros2Rag.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() {
    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);
    return result;
  }
}

aspect GrammarExtension {
  refine BackendAbstractGrammar public void TokenComponent.generateAbstractGrammar(StringBuilder b) {
    if (getNTA()) {
      b.append("/");
    }
    b.append("<");
    if (!getName().equals("")) {
      b.append(internalName()).append(":");
    }
    getJavaTypeUse().generateAbstractGrammar(b);
    b.append(">");
    if (getNTA()) {
      b.append("/");
    }
  }
}