@darabonba/python-generator 1.2.19 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/ChangeLog.md +0 -158
  2. package/lib/builtin.js +818 -0
  3. package/lib/generator.js +2708 -0
  4. package/lib/helper.js +422 -0
  5. package/package.json +6 -5
  6. package/tests/expected/alias/setup.py +79 -0
  7. package/tests/expected/alias/tea_python_tests/__init__.py +1 -0
  8. package/tests/expected/alias/tea_python_tests/client.py +35 -0
  9. package/tests/expected/annotation/tea_python_tests/__init__.py +1 -0
  10. package/tests/expected/annotation/tea_python_tests/client.py +93 -0
  11. package/tests/expected/annotation/tea_python_tests/models.py +37 -0
  12. package/tests/expected/api/tea_python_tests/__init__.py +1 -0
  13. package/tests/expected/api/tea_python_tests/client.py +106 -0
  14. package/tests/expected/builtin/tea_python_tests/client.py +685 -0
  15. package/tests/expected/comment/tea_python_tests/__init__.py +1 -0
  16. package/tests/expected/comment/tea_python_tests/client.py +288 -0
  17. package/tests/expected/comment/tea_python_tests/models.py +195 -0
  18. package/tests/expected/complex/tea_python_tests/__init__.py +1 -0
  19. package/tests/expected/complex/tea_python_tests/client.py +1169 -0
  20. package/tests/expected/complex/tea_python_tests/exceptions.py +39 -0
  21. package/tests/expected/complex/tea_python_tests/models.py +570 -0
  22. package/tests/expected/const/tea_python_tests/__init__.py +1 -0
  23. package/tests/expected/const/tea_python_tests/client.py +14 -0
  24. package/{src/langs/python/files/setup.py.tmpl → tests/expected/empty/setup.py} +11 -11
  25. package/tests/expected/empty/tea_python_tests/__init__.py +1 -0
  26. package/tests/expected/empty/tea_python_tests/client.py +10 -0
  27. package/tests/expected/exec/tea_python_tests/__init__.py +1 -0
  28. package/tests/expected/exec/tea_python_tests/exec_client.py +21 -0
  29. package/tests/expected/function/tea_python_tests/__init__.py +1 -0
  30. package/tests/expected/function/tea_python_tests/client.py +64 -0
  31. package/tests/expected/import/setup.py +78 -0
  32. package/tests/expected/import/tea_python_tests/__init__.py +1 -0
  33. package/tests/expected/import/tea_python_tests/client.py +29 -0
  34. package/tests/expected/map/tea_python_tests/__init__.py +1 -0
  35. package/tests/expected/map/tea_python_tests/client.py +39 -0
  36. package/tests/expected/model/tea_python_tests/__init__.py +1 -0
  37. package/tests/expected/model/tea_python_tests/client.py +10 -0
  38. package/tests/expected/model/tea_python_tests/exceptions.py +28 -0
  39. package/tests/expected/model/tea_python_tests/models.py +780 -0
  40. package/tests/expected/multi/tea_python_tests/api.py +95 -0
  41. package/tests/expected/multi/tea_python_tests/client.py +40 -0
  42. package/tests/expected/multi/tea_python_tests/lib/util.py +19 -0
  43. package/tests/expected/multi/tea_python_tests/model/user.py +26 -0
  44. package/tests/expected/multi/tea_python_tests/model/user_exceptions.py +83 -0
  45. package/tests/expected/multi/tea_python_tests/model/user_models.py +145 -0
  46. package/tests/expected/statements/tea_python_tests/__init__.py +1 -0
  47. package/tests/expected/statements/tea_python_tests/client.py +86 -0
  48. package/tests/expected/super/tea_python_tests/__init__.py +1 -0
  49. package/tests/expected/super/tea_python_tests/client.py +16 -0
  50. package/tests/expected/typedef/setup.py +77 -0
  51. package/tests/expected/typedef/tea_python_tests/__init__.py +1 -0
  52. package/tests/expected/typedef/tea_python_tests/client.py +74 -0
  53. package/tests/expected/typedef/tea_python_tests/models.py +42 -0
  54. package/tests/fixtures/alias/Darafile +11 -0
  55. package/tests/fixtures/alias/libraries/Alias/Darafile +11 -0
  56. package/tests/fixtures/alias/libraries/Alias-Symbol/Darafile +11 -0
  57. package/tests/fixtures/builtin/Darafile +6 -0
  58. package/tests/fixtures/builtin/main.dara +333 -0
  59. package/tests/fixtures/complex/libraries/import.dara +18 -11
  60. package/tests/fixtures/complex/main.dara +452 -103
  61. package/tests/fixtures/import/libraries/Darafile +1 -1
  62. package/tests/fixtures/import/pack/Darafile +3 -0
  63. package/tests/fixtures/map/libraries/Darafile +3 -0
  64. package/tests/fixtures/map/libraries/import.dara +4 -0
  65. package/tests/fixtures/map/main.dara +17 -2
  66. package/tests/fixtures/model/.libraries.json +3 -0
  67. package/tests/fixtures/model/Darafile +5 -2
  68. package/tests/fixtures/model/libraries/Darafile +20 -0
  69. package/tests/fixtures/model/libraries/import.dara +27 -0
  70. package/tests/fixtures/model/main.dara +60 -42
  71. package/tests/fixtures/multi/.libraries.json +3 -0
  72. package/tests/fixtures/multi/Darafile +12 -0
  73. package/tests/fixtures/multi/api.dara +20 -0
  74. package/tests/fixtures/multi/lib/util.dara +5 -0
  75. package/tests/fixtures/multi/libraries/darabonba_Util_0.2.11/Teafile +68 -0
  76. package/tests/fixtures/multi/libraries/darabonba_Util_0.2.11/main.tea +244 -0
  77. package/tests/fixtures/multi/libraries/darabonba_Util_0.2.11/util.tea +2 -0
  78. package/tests/fixtures/multi/main.dara +32 -0
  79. package/tests/fixtures/multi/model/user.dara +35 -0
  80. package/tests/{python3.tests.js → main.tests.js} +107 -65
  81. package/tests/output/alias/setup.py +79 -0
  82. package/tests/output/alias/tea_python_tests/client.py +35 -0
  83. package/{src/langs/python2/files/setup.py.tmpl → tests/output/annotation/setup.py} +19 -24
  84. package/tests/output/annotation/tea_python_tests/client.py +93 -0
  85. package/tests/output/annotation/tea_python_tests/models.py +37 -0
  86. package/tests/output/api/setup.py +77 -0
  87. package/tests/output/api/tea_python_tests/client.py +106 -0
  88. package/tests/output/builtin/setup.py +77 -0
  89. package/tests/output/builtin/tea_python_tests/client.py +685 -0
  90. package/tests/output/comment/setup.py +77 -0
  91. package/tests/output/comment/tea_python_tests/client.py +288 -0
  92. package/tests/output/comment/tea_python_tests/models.py +195 -0
  93. package/tests/output/complex/setup.py +77 -0
  94. package/tests/output/complex/tea_python_tests/client.py +1169 -0
  95. package/tests/output/complex/tea_python_tests/exceptions.py +39 -0
  96. package/tests/output/complex/tea_python_tests/models.py +570 -0
  97. package/tests/output/const/setup.py +77 -0
  98. package/tests/output/const/tea_python_tests/client.py +14 -0
  99. package/tests/output/empty/setup.py +77 -0
  100. package/tests/output/empty/tea_python_tests/client.py +10 -0
  101. package/tests/output/exec/setup.py +77 -0
  102. package/tests/output/exec/tea_python_tests/exec_client.py +21 -0
  103. package/tests/output/function/setup.py +77 -0
  104. package/tests/output/function/tea_python_tests/client.py +64 -0
  105. package/tests/output/import/setup.py +78 -0
  106. package/tests/output/import/tea_python_tests/client.py +29 -0
  107. package/tests/output/map/setup.py +77 -0
  108. package/tests/output/map/tea_python_tests/client.py +39 -0
  109. package/tests/output/model/setup.py +77 -0
  110. package/tests/output/model/tea_python_tests/client.py +10 -0
  111. package/tests/output/model/tea_python_tests/exceptions.py +28 -0
  112. package/tests/output/model/tea_python_tests/models.py +780 -0
  113. package/tests/output/multi/setup.py +77 -0
  114. package/tests/output/multi/tea_python_tests/api.py +95 -0
  115. package/tests/output/multi/tea_python_tests/client.py +40 -0
  116. package/tests/output/multi/tea_python_tests/lib/util.py +19 -0
  117. package/tests/output/multi/tea_python_tests/model/user.py +26 -0
  118. package/tests/output/multi/tea_python_tests/model/user_exceptions.py +83 -0
  119. package/tests/output/multi/tea_python_tests/model/user_models.py +145 -0
  120. package/tests/output/statements/setup.py +77 -0
  121. package/tests/output/statements/tea_python_tests/client.py +86 -0
  122. package/tests/output/super/setup.py +77 -0
  123. package/tests/output/super/tea_python_tests/client.py +16 -0
  124. package/tests/output/typedef/setup.py +78 -0
  125. package/tests/output/typedef/tea_python_tests/client.py +74 -0
  126. package/tests/output/typedef/tea_python_tests/models.py +42 -0
  127. package/src/generator.js +0 -231
  128. package/src/langs/common/combinator.js +0 -193
  129. package/src/langs/common/config.js +0 -60
  130. package/src/langs/common/enum.js +0 -179
  131. package/src/langs/common/items.js +0 -551
  132. package/src/langs/common/package_info.js +0 -53
  133. package/src/langs/python/combinator.js +0 -1898
  134. package/src/langs/python/config.js +0 -169
  135. package/src/langs/python/files/.gitignore.tmpl +0 -5
  136. package/src/langs/python/files/__init__.py.tmpl +0 -1
  137. package/src/langs/python/package_info.js +0 -78
  138. package/src/langs/python2/combinator.js +0 -1770
  139. package/src/langs/python2/config.js +0 -162
  140. package/src/langs/python2/files/.gitignore.tmpl +0 -5
  141. package/src/langs/python2/files/__init__.py.tmpl +0 -1
  142. package/src/langs/python2/package_info.js +0 -78
  143. package/src/lib/debug.js +0 -55
  144. package/src/lib/emitter.js +0 -95
  145. package/src/lib/helper.js +0 -207
  146. package/src/resolver/base.js +0 -282
  147. package/src/resolver/client.js +0 -1013
  148. package/src/resolver/model.js +0 -159
  149. package/tests/common.tests.js +0 -244
  150. package/tests/lib.tests.js +0 -269
  151. package/tests/python2.tests.js +0 -283
  152. package/tests/resolver.tests.js +0 -434
@@ -1,1898 +0,0 @@
1
- 'use strict';
2
-
3
- const assert = require('assert');
4
- const debug = require('../../lib/debug');
5
- const CombinatorBase = require('../common/combinator');
6
- const Emitter = require('../../lib/emitter');
7
- const PackageInfo = require('./package_info');
8
-
9
- const {
10
- Symbol,
11
- } = require('../common/enum');
12
-
13
- const {
14
- AnnotationItem,
15
- ConstructItem,
16
- FuncItem,
17
- PropItem,
18
-
19
- GrammerVar,
20
- GrammerCall,
21
- GrammerCatch,
22
- GrammerValue,
23
- BehaviorToMap,
24
- } = require('../common/items');
25
-
26
- const {
27
- _isBasicType,
28
- _upperFirst,
29
- _config,
30
- _convertStaticParam,
31
- _toSnakeCase,
32
- _toCamelCase,
33
- _avoidKeywords,
34
- _avoidFuncKeywords,
35
- _avoidClassKeywords,
36
- _avoidVarKeywords,
37
- _exception,
38
- _symbol,
39
- _deepClone,
40
- _isSnakeCase
41
- } = require('../../lib/helper');
42
-
43
- function _contain(str, substr) {
44
- return str.indexOf(substr) > -1;
45
- }
46
-
47
- function _name(name) {
48
- return _avoidKeywords(_toSnakeCase(name));
49
- }
50
-
51
- function _varName(name){
52
- return _avoidVarKeywords(_toSnakeCase(name));
53
- }
54
-
55
- function _funcName(name){
56
- return _avoidFuncKeywords(_toSnakeCase(name));
57
- }
58
-
59
- function _type(type) {
60
- const config = _config();
61
- let t = type instanceof Object ? type.lexeme : type;
62
- if (t) {
63
- if (config.typeMap[t]) {
64
- return config.typeMap[t];
65
- }
66
- if (t.indexOf('map[') === 0) {
67
- return 'dict';
68
- }
69
- if (!_isBasicType(t)) {
70
- return t;
71
- }
72
- if (t[0] === '$') {
73
- t = t.replace('$', 'Tea');
74
- }
75
- }
76
- return t;
77
- }
78
-
79
- class Combinator extends CombinatorBase {
80
- constructor(config, imports) {
81
- super(config, imports);
82
- this.eol = '';
83
- this.aioMode = false;
84
- this.clientMap = {};
85
- if (this.config.modelDirName) {
86
- this.config.model.dir = this.config.modelDirName;
87
- }
88
-
89
- // Darafile: name (Tea Package name)
90
- if (!_isSnakeCase(this.config.package)) {
91
- debug.stack('python package name is must be snake case, Example: alibabacloud_tea.');
92
- }
93
- }
94
-
95
- addInclude(className, fromPackage) {
96
- let importName = '';
97
- let fromName = '';
98
- let needAlias = false;
99
- let alias = '';
100
-
101
- if (className.indexOf('$') > -1) {
102
- let coreClassName = this.coreClass(className);
103
- let coreNamespl = coreClassName.split('.');
104
- importName = coreNamespl[coreNamespl.length - 1];
105
- coreNamespl.splice(coreNamespl.length - 1, 1);
106
- fromName = coreNamespl.join('.');
107
- }
108
-
109
- if (this.thirdPackageNamespace[className]) {
110
- // is third package
111
- importName = _toCamelCase(this.thirdPackageClient[className]);
112
- fromName = this.thirdPackageNamespace[className] + '.' + this.thirdPackageClient[className];
113
-
114
- if (importName === _toCamelCase(this.config.client.defaultName)) {
115
- needAlias = true;
116
- }
117
-
118
- this.includeList.forEach(item => {
119
- if (item.alias) {
120
- if (item.alias === importName) {
121
- needAlias = true;
122
- }
123
- } else {
124
- if (item.import === importName && item.from !== fromName) {
125
- needAlias = true;
126
- }
127
- }
128
- });
129
-
130
- if (needAlias === true) {
131
- className = className.replace(/[^a-zA-Z0-9_]/, '');
132
- // import classname as classname
133
- if (/^[A-Z]+$/.test(importName[0])) {
134
- alias = className + importName;
135
- } else {
136
- alias = _toSnakeCase(className) + '_' + importName;
137
- }
138
- }
139
- }
140
-
141
- if (fromPackage) {
142
- fromName = fromPackage;
143
- }
144
-
145
- let existResult = this.includeList.some(item => item.import === importName && item.from === fromName);
146
-
147
- if (!existResult) {
148
- this.includeList.push({
149
- 'from': fromName,
150
- 'import': importName,
151
- 'alias': alias,
152
- });
153
- }
154
-
155
- let packageName = '';
156
- if (alias) {
157
- packageName = alias;
158
- } else {
159
- packageName = importName;
160
- }
161
-
162
- this.clientMap[packageName] = this.thirdPackageClient[className];
163
- return packageName;
164
- }
165
-
166
- addModelInclude(modelName) {
167
- let accessPath = modelName.split('.');
168
- let importName = '';
169
- let fromName = '';
170
- let resultName = '';
171
- let alias = '';
172
-
173
- if (modelName.indexOf('$') > -1) {
174
- let coreModelName = this.coreClass(modelName);
175
- let coreNamespl = coreModelName.split('.');
176
- importName = coreNamespl[coreNamespl.length - 1];
177
- coreNamespl.splice(coreNamespl.length - 1, 1);
178
- fromName = coreNamespl.join('.');
179
- resultName = fromName.split('.').join('_') + '_' + importName + '.' + modelName.split('.').join('');
180
- } else if (accessPath.length > 1 && this.thirdPackageNamespace[accessPath[0]]) {
181
- // is third package
182
- importName = 'models';
183
- fromName = this.thirdPackageNamespace[accessPath[0]];
184
- const className = accessPath[0].replace(/[^a-zA-Z0-9_]/, '');
185
- alias = _toSnakeCase(className) + '_models';
186
- resultName = alias + '.' + accessPath.slice(1).map(item => _upperFirst(item)).join('');
187
- } else {
188
- // self model
189
- fromName = this.config.package;
190
- importName = 'models';
191
- if (this.config.emitType === 'model') {
192
- resultName = modelName.split('.').map(m => _upperFirst(m)).join('');
193
- return resultName;
194
- }
195
- alias = _toSnakeCase(this.config.name) + '_' + importName;
196
- resultName = alias + '.' + modelName.split('.').map(m => _upperFirst(m)).join('');
197
- }
198
-
199
- let existResult = this.includeList.some(item => {
200
- if (item.import === importName && item.from === fromName) {
201
- return true;
202
- }
203
- });
204
-
205
- if (!existResult) {
206
- this.includeList.push({
207
- 'from': fromName,
208
- 'import': importName,
209
- 'alias': alias,
210
- });
211
- }
212
- return resultName;
213
- }
214
-
215
- addTypedefInclude(typeName) {
216
- let accessPath = typeName.split('.');
217
- let importName = '';
218
- let fromName = '';
219
- let typedefModule = {};
220
- if (accessPath.length === 2) {
221
- if (this.importsTypedef[accessPath[0]] && this.importsTypedef[accessPath[0]][accessPath[1]]) {
222
- typedefModule = this.importsTypedef[accessPath[0]][accessPath[1]];
223
- }
224
- } else if (accessPath.length === 1 && this.typedef[accessPath[0]]) {
225
- typedefModule = this.typedef[accessPath[0]];
226
- }
227
- if (typedefModule.import || typedefModule.package) {
228
- if (typedefModule.import) {
229
- fromName = typedefModule.import;
230
- }
231
- if (typedefModule.type) {
232
- importName = typedefModule.type;
233
- }
234
- }
235
-
236
- let existResult = this.includeList.some(item => item.import === importName && item.from === fromName);
237
- if (!existResult) {
238
- this.includeList.push({
239
- 'from': fromName,
240
- 'import': importName,
241
- 'alias': '',
242
- });
243
- }
244
- return typedefModule.type || typeName;
245
- }
246
-
247
- simpleImport(imp, from = null) {
248
- let existResult = this.includeList.some(item => {
249
- if (item.import === imp && item.from === from) {
250
- return true;
251
- }
252
- });
253
- if (!existResult) {
254
- this.includeList.push({
255
- from: from,
256
- import: imp
257
- });
258
- }
259
- }
260
-
261
- combine(objectArr = []) {
262
- super.combine(objectArr);
263
- this.config.dir = this.config.outputDir + '/' + this.config.package + '/';
264
- const [clientObjectItem] = objectArr.filter(obj => obj.type === 'client');
265
- this.combineClient(clientObjectItem);
266
- this.includeList = [];
267
- const models = objectArr.filter(obj => obj.type === 'model');
268
- if (models.length > 0) {
269
- this.combineModel(models);
270
- }
271
- }
272
-
273
- checkSyntax(content, emitter) {
274
- const includeList = this.includeList;
275
- includeList.forEach(i => {
276
- let importName = i.import;
277
- if (i.alias) {
278
- importName = i.alias;
279
- }
280
-
281
- const re = new RegExp(importName);
282
- const ignoreModule = ['sys'];
283
- if (!re.test(content) && ignoreModule.indexOf(importName) === -1) {
284
- this.includeList.splice(this.includeList.indexOf(i), 1);
285
- }
286
- });
287
-
288
- let contentLine = content.split(emitter.eol);
289
- contentLine.forEach((l, index) => {
290
- const symbol = ['+', '-', '=', '*', '/', '%'];
291
- l = l.replace(/(\s*$)/g, '');
292
- if (symbol.indexOf(l[l.length - 1]) > -1) {
293
- contentLine[index] = `${l}\\`;
294
- }
295
- });
296
- return contentLine.join(emitter.eol);
297
- }
298
-
299
- combineClient(object) {
300
- this.config.emitType = 'client';
301
- this.includeList = object.includeList;
302
- if (this.config.packageInfo) {
303
- const packageInfo = new PackageInfo(this.config);
304
- packageInfo.emit(this.config.packageInfo, this.requirePackage);
305
- }
306
- let emitter, outputParts = {
307
- head: '',
308
- body: '',
309
- foot: ''
310
- };
311
- // generate __init__.py
312
- emitter = new Emitter(this.config);
313
- emitter.config.filename = '__init__';
314
- emitter.emitln('__version__ = "1.0.0"');
315
- emitter.save();
316
- /******************************** emit foot ********************************/
317
- if (this.config.exec) {
318
- emitter = new Emitter(this.config);
319
- this.emitExec(emitter);
320
- outputParts.foot = emitter.output;
321
- }
322
- /******************************** emit body ********************************/
323
- emitter = new Emitter(this.config);
324
- this.emitClass(emitter, object);
325
-
326
- outputParts.body = this.checkSyntax(emitter.output, emitter);
327
- /******************************** emit head *******************************/
328
- emitter = new Emitter(this.config);
329
- emitter.emitln('# -*- coding: utf-8 -*-');
330
- if (object.topAnnotation.length > 0) {
331
- this.emitAnnotations(emitter, object.topAnnotation);
332
- }
333
- this.emitInclude(emitter);
334
- outputParts.head = emitter.output;
335
-
336
- /***************************** combine output ******************************/
337
- const config = _deepClone(this.config);
338
- if (_isSnakeCase(this.config.clientName)) {
339
- config.filename = this.config.clientName;
340
- } else {
341
- debug.stack('python clientName is must be snake case, Example: rpc_client.');
342
- }
343
-
344
- this.combineOutputParts(config, outputParts);
345
- }
346
-
347
- combineModel(models) {
348
- this.config.emitType = 'model';
349
- let emitter, outputParts = {
350
- head: '',
351
- body: '',
352
- foot: ''
353
- };
354
- let includeSet = [];
355
- // merge includeList
356
- models.forEach(object => {
357
- object.includeList.forEach(include => {
358
- let key = `${include.import}:${include.from}`;
359
- if (includeSet.indexOf(key) === -1) {
360
- this.includeList.push(include);
361
- includeSet.push(key);
362
- }
363
- });
364
-
365
- object.subObject.forEach(subObject => {
366
- subObject.includeList.forEach(include => {
367
- let key = `${include.import}:${include.from}`;
368
- if (includeSet.indexOf(key) === -1) {
369
- this.includeList.push(include);
370
- includeSet.push(key);
371
- }
372
- });
373
- });
374
- });
375
- /******************************** emit body ********************************/
376
- emitter = new Emitter(this.config);
377
- this.definedModels = [];
378
- this.models = models;
379
- models.forEach(model => this.emitModel(emitter, model));
380
- outputParts.body = this.checkSyntax(emitter.output, emitter);
381
-
382
- /******************************** emit head ********************************/
383
- emitter = new Emitter(this.config);
384
- emitter.emitln('# -*- coding: utf-8 -*-');
385
- for (let i = 0; i < models.length; i++) {
386
- if (models[0].topAnnotation) {
387
- this.emitAnnotations(emitter, models[0].topAnnotation);
388
- break;
389
- }
390
- }
391
- this.emitInclude(emitter);
392
- outputParts.head = emitter.output;
393
-
394
- /***************************** combine output ******************************/
395
- const config = _deepClone(this.config);
396
- config.layer = '';
397
- config.filename = 'models';
398
- this.combineOutputParts(config, outputParts);
399
- }
400
-
401
- emitModel(emitter, model) {
402
- const model_name = model.name;
403
- if (_contain(this.definedModels, model.name)) {
404
- return;
405
- }
406
- this.definedModels.push(model_name);
407
- if (model.subObject.length) {
408
- model.subObject.forEach(obj => {
409
- this.emitModel(emitter, obj);
410
- });
411
- }
412
- model.body.filter(node => node instanceof PropItem && !this.hasModel(node.type, model.name)).forEach(item => {
413
- this.findUndefinedModel(emitter, item.type);
414
- });
415
- this.emitClass(emitter, model);
416
- emitter.emitln().emitln();
417
- }
418
-
419
- findUndefinedModel(emitter, type) {
420
- const models = this.models;
421
- if (type.objectType === 'array') {
422
- this.findUndefinedModel(emitter, type.itemType);
423
- } else if (type.objectType === 'map') {
424
- this.findUndefinedModel(emitter, type.valType);
425
- } else if (type.objectType === 'model' || !this.config.typeMap[type] && !this.thirdPackageNamespace[type]) {
426
- let objectName = type.lexeme;
427
- if (!_contain(this.definedModels, objectName)) {
428
- const [obj] = models.filter(node => node.name === objectName);
429
- if (obj) {
430
- obj.body.filter(node => node instanceof PropItem && !this.hasModel(node.type, obj.name)).forEach(item => {
431
- this.findUndefinedModel(emitter, item.type);
432
- });
433
- this.emitModel(emitter, obj);
434
- }
435
- }
436
- }
437
- }
438
-
439
- hasModel(obj, target) {
440
- if (obj.objectType === 'array') {
441
- return this.hasModel(obj.itemType, target);
442
- } else if (obj.objectType === 'map') {
443
- return this.hasModel(obj.valType, target);
444
- } else if (obj.objectType === 'model' || !this.config.typeMap[obj] && !this.thirdPackageNamespace[obj]) {
445
- if (_type(obj) === target) {
446
- return true;
447
- }
448
- }
449
- return false;
450
- }
451
-
452
- getClassName(name) {
453
- let className = name;
454
- if (this.config.emitType === 'client') {
455
- className = this.config.clientName;
456
- } else {
457
- className = name.split('.').map(item => _upperFirst(item)).join('');
458
- }
459
- return _toCamelCase(_avoidClassKeywords(className));
460
- }
461
-
462
- emitClass(emitter, object) {
463
- var parent = '';
464
- let className = this.getClassName(object.name);
465
- this.className = className;
466
-
467
- let tmp = [];
468
- if (!(object.extends instanceof Array)) {
469
- object.extends = [object.extends];
470
- }
471
-
472
- object.extends.forEach(baseClass => {
473
- tmp.push(baseClass);
474
- });
475
- if (tmp.length > 0) {
476
- parent = '(' + tmp.join(', ') + ')';
477
- }
478
-
479
- emitter.emitln(`class ${className}${parent}:`, this.level);
480
-
481
- this.levelUp();
482
- if (object.annotations.length > 0) {
483
- this.emitAnnotations(emitter, object.annotations);
484
- }
485
- const notes = this.resolveNotes(object.body);
486
- if (Object.keys(notes).length > 0) {
487
- this.emitNotes(emitter, notes);
488
- }
489
- let props = object.body.filter(node => node instanceof PropItem);
490
- let propItems = object.body.filter(node => node instanceof PropItem || node instanceof AnnotationItem);
491
-
492
- if (object.body.filter(node => node instanceof ConstructItem).length === 0) {
493
- object.body.unshift(new ConstructItem());
494
- }
495
-
496
- // emit body nodes : PropItem | FuncItem | ConstructItem | AnnotationItem
497
- object.body.forEach(node => {
498
- if (node instanceof FuncItem) {
499
- this.emitFunc(emitter, node);
500
- } else if (node instanceof ConstructItem) {
501
- if (this.config.emitType === 'model') {
502
- this.emitConstruct(emitter, node, propItems, false);
503
- } else if (this.config.emitType === 'client') {
504
- if (propItems.length > 0) {
505
- // emit @type
506
- propItems.forEach(p => {
507
- if (p instanceof AnnotationItem) {
508
- this.emitAnnotation(emitter, p);
509
- } else if (p instanceof PropItem) {
510
- const type = this.getTypeHints(p.type);
511
- if (type) {
512
- emitter.emitln(`${_varName(p.name)}: ${type} = None`, this.level);
513
- }
514
- }
515
- });
516
- emitter.emitln();
517
- }
518
- this.emitConstruct(emitter, node, [], true);
519
- }
520
- }
521
- });
522
-
523
- if (this.config.emitType === 'model') {
524
- this.emitValidate(emitter, props, notes);
525
- this.emitToMap(emitter, props, notes);
526
- this.emitFromMap(emitter, object.name, props, notes);
527
- }
528
- this.levelDown();
529
- this.className = null;
530
- }
531
-
532
- emitComplexValidate(emitter, name, fieldType, depth) {
533
- if (fieldType.objectType) {
534
- if (fieldType.objectType === 'array') {
535
- if (depth > 0) {
536
- emitter.emitln(`for k${depth} in ${name}:`, this.level);
537
- this.levelUp();
538
- this.emitComplexValidate(emitter, `k${depth}`, fieldType.itemType, depth + 1);
539
- this.levelDown();
540
- } else {
541
- emitter.emitln(`if self.${_varName(name)}:`, this.level);
542
- this.levelUp();
543
- emitter.emitln(`for k in self.${_varName(name)}:`, this.level);
544
- this.levelUp();
545
- this.emitComplexValidate(emitter, 'k', fieldType.itemType, depth + 1);
546
- this.levelDown();
547
- this.levelDown();
548
- }
549
- } else if (fieldType.objectType === 'map') {
550
- if (depth > 0) {
551
- emitter.emitln(`for v${depth} in ${name}.values():`, this.level);
552
- this.levelUp();
553
- this.emitComplexValidate(emitter, `v${depth}`, fieldType.valType, depth + 1);
554
- this.levelDown();
555
- } else {
556
- emitter.emitln(`if self.${_varName(name)}:`, this.level);
557
- this.levelUp();
558
- emitter.emitln(`for v in self.${_varName(name)}.values():`, this.level);
559
- this.levelUp();
560
- this.emitComplexValidate(emitter, 'v', fieldType.valType, depth + 1);
561
- this.levelDown();
562
- this.levelDown();
563
- }
564
- } else if (fieldType.objectType === 'model') {
565
- emitter.emitln(`if ${name}:`, this.level);
566
- this.levelUp();
567
- emitter.emitln(`${name}.validate()`, this.level);
568
- this.levelDown();
569
- emitter.needSave = true;
570
- }
571
- }
572
- }
573
-
574
- emitValidate(emitter, props, notes) {
575
- //print validate
576
- emitter.emitln('');
577
- emitter.emitln('def validate(self):', this.level);
578
- this.levelUp();
579
- let haveValidate = false;
580
- props.forEach(prop => {
581
-
582
- let required = prop.notes.filter(item => item.key === 'required');
583
- let maxLength = prop.notes.filter(item => item.key === 'maxLength');
584
- let pattern = prop.notes.filter(item => item.key === 'pattern');
585
- let maximum = prop.notes.filter(item => item.key === 'maximum');
586
- let minimum = prop.notes.filter(item => item.key === 'minimum');
587
-
588
- if (required.length > 0) {
589
- emitter.emitln(
590
- `self.validate_required(self.${_varName(prop.name)}, '${_varName(prop.name)}')`,
591
- this.level
592
- );
593
- haveValidate = true;
594
- }
595
- if (maxLength.length > 0 || pattern.length > 0 || maximum.length > 0 || minimum.length > 0) {
596
- emitter.emitln(`if self.${_varName(prop.name)} is not None:`, this.level);
597
- this.levelUp();
598
-
599
- if (maxLength.length > 0) {
600
- emitter.emitln(`self.validate_max_length(self.${_varName(prop.name)}, '${_varName(prop.name)}', ${maxLength[0].value})`, this.level);
601
- }
602
-
603
- if (pattern.length > 0) {
604
- emitter.emitln(`self.validate_pattern(self.${_varName(prop.name)}, '${_varName(prop.name)}', '${pattern[0].value}')`, this.level);
605
- }
606
-
607
- if (maximum.length > 0) {
608
- emitter.emitln(`self.validate_maximum(self.${_varName(prop.name)}, '${_varName(prop.name)}', ${maximum[0].value})`, this.level);
609
- }
610
-
611
- if (minimum.length > 0) {
612
- emitter.emitln(`self.validate_minimum(self.${_varName(prop.name)}, '${_varName(prop.name)}', ${minimum[0].value})`, this.level);
613
- }
614
- this.levelDown();
615
- haveValidate = true;
616
- }
617
-
618
-
619
- if (prop.type.objectType === 'array' || prop.type.objectType === 'map') {
620
- let emt = new Emitter(emitter.config);
621
- this.emitComplexValidate(emt, prop.name, prop.type, 0);
622
- if (emt.needSave === true) {
623
- haveValidate = true;
624
- emitter.emit(emt.output);
625
- }
626
- } else if (prop.type.objectType === 'model') {
627
- emitter.emitln(`if self.${_varName(prop.name)}:`, this.level);
628
- this.levelUp();
629
- emitter.emitln(`self.${_varName(prop.name)}.validate()`, this.level);
630
- this.levelDown();
631
- haveValidate = true;
632
- }
633
- });
634
-
635
- if (props.length === 0 || !haveValidate) {
636
- emitter.emitln('pass', this.level);
637
- }
638
- this.levelDown();
639
- emitter.emitln();
640
- }
641
-
642
- emitComplexToMap(emitter, prop, carrier, depth) {
643
- const name = prop.name;
644
- const fieldName = prop.fieldName;
645
- const type = prop.type;
646
- const parentType = prop.parentType;
647
-
648
- if (type.objectType === 'array') {
649
- if (depth > 0) {
650
- emitter.emitln(`l${depth} = []`, this.level);
651
- emitter.emitln(`for k${depth} in ${name}:`, this.level);
652
- this.levelUp();
653
- const propInfo = {
654
- name: `k${depth}`,
655
- fieldName: fieldName,
656
- type: type.itemType,
657
- parentType: type.lexeme
658
- };
659
- this.emitComplexToMap(emitter, propInfo, `l${depth}`, depth + 1);
660
- this.levelDown();
661
- if (parentType === 'array') {
662
- emitter.emitln(`${carrier}.append(l${depth})`, this.level);
663
- } else if (parentType === 'map') {
664
- const num = depth - 1 > 0 ? depth - 1 : '';
665
- emitter.emitln(`${carrier}[k${num}] = l${depth}`, this.level);
666
- }
667
- } else {
668
- emitter.emitln(`result['${fieldName}'] = []`, this.level);
669
- emitter.emitln(`if self.${_varName(name)} is not None:`, this.level);
670
- this.levelUp();
671
- emitter.emitln(`for k in self.${_varName(name)}:`, this.level);
672
- this.levelUp();
673
- if (type.itemType.valType || type.itemType.itemType) {
674
- const propInfo = {
675
- name: 'k',
676
- fieldName: fieldName,
677
- type: type.itemType,
678
- parentType: type.lexeme
679
- };
680
- this.emitComplexToMap(emitter, propInfo, `result['${fieldName}']`, depth + 1);
681
- } else {
682
- if (type.itemType.objectType === 'model') {
683
- emitter.emitln(`result['${fieldName}'].append(k.to_map() if k else None)`, this.level);
684
- emitter.needSave = true;
685
- } else {
686
- emitter.needSave = false;
687
- }
688
- }
689
- this.levelDown();
690
- this.levelDown();
691
- }
692
- } else if (type.objectType === 'map') {
693
- if (depth > 0) {
694
- emitter.emitln(`d${depth} = {}`, this.level);
695
- emitter.emitln(`for k${depth} ,v${depth} in ${name}.items():`, this.level);
696
- this.levelUp();
697
- const propInfo = {
698
- name: `v${depth}`,
699
- fieldName: fieldName,
700
- type: type.valType,
701
- parentType: type.lexeme
702
- };
703
- this.emitComplexToMap(emitter, propInfo, `d${depth}`, depth + 1);
704
- this.levelDown();
705
- if (parentType === 'array') {
706
- emitter.emitln(`${carrier}.append(d${depth})`, this.level);
707
- } else if (parentType === 'map') {
708
- const num = depth - 1 > 0 ? depth - 1 : '';
709
- emitter.emitln(`${carrier}[k${num}] = d${depth}`, this.level);
710
- }
711
- } else {
712
- emitter.emitln(`result['${fieldName}'] = {}`, this.level);
713
- emitter.emitln(`if self.${_varName(name)} is not None:`, this.level);
714
- this.levelUp();
715
- emitter.emitln(`for k, v in self.${_varName(name)}.items():`, this.level);
716
- this.levelUp();
717
- if (type.valType.valType || type.valType.itemType) {
718
- const propInfo = {
719
- name: 'v',
720
- fieldName: fieldName,
721
- type: type.valType,
722
- parentType: type.lexeme
723
- };
724
- this.emitComplexToMap(emitter, propInfo, `result['${fieldName}']`, depth + 1);
725
- } else {
726
- if (type.valType.objectType === 'model') {
727
- emitter.emitln(`result['${fieldName}'][k] = v.to_map()`, this.level);
728
- emitter.needSave = true;
729
- } else {
730
- emitter.needSave = false;
731
- }
732
- }
733
- this.levelDown();
734
- this.levelDown();
735
- }
736
- } else if (type.objectType === 'model' || !this.config.typeMap[type] && !this.thirdPackageNamespace[type]) {
737
- const num = depth - 1 > 0 ? depth - 1 : '';
738
- if (parentType === 'array') {
739
- emitter.emitln(`l${num}.append(k${num}.to_map() if k${num} else None)`, this.level);
740
- } else if (parentType === 'map') {
741
- emitter.emitln(`d${num}[k${num}] = v${num}.to_map()`, this.level);
742
- }
743
- emitter.needSave = true;
744
- }
745
- }
746
-
747
- emitToMap(emitter, props, notes) {
748
- emitter.emitln('def to_map(self):', this.level);
749
- this.levelUp();
750
- emitter.emitln('_map = super().to_map()', this.level);
751
- emitter.emitln('if _map is not None:', this.level);
752
- this.levelUp();
753
- emitter.emitln('return _map', this.level);
754
- this.levelDown();
755
- emitter.emitln();
756
- emitter.emitln('result = dict()', this.level);
757
- props.forEach(prop => {
758
- let noteName = prop.notes.filter(item => item.key === 'name');
759
- let name = noteName.length > 0 ? noteName[0].value : prop.name;
760
- if (prop.type.objectType === 'array' || prop.type.objectType === 'map') {
761
- let emt = new Emitter(emitter.config);
762
- const propInfo = {
763
- name: prop.name,
764
- fieldName: name,
765
- parentType: prop.type.objectType,
766
- type: prop.type,
767
- };
768
- this.emitComplexToMap(emt, propInfo, null, 0);
769
- if (emt.needSave === true) {
770
- emitter.emit(emt.output);
771
- } else {
772
- emitter.emitln(`if self.${_varName(prop.name)} is not None:`, this.level);
773
- this.levelUp();
774
- emitter.emitln(`result['${name}'] = self.${_varName(prop.name)}`, this.level);
775
- this.levelDown();
776
- }
777
-
778
- } else {
779
- emitter.emitln(`if self.${_varName(prop.name)} is not None:`, this.level);
780
- this.levelUp();
781
- if (prop.type.objectType === 'model') {
782
- emitter.emitln(`result['${name}'] = self.${_varName(prop.name)}.to_map()`, this.level);
783
- } else {
784
- emitter.emitln(`result['${name}'] = self.${_varName(prop.name)}`, this.level);
785
- }
786
- this.levelDown();
787
- }
788
- });
789
-
790
- emitter.emitln('return result', this.level);
791
- this.levelDown();
792
- emitter.emitln();
793
- }
794
-
795
- emitComplexFromMap(emitter, prop, carrier, depth) {
796
- const name = prop.name;
797
- const fieldName = prop.fieldName;
798
- const type = prop.type;
799
- const parentType = prop.parentType;
800
-
801
- if (type.objectType === 'array') {
802
- if (depth > 0) {
803
- const propInfo = {
804
- name: `k${depth}`,
805
- fieldName: fieldName,
806
- type: type.itemType,
807
- parentType: type.lexeme
808
- };
809
-
810
- emitter.emitln(`l${depth} = []`, this.level);
811
- emitter.emitln(`for k${depth} in ${name}:`, this.level);
812
- this.levelUp();
813
- this.emitComplexFromMap(emitter, propInfo, `l${depth}`, depth + 1);
814
- this.levelDown();
815
- if (parentType === 'array') {
816
- emitter.emitln(`${carrier}.append(l${depth})`, this.level);
817
- } else if (parentType === 'map') {
818
- const num = depth - 1 > 0 ? depth - 1 : '';
819
- emitter.emitln(`${carrier}['k${num}'] = l${depth}`, this.level);
820
- }
821
- } else {
822
- emitter.emitln(`self.${_varName(name)} = []`, this.level);
823
- emitter.emitln(`if m.get('${fieldName}') is not None:`, this.level);
824
- this.levelUp();
825
- emitter.emitln(`for k in m.get('${fieldName}'):`, this.level);
826
- this.levelUp();
827
- if (type.itemType.valType || type.itemType.itemType) {
828
- const propInfo = {
829
- name: 'k',
830
- fieldName: fieldName,
831
- type: type.itemType,
832
- parentType: type.lexeme
833
- };
834
- this.emitComplexFromMap(emitter, propInfo, `self.${_varName(name)}`, depth + 1);
835
- } else {
836
- if (type.itemType.objectType === 'model') {
837
- emitter.emitln(`temp_model = ${type.itemType.lexeme}()`, this.level);
838
- emitter.emitln(`self.${_varName(name)}.append(temp_model.from_map(k))`, this.level);
839
- emitter.needSave = true;
840
- } else {
841
- emitter.needSave = false;
842
- }
843
- }
844
- this.levelDown();
845
- this.levelDown();
846
- }
847
- } else if (type.objectType === 'map') {
848
- if (depth > 0) {
849
- const propInfo = {
850
- name: `v${depth}`,
851
- fieldName: fieldName,
852
- type: type.valType,
853
- parentType: type.lexeme
854
- };
855
-
856
- emitter.emitln(`d${depth} = {}`, this.level);
857
- emitter.emitln(`for k${depth}, v${depth} in ${name}.items():`, this.level);
858
- this.levelUp();
859
- this.emitComplexFromMap(emitter, propInfo, `d${depth}`, depth + 1);
860
- this.levelDown();
861
- if (parentType === 'array') {
862
- emitter.emitln(`${carrier}.append(d${depth})`, this.level);
863
- } else if (parentType === 'map') {
864
- const num = depth - 1 > 0 ? depth - 1 : '';
865
- emitter.emitln(`${carrier}[k${num}] = d${depth}`, this.level);
866
- }
867
- } else {
868
- emitter.emitln(`self.${_varName(name)} = {}`, this.level);
869
- emitter.emitln(`if m.get('${fieldName}') is not None:`, this.level);
870
- this.levelUp();
871
- emitter.emitln(`for k, v in m.get('${fieldName}').items():`, this.level);
872
- this.levelUp();
873
- if (type.valType.valType || type.valType.itemType) {
874
- const propInfo = {
875
- name: 'v',
876
- fieldName: fieldName,
877
- type: type.valType,
878
- parentType: type.lexeme
879
- };
880
- this.emitComplexFromMap(emitter, propInfo, `self.${_varName(name)}`, depth + 1);
881
- } else {
882
- if (type.valType.objectType === 'model') {
883
- emitter.emitln(`temp_model = ${type.valType.lexeme}()`, this.level);
884
- emitter.emitln(`self.${_varName(name)}[k] = temp_model.from_map(v)`, this.level);
885
- emitter.needSave = true;
886
- } else {
887
- emitter.needSave = false;
888
- }
889
- }
890
- this.levelDown();
891
- this.levelDown();
892
- }
893
- } else if (type.objectType === 'model') {
894
- const num = depth - 1 > 0 ? depth - 1 : '';
895
- if (parentType === 'array') {
896
- emitter.emitln(`temp_model = ${type.lexeme}()`, this.level);
897
- emitter.emitln(`l${num}.append(temp_model.from_map(${name}))`, this.level);
898
- } else if (parentType === 'map') {
899
- emitter.emitln(`temp_model = ${type.lexeme}()`, this.level);
900
- emitter.emitln(`d${num}[k${num}] = temp_model.from_map(${name})`, this.level);
901
- }
902
- emitter.needSave = true;
903
- } else if (!this.config.typeMap[type] && !this.thirdPackageNamespace[type]) {
904
- const num = depth - 1 > 0 ? depth - 1 : '';
905
- if (parentType === 'array') {
906
- emitter.emitln(`temp_model = ${type}()`, this.level);
907
- emitter.emitln(`l${num}.append(temp_model.from_map(${name}))`, this.level);
908
- } else if (parentType === 'map') {
909
- emitter.emitln(`temp_model = ${type}()`, this.level);
910
- emitter.emitln(`d${num}[k${num}] = temp_model.from_map(${name})`, this.level);
911
- }
912
- emitter.needSave = true;
913
- }
914
- }
915
-
916
- emitFromMap(emitter, modelName, props, notes) {
917
- emitter.emitln('def from_map(self, m: dict = None):', this.level);
918
- this.levelUp();
919
- emitter.emitln('m = m or dict()', this.level);
920
- props.forEach(prop => {
921
- let noteName = prop.notes.filter(item => item.key === 'name');
922
- let name = noteName.length > 0 ? noteName[0].value : prop.name;
923
-
924
- if (prop.type.objectType === 'array' || prop.type.objectType === 'map') {
925
- let emt = new Emitter(emitter.config);
926
- const propInfo = {
927
- name: prop.name,
928
- fieldName: name,
929
- parentType: prop.type.objectType,
930
- type: prop.type,
931
- };
932
- this.emitComplexFromMap(emt, propInfo, null, 0);
933
- if (emt.needSave === true) {
934
- emitter.emit(emt.output);
935
- } else {
936
- emitter.emitln(`if m.get('${name}') is not None:`, this.level);
937
- this.levelUp();
938
- emitter.emitln(`self.${_varName(prop.name)} = m.get('${name}')`, this.level);
939
- this.levelDown();
940
- }
941
- } else {
942
- emitter.emitln(`if m.get('${name}') is not None:`, this.level);
943
- this.levelUp();
944
- if (prop.type.objectType === 'model') {
945
- let type = _type(prop.type);
946
- emitter.emitln(`temp_model = ${type}()`, this.level);
947
- emitter.emitln(`self.${_varName(prop.name)} = temp_model.from_map(m['${name}'])`, this.level);
948
- } else {
949
- emitter.emitln(`self.${_varName(prop.name)} = m.get('${name}')`, this.level);
950
- }
951
- this.levelDown();
952
- }
953
- });
954
- emitter.emitln('return self', this.level);
955
- this.levelDown();
956
- }
957
-
958
- emitNotes(emitter, notes) { }
959
-
960
- emitConstruct(emitter, construct, props, isModule = false) {
961
- if (construct.params.length + props.length > 0) {
962
- let constructParams = [];
963
- construct.params.forEach(param => {
964
- const typeHints = this.getTypeHints(param.type);
965
- if (param.value !== null && param.value !== 'null') {
966
- constructParams.push(`${_varName(param.key)}: ${typeHints} = ${param.value},`);
967
- } else {
968
- constructParams.push(`${_varName(param.key)}: ${typeHints},`);
969
- }
970
- });
971
- emitter.emitln('def __init__(', this.level);
972
- this.levelUp();
973
- emitter.emit('self', this.level);
974
-
975
- if (constructParams.length > 0) {
976
- emitter.emitln(', ');
977
- constructParams.forEach(porp => {
978
- emitter.emitln(porp, this.level);
979
- });
980
- }
981
-
982
- if (props.length > 0) {
983
- emitter.emitln(',');
984
- props.forEach((prop) => {
985
- if (prop instanceof PropItem) {
986
- const typeHints = this.getTypeHints(prop.type);
987
- if (typeHints === this.className) {
988
- emitter.emitln(`${_varName(prop.name)}: '${typeHints}' = None,`, this.level);
989
- } else {
990
- emitter.emitln(`${_varName(prop.name)}: ${typeHints} = None,`, this.level);
991
- }
992
-
993
- }
994
- });
995
- }
996
- this.levelDown();
997
- emitter.emitln('):', this.level);
998
- this.levelUp();
999
- this.func_self = 'self';
1000
-
1001
- } else {
1002
- emitter.emitln('def __init__(self):', this.level);
1003
- this.levelUp();
1004
- }
1005
- if (construct.annotations) {
1006
- this.emitFuncComment(emitter, construct);
1007
- //this.emitAnnotations(emitter, construct.annotations);
1008
- }
1009
-
1010
- props.forEach(prop => {
1011
- if (prop instanceof AnnotationItem) {
1012
- this.emitAnnotation(emitter, prop);
1013
- return;
1014
- }
1015
- const description = prop.notes.filter(note => {
1016
- if (note.key === 'description') {
1017
- return note.value;
1018
- }
1019
- });
1020
- if (description.length === 1) {
1021
- const desc = description[0].value.split(emitter.eol);
1022
- desc.forEach(d => {
1023
- emitter.emitln(`# ${d}`, this.level);
1024
- });
1025
- }
1026
- emitter.emitln(`self.${_varName(prop.name)} = ${_varName(prop.name)}`, this.level);
1027
- });
1028
- if (construct.body.length > 0) {
1029
- construct.body.forEach(gram => {
1030
- this.grammer(emitter, gram, true, true);
1031
- });
1032
- }
1033
-
1034
- if (construct.body.length + props.length <= 0) {
1035
- emitter.emitln('pass', this.level);
1036
- }
1037
- this.levelDown();
1038
- //emitter.emitln();
1039
- }
1040
-
1041
- getTypeHints(fieldType, manualImport = []) {
1042
- if (fieldType) {
1043
- let [typeHints, imports] = this.typeHint(fieldType);
1044
- const importList = imports.concat(manualImport);
1045
- importList.forEach(i => {
1046
- let existResult = this.includeList.some(item => {
1047
- if (item.import === i && item.from === 'typing') {
1048
- return true;
1049
- }
1050
- });
1051
- if (!existResult) {
1052
- this.includeList.push({
1053
- from: 'typing',
1054
- import: i
1055
- });
1056
- }
1057
- });
1058
- return typeHints;
1059
- }
1060
- }
1061
-
1062
- typeHint(fieldType) {
1063
- let importType = [];
1064
- const typeHints = this.config.typeHints[_type(fieldType.lexeme ? fieldType.lexeme : fieldType)];
1065
-
1066
- if (fieldType.objectType === 'array') {
1067
- importType.push(typeHints);
1068
- let [itemType, imports] = this.typeHint(fieldType.itemType);
1069
- importType.push.apply(importType, imports);
1070
- return [`List[${itemType}]`, importType];
1071
- } else if (fieldType.objectType === 'map') {
1072
- importType.push(typeHints);
1073
- let [keyType, keyImports] = this.typeHint(fieldType.keyType);
1074
- let [valueType, valueImports] = this.typeHint(fieldType.valType);
1075
- importType.push.apply(importType, keyImports);
1076
- importType.push.apply(importType, valueImports);
1077
- return [`Dict[${keyType}, ${valueType}]`, importType];
1078
- } else if (fieldType.objectType === 'model' || !this.config.typeMap[fieldType] && !this.thirdPackageNamespace[fieldType]) {
1079
- if (_type(fieldType) === this.className) {
1080
- return [`'${_type(fieldType)}'`, importType];
1081
- }
1082
- }
1083
-
1084
- if (typeHints && typeHints !== 'Dict' && typeHints !== 'List') {
1085
- if (typeHints) {
1086
- importType.push(typeHints);
1087
- }
1088
- return [typeHints, importType];
1089
- }
1090
-
1091
- return [_type(fieldType), importType];
1092
- }
1093
-
1094
- emitAnnotation(emitter, annotation, level) {
1095
- if (typeof level === 'undefined') {
1096
- level = this.level;
1097
- }
1098
- if (annotation.mode === 'single') {
1099
- emitter.emitln(`# ${annotation.content}`, level);
1100
- } else if (annotation.mode === 'multi') {
1101
- emitter.emitln('"""', level);
1102
- annotation.content.forEach(c => {
1103
- emitter.emitln(`${c}`, level);
1104
- });
1105
- emitter.emitln('"""', level);
1106
- } else {
1107
- debug.stack('Unsupported annotation.mode :' + annotation.mode, annotation);
1108
- }
1109
- }
1110
-
1111
- emitAsyncFunc(emitter, func) {
1112
- emitter.emitln();
1113
- this.func_async = func.modify.indexOf('ASYNC') > -1;
1114
- this.func_static = func.modify.indexOf('STATIC') > -1;
1115
- this.func_self = this.func_static ? this.getClassName(this.config.clientName) : 'self';
1116
- if (this.func_static) {
1117
- emitter.emitln('@staticmethod', this.level);
1118
- }
1119
- emitter.emit('async ', this.level);
1120
- const rtype = this.getTypeHints(func.return[0]);
1121
- // def func.
1122
- let selfVar = this.func_static ? '' : 'self';
1123
-
1124
- if (func.params.length > 0) {
1125
- emitter.emitln(`def ${_funcName(func.name)}_async(`);
1126
- this.levelUp();
1127
- if (selfVar) {
1128
- emitter.emitln(`${selfVar},`, this.level);
1129
- }
1130
- func.params.forEach(p => {
1131
- const type = this.getTypeHints(p.type);
1132
- emitter.emitln(`${_varName(p.key)}: ${type},`, this.level);
1133
- });
1134
- this.levelDown();
1135
- emitter.emitln(`) -> ${rtype}:`, this.level);
1136
- } else {
1137
- emitter.emit(`def ${_funcName(func.name)}_async(`);
1138
- if (selfVar) {
1139
- emitter.emit(`${selfVar}`);
1140
- }
1141
- emitter.emitln(`) -> ${rtype}:`);
1142
- }
1143
- this.levelUp();
1144
- this.emitFuncComment(emitter, func);
1145
- func.body.forEach(gram => {
1146
- this.grammer(emitter, gram);
1147
- });
1148
- if (func.body.filter(i => !(i instanceof AnnotationItem)).length === 0) {
1149
- emitter.emitln('pass', this.level);
1150
- }
1151
- this.levelDown();
1152
- }
1153
-
1154
- emitFunc(emitter, func) {
1155
- emitter.emitln();
1156
- this.func_async = func.modify.indexOf('ASYNC') > -1;
1157
- this.func_static = func.modify.indexOf('STATIC') > -1;
1158
- this.func_self = this.func_static ? this.getClassName(this.config.clientName) : 'self';
1159
- if (this.func_static) {
1160
- emitter.emitln('@staticmethod', this.level);
1161
- }
1162
- emitter.emit('', this.level);
1163
- const rtype = this.getTypeHints(func.return[0]);
1164
- // def func.
1165
- let selfVar = this.func_static ? '' : 'self';
1166
-
1167
- if (func.params.length > 0) {
1168
- emitter.emitln(`def ${_funcName(func.name)}(`);
1169
- this.levelUp();
1170
- if (selfVar) {
1171
- emitter.emitln(`${selfVar},`, this.level);
1172
- }
1173
- func.params.forEach(p => {
1174
- const type = this.getTypeHints(p.type);
1175
- emitter.emitln(`${_varName(p.key)}: ${type},`, this.level);
1176
- });
1177
- this.levelDown();
1178
- emitter.emitln(`) -> ${rtype}:`, this.level);
1179
- } else {
1180
- emitter.emit(`def ${_funcName(func.name)}(`);
1181
- if (selfVar) {
1182
- emitter.emit(`${selfVar}`);
1183
- }
1184
- emitter.emitln(`) -> ${rtype}:`);
1185
- }
1186
- this.levelUp();
1187
- this.emitFuncComment(emitter, func);
1188
- func.body.forEach(gram => {
1189
- this.grammer(emitter, gram);
1190
- });
1191
- if (func.body.filter(i => !(i instanceof AnnotationItem)).length === 0) {
1192
- emitter.emitln('pass', this.level);
1193
- }
1194
- this.levelDown();
1195
- if (this.func_async) {
1196
- this.aioMode = true;
1197
- this.emitAsyncFunc(emitter, func);
1198
- this.aioMode = false;
1199
- }
1200
- }
1201
-
1202
- emitFuncComment(emitter, func) {
1203
- const commentTag = ['@param', '@return'];
1204
- if (func.annotations.length > 0) {
1205
- emitter.emitln('"""', this.level);
1206
- func.annotations.forEach(annotation => {
1207
- if (annotation.mode === 'multi') {
1208
- annotation.content.forEach(c => {
1209
- c = c.replace('*', '').trim('', 'left');
1210
- let tagIndex = null;
1211
- c.split(' ').forEach((item, index) => {
1212
- if (commentTag.indexOf(item) > -1) {
1213
- tagIndex = index;
1214
- }
1215
- });
1216
- if (tagIndex !== null) {
1217
- let tmp = c.split(' ');
1218
- if (tmp[tagIndex] === '@param') {
1219
- const param = tmp[tagIndex + 1];
1220
- tmp[tagIndex + 1] = _name(param) + ':';
1221
- emitter.emitln(tmp.join(' '), this.level);
1222
- } else if (tmp[tagIndex] === '@return') {
1223
- tmp[tagIndex] = '@return:';
1224
- emitter.emitln(tmp.join(' '), this.level);
1225
- }
1226
- } else {
1227
- emitter.emitln(`${c}`, this.level);
1228
- }
1229
- });
1230
- } else {
1231
- emitter.emitln(`${annotation.content}`, this.level);
1232
- }
1233
- });
1234
- emitter.emitln('"""', this.level);
1235
- }
1236
- }
1237
-
1238
- emitInclude(emitter) {
1239
- let importList = this.includeList.filter(node => !node.from && node.import);
1240
- let aliasList = this.includeList.filter(node => node.from && node.alias);
1241
- let list = this.includeList.filter(node => node.from && !node.alias);
1242
-
1243
- let from = {};
1244
- let fromList = [];
1245
- fromList = fromList.concat(this.additionalPackage);
1246
-
1247
- list.forEach(item => {
1248
- if (!from[item.from]) {
1249
- from[item.from] = [item.import];
1250
- } else {
1251
- from[item.from].push(item.import);
1252
- }
1253
- });
1254
-
1255
- Object.keys(from).forEach(key => {
1256
- fromList.push({
1257
- from: key,
1258
- import: from[key]
1259
- });
1260
- });
1261
-
1262
- if (importList.length) {
1263
- importList.forEach(include => {
1264
- this.emitIncludeRow(emitter, include);
1265
- });
1266
- emitter.emitln();
1267
- }
1268
-
1269
- if (fromList.length) {
1270
- fromList.forEach(include => {
1271
- this.emitIncludeRow(emitter, include);
1272
- });
1273
- emitter.emitln();
1274
- }
1275
-
1276
- if (aliasList.length) {
1277
- aliasList.forEach(include => {
1278
- this.emitIncludeRow(emitter, include);
1279
- });
1280
- emitter.emitln();
1281
- }
1282
-
1283
- if (importList.length || fromList.length || aliasList.length) {
1284
- emitter.emitln();
1285
- }
1286
- }
1287
-
1288
- emitIncludeRow(emitter, include) {
1289
- if (include.from) {
1290
- emitter.emit(`from ${include.from} `, this.level);
1291
- if (include.import instanceof Array) {
1292
- emitter.emitln(`import ${include.import.join(', ')}`);
1293
- } else if (include.alias) {
1294
- emitter.emitln(`import ${include.import} as ${include.alias}`);
1295
- } else {
1296
- emitter.emitln(`import ${include.import}`);
1297
- }
1298
- } else if (include.import) {
1299
- emitter.emitln(`import ${include.import}`, this.level);
1300
- }
1301
- }
1302
-
1303
- emitExec(emitter) {
1304
- this.simpleImport('sys');
1305
- emitter.emitln();
1306
- emitter.emitln();
1307
- emitter.emitln('if __name__ == \'__main__\':');
1308
- this.levelUp();
1309
- emitter.emitln(`${this.getClassName(this.config.clientName)}.main(sys.argv[1:])`, this.level);
1310
- this.levelDown();
1311
- }
1312
-
1313
- grammerCall(emitter, gram) {
1314
- // path : 'parent', 'object', 'object_static', 'call', 'call_static', 'prop', 'prop_static', 'map', 'list'
1315
- var pre = '';
1316
- let params = '';
1317
- if (gram.params.length > 0) {
1318
- let tmp = [];
1319
- gram.params.forEach(p => {
1320
- let emit = new Emitter();
1321
- if (p.value instanceof BehaviorToMap) {
1322
- if (gram.path[1].name === 'isUnset') {
1323
- this.grammer(emit, p.value.grammer, false, false);
1324
- } else {
1325
- emit.emit(`${this.addInclude('$Core')}.${this.config.tea.core.toMap}(`);
1326
- this.grammer(emit, p.value.grammer, false, false);
1327
- emit.emit(')');
1328
- }
1329
- } else {
1330
- this.grammer(emit, p, false, false);
1331
- }
1332
- tmp.push(emit.output);
1333
- });
1334
- params = tmp.join(', ');
1335
- }
1336
- if (gram.type === 'super') {
1337
- pre = `super().__init__(${params})`;
1338
- } else {
1339
- gram.path.forEach((path, i) => {
1340
- let pathName = path.name;
1341
- if (typeof pathName === 'string') {
1342
- if (path.type === 'object') {
1343
- pathName = path.name.replace('@', 'self._');
1344
- } else {
1345
- pathName = path.name.replace('@', '_');
1346
- }
1347
- }
1348
-
1349
- if (path.type === 'parent' || path.type === 'parent_async') {
1350
- if (this.aioMode && path.type === 'parent_async') {
1351
- pre += `await ${this.func_self}`;
1352
- } else {
1353
- pre += this.func_self;
1354
- }
1355
- if (path.name) {
1356
- pre += `.${_name(path.name)}`;
1357
- }
1358
- } else if (path.type === 'object') {
1359
- pre += `${_varName(_convertStaticParam(pathName))}`;
1360
- } else if (path.type === 'object_async') {
1361
- if (this.aioMode) {
1362
- pre += `await ${_varName(_convertStaticParam(pathName))}`;
1363
- } else {
1364
- pre += `${_varName(_convertStaticParam(pathName))}`;
1365
- }
1366
- } else if (path.type === 'object_static') {
1367
- pre += `${_convertStaticParam(pathName)}`;
1368
- } else if (path.type === 'object_static_async') {
1369
- if (this.aioMode) {
1370
- pre += `await ${_convertStaticParam(pathName)}`;
1371
- } else {
1372
- pre += `${_convertStaticParam(pathName)}`;
1373
- }
1374
- } else if (path.type === 'call' || path.type === 'call_static') {
1375
- pre += `.${_funcName(pathName)}(${params})`;
1376
- } else if (path.type === 'call_async' || path.type === 'call_static_async') {
1377
- if (this.aioMode) {
1378
- pre += `.${_funcName(pathName)}_async(${params})`;
1379
- } else {
1380
- pre += `.${_funcName(pathName)}(${params})`;
1381
- }
1382
- } else if (path.type === 'prop') {
1383
- pre += `.${_name(pathName)}`;
1384
- } else if (path.type === 'prop_static') {
1385
- pre += `.${_name(pathName)}`;
1386
- } else if (path.type === 'map') {
1387
- pre += path.isVar ? `.get(${_varName(pathName)})` : `.get('${pathName}')`;
1388
- } else if (path.type === 'map_set') {
1389
- const quote = this._adaptedQuotes(pathName, emitter);
1390
- pre += `[${quote}${pathName}${quote}]`;
1391
- } else if (path.type === 'list') {
1392
- pre += path.isVar ? `[${_varName(pathName)}]` : `[${pathName}]`;
1393
- } else {
1394
- debug.stack(gram);
1395
- }
1396
- });
1397
- }
1398
- if (pre[0] === '.') {
1399
- pre = pre.slice(1);
1400
- }
1401
-
1402
- emitter.emit(pre);
1403
- }
1404
-
1405
- grammerExpr(emitter, gram) {
1406
- if (!gram.left && !gram.right) {
1407
- emitter.emit(` ${_symbol(gram.opt)} `);
1408
- return;
1409
- }
1410
- this.grammer(emitter, gram.left, false, false);
1411
- emitter.emit(` ${_symbol(gram.opt)} `);
1412
- this.grammer(emitter, gram.right, false, false);
1413
- }
1414
-
1415
- grammerVar(emitter, gram) {
1416
- if (gram.varType === 'static_class') {
1417
- const name = gram.name ? gram.name : gram.key;
1418
- emitter.emit(`${name}()`);
1419
- } else if (gram.varType === 'var' || gram.varType === 'const') {
1420
- const name = gram.name ? gram.name : gram.key;
1421
- emitter.emit(`${_convertStaticParam(_varName(name))}`);
1422
- } else {
1423
- debug.stack(gram);
1424
- }
1425
- }
1426
-
1427
- grammerValue(emitter, gram, layer = 1, isparams = false) {
1428
- if (gram.key) {
1429
- if (!isparams) {
1430
- const quote = this._adaptedQuotes(gram.key, emitter);
1431
- emitter.emit(`${quote}${gram.key}${quote}: `);
1432
- } else {
1433
- emitter.emit(`${_varName(gram.key)}=`, this.level);
1434
- }
1435
- }
1436
- if (gram instanceof GrammerCall) {
1437
- this.grammerCall(emitter, gram);
1438
- } else if (gram.type === 'array') {
1439
- if (gram.needCast) {
1440
- if (gram.value.length > 0) {
1441
- emitter.emit(`${this.addInclude('$Core')}.${this.config.tea.core.merge}(`);
1442
- let expandParams = gram.value.filter((item) => {
1443
- return item.isExpand !== true;
1444
- });
1445
- let notExpandParams = gram.value.filter((item) => {
1446
- return item.isExpand === true;
1447
- });
1448
- if (expandParams.length > 0) {
1449
- emitter.emitln('{');
1450
- for (let i = 0; i < expandParams.length; i++) {
1451
- emitter.emit('', this.level + layer);
1452
- let v = expandParams[i];
1453
- if (v instanceof AnnotationItem) {
1454
- this.emitAnnotation(emitter, v, 0);
1455
- continue;
1456
- }
1457
- this.grammerValue(emitter, v, layer + 1);
1458
- if (i < expandParams.length - 1) {
1459
- emitter.emitln(',');
1460
- } else {
1461
- emitter.emitln('');
1462
- }
1463
- }
1464
- emitter.emit('}', this.level + layer - 1);
1465
- }
1466
- if (notExpandParams.length > 0) {
1467
- if (expandParams.length > 0) {
1468
- emitter.emit(', ');
1469
- }
1470
- for (let i = 0; i < notExpandParams.length; i++) {
1471
- let v = notExpandParams[i];
1472
- if (v instanceof AnnotationItem) {
1473
- this.emitAnnotation(emitter, v, 0);
1474
- continue;
1475
- }
1476
- this.grammerValue(emitter, v, layer + 1);
1477
- if (i < notExpandParams.length - 1) {
1478
- emitter.emitln(',');
1479
- emitter.emit('', this.level + layer);
1480
- }
1481
- }
1482
- }
1483
- emitter.emit(')');
1484
- } else {
1485
- emitter.emit('{}');
1486
- }
1487
- } else {
1488
- if (gram.value.length > 0) {
1489
- const tmp = gram.value.filter(item => !(item instanceof AnnotationItem));
1490
- const isMap = tmp[0] && tmp[0].key && tmp[0].key !== '';
1491
- if (isMap) {
1492
- emitter.emitln('{');
1493
- } else {
1494
- emitter.emitln('[');
1495
- }
1496
- let len = gram.value.length;
1497
- let i = 0;
1498
- for (i = 0; i < gram.value.length; i++) {
1499
- let item = gram.value[i];
1500
- emitter.emit('', this.level + layer);
1501
- if (item instanceof AnnotationItem) {
1502
- this.emitAnnotation(emitter, item, 0);
1503
- continue;
1504
- }
1505
- this.grammerValue(emitter, item, layer + 1);
1506
- if (i < len - 1) {
1507
- emitter.emitln(',');
1508
- } else {
1509
- emitter.emitln('');
1510
- }
1511
- }
1512
- if (isMap) {
1513
- emitter.emit('}', this.level + layer - 1);
1514
- } else {
1515
- emitter.emit(']', this.level + layer - 1);
1516
- }
1517
-
1518
- } else {
1519
- emitter.emit('{}');
1520
- }
1521
- }
1522
- } else if (gram.type === 'model_construct_params') {
1523
- if (gram.value.length > 0) {
1524
- let tmp = [];
1525
- emitter.emitln();
1526
- this.levelUp();
1527
- gram.value.forEach(item => {
1528
- let emit = new Emitter();
1529
- if (item instanceof AnnotationItem) {
1530
- if (item.mode === 'single') {
1531
- emit.emit(`# ${item.content}`, this.level);
1532
- }
1533
- tmp.push(emit.output);
1534
- return true;
1535
- }
1536
-
1537
- this.grammerValue(emit, item, 1, true);
1538
- tmp.push(emit.output);
1539
- });
1540
- this.levelDown();
1541
- emitter.emit(tmp.join(',' + emitter.eol));
1542
- emitter.emitln();
1543
- emitter.emit('', this.level);
1544
- }
1545
- } else if (gram.type === 'string') {
1546
- const quote = this._adaptedQuotes(gram.value, emitter);
1547
- emitter.emit(`${quote}${gram.value}${quote}`);
1548
- } else if (gram.type === 'param') {
1549
- emitter.emit(`${_convertStaticParam(_varName(gram.value))}`);
1550
- } else if (gram.type === 'call') {
1551
- this.grammerCall(emitter, gram.value);
1552
- } else if (gram.type === 'number') {
1553
- emitter.emit(gram.value);
1554
- } else if (gram.type === 'null') {
1555
- emitter.emit('None');
1556
- } else if (gram.type === 'behavior') {
1557
- this.grammer(emitter, gram.value);
1558
- } else if (gram.type === 'expr') {
1559
- if (Array.isArray(gram.value)) {
1560
- const isConcatString = gram.value.some(item => {
1561
- return item.opt === 'CONCAT';
1562
- });
1563
- if (isConcatString) {
1564
- gram.value.forEach(gramItem => {
1565
- const needTanslate = gramItem.opt !== 'CONCAT' && gramItem.type !== 'string';
1566
- if (needTanslate) {
1567
- emitter.emit('str(');
1568
- this.grammer(emitter, gramItem, false, false);
1569
- emitter.emit(')');
1570
- } else {
1571
- this.grammer(emitter, gramItem, false, false);
1572
- }
1573
- });
1574
- } else {
1575
- gram.value.forEach(gramItem => {
1576
- this.grammer(emitter, gramItem, false, false);
1577
- });
1578
- }
1579
- } else {
1580
- this.grammer(emitter, gram.value, false, false);
1581
- }
1582
- } else if (gram.type === 'instance') {
1583
- this.grammerNewObject(emitter, gram.value);
1584
- } else if (gram.type === 'module_instance') {
1585
- if (this.aioMode) {
1586
- this.grammerNewObject(emitter, gram.value, true);
1587
- } else {
1588
- this.grammerNewObject(emitter, gram.value);
1589
- }
1590
- } else if (gram.type === 'bool' || gram.type === 'boolean') {
1591
- emitter.emit(gram.value ? 'True' : 'False');
1592
- } else if (gram.type === 'var') {
1593
- this.grammerVar(emitter, gram.value);
1594
- } else if (gram.type === 'class') {
1595
- emitter.emit(`${gram.value.name}`);
1596
- } else if (gram.type === 'not') {
1597
- emitter.emit(_symbol(Symbol.reverse()));
1598
- this.grammerValue(emitter, gram.value);
1599
- } else if (gram.type === '') {
1600
- if (gram.varType) {
1601
- this.grammerVar(emitter, gram);
1602
- } else {
1603
- debug.stack('Unsupported GrammerValue type', gram);
1604
- }
1605
- } else if (Array.isArray(gram)) {
1606
- let grammerValue = new GrammerValue();
1607
- grammerValue.type = 'array';
1608
- grammerValue.value = gram;
1609
- this.grammerValue(emitter, grammerValue);
1610
- } else {
1611
- debug.stack('Unsupported GrammerValue type', gram);
1612
- }
1613
- }
1614
-
1615
- grammerLoop(emitter, gram) {
1616
- if (gram.type === 'foreach') {
1617
- emitter.emit('for ');
1618
- this.grammerVar(emitter, gram.item);
1619
- emitter.emit(' in ');
1620
- this.grammer(emitter, gram.source, false, false);
1621
- emitter.emitln(':');
1622
- }
1623
- this.levelUp();
1624
- gram.body.forEach(node => {
1625
- this.grammer(emitter, node);
1626
- });
1627
- this.levelDown();
1628
- }
1629
-
1630
- grammerBreak(emitter, gram) {
1631
- emitter.emit('break');
1632
- }
1633
-
1634
- grammerCondition(emitter, gram) {
1635
- if (gram.type === 'elseif') {
1636
- emitter.emit('elif');
1637
- } else {
1638
- emitter.emit(`${gram.type}`);
1639
- }
1640
-
1641
- if (gram.type !== 'else') {
1642
- emitter.emit(' ');
1643
- let emit = new Emitter();
1644
- gram.conditionBody.forEach(condition => {
1645
- this.grammer(emit, condition, false, false);
1646
- });
1647
- emitter.emit(`${emit.output}`);
1648
- }
1649
-
1650
- emitter.emitln(':');
1651
- this.levelUp();
1652
- gram.body.forEach(node => {
1653
- this.grammer(emitter, node);
1654
- });
1655
- if (gram.body.filter(i => !(i instanceof AnnotationItem)).length === 0) {
1656
- emitter.emitln('pass', this.level);
1657
- }
1658
-
1659
- this.levelDown();
1660
- if (gram.elseItem.length && gram.elseItem.length > 0) {
1661
- gram.elseItem.forEach(e => {
1662
- this.grammer(emitter, e);
1663
- });
1664
- }
1665
- }
1666
-
1667
- grammerReturn(emitter, gram) {
1668
- if (gram.type === 'null') {
1669
- emitter.emit('return');
1670
- return;
1671
- }
1672
- emitter.emit('return ');
1673
-
1674
- if (gram.type === 'grammer') {
1675
- this.grammer(emitter, gram.expr, false, false);
1676
- } else if (gram.type === 'string') {
1677
- emitter.emit('\'\'');
1678
- } else {
1679
- this.grammer(emitter, gram.expr, false, false);
1680
- }
1681
- }
1682
-
1683
- grammerContinue(emitter, gram) {
1684
- emitter.emit('continue');
1685
- }
1686
-
1687
- grammerThrows(emitter, gram) {
1688
- if (gram.exception === null) {
1689
- emitter.emit('raise ');
1690
- this.grammerValue(emitter, gram.params[0]);
1691
- } else {
1692
- if (gram.params.length > 0) {
1693
- emitter.emit(`raise ${_exception(gram.exception)}(`);
1694
- if (gram.params.length === 1) {
1695
- this.grammerValue(emitter, gram.params[0]);
1696
- } else {
1697
- let tmp = [];
1698
- gram.params.forEach(p => {
1699
- let emit = new Emitter();
1700
- this.grammerValue(emit, p);
1701
- tmp.push(emit.output);
1702
- });
1703
- emitter.emit(tmp.join(', '));
1704
- }
1705
- emitter.emit(')');
1706
- } else {
1707
- let msg = gram.message ? `'${gram.message}'` : '';
1708
- emitter.emit(`raise ${_exception(gram.exception)}(${msg})`);
1709
- }
1710
- }
1711
- }
1712
-
1713
- grammerTryCatch(emitter, gram) {
1714
- emitter.emitln('try:');
1715
- this.levelUp();
1716
- gram.body.forEach(node => {
1717
- this.grammer(emitter, node, true, true);
1718
- });
1719
- this.levelDown();
1720
- gram.catchBody.forEach(node => {
1721
- assert.equal(true, node instanceof GrammerCatch);
1722
- this.grammerCatch(emitter, node);
1723
- });
1724
-
1725
- if (gram.finallyBody) {
1726
- this.grammerFinally(emitter, gram.finallyBody);
1727
- }
1728
- }
1729
-
1730
- grammerFinally(emitter, gram) {
1731
- emitter.emitln('finally:', this.level);
1732
- this.levelUp();
1733
- gram.body.forEach(childGram => {
1734
- this.grammer(emitter, childGram);
1735
- });
1736
- this.levelDown();
1737
- }
1738
-
1739
- grammerCatch(emitter, gram) {
1740
- emitter.emit('except', this.level);
1741
- if (gram.exceptions.type === 'BASE') {
1742
- emitter.emit(' Exception as ');
1743
- this.grammerVar(emitter, gram.exceptions.exceptionVar);
1744
- } else {
1745
- emitter.emit(` ${_exception(gram.exceptions.type)} as `);
1746
- this.grammerVar(emitter, gram.exceptions.exceptionVar);
1747
- }
1748
-
1749
- emitter.emitln(':');
1750
- this.levelUp();
1751
- gram.body.forEach(childGram => {
1752
- this.grammer(emitter, childGram);
1753
- });
1754
- this.levelDown();
1755
- }
1756
-
1757
- grammerNewObject(emitter, gram, isModule = false) {
1758
- let objectName = gram.name;
1759
-
1760
- emitter.emit(`${objectName}(`);
1761
- if (!Array.isArray(gram.params)) {
1762
- this.grammerValue(emitter, gram.params);
1763
- } else {
1764
- if (gram.params.length > 0) {
1765
- let params = [];
1766
- gram.params.forEach(p => {
1767
- let emit = new Emitter();
1768
- if (p.key) {
1769
- emit.emit(`${_varName(p.key)}`);
1770
- emit.emit('=');
1771
- }
1772
- if (typeof (p.value) === 'string') {
1773
- if (p.value) {
1774
- emit.emit(`${p.value}`);
1775
- } else if (p.key) {
1776
- emit.emit('\'\'');
1777
- }
1778
- } else {
1779
- this.grammerValue(emit, p.value);
1780
- }
1781
- params.push(emit.output);
1782
- });
1783
- emitter.emit(params.join(', '));
1784
- }
1785
- }
1786
- emitter.emit(')');
1787
- }
1788
-
1789
- behaviorTimeNow(emitter, behavior) {
1790
- this.simpleImport('time');
1791
- emitter.emit('time.time()');
1792
- }
1793
-
1794
- behaviorSetMapItem(emitter, behavior) {
1795
- let emit = new Emitter();
1796
- this.grammerCall(emit, behavior.call);
1797
-
1798
- if (behavior.isVar) {
1799
- emitter.emit(`${emit.output}[${_varName(behavior.key)}] = `, this.level);
1800
- } else {
1801
- const quote = this._adaptedQuotes(behavior.key, emitter);
1802
- emitter.emit(`${emit.output}[${quote}${behavior.key}${quote}] = `, this.level);
1803
- }
1804
-
1805
- this.grammerValue(emitter, behavior.value);
1806
- emitter.emitln('');
1807
- }
1808
-
1809
- behaviorDoAction(emitter, behavior) {
1810
- emitter.emit('', this.level);
1811
- this.grammerVar(emitter, behavior.var);
1812
- if (this.aioMode) {
1813
- emitter.emit(` = await ${this.addInclude('$Core')}.${this.config.tea.core.asyncDoAction}(`);
1814
- } else {
1815
- emitter.emit(` = ${this.addInclude('$Core')}.${this.config.tea.core.doAction}(`);
1816
- }
1817
-
1818
- let params = [];
1819
- behavior.params.forEach(p => {
1820
- let emit = new Emitter();
1821
- this.grammerValue(emit, p);
1822
- params.push(emit.output);
1823
- });
1824
- emitter.emit(params.join(', '));
1825
- emitter.emitln(')');
1826
- behavior.body.forEach(node => {
1827
- this.grammer(emitter, node);
1828
- });
1829
- }
1830
-
1831
- behaviorRetry(emitter, behavior) {
1832
- emitter.emitln(`raise TeaException(${this.config.request}, ${this.config.response})`, this.level);
1833
- }
1834
-
1835
- behaviorToModel(emitter, behavior) {
1836
- emitter.emitln(`${this.addInclude('$Core')}.${this.config.tea.core.fromMap}(`);
1837
- this.levelUp();
1838
- emitter.emitln(`${this.addModelInclude(behavior.expected)}(),`, this.level);
1839
- this.grammer(emitter, behavior.grammer);
1840
- this.levelDown();
1841
- emitter.emit(')', this.level);
1842
- }
1843
-
1844
- behaviorToMap(emitter, behavior) {
1845
- const grammer = behavior.grammer;
1846
- if (grammer instanceof GrammerCall) {
1847
- grammer.path.push({
1848
- type: 'call',
1849
- name: 'to_map'
1850
- });
1851
- this.grammerCall(emitter, grammer);
1852
- } else if (grammer instanceof GrammerVar) {
1853
- const grammerCall = new GrammerCall('method');
1854
- grammerCall.path.push({
1855
- type: 'object',
1856
- name: grammer.name
1857
- });
1858
- grammerCall.path.push({
1859
- type: 'call',
1860
- name: 'to_map'
1861
- });
1862
- this.grammerCall(emitter, grammerCall);
1863
- } else {
1864
- debug.stack(grammer);
1865
- }
1866
- }
1867
-
1868
- _adaptedQuotes(str, emit) {
1869
- const line = str.split(emit.eol);
1870
- let quote = '\'';
1871
- if (str.indexOf('\'') !== -1 && str.indexOf('"') !== -1 || line.length > 1) {
1872
- quote = '\'\'\'';
1873
- } else if (str.indexOf('\'') !== -1) {
1874
- quote = '"';
1875
- }
1876
- return quote;
1877
- }
1878
-
1879
- behaviorStrFormat(emitter, behavior) {
1880
- behavior.item.forEach(gram => {
1881
- let valEmitter = new Emitter();
1882
- this.grammerValue(valEmitter, gram);
1883
- behavior.tmp = behavior.tmp.replace('${}', `{${valEmitter.output}}`);
1884
- });
1885
- const quote = this._adaptedQuotes(behavior.tmp, emitter);
1886
- emitter.emit(`f${quote}${behavior.tmp}${quote}`);
1887
- }
1888
-
1889
- behaviorTypeInstance(emitter, behavior) {
1890
-
1891
- }
1892
-
1893
- grammerSymbol(emitter, gram) {
1894
- emitter.emit(_symbol(gram));
1895
- }
1896
- }
1897
-
1898
- module.exports = Combinator;