UNPKG

15.5 kBJavaScriptView Raw
1/*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15'use strict';
16
17var NS_PREFIX_TemplateMarkModel = require('./externalModels/TemplateMarkModel').NS_PREFIX_TemplateMarkModel;
18var _throwTemplateExceptionForElement = require('./errorutil')._throwTemplateExceptionForElement;
19
20/**
21 * @param {*} serializer - the serializer
22 * @param {object} decorated - the property
23 * @return {object} the array of decorators compliant with the Concerto metamodel (JSON)
24 */
25function processDecorators(serializer, decorated) {
26 var result = [];
27 var decorators = decorated.getDecorators();
28 decorators.forEach(decorator => {
29 var metaDecorator = {
30 '$class': 'concerto.metamodel.Decorator'
31 };
32
33 // The decorator's name
34 var name = decorator.getName();
35 metaDecorator.name = name;
36 metaDecorator.arguments = [];
37
38 // The decorator's arguments
39 var args = decorator.getArguments();
40 args.forEach(arg => {
41 var metaArgument;
42 if (typeof arg === 'string') {
43 metaArgument = {
44 '$class': 'concerto.metamodel.DecoratorString',
45 'value': arg
46 };
47 } else if (typeof arg === 'number') {
48 metaArgument = {
49 '$class': 'concerto.metamodel.DecoratorNumber',
50 'value': arg
51 };
52 } else if (typeof arg === 'boolean') {
53 metaArgument = {
54 '$class': 'concerto.metamodel.DecoratorBoolean',
55 'value': arg
56 };
57 } else {
58 metaArgument = {
59 '$class': 'concerto.metamodel.DecoratorTypeReference',
60 'type': {
61 '$class': 'concerto.metamodel.TypeIdentifier',
62 'name': arg.name
63 },
64 'isArray': arg.array
65 };
66 }
67 metaDecorator.arguments.push(metaArgument);
68 });
69
70 // Validate individual arguments here
71 //console.log('DECORATE ' + JSON.stringify(metaDecorator));
72 result.push(serializer.fromJSON(metaDecorator));
73 });
74 if (result.length === 0) {
75 return null;
76 } else {
77 return result;
78 }
79}
80
81/**
82 * Converts a CommonMark DOM to a CiceroMark DOM
83 */
84class TypeVisitor {
85 /**
86 * Visits a sub-tree and return CiceroMark DOM
87 * @param {*} visitor the visitor to use
88 * @param {*} thing the node to visit
89 * @param {*} [parameters] optional parameters
90 * @param {string} field where the children are
91 */
92 static visitChildren(visitor, thing, parameters) {
93 var field = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'nodes';
94 if (thing[field]) {
95 TypeVisitor.visitNodes(visitor, thing[field], parameters);
96 }
97 }
98
99 /**
100 * Visits a list of nodes and return the CiceroMark DOM
101 * @param {*} visitor the visitor to use
102 * @param {*} things the list node to visit
103 * @param {*} [parameters] optional parameters
104 */
105 static visitNodes(visitor, things, parameters) {
106 things.forEach(node => {
107 node.accept(visitor, parameters);
108 });
109 }
110
111 /**
112 * Visit a node
113 * @param {*} thing the object being visited
114 * @param {*} parameters the parameters
115 */
116 visit(thing, parameters) {
117 var currentModel = parameters.model;
118 switch (thing.getType()) {
119 case 'VariableDefinition':
120 case 'FormattedVariableDefinition':
121 {
122 if (!currentModel) {
123 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
124 }
125 if (thing.name === 'this') {
126 var property = currentModel;
127 if (property) {
128 var _property$isRelations;
129 var serializer = parameters.templateMarkModelManager.getSerializer();
130 thing.decorators = processDecorators(serializer, property);
131 if (property.isTypeEnum()) {
132 var enumVariableDeclaration = parameters.templateMarkModelManager.getType(NS_PREFIX_TemplateMarkModel + 'EnumVariableDefinition');
133 var enumType = property.getParent().getModelFile().getType(property.getType());
134 thing.elementType = property.getFullyQualifiedTypeName();
135 thing.$classDeclaration = enumVariableDeclaration;
136 thing.enumValues = enumType.getOwnProperties().map(x => x.getName());
137 } else if (property.isPrimitive()) {
138 thing.elementType = property.getFullyQualifiedTypeName();
139 } else if ((_property$isRelations = property.isRelationship) !== null && _property$isRelations !== void 0 && _property$isRelations.call(property)) {
140 var elementType = property.getFullyQualifiedTypeName();
141 thing.elementType = elementType;
142 var nestedTemplateModel = parameters.introspector.getClassDeclaration(elementType);
143 var identifier = nestedTemplateModel.getIdentifierFieldName();
144 thing.identifiedBy = identifier ? identifier : '$identifier'; // Consistent with Concerto 1.0 semantics
145 } else {
146 var _elementType = property.getFullyQualifiedTypeName();
147 thing.elementType = _elementType;
148 }
149 }
150 } else {
151 if (!currentModel.getProperty) {
152 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
153 }
154 var _property = currentModel.getProperty(thing.name);
155 if (_property) {
156 var _property$isRelations2;
157 var _serializer = parameters.templateMarkModelManager.getSerializer();
158 thing.decorators = processDecorators(_serializer, _property);
159 if (_property.isTypeEnum()) {
160 var _enumVariableDeclaration = parameters.templateMarkModelManager.getType(NS_PREFIX_TemplateMarkModel + 'EnumVariableDefinition');
161 var _enumType = _property.getParent().getModelFile().getType(_property.getType());
162 thing.elementType = _property.getFullyQualifiedTypeName();
163 thing.$classDeclaration = _enumVariableDeclaration;
164 thing.enumValues = _enumType.getOwnProperties().map(x => x.getName());
165 } else if (_property.isPrimitive()) {
166 thing.elementType = _property.getFullyQualifiedTypeName();
167 } else if ((_property$isRelations2 = _property.isRelationship) !== null && _property$isRelations2 !== void 0 && _property$isRelations2.call(_property)) {
168 var _elementType2 = _property.getFullyQualifiedTypeName();
169 thing.elementType = _elementType2;
170 var _nestedTemplateModel = parameters.introspector.getClassDeclaration(_elementType2);
171 var _identifier = _nestedTemplateModel.getIdentifierFieldName();
172 thing.identifiedBy = _identifier ? _identifier : '$identifier'; // Consistent with Concerto 1.0 semantics
173 } else {
174 var _elementType3 = _property.getFullyQualifiedTypeName();
175 thing.elementType = _elementType3;
176 }
177 } else {
178 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
179 }
180 }
181 }
182 break;
183 case 'ClauseDefinition':
184 {
185 if (parameters.kind === 'contract') {
186 if (!currentModel) {
187 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
188 }
189 var _property2 = currentModel.getOwnProperty(thing.name);
190 var nextModel;
191 if (!_property2) {
192 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
193 }
194 if (_property2.isPrimitive()) {
195 nextModel = _property2;
196 } else {
197 thing.elementType = _property2.getFullyQualifiedTypeName();
198 nextModel = parameters.introspector.getClassDeclaration(thing.elementType);
199 }
200 var _serializer2 = parameters.templateMarkModelManager.getSerializer();
201 thing.decorators = processDecorators(_serializer2, nextModel);
202 TypeVisitor.visitChildren(this, thing, {
203 templateMarkModelManager: parameters.templateMarkModelManager,
204 introspector: parameters.introspector,
205 model: nextModel,
206 kind: parameters.kind
207 });
208 } else {
209 if (!currentModel) {
210 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
211 }
212 var _serializer3 = parameters.templateMarkModelManager.getSerializer();
213 thing.decorators = processDecorators(_serializer3, currentModel);
214 thing.elementType = currentModel.getFullyQualifiedName();
215 TypeVisitor.visitChildren(this, thing, parameters);
216 }
217 }
218 break;
219 case 'WithDefinition':
220 {
221 var _property3 = currentModel.getOwnProperty(thing.name);
222 var _nextModel;
223 if (!_property3) {
224 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
225 }
226 if (_property3.isPrimitive()) {
227 _nextModel = _property3;
228 } else {
229 thing.elementType = _property3.getFullyQualifiedTypeName();
230 _nextModel = parameters.introspector.getClassDeclaration(thing.elementType);
231 }
232 var _serializer4 = parameters.templateMarkModelManager.getSerializer();
233 thing.decorators = processDecorators(_serializer4, _nextModel);
234 TypeVisitor.visitChildren(this, thing, {
235 templateMarkModelManager: parameters.templateMarkModelManager,
236 introspector: parameters.introspector,
237 model: _nextModel,
238 kind: parameters.kind
239 });
240 }
241 break;
242 case 'ListBlockDefinition':
243 {
244 var _property4 = currentModel.getOwnProperty(thing.name);
245 var _nextModel2;
246 if (!_property4) {
247 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
248 }
249 if (!_property4.isArray()) {
250 _throwTemplateExceptionForElement('List template not on an array property: ' + thing.name, thing);
251 }
252 var _serializer5 = parameters.templateMarkModelManager.getSerializer();
253 thing.decorators = processDecorators(_serializer5, _property4);
254 if (_property4.isPrimitive()) {
255 _nextModel2 = _property4;
256 } else {
257 thing.elementType = _property4.getFullyQualifiedTypeName();
258 _nextModel2 = parameters.introspector.getClassDeclaration(thing.elementType);
259 }
260 TypeVisitor.visitChildren(this, thing, {
261 templateMarkModelManager: parameters.templateMarkModelManager,
262 introspector: parameters.introspector,
263 model: _nextModel2,
264 kind: parameters.kind
265 });
266 }
267 break;
268 case 'JoinDefinition':
269 {
270 var _property5 = currentModel.getOwnProperty(thing.name);
271 var _nextModel3;
272 if (!_property5) {
273 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
274 }
275 if (!_property5.isArray()) {
276 _throwTemplateExceptionForElement('Join template not on an array property: ' + thing.name, thing);
277 }
278 var _serializer6 = parameters.templateMarkModelManager.getSerializer();
279 thing.decorators = processDecorators(_serializer6, _property5);
280 if (_property5.isPrimitive()) {
281 _nextModel3 = _property5;
282 } else {
283 thing.elementType = _property5.getFullyQualifiedTypeName();
284 _nextModel3 = parameters.introspector.getClassDeclaration(thing.elementType);
285 }
286 TypeVisitor.visitChildren(this, thing, {
287 templateMarkModelManager: parameters.templateMarkModelManager,
288 introspector: parameters.introspector,
289 model: _nextModel3,
290 kind: parameters.kind
291 });
292 }
293 break;
294 case 'ConditionalDefinition':
295 {
296 var _property6 = currentModel.getOwnProperty(thing.name);
297 var _nextModel4;
298 if (!_property6) {
299 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
300 }
301 if (_property6.getType() !== 'Boolean') {
302 _throwTemplateExceptionForElement('Conditional template not on a boolean property: ' + thing.name, thing);
303 }
304 var _serializer7 = parameters.templateMarkModelManager.getSerializer();
305 thing.decorators = processDecorators(_serializer7, _property6);
306 _nextModel4 = _property6;
307 TypeVisitor.visitChildren(this, thing, {
308 templateMarkModelManager: parameters.templateMarkModelManager,
309 introspector: parameters.introspector,
310 model: _nextModel4,
311 kind: parameters.kind
312 }, 'whenTrue');
313 TypeVisitor.visitChildren(this, thing, {
314 templateMarkModelManager: parameters.templateMarkModelManager,
315 introspector: parameters.introspector,
316 model: null,
317 kind: parameters.kind
318 }, 'whenFalse');
319 }
320 break;
321 case 'OptionalDefinition':
322 {
323 var _property7 = currentModel.getOwnProperty(thing.name);
324 var _nextModel5;
325 if (!_property7) {
326 _throwTemplateExceptionForElement('Unknown property: ' + thing.name, thing);
327 }
328 if (!_property7.isOptional()) {
329 _throwTemplateExceptionForElement('Optional template not on an optional property: ' + thing.name, thing);
330 }
331 var _serializer8 = parameters.templateMarkModelManager.getSerializer();
332 thing.decorators = processDecorators(_serializer8, _property7);
333 if (_property7.isPrimitive()) {
334 thing.elementType = _property7.getFullyQualifiedTypeName();
335 _nextModel5 = _property7;
336 } else {
337 thing.elementType = _property7.getFullyQualifiedTypeName();
338 _nextModel5 = parameters.introspector.getClassDeclaration(thing.elementType);
339 }
340 TypeVisitor.visitChildren(this, thing, {
341 templateMarkModelManager: parameters.templateMarkModelManager,
342 introspector: parameters.introspector,
343 model: _nextModel5,
344 kind: parameters.kind
345 }, 'whenSome');
346 TypeVisitor.visitChildren(this, thing, {
347 templateMarkModelManager: parameters.templateMarkModelManager,
348 introspector: parameters.introspector,
349 model: null,
350 kind: parameters.kind
351 }, 'whenNone');
352 }
353 break;
354 case 'ContractDefinition':
355 {
356 thing.elementType = currentModel.getFullyQualifiedName();
357 TypeVisitor.visitChildren(this, thing, parameters);
358 }
359 break;
360 default:
361 TypeVisitor.visitChildren(this, thing, parameters);
362 }
363 }
364}
365module.exports = TypeVisitor;
\No newline at end of file