@darabonba/python-generator 2.0.1 → 2.0.3

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 (179) hide show
  1. package/.github/workflows/ci.yml +1 -1
  2. package/ChangeLog.md +12 -0
  3. package/lib/generator.js +223 -127
  4. package/lib/helper.js +21 -1
  5. package/package.json +1 -1
  6. package/tests/expected/{python3/model/tea_python_tests/client.py → annotation/tea_python_tests/models/__init__.py} +6 -3
  7. package/tests/expected/annotation/tea_python_tests/{models.py → models/_test.py} +1 -1
  8. package/tests/expected/comment/tea_python_tests/models/__init__.py +15 -0
  9. package/tests/expected/comment/tea_python_tests/models/_test_1.py +91 -0
  10. package/tests/expected/comment/tea_python_tests/models/_test_2.py +55 -0
  11. package/tests/expected/comment/tea_python_tests/models/_test_3.py +61 -0
  12. package/tests/expected/complex/tea_python_tests/client.py +6 -6
  13. package/tests/expected/complex/tea_python_tests/exceptions/__init__.py +13 -0
  14. package/tests/expected/complex/tea_python_tests/exceptions/_err_1.py +23 -0
  15. package/tests/expected/complex/tea_python_tests/exceptions/_err_2.py +22 -0
  16. package/tests/expected/complex/tea_python_tests/models/__init__.py +19 -0
  17. package/tests/{output/complex/tea_python_tests/models.py → expected/complex/tea_python_tests/models/_complex_request.py} +22 -151
  18. package/tests/expected/complex/tea_python_tests/models/_complex_request_configs.py +47 -0
  19. package/tests/expected/complex/tea_python_tests/models/_complex_request_header.py +42 -0
  20. package/tests/expected/complex/tea_python_tests/models/_complex_request_part.py +33 -0
  21. package/tests/expected/complex/tea_python_tests/models/_response.py +33 -0
  22. package/tests/expected/model/tea_python_tests/exceptions/__init__.py +11 -0
  23. package/tests/expected/model/tea_python_tests/{exceptions.py → exceptions/_main_file.py} +1 -1
  24. package/tests/expected/model/tea_python_tests/models/__init__.py +33 -0
  25. package/tests/expected/model/tea_python_tests/models/_class.py +24 -0
  26. package/tests/expected/model/tea_python_tests/models/_m.py +38 -0
  27. package/tests/expected/model/tea_python_tests/models/_main_file_model.py +45 -0
  28. package/tests/expected/model/tea_python_tests/models/_main_file_model_model.py +32 -0
  29. package/tests/expected/model/tea_python_tests/models/_model.py +32 -0
  30. package/tests/expected/model/tea_python_tests/models/_msub_m.py +26 -0
  31. package/tests/expected/model/tea_python_tests/{models.py → models/_my_model.py} +41 -363
  32. package/tests/expected/model/tea_python_tests/models/_my_model_model.py +45 -0
  33. package/tests/expected/model/tea_python_tests/models/_my_model_model_model.py +32 -0
  34. package/tests/expected/model/tea_python_tests/models/_my_model_subarraymodel.py +24 -0
  35. package/tests/expected/model/tea_python_tests/models/_my_model_submodel.py +45 -0
  36. package/tests/expected/model/tea_python_tests/models/_my_model_submodel_model.py +32 -0
  37. package/tests/expected/multi/tea_python_tests/api.py +0 -2
  38. package/tests/expected/multi/tea_python_tests/api_models/__init__.py +11 -0
  39. package/tests/expected/{python3/annotation/tea_python_tests/models.py → multi/tea_python_tests/api_models/_test_model_dir_2.py} +7 -9
  40. package/tests/expected/multi/tea_python_tests/client.py +0 -2
  41. package/tests/expected/multi/tea_python_tests/exceptions/__init__.py +13 -0
  42. package/tests/{output/complex/tea_python_tests/exceptions.py → expected/multi/tea_python_tests/exceptions/_err.py} +10 -11
  43. package/tests/expected/multi/tea_python_tests/model/user_exceptions/__init__.py +15 -0
  44. package/tests/expected/multi/tea_python_tests/model/user_exceptions/_err.py +22 -0
  45. package/tests/expected/multi/tea_python_tests/model/{user_exceptions.py → user_exceptions/_err_1.py} +3 -32
  46. package/tests/expected/multi/tea_python_tests/model/user_exceptions/_err_2.py +18 -0
  47. package/tests/expected/multi/tea_python_tests/model/user_models/__init__.py +13 -0
  48. package/tests/expected/multi/tea_python_tests/model/user_models/_base_info.py +72 -0
  49. package/tests/expected/multi/tea_python_tests/model/{user_models.py → user_models/_info.py} +3 -69
  50. package/tests/expected/multi/tea_python_tests/models/__init__.py +13 -0
  51. package/tests/expected/multi/tea_python_tests/models/_test_model_dir.py +79 -0
  52. package/tests/expected/{python2/empty/tea_python_tests/client.py → typedef/tea_python_tests/models/__init__.py} +9 -3
  53. package/tests/{output/typedef/tea_python_tests/models.py → expected/typedef/tea_python_tests/models/_m.py} +1 -1
  54. package/tests/fixtures/multi/api.dara +4 -0
  55. package/tests/fixtures/multi/main.dara +18 -0
  56. package/tests/main.tests.js +194 -219
  57. package/tests/output/annotation/tea_python_tests/models/__init__.py +11 -0
  58. package/tests/output/annotation/tea_python_tests/{models.py → models/_test.py} +1 -1
  59. package/tests/output/comment/tea_python_tests/models/__init__.py +15 -0
  60. package/tests/output/comment/tea_python_tests/models/_test_1.py +91 -0
  61. package/tests/output/comment/tea_python_tests/models/_test_2.py +55 -0
  62. package/tests/output/comment/tea_python_tests/models/_test_3.py +61 -0
  63. package/tests/output/complex/tea_python_tests/client.py +6 -6
  64. package/tests/output/complex/tea_python_tests/exceptions/__init__.py +13 -0
  65. package/tests/output/complex/tea_python_tests/exceptions/_err_1.py +23 -0
  66. package/tests/output/complex/tea_python_tests/exceptions/_err_2.py +22 -0
  67. package/tests/output/complex/tea_python_tests/models/__init__.py +19 -0
  68. package/tests/{expected/complex/tea_python_tests/models.py → output/complex/tea_python_tests/models/_complex_request.py} +22 -151
  69. package/tests/output/complex/tea_python_tests/models/_complex_request_configs.py +47 -0
  70. package/tests/output/complex/tea_python_tests/models/_complex_request_header.py +42 -0
  71. package/tests/output/complex/tea_python_tests/models/_complex_request_part.py +33 -0
  72. package/tests/output/complex/tea_python_tests/models/_response.py +33 -0
  73. package/tests/output/model/tea_python_tests/exceptions/__init__.py +11 -0
  74. package/tests/output/model/tea_python_tests/{exceptions.py → exceptions/_main_file.py} +1 -1
  75. package/tests/output/model/tea_python_tests/models/__init__.py +33 -0
  76. package/tests/output/model/tea_python_tests/models/_class.py +24 -0
  77. package/tests/output/model/tea_python_tests/models/_m.py +38 -0
  78. package/tests/output/model/tea_python_tests/models/_main_file_model.py +45 -0
  79. package/tests/output/model/tea_python_tests/models/_main_file_model_model.py +32 -0
  80. package/tests/output/model/tea_python_tests/models/_model.py +32 -0
  81. package/tests/output/model/tea_python_tests/models/_msub_m.py +26 -0
  82. package/tests/output/model/tea_python_tests/{models.py → models/_my_model.py} +41 -363
  83. package/tests/output/model/tea_python_tests/models/_my_model_model.py +45 -0
  84. package/tests/output/model/tea_python_tests/models/_my_model_model_model.py +32 -0
  85. package/tests/output/model/tea_python_tests/models/_my_model_subarraymodel.py +24 -0
  86. package/tests/output/model/tea_python_tests/models/_my_model_submodel.py +45 -0
  87. package/tests/output/model/tea_python_tests/models/_my_model_submodel_model.py +32 -0
  88. package/tests/output/multi/tea_python_tests/api.py +0 -2
  89. package/tests/output/multi/tea_python_tests/api_models/__init__.py +11 -0
  90. package/tests/{expected/python2/annotation/tea_python_tests/models.py → output/multi/tea_python_tests/api_models/_test_model_dir_2.py} +12 -11
  91. package/tests/output/multi/tea_python_tests/client.py +0 -2
  92. package/tests/output/multi/tea_python_tests/exceptions/__init__.py +13 -0
  93. package/tests/{expected/complex/tea_python_tests/exceptions.py → output/multi/tea_python_tests/exceptions/_err.py} +10 -11
  94. package/tests/output/multi/tea_python_tests/model/user_exceptions/__init__.py +15 -0
  95. package/tests/output/multi/tea_python_tests/model/user_exceptions/_err.py +22 -0
  96. package/tests/output/multi/tea_python_tests/model/{user_exceptions.py → user_exceptions/_err_1.py} +3 -32
  97. package/tests/output/multi/tea_python_tests/model/user_exceptions/_err_2.py +18 -0
  98. package/tests/output/multi/tea_python_tests/model/user_models/__init__.py +13 -0
  99. package/tests/output/multi/tea_python_tests/model/user_models/_base_info.py +72 -0
  100. package/tests/output/multi/tea_python_tests/model/{user_models.py → user_models/_info.py} +3 -69
  101. package/tests/output/multi/tea_python_tests/models/__init__.py +13 -0
  102. package/tests/output/multi/tea_python_tests/models/_test_model_dir.py +79 -0
  103. package/tests/{expected/python2/model/tea_python_tests/client.py → output/typedef/tea_python_tests/models/__init__.py} +9 -3
  104. package/tests/{expected/typedef/tea_python_tests/models.py → output/typedef/tea_python_tests/models/_m.py} +1 -1
  105. package/tests/expected/comment/tea_python_tests/models.py +0 -195
  106. package/tests/expected/python2/alias/setup.py +0 -79
  107. package/tests/expected/python2/alias/tea_python_tests/client.py +0 -23
  108. package/tests/expected/python2/annotation/tea_python_tests/client.py +0 -54
  109. package/tests/expected/python2/api/tea_python_tests/client.py +0 -54
  110. package/tests/expected/python2/comment/tea_python_tests/client.py +0 -188
  111. package/tests/expected/python2/comment/tea_python_tests/models.py +0 -146
  112. package/tests/expected/python2/complex/tea_python_tests/client.py +0 -301
  113. package/tests/expected/python2/complex/tea_python_tests/models.py +0 -315
  114. package/tests/expected/python2/const/tea_python_tests/client.py +0 -14
  115. package/tests/expected/python2/empty/setup.py +0 -76
  116. package/tests/expected/python2/exec/tea_python_tests/exec_client.py +0 -16
  117. package/tests/expected/python2/function/tea_python_tests/client.py +0 -47
  118. package/tests/expected/python2/import/setup.py +0 -85
  119. package/tests/expected/python2/import/tea_python_tests/client.py +0 -24
  120. package/tests/expected/python2/map/tea_python_tests/client.py +0 -19
  121. package/tests/expected/python2/model/tea_python_tests/models.py +0 -575
  122. package/tests/expected/python2/statements/tea_python_tests/client.py +0 -64
  123. package/tests/expected/python2/super/tea_python_tests/client.py +0 -8
  124. package/tests/expected/python2/typedef/setup.py +0 -85
  125. package/tests/expected/python2/typedef/tea_python_tests/client.py +0 -38
  126. package/tests/expected/python2/typedef/tea_python_tests/models.py +0 -35
  127. package/tests/expected/python3/alias/setup.py +0 -77
  128. package/tests/expected/python3/alias/tea_python_tests/client.py +0 -32
  129. package/tests/expected/python3/annotation/tea_python_tests/client.py +0 -88
  130. package/tests/expected/python3/api/tea_python_tests/client.py +0 -92
  131. package/tests/expected/python3/comment/tea_python_tests/__init__.py +0 -1
  132. package/tests/expected/python3/comment/tea_python_tests/client.py +0 -319
  133. package/tests/expected/python3/comment/tea_python_tests/models.py +0 -163
  134. package/tests/expected/python3/complex/tea_python_tests/__init__.py +0 -1
  135. package/tests/expected/python3/complex/tea_python_tests/client.py +0 -514
  136. package/tests/expected/python3/complex/tea_python_tests/models.py +0 -349
  137. package/tests/expected/python3/const/tea_python_tests/__init__.py +0 -1
  138. package/tests/expected/python3/const/tea_python_tests/client.py +0 -9
  139. package/tests/expected/python3/empty/setup.py +0 -74
  140. package/tests/expected/python3/empty/tea_python_tests/__init__.py +0 -1
  141. package/tests/expected/python3/empty/tea_python_tests/client.py +0 -5
  142. package/tests/expected/python3/exec/tea_python_tests/__init__.py +0 -1
  143. package/tests/expected/python3/exec/tea_python_tests/exec_client.py +0 -20
  144. package/tests/expected/python3/function/tea_python_tests/__init__.py +0 -1
  145. package/tests/expected/python3/function/tea_python_tests/client.py +0 -67
  146. package/tests/expected/python3/import/setup.py +0 -77
  147. package/tests/expected/python3/import/tea_python_tests/__init__.py +0 -1
  148. package/tests/expected/python3/import/tea_python_tests/client.py +0 -28
  149. package/tests/expected/python3/map/tea_python_tests/__init__.py +0 -1
  150. package/tests/expected/python3/map/tea_python_tests/client.py +0 -22
  151. package/tests/expected/python3/model/tea_python_tests/__init__.py +0 -1
  152. package/tests/expected/python3/model/tea_python_tests/models.py +0 -631
  153. package/tests/expected/python3/statements/tea_python_tests/__init__.py +0 -1
  154. package/tests/expected/python3/statements/tea_python_tests/client.py +0 -83
  155. package/tests/expected/python3/super/tea_python_tests/__init__.py +0 -1
  156. package/tests/expected/python3/super/tea_python_tests/client.py +0 -13
  157. package/tests/expected/python3/typedef/setup.py +0 -77
  158. package/tests/expected/python3/typedef/tea_python_tests/__init__.py +0 -1
  159. package/tests/expected/python3/typedef/tea_python_tests/client.py +0 -72
  160. package/tests/expected/python3/typedef/tea_python_tests/models.py +0 -39
  161. package/tests/output/comment/tea_python_tests/models.py +0 -195
  162. /package/tests/expected/{python2/alias → multi}/tea_python_tests/__init__.py +0 -0
  163. /package/tests/{expected/python2/annotation → output/alias}/tea_python_tests/__init__.py +0 -0
  164. /package/tests/{expected/python2/api → output/annotation}/tea_python_tests/__init__.py +0 -0
  165. /package/tests/{expected/python2/comment → output/api}/tea_python_tests/__init__.py +0 -0
  166. /package/tests/{expected/python2/complex → output/builtin}/tea_python_tests/__init__.py +0 -0
  167. /package/tests/{expected/python2/const → output/comment}/tea_python_tests/__init__.py +0 -0
  168. /package/tests/{expected/python2/empty → output/complex}/tea_python_tests/__init__.py +0 -0
  169. /package/tests/{expected/python2/exec → output/const}/tea_python_tests/__init__.py +0 -0
  170. /package/tests/{expected/python2/function → output/empty}/tea_python_tests/__init__.py +0 -0
  171. /package/tests/{expected/python2/import → output/exec}/tea_python_tests/__init__.py +0 -0
  172. /package/tests/{expected/python2/map → output/function}/tea_python_tests/__init__.py +0 -0
  173. /package/tests/{expected/python2/model → output/import}/tea_python_tests/__init__.py +0 -0
  174. /package/tests/{expected/python2/statements → output/map}/tea_python_tests/__init__.py +0 -0
  175. /package/tests/{expected/python2/super → output/model}/tea_python_tests/__init__.py +0 -0
  176. /package/tests/{expected/python2/typedef → output/multi}/tea_python_tests/__init__.py +0 -0
  177. /package/tests/{expected/python3/alias → output/statements}/tea_python_tests/__init__.py +0 -0
  178. /package/tests/{expected/python3/annotation → output/super}/tea_python_tests/__init__.py +0 -0
  179. /package/tests/{expected/python3/api → output/typedef}/tea_python_tests/__init__.py +0 -0
package/lib/generator.js CHANGED
@@ -9,24 +9,13 @@ const DSL = require('@darabonba/parser');
9
9
  const {
10
10
  _name, _vid, _string, _upperFirst, _type, _escape,
11
11
  _subModelName, _camelCase, _snakeCase, _getImport,
12
- _isBinaryOp, _adaptedQuotes, CORE, REQUEST, RESPONSE
12
+ _isBinaryOp, _adaptedQuotes, CORE, REQUEST, RESPONSE,
13
+ _avoidKeywords, _removeFilesInDirectory
13
14
  } = require('./helper');
14
15
  const getBuiltin = require('./builtin');
15
16
  const { Tag } = require('@darabonba/parser/lib/tag');
16
17
  const Annotation = require('@darabonba/annotation-parser');
17
18
 
18
- function avoidReserveName(name) {
19
- const reserves = [
20
- 'function'
21
- ];
22
-
23
- if (reserves.indexOf(name) !== -1) {
24
- return `_${name}`;
25
- }
26
-
27
- return name;
28
- }
29
-
30
19
  class Visitor {
31
20
 
32
21
  static get supportGenerateTest() {
@@ -52,8 +41,10 @@ class Visitor {
52
41
  this.imports = [];
53
42
  this.outputDir = this.config.outputDir;
54
43
  this.setupPath = path.join(this.outputDir, 'setup.py');
55
- this.modelPath = path.join(this.outputDir, this.config.package, 'models.py');
56
- this.exceptionPath = path.join(this.outputDir, this.config.package, 'exceptions.py');
44
+ this.modelPath = path.join(this.outputDir, this.config.package, 'models');
45
+ this.modelPackage = 'models';
46
+ this.exceptionPath = path.join(this.outputDir, this.config.package, 'exceptions');
47
+ this.exceptionPackage = 'exceptions';
57
48
  this.config.clientPath = path.join(this.outputDir, this.config.package, `${_snakeCase(this.config.clientName)}.py`);
58
49
  this.classNamespace = new Map();
59
50
  // 新增:用于存储已使用的类型
@@ -211,8 +202,10 @@ setup(
211
202
  // this.exceptionPath = path.join(this.outputDir, this.config.package, 'exceptions.py');
212
203
  const filepath = ast.innerModule.get(aliasId);
213
204
  this.className = this.getInnerClient(aliasId);
214
- this.modelPath = filepath.replace('.py', '_models.py');
215
- this.exceptionPath = filepath.replace('.py', '_exceptions.py');
205
+ this.modelPath = filepath.replace('.py', '_models');
206
+ this.modelPackage = path.basename(this.modelPath);
207
+ this.exceptionPath = filepath.replace('.py', '_exceptions');
208
+ this.exceptionPackage = path.basename(this.exceptionPath);
216
209
  this.visitModule(moduleAst, filepath, false, 0);
217
210
  data = keys.next();
218
211
  }
@@ -262,6 +255,27 @@ setup(
262
255
  return true;
263
256
  }
264
257
 
258
+ modelBefore() {
259
+ // clear model.py
260
+ if(fs.existsSync(this.modelPath + '.py')) {
261
+ fs.unlinkSync(this.modelPath + '.py');
262
+ }
263
+ _removeFilesInDirectory(this.modelPath);
264
+ _removeFilesInDirectory(this.exceptionPath);
265
+ }
266
+
267
+ visitModuleInit() {
268
+ const initFile = path.join(this.outputDir, this.config.package, '__init__.py');
269
+ if(!fs.existsSync(initFile)) {
270
+ if(!fs.existsSync(path.dirname(initFile))) {
271
+ fs.mkdirSync(path.dirname(initFile), {
272
+ recursive: true
273
+ });
274
+ }
275
+ fs.writeFileSync(initFile, '__version__ = "1.0.0"\n');
276
+ }
277
+ }
278
+
265
279
  visitModule(ast, filepath, level) {
266
280
  assert.equal(ast.type, 'module');
267
281
  this.ast = ast;
@@ -276,6 +290,7 @@ setup(
276
290
 
277
291
  this.clientName = new Map();
278
292
  this.packageInfo = {};
293
+ this.fileBuffer = {};
279
294
  this.usedTypes = [];
280
295
  this.imports = [];
281
296
  if(this.overwrite(ast, filepath) === false) {
@@ -310,12 +325,10 @@ setup(
310
325
  for (let i = 0; i < models.length; i++) {
311
326
  this.eachModel(models[i], level);
312
327
  }
313
- if (models.length > 0) {
328
+ if (models.length > 0 || subModels.length > 0) {
314
329
  // 存一笔 models
315
-
316
- this.save(this.modelPath);
317
- this.usedTypes = [];
318
- this.imports = [];
330
+ this.modelInitBefore(ast, level);
331
+ this.visitModelInit(subModels.concat(models));
319
332
  }
320
333
 
321
334
  const exceptions = ast.moduleBody.nodes.filter((item) => {
@@ -324,17 +337,15 @@ setup(
324
337
 
325
338
 
326
339
  if (exceptions.length > 0) {
327
- this.exceptionsBody = true;
328
340
  for (let i = 0; i < exceptions.length; i++) {
329
341
  this.eachException(exceptions[i], level);
330
342
  }
331
- this.exceptionsBody = false;
332
- this.save(this.exceptionPath);
333
- this.usedTypes = [];
334
- this.imports = [];
343
+ this.visitExceptionInit(exceptions);
335
344
  }
345
+ this.flushBuffer();
336
346
 
337
347
 
348
+ this.visitModuleInit();
338
349
  this.moduleBefore(ast, level);
339
350
 
340
351
  this.visitAnnotation(ast.annotation, level);
@@ -554,8 +565,8 @@ setup(
554
565
  for (var i = 0; i < ast.params.params.length; i++) {
555
566
  const node = ast.params.params[i];
556
567
  assert.equal(node.type, 'param');
557
- const name = _snakeCase(_name(node.paramName));
558
- this.emit(`${avoidReserveName(name)}: `, level + 4);
568
+ const name = _avoidKeywords(_snakeCase(_name(node.paramName)));
569
+ this.emit(`${name}: `, level + 4);
559
570
  this.visitType(node.paramType, level);
560
571
  this.emit(',');
561
572
  if (i !== ast.params.length - 1) {
@@ -741,8 +752,8 @@ setup(
741
752
  for (var i = 0; i < ast.params.length; i++) {
742
753
  const node = ast.params[i];
743
754
  assert.equal(node.type, 'param');
744
- const name = _snakeCase(_name(node.paramName));
745
- this.emit(`${avoidReserveName(name)}: `, level);
755
+ const name = _avoidKeywords(_snakeCase(_name(node.paramName)));
756
+ this.emit(`${name}: `, level);
746
757
  this.visitType(node.paramType, level);
747
758
  this.emit(',');
748
759
  if (i !== ast.params.length - 1) {
@@ -762,13 +773,18 @@ setup(
762
773
  } else if (ast.type === 'moduleModel') {
763
774
  const [moduleId, ...rest] = ast.path;
764
775
  const modelName = _subModelName(rest.map((item) => item.lexeme).join('.'));
765
- this.emit(this.getModelName(modelName, _name(moduleId)));
776
+ let type = 'model';
777
+ const externEx = this.usedExternException.get(_name(moduleId));
778
+ if (externEx && externEx.has(modelName)) {
779
+ type = 'exception';
780
+ }
781
+ this.emit(this.getModelName(modelName, _name(moduleId), type));
766
782
  } else if (ast.type === 'subModel') {
767
783
  const [moduleId, ...rest] = ast.path;
768
- this.emit('main_models.');
769
- this.emit(_subModelName([moduleId.lexeme, ...rest.map((item) => {
784
+ const modelName = _subModelName([moduleId.lexeme, ...rest.map((item) => {
770
785
  return item.lexeme;
771
- })].join('.')));
786
+ })].join('.'));
787
+ this.emit(this.getModelName(modelName));
772
788
  } else if (ast.type === 'moduleTypedef') {
773
789
  const [moduleId, ...rest] = ast.path;
774
790
  const type = rest.map((item) => { return item.lexeme; }).join('.');
@@ -784,9 +800,19 @@ setup(
784
800
  this.visitType(ast.valueType, level);
785
801
  this.emit(']');
786
802
  } else if (ast.type === 'model') {
787
- this.emit(this.getModelName(_upperFirst(_name(ast)), ast.moduleName));
803
+ const predefined = ast.moduleName ? this.usedExternException.get(ast.moduleName) : this.predefined;
804
+ let type = 'model';
805
+ if (predefined[_name(ast)] && predefined[_name(ast)].isException) {
806
+ type = 'exception';
807
+ }
808
+ this.emit(this.getModelName(_upperFirst(_name(ast)), ast.moduleName, type));
788
809
  } else if (ast.idType === 'model') {
789
- this.emit(this.getModelName(_upperFirst(_name(ast)), ast.moduleName));
810
+ const predefined = ast.moduleName ? this.usedExternException.get(ast.moduleName) : this.predefined;
811
+ let type = 'model';
812
+ if (predefined[_name(ast)] && predefined[_name(ast)].isException) {
813
+ type = 'exception';
814
+ }
815
+ this.emit(this.getModelName(_upperFirst(_name(ast)), ast.moduleName, type));
790
816
  } else if (ast.type === 'module') {
791
817
  this.emit(this.getModelName('', _name(ast), 'module'));
792
818
  } else if (ast.idType === 'module') {
@@ -895,10 +921,8 @@ setup(
895
921
 
896
922
  visitFieldType(value, level, modelName, fieldName) {
897
923
  if (value.type === 'modelBody') {
898
- if(this.exceptionsBody) {
899
- this.emit('main_models.');
900
- }
901
- this.emit(`${_subModelName([modelName, fieldName].join('.'))}`);
924
+ const subModelName = _subModelName([modelName, fieldName].join('.'))
925
+ this.emit(this.getModelName(subModelName));
902
926
  } else if (value.type === 'array') {
903
927
  this.visitType(value);
904
928
  } else if (value.fieldType === 'array') {
@@ -972,8 +996,9 @@ setup(
972
996
  this.pushImports(type);
973
997
  this.emit(`${type}`);
974
998
  } else if (value.fieldType.idType === 'model') {
999
+ const predefined = value.fieldType.moduleName ? this.usedExternException.get(value.fieldType.moduleName) : this.predefined;
975
1000
  let type = 'model';
976
- if (this.predefined[_name(type)] && this.predefined[_name(type)].isException) {
1001
+ if (predefined[_name(value.fieldType)] && predefined[_name(value.fieldType)].isException) {
977
1002
  type = 'exception';
978
1003
  }
979
1004
  this.emit(this.getModelName(_name(value.fieldType), value.fieldType.moduleName, type));
@@ -995,7 +1020,7 @@ setup(
995
1020
  node = ast.nodes[i];
996
1021
  let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]);
997
1022
  this.visitComments(comments, level);
998
- let param = _snakeCase(_escape(_name(node.fieldName)));
1023
+ let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName))));
999
1024
  const description = this.getAttributes(node, 'description');
1000
1025
  if (description) {
1001
1026
  const descriptions = description.trimEnd().split('\n');
@@ -1048,7 +1073,7 @@ setup(
1048
1073
  const minimum = this.getAttributes(node, 'minimum') || 0;
1049
1074
  let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]);
1050
1075
  this.visitComments(comments, level);
1051
- let param = _snakeCase(_escape(_name(node.fieldName)));
1076
+ let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName))));
1052
1077
  // 这里判断类中属性是否是必填
1053
1078
  if (node.required) {
1054
1079
  notPass = true;
@@ -1128,29 +1153,27 @@ setup(
1128
1153
  }
1129
1154
  }
1130
1155
 
1131
- visitToMapField(fieldValue, key, value, level) {
1156
+ visitToMapField(fieldValue, fieldName, key, value, level, arr = false) {
1132
1157
  const deep = Math.floor(level / 4);
1133
1158
  if (fieldValue.type === 'modelBody' || fieldValue.type === 'moduleModel' ||
1134
1159
  fieldValue.type === 'subModel' || fieldValue.idType === 'model' ||
1135
1160
  (fieldValue.fieldType && (fieldValue.fieldType.type === 'moduleModel' ||
1136
1161
  fieldValue.fieldType.idType === 'model' || fieldValue.fieldType.idType === 'builtin_model'))) {
1137
- this.emit(`${key} = ${value}.to_map()`, level);
1162
+ let realVal = `${value}.to_map()`;
1138
1163
  if(deep > 1) {
1139
- this.emit(` if ${value} else None\n`);
1164
+ realVal += ` if ${value} else None`;
1140
1165
  }
1141
- this.emit('\n');
1166
+ this.emitFieldConvert(key, realVal, level, arr);
1142
1167
  } else if (fieldValue.type === 'array' || fieldValue.fieldType === 'array') {
1143
- this.emit(`l${deep} = 0\n`, level);
1144
1168
  this.emit(`${key} = []\n`, level);
1145
1169
  this.emit(`for k${deep} in ${value}:\n`, level);
1146
- this.emit(`l${deep} += 1\n`, level + 2);
1147
- this.visitToMapField(fieldValue.fieldItemType || fieldValue.subType, `${key}[l${deep}]`, `k${deep}`, level + 2);
1170
+ this.visitToMapField(fieldValue.fieldItemType || fieldValue.subType, fieldName, `${key}`, `k${deep}`, level + 2, true);
1148
1171
  } else if (fieldValue.fieldType === 'map' || fieldValue.type === 'map') {
1149
1172
  this.emit(`${key} = {}\n`, level);
1150
- this.emit(`for k${deep}, v${deep} in k.items():\n`, level);
1151
- this.visitToMapField(fieldValue.valueType, `${key}[k${deep}]`, `v${deep}`, level + 2);
1173
+ this.emit(`for k${deep}, v${deep} in self.${fieldName}.items():\n`, level);
1174
+ this.visitToMapField(fieldValue.valueType, fieldName, `${key}[k${deep}]`, `v${deep}`, level + 2);
1152
1175
  } else {
1153
- this.emit(`${key} = ${value}\n`, level);
1176
+ this.emitFieldConvert(key, value, level, arr);
1154
1177
  }
1155
1178
 
1156
1179
  }
@@ -1167,12 +1190,12 @@ setup(
1167
1190
  let realName = this.getRealName(node);
1168
1191
  let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]);
1169
1192
  this.visitComments(comments, level);
1170
- let param = _snakeCase(_escape(_name(node.fieldName)));
1193
+ let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName))));
1171
1194
  this.emit(`if self.${param} is not None:\n`, level + 2);
1172
1195
  if(!this.checkFieldHasModel(node.fieldValue)) {
1173
1196
  this.emit(`result['${realName}'] = self.${param}`, level + 4);
1174
1197
  } else {
1175
- this.visitToMapField(node.fieldValue, `result['${realName}']`, `self.${param}`, level + 4);
1198
+ this.visitToMapField(node.fieldValue, param, `result['${realName}']`, `self.${param}`, level + 4);
1176
1199
  }
1177
1200
  this.emit('\n');
1178
1201
  }
@@ -1180,18 +1203,25 @@ setup(
1180
1203
  this.emit('\n');
1181
1204
  }
1182
1205
 
1183
- visitFromField(fieldValue, fieldName, key, value, level) {
1206
+ emitFieldConvert(key, value, level, arr) {
1207
+ if(arr) {
1208
+ this.emit(`${key}.append(${value})\n`, level);
1209
+ return;
1210
+ }
1211
+ this.emit(`${key} = ${value}\n`, level);
1212
+ }
1213
+
1214
+ visitFromField(fieldValue, fieldName, key, value, level, arr = false) {
1184
1215
  const deep = Math.floor(level / 4);
1185
1216
  if (fieldValue.type === 'modelBody') {
1186
- const subModelName = _subModelName(fieldName);
1187
- this.emit(`temp_model = ${subModelName}\n`, level);
1188
- this.emit(`${key} = temp_model.from_map(${value})\n`, level);
1217
+ const subModelName = _subModelName(_camelCase(fieldName));
1218
+ this.emit(`temp_model = ${this.getModelName(subModelName)}()\n`, level);
1219
+ this.emitFieldConvert(key, `temp_model.from_map(${value})`, level, arr);
1189
1220
  } else if (fieldValue.type === 'array' || fieldValue.fieldType === 'array') {
1190
1221
  this.emit(`l${deep} = 0\n`, level);
1191
1222
  this.emit(`${key} = []\n`, level);
1192
1223
  this.emit(`for k${deep} in ${value}:\n`, level);
1193
- this.emit(`l${deep} += 1\n`, level + 2);
1194
- this.visitFromField(fieldValue.fieldItemType || fieldValue.subType, fieldName, `${key}[l${deep}]`, `k${deep}`, level + 2);
1224
+ this.visitFromField(fieldValue.fieldItemType || fieldValue.subType, fieldName, `${key}`, `k${deep}`, level + 2, true);
1195
1225
  } else if (fieldValue.fieldType === 'map' || fieldValue.type === 'map') {
1196
1226
  this.emit(`${key} = {}\n`, level);
1197
1227
  this.emit(`for k${deep}, v${deep} in ${value}.items():\n`, level);
@@ -1202,25 +1232,30 @@ setup(
1202
1232
  const modelName = _subModelName(rest.map((item) => {
1203
1233
  return item.lexeme;
1204
1234
  }).join('.'));
1205
- this.emit(`${key} = ${this.getModelName(modelName, _name(moduleId), 'module')}.from_map(${value})\n`, level);
1235
+ this.emit(`temp_model = ${this.getModelName(modelName, _name(moduleId))}()\n`, level);
1236
+ this.emitFieldConvert(key, `temp_model.from_map(${value})`, level, arr);
1206
1237
  } else if (fieldValue.type === 'subModel') {
1207
1238
  const [moduleId, ...rest] = fieldValue.path;
1208
1239
  const subModelName = _subModelName([moduleId.lexeme, ...rest.map((item) => {
1209
1240
  return item.lexeme;
1210
1241
  })].join('.'));
1211
- this.emit(`${key} = ${subModelName}.from_map(${value})\n`, level);
1242
+ this.emit(`temp_model = ${this.getModelName(subModelName)}()\n`, level);
1243
+ this.emitFieldConvert(key, `temp_model.from_map(${value})`, level, arr);
1212
1244
  } else if (fieldValue.idType === 'model') {
1213
1245
  const modelName = _type(_name(fieldValue));
1214
- this.emit(`${key} = ${modelName}.from_map(${value})\n`, level);
1246
+ this.emit(`temp_model = ${this.getModelName(modelName)}()\n`, level);
1247
+ this.emitFieldConvert(key, `temp_model.from_map(${value})`, level, arr);
1215
1248
  } else if (fieldValue.fieldType && fieldValue.fieldType.idType === 'model') {
1216
1249
  const modelName = _type(_name(fieldValue.fieldType));
1217
- this.emit(`${key} = ${modelName}.from_map(${value})\n`, level);
1250
+ this.emit(`temp_model = ${this.getModelName(modelName)}()\n`, level);
1251
+ this.emitFieldConvert(key, `temp_model.from_map(${value})`, level, arr);
1218
1252
  } else if (fieldValue.fieldType && fieldValue.fieldType.idType === 'builtin_model') {
1219
1253
  const typeName = _type(_name(fieldValue.fieldType));
1220
1254
  this.pushImports(typeName);
1221
- this.emit(`${key} = ${typeName}.from_map(${value})\n`, level);
1255
+ this.emit(`temp_model = ${typeName}()\n`, level);
1256
+ this.emitFieldConvert(key, `temp_model.from_map(${value})`, level, arr);
1222
1257
  } else {
1223
- this.emit(`${key} = ${value}\n`, level);
1258
+ this.emitFieldConvert(key, value, level, arr);
1224
1259
  }
1225
1260
  }
1226
1261
 
@@ -1233,7 +1268,7 @@ setup(
1233
1268
  let realName = this.getRealName(node);
1234
1269
  let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]);
1235
1270
  this.visitComments(comments, level);
1236
- let param = _snakeCase(_escape(_name(node.fieldName)));
1271
+ let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName))));
1237
1272
  this.emit(`if m.get('${realName}') is not None:\n`, level + 2);
1238
1273
  if(!this.checkFieldHasModel(node.fieldValue)) {
1239
1274
  this.emit(`self.${param} = m.get('${realName}')`, level + 4);
@@ -1323,40 +1358,13 @@ setup(
1323
1358
  this.emit(`(${this.getModelName(modelName, moduleName, type)}`);
1324
1359
  } else if (extendOn.type === 'subModel') {
1325
1360
  const [moduleId, ...rest] = extendOn.path;
1326
- if (type === 'exception') {
1327
- needBaseException = true;
1328
- const modelPkgName = path.basename(this.modelPath, '.py');
1329
- this.imports.push({
1330
- className: modelPkgName,
1331
- });
1332
- this.emit(`${modelPkgName}.`);
1333
- }
1334
- this.emit(`(${_subModelName([moduleId.lexeme, ...rest.map((item) => {
1361
+ const subModelName = _subModelName([moduleId.lexeme, ...rest.map((item) => {
1335
1362
  return item.lexeme;
1336
- })].join('.'))}`);
1363
+ })].join('.'));
1364
+ this.emit(`(${this.emit(this.getModelName(subModelName, '', type))}`);
1337
1365
  } else {
1338
- let modelName = _upperFirst(_name(extendOn));
1339
1366
  this.emit('(');
1340
- if(extendOn.moduleName){
1341
- this.getModelName(_upperFirst(_name(extendOn)), extendOn.moduleName, type);
1342
- } else if (this.predefined[modelName] && this.predefined[modelName].isException && type === 'model') {
1343
- const exPkgName = path.basename(this.exceptionPath, '.py');
1344
- this.imports.push({
1345
- className: exPkgName,
1346
- });
1347
- this.emit(`${exPkgName}.`);
1348
- } else if (this.predefined[modelName] && !this.predefined[modelName].isException && type === 'exception') {
1349
- needBaseException = true;
1350
- const modelPkgName = path.basename(this.modelPath, '.py');
1351
- this.imports.push({
1352
- className: modelPkgName,
1353
- });
1354
- this.emit(`${modelPkgName}.`);
1355
- }
1356
- this.emit(`${modelName}`);
1357
- if(type === 'exception' && !needBaseException) {
1358
- this.emit('Exception');
1359
- }
1367
+ this.emit(this.getModelName(_upperFirst(_name(extendOn)), extendOn.moduleName, type));
1360
1368
  }
1361
1369
  if(needBaseException) {
1362
1370
  this.emit(`, ${CORE}Exception`);
@@ -1391,6 +1399,37 @@ setup(
1391
1399
  this.visitExtendOn(extendOn);
1392
1400
  this.emit(':\n');
1393
1401
  this.visitModelBody(modelBody, level + 2, modelName);
1402
+ this.saveBuffer(path.join(this.modelPath, `_${_snakeCase(modelName)}.py`));
1403
+ this.usedTypes = [];
1404
+ this.imports = [];
1405
+ this.output = '';
1406
+ }
1407
+
1408
+ saveBuffer(filepath) {
1409
+ if(this.fileBuffer[filepath]) {
1410
+ this.fileBuffer[filepath].imports = this.imports.concat(this.fileBuffer[filepath].imports);
1411
+ this.fileBuffer[filepath].usedTypes = this.usedTypes.concat(this.fileBuffer[filepath].usedTypes);
1412
+ this.fileBuffer[filepath].output = this.output + this.fileBuffer[filepath].output;
1413
+ return;
1414
+ }
1415
+
1416
+ this.fileBuffer[filepath] = {
1417
+ imports: this.imports,
1418
+ usedTypes: this.usedTypes,
1419
+ output: this.output,
1420
+ };
1421
+ }
1422
+
1423
+ flushBuffer() {
1424
+ Object.keys(this.fileBuffer).map(filepath => {
1425
+ this.output = this.fileBuffer[filepath].output;
1426
+ this.imports = this.fileBuffer[filepath].imports;
1427
+ this.usedTypes = this.fileBuffer[filepath].usedTypes;
1428
+ this.save(filepath);
1429
+ this.output = '';
1430
+ this.imports = [];
1431
+ this.usedTypes = [];
1432
+ });
1394
1433
  }
1395
1434
 
1396
1435
  eachModel(ast, level) {
@@ -1402,6 +1441,29 @@ setup(
1402
1441
  this.visitModel(ast.modelBody, modelName, ast.extendOn, level);
1403
1442
  }
1404
1443
 
1444
+ visitModelInit(models) {
1445
+ const modelNames = [];
1446
+ const moreExports = this.moreExports || [];
1447
+ for (let i = 0; i < models.length; i++) {
1448
+ const ast = models[i];
1449
+ const modelName = _subModelName(_name(ast.modelName));
1450
+ modelNames.push(modelName);
1451
+ this.emit(`from ._${_snakeCase(modelName)} import ${modelName}\n`);
1452
+ }
1453
+
1454
+ this.emit('\n__all__ = [\n');
1455
+ this.emit(modelNames.join(',\n '), 2);
1456
+ if(moreExports && moreExports.length > 0) {
1457
+ this.emit((',\n'));
1458
+ this.emit(moreExports.join(',\n '), 2);
1459
+ }
1460
+
1461
+ this.emit('\n]\n');
1462
+
1463
+ this.save(path.join(this.modelPath, '__init__.py'));
1464
+ this.moreExports = [];
1465
+ }
1466
+
1405
1467
  visitFieldsInit(ast, level, modelName, type = 'model', baseErr = false){
1406
1468
  let node;
1407
1469
  this.emit(' def __init__(');
@@ -1412,14 +1474,14 @@ setup(
1412
1474
  return;
1413
1475
  }
1414
1476
  this.emit('\n');
1415
- this.emit('self, \n', level + 2);
1477
+ this.emit('self, *,\n', level + 2);
1416
1478
  for (let i = 0; i < paramNodes.length; i++) {
1417
1479
  node = paramNodes[i];
1418
1480
  if(!node.extend) {
1419
1481
  let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]);
1420
1482
  this.visitComments(comments, level);
1421
1483
  }
1422
- let param = _snakeCase(_escape(_name(node.fieldName)));
1484
+ let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName))));
1423
1485
  if(param === 'name' && type === 'exception') {
1424
1486
  continue;
1425
1487
  }
@@ -1436,7 +1498,7 @@ setup(
1436
1498
  for (let i = 0; i < ast.extendFileds.length; i++) {
1437
1499
  node = ast.extendFileds[i];
1438
1500
  let value = _snakeCase(_escape(_name(node.fieldName)));
1439
- let key = _escape(_name(node.fieldName));
1501
+ let key = _avoidKeywords(_escape(_name(node.fieldName)));
1440
1502
  if(key === 'name' && type === 'exception') {
1441
1503
  continue;
1442
1504
  }
@@ -1447,7 +1509,7 @@ setup(
1447
1509
  this.emit('\n');
1448
1510
  for (let i = 0; i < ast.extendFileds.length; i++) {
1449
1511
  node = ast.extendFileds[i];
1450
- let param = _snakeCase(_escape(_name(node.fieldName)));
1512
+ let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName))));
1451
1513
  if(param === 'name' && type === 'exception') {
1452
1514
  continue;
1453
1515
  }
@@ -1468,7 +1530,7 @@ setup(
1468
1530
  node = ast.nodes[i];
1469
1531
  let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]);
1470
1532
  this.visitComments(comments, level);
1471
- let param = _snakeCase(_escape(_name(node.fieldName)));
1533
+ let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName))));
1472
1534
  if(param === 'name') {
1473
1535
  continue;
1474
1536
  }
@@ -1493,6 +1555,10 @@ setup(
1493
1555
  this.visitExtendOn(extendOn, 'exception');
1494
1556
  this.emit(':\n');
1495
1557
  this.visitEcxceptionBody(exceptionBody, extendOn, exceptionName, level + 2);
1558
+ this.saveBuffer(path.join(this.exceptionPath, `_${_snakeCase(exceptionName)}.py`));
1559
+ this.usedTypes = [];
1560
+ this.imports = [];
1561
+ this.output = '';
1496
1562
  }
1497
1563
 
1498
1564
  eachException(ast, level) {
@@ -1504,6 +1570,22 @@ setup(
1504
1570
  this.visitException(ast.exceptionBody, exceptionName, ast.extendOn, level);
1505
1571
  }
1506
1572
 
1573
+ visitExceptionInit(excpetions) {
1574
+ const exceptionNames = [];
1575
+ for (let i = 0; i < excpetions.length; i++) {
1576
+ const ast = excpetions[i];
1577
+ const exceptionName = _subModelName(_name(ast.exceptionName));
1578
+ exceptionNames.push(exceptionName);
1579
+ this.emit(`from ._${_snakeCase(exceptionName)} import ${exceptionName}Exception\n`);
1580
+ }
1581
+
1582
+ this.emit('\n__all__ = [\n');
1583
+ this.emit(exceptionNames.join('Exception,\n '), 2);
1584
+ this.emit('Exception\n]\n');
1585
+
1586
+ this.save(path.join(this.exceptionPath, '__init__.py'));
1587
+ }
1588
+
1507
1589
  eachSubModel(ast, level) {
1508
1590
  assert.equal(ast.type, 'model');
1509
1591
  const modelName = _subModelName(_name(ast.modelName));
@@ -1538,7 +1620,7 @@ setup(
1538
1620
  if (ast.type === 'objectField') {
1539
1621
  // TODO 这里粗暴处理的双引号,可以考虑优化
1540
1622
  var key = _escape(_name(ast.fieldName) || _string(ast.fieldName)).replace(/['"]/g, '');
1541
- this.emit(`${_snakeCase(key)} = `, level + 2);
1623
+ this.emit(`${_avoidKeywords(_snakeCase(key))} = `, level + 2);
1542
1624
  this.visitObjectFieldValue(ast.expr, level + 2);
1543
1625
  if (!end) {
1544
1626
  this.emit(',\n');
@@ -1605,7 +1687,7 @@ setup(
1605
1687
  visitMethodCall(ast, level) {
1606
1688
  assert.equal(ast.left.type, 'method_call');
1607
1689
  const name = _name(ast.left.id);
1608
- const functionName = _snakeCase(name);
1690
+ const functionName = _avoidKeywords(_snakeCase(name));
1609
1691
  if (name.startsWith('$') && this.builtin[name]) {
1610
1692
  const method = name.replace('$', '');
1611
1693
  this.builtin[name][method](ast, level, ast.isAsync && this.isAsyncFunction);
@@ -1640,7 +1722,7 @@ setup(
1640
1722
  const aliasId = _snakeCase(_name(ast.left.id));
1641
1723
  this.emit(aliasId);
1642
1724
  }
1643
- this.emit(`.${(_snakeCase(method))}`);
1725
+ this.emit(`.${(_avoidKeywords(_snakeCase(method)))}`);
1644
1726
  if(async) {
1645
1727
  this.emit('_async');
1646
1728
  }
@@ -1659,7 +1741,7 @@ setup(
1659
1741
  const aliasId = _name(ast.left.id);
1660
1742
  let clientName = this.getModelName('', aliasId, 'module');
1661
1743
 
1662
- const functionName = _snakeCase(_name(ast.left.propertyPath[0]));
1744
+ const functionName = _avoidKeywords(_snakeCase(_name(ast.left.propertyPath[0])));
1663
1745
 
1664
1746
  if (ast.isAsync && this.isAsyncFunction) {
1665
1747
  this.emit(`await ${clientName}.${functionName}_async`);
@@ -1740,7 +1822,7 @@ setup(
1740
1822
  if (ast.id.tag === Tag.VID) {
1741
1823
  id = `self.${_snakeCase(_vid(ast.id))}`;
1742
1824
  }
1743
- var expr = avoidReserveName(id);
1825
+ var expr = _avoidKeywords(id);
1744
1826
  const prefix = env.left ? '[' : '.get(';
1745
1827
  const suffix = env.left ? ']' : ')';
1746
1828
  var current = ast.id.inferred;
@@ -1748,7 +1830,7 @@ setup(
1748
1830
  for (var i = 0; i < ast.propertyPath.length; i++) {
1749
1831
  var name = _name(ast.propertyPath[i]);
1750
1832
  if (current.type === 'model') {
1751
- expr += `.${_snakeCase(name)}`;
1833
+ expr += `.${_avoidKeywords(_snakeCase(name))}`;
1752
1834
  } else {
1753
1835
  expr += `${prefix}"${name}"${suffix}`;
1754
1836
  }
@@ -1774,7 +1856,7 @@ setup(
1774
1856
  if(ast.inferred && ast.inferred.type === 'basic' && ast.inferred.name === 'class') {
1775
1857
  this.emit(this.getModelName('', _name(ast.id), 'module'));
1776
1858
  } else {
1777
- this.emit(avoidReserveName(_snakeCase(_name(ast.id))));
1859
+ this.emit(_avoidKeywords(_snakeCase(_name(ast.id))));
1778
1860
  }
1779
1861
  } else if (ast.type === 'virtualVariable') {
1780
1862
  this.emit(`self.${_snakeCase(_vid(ast.vid))}`);
@@ -1916,7 +1998,7 @@ setup(
1916
1998
  if (ast.id.tag === DSL.Tag.Tag.VID) {
1917
1999
  expr = `self.${_snakeCase(_vid(ast.id))}`;
1918
2000
  } else {
1919
- expr = `${_snakeCase(_name(ast.id))}`;
2001
+ expr = `${_avoidKeywords(_snakeCase(_name(ast.id)))}`;
1920
2002
  }
1921
2003
  const prefix = env.left ? '[' : '.get(';
1922
2004
  const suffix = env.left ? ']' : ')';
@@ -1925,7 +2007,7 @@ setup(
1925
2007
  for (var i = 0; i < ast.propertyPath.length; i++) {
1926
2008
  var name = _name(ast.propertyPath[i]);
1927
2009
  if (current.type === 'model') {
1928
- expr += `.${_snakeCase(name)}`;
2010
+ expr += `.${_avoidKeywords(_snakeCase(name))}`;
1929
2011
  } else {
1930
2012
  expr += `${prefix}"${name}"${suffix}`;
1931
2013
  }
@@ -1944,14 +2026,14 @@ setup(
1944
2026
  // 这个判断很奇怪诶
1945
2027
  expr = `self.${_snakeCase(_vid(ast.id))}`;
1946
2028
  } else {
1947
- expr = `${_snakeCase(_name(ast.id))}`;
2029
+ expr = `${_avoidKeywords(_snakeCase(_name(ast.id)))}`;
1948
2030
  }
1949
2031
  if (ast.propertyPath && ast.propertyPath.length) {
1950
2032
  var current = ast.id.inferred;
1951
2033
  for (var i = 0; i < ast.propertyPath.length; i++) {
1952
2034
  var name = _name(ast.propertyPath[i]);
1953
2035
  if (current.type === 'model') {
1954
- expr += `.${_snakeCase(name)}`;
2036
+ expr += `.${_avoidKeywords(_snakeCase(name))}`;
1955
2037
  } else {
1956
2038
  expr += `["${name}"]`;
1957
2039
  }
@@ -2068,16 +2150,16 @@ setup(
2068
2150
  return;
2069
2151
  }
2070
2152
  if (!catchBlock.id.type) {
2071
- this.emit(`except Exception as ${_name(ast.catchId)} :\n`, level);
2153
+ this.emit(`except Exception as ${_avoidKeywords(_name(ast.catchId))} :\n`, level);
2072
2154
  } else {
2073
2155
  this.emit('except ', level);
2074
2156
  this.visitType(catchBlock.id.type);
2075
- this.emit(` as ${_name(ast.catchId)} :\n`);
2157
+ this.emit(` as ${_avoidKeywords(_name(ast.catchId))} :\n`);
2076
2158
  }
2077
2159
  this.visitStmts(catchBlock.catchStmts, level + 2);
2078
2160
  });
2079
2161
  } else if (ast.catchBlock && ast.catchBlock.stmts.length > 0) {
2080
- this.emit(`except Exception as ${_name(ast.catchId)} :\n`, level);
2162
+ this.emit(`except Exception as ${_avoidKeywords(_name(ast.catchId))} :\n`, level);
2081
2163
  this.visitStmts(ast.catchBlock, level + 2);
2082
2164
  }
2083
2165
  if (ast.finallyBlock && ast.finallyBlock.stmts.length > 0) {
@@ -2109,7 +2191,7 @@ setup(
2109
2191
  this.emit('k, v in ');
2110
2192
  this.visitExpr(ast.list, level);
2111
2193
  } else {
2112
- this.emit(`${_snakeCase(_name(ast.id))} in `);
2194
+ this.emit(`${_avoidKeywords(_snakeCase(_name(ast.id)))} in `);
2113
2195
  this.visitExpr(ast.list, level);
2114
2196
  }
2115
2197
  this.emit(':\n');
@@ -2167,7 +2249,7 @@ setup(
2167
2249
  } else if (ast.left.type === 'virtualVariable') { // vid
2168
2250
  this.emit(`self.${_snakeCase(_vid((ast.left.vid)))}`, level);
2169
2251
  } else if (ast.left.type === 'variable') {
2170
- this.emit(`${_snakeCase(_name(ast.left.id))}`, level);
2252
+ this.emit(`${_avoidKeywords(_snakeCase(_name(ast.left.id)))}`, level);
2171
2253
  } else if (ast.left.type === 'map_access') {
2172
2254
  // 声明时不能用get去赋值
2173
2255
  this.emit('', level);
@@ -2192,7 +2274,7 @@ setup(
2192
2274
 
2193
2275
  // 实例初始化 new的地方
2194
2276
  visitDeclare(ast, level) {
2195
- var id = _snakeCase(_name(ast.id));
2277
+ var id = _avoidKeywords(_snakeCase(_name(ast.id)));
2196
2278
  this.emit(`${id}`, level);
2197
2279
  if(id === 'new_full_str'){
2198
2280
  this.emit('');
@@ -2258,7 +2340,7 @@ setup(
2258
2340
  // this.visitAnnotation(ast.annotation, level);
2259
2341
  // let comments = DSL.comment.getFrontComments(this.comments, ast.tokenRange[0]);
2260
2342
  // this.visitComments(comments, level);
2261
- const functionName = _snakeCase(_name(ast.functionName));
2343
+ const functionName = _avoidKeywords(_snakeCase(_name(ast.functionName)));
2262
2344
 
2263
2345
  if (ast.isStatic) {
2264
2346
  this.emit('@staticmethod\n', level);
@@ -2335,7 +2417,7 @@ setup(
2335
2417
  let comments = DSL.comment.getFrontComments(this.comments, ast.tokenRange[0]);
2336
2418
  this.visitComments(comments, level);
2337
2419
  // set api name to _snakeCase
2338
- const apiName = _snakeCase(_name(ast.apiName));
2420
+ const apiName = _avoidKeywords(_snakeCase(_name(ast.apiName)));
2339
2421
  this.isStaticFunction = false;
2340
2422
  this.emit(`def ${apiName}`, level);
2341
2423
  this.visitParams(ast.params, level, true);
@@ -2460,7 +2542,7 @@ setup(
2460
2542
  this.output = tempOutput + '\n\n' + this.output;
2461
2543
  }
2462
2544
 
2463
- modelBefore(ast, level) {
2545
+ modelInitBefore(ast, level) {
2464
2546
  let beginToken = 0;
2465
2547
  if(ast.imports.length > 0) {
2466
2548
  const lastIndex = ast.imports.length - 1;
@@ -2475,6 +2557,20 @@ setup(
2475
2557
  if(part && part.arg.value) {
2476
2558
  this.emit(_string(part.arg.value));
2477
2559
  }
2560
+
2561
+ if(part && part.arg.type === 'object') {
2562
+ part.arg.fields.map(field => {
2563
+ if(_name(field.fieldName) === 'header') {
2564
+ this.emit(_string(field.expr.value));
2565
+ }
2566
+
2567
+ if(_name(field.fieldName) === 'exports') {
2568
+ this.moreExports = field.expr.items.map(item => {
2569
+ return _string(item.value);
2570
+ });
2571
+ }
2572
+ });
2573
+ }
2478
2574
  }
2479
2575
 
2480
2576
  moduleBefore(ast, level) {
@@ -2604,7 +2700,7 @@ setup(
2604
2700
  this.imports.push({
2605
2701
  aliasName,
2606
2702
  packageName: this.config.package,
2607
- className: 'models',
2703
+ className: this.modelPackage,
2608
2704
  });
2609
2705
  return `${aliasName}.${name}`;
2610
2706
  }
@@ -2625,7 +2721,7 @@ setup(
2625
2721
  this.imports.push({
2626
2722
  aliasName,
2627
2723
  packageName: this.config.package,
2628
- className: 'exceptions',
2724
+ className: this.exceptionPackage,
2629
2725
  });
2630
2726
  return `${aliasName}.${name}Exception`;
2631
2727
  }