Generation.jadd 14 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
40
41
42

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

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

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

René Schöne's avatar
René Schöne committed
52
53
54
55
56
  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();
57
58
  syn String MUpdateDefinition.tokenName() = token().getName();
  syn MInnerMappingDefinition MUpdateDefinition.lastDefinition() = getInnerMappingDefinition(getNumInnerMappingDefinition() - 1);
René Schöne's avatar
René Schöne committed
59
  syn String MUpdateDefinition.lastDefinitionToType() = lastDefinition().ToType();
René Schöne's avatar
René Schöne committed
60
  syn String MUpdateDefinition.lastDefinitionName() = lastDefinition().methodName();
61
  syn String MUpdateDefinition.lastResult() = resultVarPrefix() + lastDefinitionName();
René Schöne's avatar
René Schöne committed
62
63
  syn String MUpdateDefinition.condition() {
    if (lastDefinition().getMappingDefinition().getToType().isArray()) {
64
      return "java.util.Arrays.equals(" + preemptiveExpectedValue() + ", " + lastResult() + ")";
René Schöne's avatar
René Schöne committed
65
66
    }
    if (token().isPrimitiveType() && lastDefinition().getMappingDefinition().getToType().isPrimitiveType()) {
67
      return preemptiveExpectedValue() + " == " + lastResult();
René Schöne's avatar
René Schöne committed
68
69
    }
    if (lastDefinition().getMappingDefinition().isDefaultMappingDefinition()) {
70
      return preemptiveExpectedValue() + " != null && " + preemptiveExpectedValue() + ".equals(" + lastResult() + ")";
René Schöne's avatar
René Schöne committed
71
    }
72
    return preemptiveExpectedValue() + " != null ? " + preemptiveExpectedValue() + ".equals(" + lastResult() + ") : " + lastResult() + " == null";
René Schöne's avatar
René Schöne committed
73
74
75
76
77
78
79
80
81
82
  }

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

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

  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() {
113
    return getDependencyDefinition().targetUpdateDefinition().toMustache();
René Schöne's avatar
René Schöne committed
114
115
116
117
  }

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

  // --- 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
127

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

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

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

  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();
219
  syn String DependencyDefinition.internalTokenName() = getSource().internalName();
René Schöne's avatar
René Schöne committed
220

221
222
  syn String RagConnect.mqttHandlerAttribute() = "_mqttHandler";
  syn String RagConnect.mqttHandlerField() = "_mqttHandler";
René Schöne's avatar
René Schöne committed
223

224
225
226
  syn String RagConnect.mqttSetHostMethod() = "MqttSetHost";
  syn String RagConnect.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady";
  syn String RagConnect.mqttCloseMethod() = "MqttCloseConnections";
René Schöne's avatar
René Schöne committed
227

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

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

238
  public String RagConnect.generateAspect(String rootNodeName) {
René Schöne's avatar
René Schöne committed
239
    rootNode = getProgram().resolveTypeDecl(rootNodeName);
René Schöne's avatar
René Schöne committed
240
241
242
    return toMustache().generateAspect();
  }

243
  public String MRagConnect.generateAspect() {
René Schöne's avatar
René Schöne committed
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
    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);
262
263
    com.github.mustachejava.Mustache m = mf.compile("ragconnect.mustache");
    m.execute(new java.io.PrintWriter(new org.jastadd.ragconnect.compiler.AppendableWriter(sb)), this);
264
    return sb.toString();
René Schöne's avatar
René Schöne committed
265
266
  }
}
267
268

aspect RelationGeneration {
269
  syn java.util.List<Relation> RagConnect.additionalRelations() {
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
    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);
285
    result.addComment(new WhitespaceComment("\n"));
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
    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("/");
    }
  }
}