Generation.jadd 15.5 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
/* Open questions
- Should all string constants be defined on the normal AST, or on the special mustache AST?
*/

aspect AttributesForMustache {
29
30
31
32
  // --- MRagConnect ---
  eq MRagConnect.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
  eq MRagConnect.getChild().mqttHandlerField() = mqttHandlerField();
  eq MRagConnect.getRootTypeComponent(int i).isFirst() = i == 0;
René Schöne's avatar
René Schöne committed
33

34
35
36
37
38
  syn String MRagConnect.mqttHandlerAttribute() = getRagConnect().mqttHandlerAttribute();
  syn String MRagConnect.mqttHandlerField() = getRagConnect().mqttHandlerField();
  syn String MRagConnect.mqttSetHostMethod() = getRagConnect().mqttSetHostMethod();
  syn String MRagConnect.mqttWaitUntilReadyMethod() = getRagConnect().mqttWaitUntilReadyMethod();
  syn String MRagConnect.mqttCloseMethod() = getRagConnect().mqttCloseMethod();
René Schöne's avatar
René Schöne committed
39

René Schöne's avatar
René Schöne committed
40
41
  syn String MRagConnect.restHandlerAttribute() = getRagConnect().restHandlerAttribute();

42
43
44
45
46
47
48
49
50
51
52
53
  // --- MEndpointDefinition ---
  syn String MEndpointDefinition.preemptiveExpectedValue();
  syn String MEndpointDefinition.preemptiveReturn();
  syn TokenEndpointDefinition MEndpointDefinition.endpointDef();
  syn String MEndpointDefinition.firstInputVarName();

  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).getMappingDefinition().methodName();

  inh String MEndpointDefinition.mqttHandlerAttribute();

René Schöne's avatar
René Schöne committed
54
  syn String MEndpointDefinition.handlerAttribute() = endpointDef().handlerAttribute();
55
56
57
58
59
60
61
62
63
64
65
  syn String MEndpointDefinition.connectMethod() = endpointDef().connectMethod();
  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() {
René Schöne's avatar
René Schöne committed
66
    if (lastDefinition().getMappingDefinition().getToType().isArray()) {
67
      return "java.util.Arrays.equals(" + preemptiveExpectedValue() + ", " + lastResult() + ")";
René Schöne's avatar
René Schöne committed
68
69
    }
    if (token().isPrimitiveType() && lastDefinition().getMappingDefinition().getToType().isPrimitiveType()) {
70
      return preemptiveExpectedValue() + " == " + lastResult();
René Schöne's avatar
René Schöne committed
71
72
    }
    if (lastDefinition().getMappingDefinition().isDefaultMappingDefinition()) {
73
      return preemptiveExpectedValue() + " != null && " + preemptiveExpectedValue() + ".equals(" + lastResult() + ")";
René Schöne's avatar
René Schöne committed
74
    }
75
    return preemptiveExpectedValue() + " != null ? " + preemptiveExpectedValue() + ".equals(" + lastResult() + ") : " + lastResult() + " == null";
René Schöne's avatar
René Schöne committed
76
77
78
79
80
81
82
83
84
  }

  // --- 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();

85
86
87
  // --- MReceiveDefinition ---
  eq MReceiveDefinition.preemptiveExpectedValue() = "get" + tokenName() + "()";
  eq MReceiveDefinition.preemptiveReturn() = "return;";
René Schöne's avatar
René Schöne committed
88
  eq MReceiveDefinition.endpointDef() = getReceiveTokenEndpointDefinition();
89
90
91
92
93
  eq MReceiveDefinition.firstInputVarName() = "message";

  // --- MSendDefinition ---
  eq MSendDefinition.preemptiveExpectedValue() = lastValue();
  eq MSendDefinition.preemptiveReturn() = "return false;";
René Schöne's avatar
René Schöne committed
94
  eq MSendDefinition.endpointDef() = getSendTokenEndpointDefinition();
95
96
  eq MSendDefinition.firstInputVarName() = "get" + tokenName() + "()";

René Schöne's avatar
René Schöne committed
97
98
99
100
101
  syn String MSendDefinition.sendTopic() = getSendTokenEndpointDefinition().sendTopic();
  syn String MSendDefinition.lastValue() = getSendTokenEndpointDefinition().lastValue();
  syn String MSendDefinition.updateMethod() = getSendTokenEndpointDefinition().updateMethod();
  syn String MSendDefinition.writeMethod() = getSendTokenEndpointDefinition().writeMethod();
  syn String MSendDefinition.tokenResetMethod() = getSendTokenEndpointDefinition().tokenResetMethod();
René Schöne's avatar
René Schöne committed
102
103
104
105
106
107
108
109
110
111
112
113
114

  // --- 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();
115
116
  syn nta MEndpointDefinition MDependencyDefinition.targetEndpointDefinition() {
    return getDependencyDefinition().targetEndpointDefinition().toMustache();
René Schöne's avatar
René Schöne committed
117
118
119
120
  }

  // --- MTypeComponent ---
  syn String MTypeComponent.name() = getTypeComponent().getName();
121
122
  inh String MTypeComponent.mqttHandlerAttribute();
  inh String MTypeComponent.mqttHandlerField();
123
  inh boolean MTypeComponent.isFirst();
124
125
126
127

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

131
  // --- toMustache ---
132
133
134
  syn lazy MRagConnect RagConnect.toMustache() {
    MRagConnect result = new MRagConnect();
    result.setRagConnect(this);
135
    for (EndpointDefinition def : getEndpointDefinitionList()) {
René Schöne's avatar
René Schöne committed
136
137
      if (def.isSendTokenEndpointDefinition()) {
        result.addSendDefinition(def.asSendTokenEndpointDefinition().toMustache());
René Schöne's avatar
René Schöne committed
138
      } else {
René Schöne's avatar
René Schöne committed
139
        result.addReceiveDefinition(def.asReceiveTokenEndpointDefinition().toMustache());
René Schöne's avatar
René Schöne committed
140
141
142
      }
    }
    for (MappingDefinition def : allMappingDefinitions()) {
143
      result.addMappingDefinition(def.toMustache());
René Schöne's avatar
René Schöne committed
144
145
    }
    for (DependencyDefinition def : getDependencyDefinitionList()) {
146
      result.addDependencyDefinition(def.toMustache());
René Schöne's avatar
René Schöne committed
147
148
    }
    for (TokenComponent token : getProgram().allTokenComponents()) {
René Schöne's avatar
René Schöne committed
149
150
151
      if (!token.getDependencySourceDefinitionList().isEmpty()) {
        result.addTokenComponent(token.toMustache());
      }
152
153
154
    }
    for (Component child : rootNode.getComponentList()) {
      if (child.isTypeComponent()) {
René Schöne's avatar
René Schöne committed
155
        result.addRootTypeComponent(child.asTypeComponent().toMustache());
156
      }
René Schöne's avatar
René Schöne committed
157
158
159
    }
    return result;
  }
160

René Schöne's avatar
René Schöne committed
161
//MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
162
163
  protected void MEndpointDefinition.addInnerMappings() {
    for (MappingDefinition def : endpointDef().effectiveMappings()) {
164
165
166
      MInnerMappingDefinition inner = new MInnerMappingDefinition();
      inner.setMappingDefinition(def);
      addInnerMappingDefinition(inner);
René Schöne's avatar
René Schöne committed
167
168
    }
  }
René Schöne's avatar
René Schöne committed
169
170
171
172
173
174
175
176
  syn lazy MReceiveDefinition ReceiveTokenEndpointDefinition.toMustache();
  eq ReceiveFromMqttDefinition.toMustache() {
    MReceiveDefinition result = new MReceiveDefinition();
    result.setReceiveTokenEndpointDefinition(this);
    result.addInnerMappings();
    return result;
  }
  eq ReceiveFromRestDefinition.toMustache() {
177
    MReceiveDefinition result = new MReceiveDefinition();
René Schöne's avatar
René Schöne committed
178
179
180
181
182
183
184
185
186
    System.err.println("REST not implemented!");
    result.setReceiveTokenEndpointDefinition(this);
    result.addInnerMappings();
    return result;
  }
  syn lazy MSendDefinition SendTokenEndpointDefinition.toMustache();
  eq SendToMqttDefinition.toMustache() {
    MSendDefinition result = new MSendDefinition();
    result.setSendTokenEndpointDefinition(this);
René Schöne's avatar
René Schöne committed
187
188
189
    result.addInnerMappings();
    return result;
  }
René Schöne's avatar
René Schöne committed
190
  eq SendToRestDefinition.toMustache() {
191
    MSendDefinition result = new MSendDefinition();
René Schöne's avatar
René Schöne committed
192
193
    System.err.println("REST not implemented!");
    result.setSendTokenEndpointDefinition(this);
René Schöne's avatar
René Schöne committed
194
195
196
    result.addInnerMappings();
    return result;
  }
197
  syn lazy MMappingDefinition MappingDefinition.toMustache() {
René Schöne's avatar
René Schöne committed
198
199
200
201
    MMappingDefinition result = new MMappingDefinition();
    result.setMappingDefinition(this);
    return result;
  }
202
  syn lazy MDependencyDefinition DependencyDefinition.toMustache() {
René Schöne's avatar
René Schöne committed
203
204
205
206
    MDependencyDefinition result = new MDependencyDefinition();
    result.setDependencyDefinition(this);
    return result;
  }
207
  syn lazy MTypeComponent TypeComponent.toMustache() {
René Schöne's avatar
René Schöne committed
208
209
    MTypeComponent result = new MTypeComponent();
    result.setTypeComponent(this);
210
211
212
213
214
    return result;
  }
  syn lazy MTokenComponent TokenComponent.toMustache() {
    MTokenComponent result = new MTokenComponent();
    result.setTokenComponent(this);
René Schöne's avatar
René Schöne committed
215
    for (DependencyDefinition def : getDependencySourceDefinitionList()) {
216
      result.addDependencyDefinition(def.toMustache());
René Schöne's avatar
René Schöne committed
217
218
219
220
221
    }
    return result;
  }
}

René Schöne's avatar
René Schöne committed
222
aspect AspectGeneration {
René Schöne's avatar
René Schöne committed
223
  // naming convention attributes
224
225
  syn String TokenComponent.internalName() = getDependencySourceDefinitionList().isEmpty() ? externalName() : "_internal_" + getName();
  syn String TokenComponent.externalName() = getName();
René Schöne's avatar
René Schöne committed
226

227
  syn String TokenEndpointDefinition.connectMethod() = "connect" + getToken().getName();
René Schöne's avatar
René Schöne committed
228
229
230
231
232
  syn String SendTokenEndpointDefinition.sendTopic() = "_topic_" + getToken().getName();
  syn String SendTokenEndpointDefinition.lastValue() = "_lastValue" + getToken().getName();
  syn String SendTokenEndpointDefinition.updateMethod() = "_update_" + getToken().getName();
  syn String SendTokenEndpointDefinition.writeMethod() = "_writeLastValue_" + getToken().getName();
  syn String SendTokenEndpointDefinition.tokenResetMethod() = "get" + getToken().getName() + "_reset";
René Schöne's avatar
René Schöne committed
233
234
235
236
237
  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();
238
  syn String DependencyDefinition.internalTokenName() = getSource().internalName();
René Schöne's avatar
René Schöne committed
239

240
241
  syn String RagConnect.mqttHandlerAttribute() = "_mqttHandler";
  syn String RagConnect.mqttHandlerField() = "_mqttHandler";
René Schöne's avatar
René Schöne committed
242

243
244
245
  syn String RagConnect.mqttSetHostMethod() = "MqttSetHost";
  syn String RagConnect.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady";
  syn String RagConnect.mqttCloseMethod() = "MqttCloseConnections";
René Schöne's avatar
René Schöne committed
246

René Schöne's avatar
René Schöne committed
247
248
249
250
251
252
253
254
255
  syn String RagConnect.restHandlerAttribute() = "_restHandler";
  syn String RagConnect.restHandlerField() = "_restHandler";

  syn String TokenEndpointDefinition.handlerAttribute();
  eq ReceiveFromMqttDefinition.handlerAttribute() = mqttHandlerAttribute();
  eq SendToMqttDefinition.handlerAttribute() = mqttHandlerAttribute();
  eq ReceiveFromRestDefinition.handlerAttribute() = restHandlerAttribute();
  eq SendToRestDefinition.handlerAttribute() = restHandlerAttribute();

René Schöne's avatar
René Schöne committed
256
  // naming copy attributes
257
  // --- mqttHandlerAttribute ---
258
  inh String EndpointDefinition.mqttHandlerAttribute();
259
  eq RagConnect.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
René Schöne's avatar
René Schöne committed
260

René Schöne's avatar
René Schöne committed
261
262
263
264
  // --- restHandlerAttribute ---
  inh String EndpointDefinition.restHandlerAttribute();
  eq RagConnect.getChild().restHandlerAttribute() = restHandlerAttribute();

René Schöne's avatar
René Schöne committed
265
266
  // --- rootNodeName ---
  syn String ASTNode.rootNodeName() = rootNode.getName();
René Schöne's avatar
René Schöne committed
267

268
  public String RagConnect.generateAspect(String rootNodeName) {
René Schöne's avatar
René Schöne committed
269
    rootNode = getProgram().resolveTypeDecl(rootNodeName);
René Schöne's avatar
René Schöne committed
270
271
272
    return toMustache().generateAspect();
  }

273
  public String MRagConnect.generateAspect() {
René Schöne's avatar
René Schöne committed
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
    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);
292
293
    com.github.mustachejava.Mustache m = mf.compile("ragconnect.mustache");
    m.execute(new java.io.PrintWriter(new org.jastadd.ragconnect.compiler.AppendableWriter(sb)), this);
294
    return sb.toString();
René Schöne's avatar
René Schöne committed
295
296
  }
}
297
298

aspect RelationGeneration {
299
  syn java.util.List<Relation> RagConnect.additionalRelations() {
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
    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);
315
    result.addComment(new WhitespaceComment("\n"));
316
317
318
319
320
321
322
323
324
325
326
327
328
    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(":");
    }
René Schöne's avatar
René Schöne committed
329
    effectiveJavaTypeUse().generateAbstractGrammar(b);
330
331
332
333
334
335
    b.append(">");
    if (getNTA()) {
      b.append("/");
    }
  }
}