@lcap/nasl 3.8.2-beta.9 → 3.8.3-beta.2

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 (233) hide show
  1. package/ai-engineer.config.js +617 -0
  2. package/out/common/BaseNode.d.ts +9 -4
  3. package/out/common/BaseNode.js +43 -10
  4. package/out/common/BaseNode.js.map +1 -1
  5. package/out/concepts/AuthLogicForCallInterface__.js +2 -50
  6. package/out/concepts/AuthLogicForCallInterface__.js.map +1 -1
  7. package/out/concepts/BackendVariable__.js +16 -1
  8. package/out/concepts/BackendVariable__.js.map +1 -1
  9. package/out/concepts/BindAttribute__.js +12 -4
  10. package/out/concepts/BindAttribute__.js.map +1 -1
  11. package/out/concepts/BindDirective__.js +1 -1
  12. package/out/concepts/BindDirective__.js.map +1 -1
  13. package/out/concepts/BindStyle__.js +1 -1
  14. package/out/concepts/BindStyle__.js.map +1 -1
  15. package/out/concepts/BusinessComponent__.js +2 -42
  16. package/out/concepts/BusinessComponent__.js.map +1 -1
  17. package/out/concepts/BusinessLogic__.js +2 -50
  18. package/out/concepts/BusinessLogic__.js.map +1 -1
  19. package/out/concepts/CallFunction__.d.ts +1 -1
  20. package/out/concepts/CallFunction__.js +1 -1
  21. package/out/concepts/CallLogic__.js +7 -1
  22. package/out/concepts/CallLogic__.js.map +1 -1
  23. package/out/concepts/CallQueryComponent__.d.ts +1 -0
  24. package/out/concepts/CallQueryComponent__.js +23 -12
  25. package/out/concepts/CallQueryComponent__.js.map +1 -1
  26. package/out/concepts/Destination__.js +11 -8
  27. package/out/concepts/Destination__.js.map +1 -1
  28. package/out/concepts/EntityProperty__.js +3 -2
  29. package/out/concepts/EntityProperty__.js.map +1 -1
  30. package/out/concepts/Entity__.js +1 -1
  31. package/out/concepts/Entity__.js.map +1 -1
  32. package/out/concepts/Identifier__.d.ts +2 -0
  33. package/out/concepts/Identifier__.js +51 -5
  34. package/out/concepts/Identifier__.js.map +1 -1
  35. package/out/concepts/Interface__.js +1 -1
  36. package/out/concepts/Interface__.js.map +1 -1
  37. package/out/concepts/Logic__.js +33 -111
  38. package/out/concepts/Logic__.js.map +1 -1
  39. package/out/concepts/MemberExpression__.d.ts +1 -1
  40. package/out/concepts/MemberExpression__.js +15 -3
  41. package/out/concepts/MemberExpression__.js.map +1 -1
  42. package/out/concepts/OqlQueryComponent__.js +37 -12
  43. package/out/concepts/OqlQueryComponent__.js.map +1 -1
  44. package/out/concepts/OverriddenLogic__.js +2 -50
  45. package/out/concepts/OverriddenLogic__.js.map +1 -1
  46. package/out/concepts/Param__.js +5 -4
  47. package/out/concepts/Param__.js.map +1 -1
  48. package/out/concepts/ProcessElementV2__.js +4 -0
  49. package/out/concepts/ProcessElementV2__.js.map +1 -1
  50. package/out/concepts/ProcessElement__.js +4 -0
  51. package/out/concepts/ProcessElement__.js.map +1 -1
  52. package/out/concepts/ProcessV2__.js +4 -0
  53. package/out/concepts/ProcessV2__.js.map +1 -1
  54. package/out/concepts/Process__.js +4 -0
  55. package/out/concepts/Process__.js.map +1 -1
  56. package/out/concepts/QueryOrderByExpression__.d.ts +0 -1
  57. package/out/concepts/QueryOrderByExpression__.js +0 -1
  58. package/out/concepts/QueryOrderByExpression__.js.map +1 -1
  59. package/out/concepts/Structure__.js +5 -7
  60. package/out/concepts/Structure__.js.map +1 -1
  61. package/out/concepts/SubLogic__.js +5 -50
  62. package/out/concepts/SubLogic__.js.map +1 -1
  63. package/out/concepts/Variable__.js +5 -0
  64. package/out/concepts/Variable__.js.map +1 -1
  65. package/out/concepts/ViewElement__.d.ts +1 -0
  66. package/out/concepts/ViewElement__.js +16 -6
  67. package/out/concepts/ViewElement__.js.map +1 -1
  68. package/out/concepts/View__.js +48 -49
  69. package/out/concepts/View__.js.map +1 -1
  70. package/out/natural/genNaturalTS.d.ts +45 -10
  71. package/out/natural/genNaturalTS.js +57 -33
  72. package/out/natural/genNaturalTS.js.map +1 -1
  73. package/out/natural/getContext/getUILib.js +6 -3
  74. package/out/natural/getContext/getUILib.js.map +1 -1
  75. package/out/natural/getContext/index.d.ts +20 -7
  76. package/out/natural/getContext/index.js +143 -23
  77. package/out/natural/getContext/index.js.map +1 -1
  78. package/out/natural/getContext/naslStdlibMap.js +8 -8
  79. package/out/natural/getContext/naslStdlibMap.js.map +1 -1
  80. package/out/natural/tools.d.ts +16 -0
  81. package/out/natural/tools.js +110 -2
  82. package/out/natural/tools.js.map +1 -1
  83. package/out/natural/transformTS2UI.js +343 -292
  84. package/out/natural/transformTS2UI.js.map +1 -1
  85. package/out/natural/transformTSCode.d.ts +3 -5
  86. package/out/natural/transformTSCode.js +30 -1089
  87. package/out/natural/transformTSCode.js.map +1 -1
  88. package/out/natural/transforms/registerTransform.d.ts +7 -0
  89. package/out/natural/transforms/registerTransform.js +24 -0
  90. package/out/natural/transforms/registerTransform.js.map +1 -0
  91. package/out/natural/transforms/transform2LogicItem.d.ts +24 -0
  92. package/out/natural/transforms/transform2LogicItem.js +1240 -0
  93. package/out/natural/transforms/transform2LogicItem.js.map +1 -0
  94. package/out/natural/transforms/transform2TypeAnnotation.d.ts +2 -0
  95. package/out/natural/transforms/transform2TypeAnnotation.js +86 -0
  96. package/out/natural/transforms/transform2TypeAnnotation.js.map +1 -0
  97. package/out/natural/transforms/utils.d.ts +8 -0
  98. package/out/natural/transforms/utils.js +59 -0
  99. package/out/natural/transforms/utils.js.map +1 -0
  100. package/out/server/getLogics.js +12 -12
  101. package/out/server/getLogics.js.map +1 -1
  102. package/out/server/naslServer.d.ts +2 -2
  103. package/out/server/naslServer.js +48 -18
  104. package/out/server/naslServer.js.map +1 -1
  105. package/out/server/semanticData.d.ts +32 -0
  106. package/out/server/semanticData.js +371 -0
  107. package/out/server/semanticData.js.map +1 -0
  108. package/out/server/translator.js +5 -0
  109. package/out/server/translator.js.map +1 -1
  110. package/out/templator/block2nasl/jsx2nasl/index.d.ts +5 -0
  111. package/out/templator/block2nasl/jsx2nasl/index.js +15 -0
  112. package/out/templator/block2nasl/jsx2nasl/index.js.map +1 -0
  113. package/out/templator/block2nasl/jsx2nasl/transform-expression2nasl.d.ts +3 -0
  114. package/out/templator/block2nasl/jsx2nasl/transform-expression2nasl.js +213 -0
  115. package/out/templator/block2nasl/jsx2nasl/transform-expression2nasl.js.map +1 -0
  116. package/out/templator/block2nasl/jsx2nasl/transform-func2nasl.d.ts +14 -0
  117. package/out/templator/block2nasl/jsx2nasl/transform-func2nasl.js +201 -0
  118. package/out/templator/block2nasl/jsx2nasl/transform-func2nasl.js.map +1 -0
  119. package/out/templator/block2nasl/jsx2nasl/transform-tstype2nasl.d.ts +4 -0
  120. package/out/templator/block2nasl/jsx2nasl/transform-tstype2nasl.js +186 -0
  121. package/out/templator/block2nasl/jsx2nasl/transform-tstype2nasl.js.map +1 -0
  122. package/out/templator/block2nasl/jsx2nasl/transform-tsx2nasl.d.ts +28 -0
  123. package/out/templator/block2nasl/jsx2nasl/transform-tsx2nasl.js +336 -0
  124. package/out/templator/block2nasl/jsx2nasl/transform-tsx2nasl.js.map +1 -0
  125. package/out/templator/block2nasl/jsx2nasl/utils.d.ts +2 -0
  126. package/out/templator/block2nasl/jsx2nasl/utils.js +26 -0
  127. package/out/templator/block2nasl/jsx2nasl/utils.js.map +1 -0
  128. package/out/templator/block2nasl/transformBlock2Nasl.d.ts +10 -0
  129. package/out/templator/block2nasl/transformBlock2Nasl.js +122 -0
  130. package/out/templator/block2nasl/transformBlock2Nasl.js.map +1 -0
  131. package/out/templator/block2nasl/viewMergeBlock.d.ts +9 -0
  132. package/out/templator/block2nasl/viewMergeBlock.js +111 -0
  133. package/out/templator/block2nasl/viewMergeBlock.js.map +1 -0
  134. package/out/translator/types.d.ts +2 -0
  135. package/out/translator/utils.js +1 -1
  136. package/out/translator/utils.js.map +1 -1
  137. package/out/utils/index.js +0 -4
  138. package/out/utils/index.js.map +1 -1
  139. package/out/utils/language-cache/constant.d.ts +2 -1
  140. package/out/utils/language-cache/constant.js +1 -0
  141. package/out/utils/language-cache/constant.js.map +1 -1
  142. package/out/utils/language-cache/nasl.d.ts +1 -0
  143. package/out/utils/language-cache/nasl.js +9 -1
  144. package/out/utils/language-cache/nasl.js.map +1 -1
  145. package/package.json +6 -2
  146. package/sandbox-natural/stdlib/nasl.core.d.ts +54 -0
  147. package/sandbox-natural/stdlib/nasl.oql.d.ts +22 -0
  148. package/sandbox-natural/stdlib/nasl.ui.d.ts +78 -0
  149. package/sandbox-natural/stdlib/nasl.ui.h5.d.ts +1684 -1643
  150. package/sandbox-natural/stdlib/nasl.ui.h5.json +15746 -15045
  151. package/sandbox-natural/stdlib/nasl.ui.pc.d.ts +5341 -5154
  152. package/sandbox-natural/stdlib/nasl.ui.pc.json +31176 -30681
  153. package/sandbox-natural/stdlib/{nasl.util.ts → nasl.util.d.ts} +49 -43
  154. package/src/common/BaseNode.ts +50 -8
  155. package/src/concepts/AuthLogicForCallInterface__.ts +3 -56
  156. package/src/concepts/BackendVariable__.ts +16 -1
  157. package/src/concepts/BindAttribute__.ts +18 -13
  158. package/src/concepts/BindDirective__.ts +1 -1
  159. package/src/concepts/BindStyle__.ts +1 -1
  160. package/src/concepts/BusinessComponent__.ts +6 -51
  161. package/src/concepts/BusinessLogic__.ts +4 -56
  162. package/src/concepts/CallFunction__.ts +1 -1
  163. package/src/concepts/CallLogic__.ts +21 -16
  164. package/src/concepts/CallQueryComponent__.ts +26 -12
  165. package/src/concepts/Destination__.ts +14 -12
  166. package/src/concepts/EntityProperty__.ts +5 -5
  167. package/src/concepts/Entity__.ts +1 -1
  168. package/src/concepts/Identifier__.ts +57 -6
  169. package/src/concepts/Interface__.ts +1 -1
  170. package/src/concepts/Logic__.ts +44 -134
  171. package/src/concepts/MemberExpression__.ts +21 -7
  172. package/src/concepts/OqlQueryComponent__.ts +29 -5
  173. package/src/concepts/OverriddenLogic__.ts +4 -56
  174. package/src/concepts/Param__.ts +5 -4
  175. package/src/concepts/ProcessElementV2__.ts +4 -0
  176. package/src/concepts/ProcessElement__.ts +4 -0
  177. package/src/concepts/ProcessV2__.ts +5 -0
  178. package/src/concepts/Process__.ts +4 -0
  179. package/src/concepts/QueryOrderByExpression__.ts +0 -1
  180. package/src/concepts/Structure__.ts +5 -7
  181. package/src/concepts/SubLogic__.ts +6 -56
  182. package/src/concepts/Variable__.ts +9 -5
  183. package/src/concepts/ViewElement__.ts +24 -7
  184. package/src/concepts/View__.ts +75 -76
  185. package/src/natural/genNaturalTS.ts +88 -39
  186. package/src/natural/getContext/getUILib.ts +6 -3
  187. package/src/natural/getContext/index.ts +125 -23
  188. package/src/natural/getContext/naslStdlibMap.ts +8 -8
  189. package/src/natural/tools.ts +107 -2
  190. package/src/natural/transformTS2UI.ts +190 -137
  191. package/src/natural/transformTSCode.ts +29 -1055
  192. package/src/natural/transforms/registerTransform.ts +34 -0
  193. package/src/natural/transforms/transform2LogicItem.ts +1335 -0
  194. package/src/natural/transforms/transform2TypeAnnotation.ts +77 -0
  195. package/src/natural/transforms/utils.ts +25 -0
  196. package/src/server/getLogics.ts +12 -12
  197. package/src/server/naslServer.ts +54 -19
  198. package/src/server/semanticData.ts +447 -0
  199. package/src/server/translator.ts +5 -0
  200. package/src/templator/block2nasl/jsx2nasl/index.ts +11 -0
  201. package/src/templator/block2nasl/jsx2nasl/transform-expression2nasl.ts +238 -0
  202. package/src/templator/block2nasl/jsx2nasl/transform-func2nasl.ts +241 -0
  203. package/src/templator/block2nasl/jsx2nasl/transform-tstype2nasl.ts +213 -0
  204. package/src/templator/block2nasl/jsx2nasl/transform-tsx2nasl.ts +422 -0
  205. package/src/templator/block2nasl/jsx2nasl/utils.ts +19 -0
  206. package/src/templator/block2nasl/transformBlock2Nasl.ts +99 -0
  207. package/src/templator/block2nasl/viewMergeBlock.ts +150 -0
  208. package/src/translator/types.ts +2 -0
  209. package/src/translator/utils.ts +2 -2
  210. package/src/utils/index.ts +0 -4
  211. package/src/utils/language-cache/constant.ts +1 -0
  212. package/src/utils/language-cache/nasl.ts +6 -0
  213. package/test/concepts/logic/__snapshots__/toEmbeddedTS.spec.ts.snap +182 -0
  214. package/test/concepts/logic/constant.ts +5 -0
  215. package/test/concepts/logic/fixtures/variable-host-call-logic-member-expression.json +267 -0
  216. package/test/concepts/logic/fixtures/variable-host-call-logic-nested-member-expression copy.json +457 -0
  217. package/test/concepts/logic/fixtures/variable-host-call-logic-with-handle-error-member-expression.json +267 -0
  218. package/test/concepts/logic/toEmbeddedTS.spec.ts +15 -0
  219. package/test/tdd/dataQuery/QueryFieldExpression/case1/ast.json +7 -0
  220. package/test/tdd/dataQuery/QueryFieldExpression/case1/natural.ts.txt +1 -0
  221. package/test/tdd/dataQuery/QueryFieldExpression/case2/ast.json +7 -0
  222. package/test/tdd/dataQuery/QueryFieldExpression/case2/natural.ts.txt +1 -0
  223. package/test/tdd/transform/case1/ast.json +243 -0
  224. package/test/tdd/transform/case1/natural.ts.md +20 -0
  225. package/test/tdd/transform/case2/ast.json +207 -0
  226. package/test/tdd/transform/case2/natural.ts.md +12 -0
  227. package/test/tdd.test.js +10 -0
  228. package/test/tdd.transform.test.js +38 -0
  229. package/test/utils.js +40 -0
  230. package/sandbox-natural/stdlib/nasl.core.ts +0 -36
  231. package/sandbox-natural/stdlib/nasl.oql.ts +0 -14
  232. package/sandbox-natural/stdlib/nasl.ui.pre.d.ts +0 -90
  233. package/sandbox-natural/stdlib/nasl.ui.ts +0 -63
@@ -49,6 +49,9 @@ import type CallFunction from './CallFunction__';
49
49
  import ProcessElementV2 from './ProcessElementV2__';
50
50
  import ProcessV2 from './ProcessV2__';
51
51
  import type SubLogic from './SubLogic__';
52
+
53
+ import { reCollectTyInferCtx, varScopeCtx } from '../../../nasl/src/server/semanticData';
54
+
52
55
  //================================================================================
53
56
  // 从这里开始到结尾注释之间的代码由 NASL Workbench 自动生成,请不手动修改!
54
57
  // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
@@ -1276,7 +1279,7 @@ export class Logic extends Annotatable {
1276
1279
  }
1277
1280
 
1278
1281
  get __isVirtual() {
1279
- const isDisabled = !!this.getAncestor('HistoryProcessV2') || ['enabled', 'history'].includes(this.processV2?.status)
1282
+ const isDisabled = !!this.getAncestor('HistoryProcessV2') || ['enabled', 'history'].includes(this.processV2?.status);
1280
1283
  return isDisabled || this.process?.__isVirtual || false;
1281
1284
  }
1282
1285
 
@@ -1551,7 +1554,7 @@ export class Logic extends Annotatable {
1551
1554
  const self = this;
1552
1555
 
1553
1556
  // 获取所有子节点用于树上填充
1554
- self.getSubLogics()
1557
+ self.getSubLogics();
1555
1558
 
1556
1559
  yield waitOqlQueryComponentChildrenFinish(self);
1557
1560
  let code = '';
@@ -1568,63 +1571,9 @@ export class Logic extends Annotatable {
1568
1571
  // 需要类型推导的局部变量/返回值需要调整申明顺序
1569
1572
  const advanceMap: Map<Return | Variable, Assignment | BatchAssignment | CallFunction> = new Map();
1570
1573
  const callFunctionAdvanceMap: Map<Return | Variable, CallFunction> = new Map();
1574
+ yield* reCollectTyInferCtx(advanceMap, callFunctionAdvanceMap, self);
1575
+
1571
1576
  const IDENTIFIERMAP = new Set<Variable | Return>();
1572
- // const needGetSourceMapOqlList: Promise<any>[] = [];
1573
- yield* self.traverseChildrenGenerator(function* traverseChildrenGenerator(el) {
1574
- if (
1575
- el &&
1576
- // 批量赋值
1577
- (asserts.isBatchAssignment(el) ||
1578
- // 赋值
1579
- (asserts.isAssignment(el) && el.left?.name) ||
1580
- // 内置函数对集合类型的推导
1581
- (asserts.isCallFunction(el) && el.derivablecollection?.name))
1582
- ) {
1583
- if (el?.getAncestor('SubLogic')) {
1584
- return;
1585
- }
1586
- if (asserts.isAssignment(el)) {
1587
- const advanceVar = self.variables?.find(
1588
- (variable) => !variable.typeAnnotation && el.left?.name === variable.name,
1589
- );
1590
- if (advanceVar && !advanceMap.get(advanceVar)) {
1591
- advanceMap.set(advanceVar, el);
1592
- }
1593
- const advanceRn = self.returns?.find((ret) => !ret.typeAnnotation && el.left?.name === ret.name);
1594
- if (advanceRn && !advanceMap.get(advanceRn)) {
1595
- advanceMap.set(advanceRn, el);
1596
- }
1597
- } else if (asserts.isCallFunction(el)) {
1598
- // 需要被推导的集合
1599
- const expression = el.derivablecollection;
1600
- // 宽泛意义上的变量(变量+出参)
1601
- const advanceVar = [...(self.variables || []), ...(self.returns || [])].find((variable) => {
1602
- return !variable.typeAnnotation && expression?.name === variable.name;
1603
- });
1604
- if (advanceVar && !callFunctionAdvanceMap.get(advanceVar)) {
1605
- callFunctionAdvanceMap.set(advanceVar, el);
1606
- }
1607
- } else if (asserts.isBatchAssignment(el)) {
1608
- yield* wrapForEach(el.assignmentLines, function* warpForEachGenerator({ leftIndex }) {
1609
- const leftCode =
1610
- leftIndex.length === 1
1611
- ? yield* el.left.expression.toEmbeddedTS(shiftState(state, code, { inline: true }))
1612
- : yield* el.left.members[leftIndex[1]]?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
1613
- returnOrigin('');
1614
- const advanceVar = self.variables?.find(
1615
- (variable) => !variable.typeAnnotation && leftCode === variable.name,
1616
- );
1617
- if (advanceVar && !advanceMap.get(advanceVar)) {
1618
- advanceMap.set(advanceVar, el);
1619
- }
1620
- const advanceRn = self.returns?.find((ret) => !ret.typeAnnotation && leftCode === ret.name);
1621
- if (advanceRn && !advanceMap.get(advanceRn)) {
1622
- advanceMap.set(advanceRn, el);
1623
- }
1624
- });
1625
- }
1626
- }
1627
- });
1628
1577
 
1629
1578
  for (const variable of self.variables) {
1630
1579
  const ts = yield* variable.defaultValue?.toEmbeddedTS?.() ?? utils.returnOrigin('');
@@ -1663,7 +1612,7 @@ export class Logic extends Annotatable {
1663
1612
  leftIndex.length === 1
1664
1613
  ? yield* assignment.left.expression.toEmbeddedTS(shiftState(state, code, { inline: true }))
1665
1614
  : yield* assignment.left.members[leftIndex[1]]?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
1666
- returnOrigin('');
1615
+ returnOrigin('');
1667
1616
  if (leftCode === node.name) {
1668
1617
  const rightNode: any =
1669
1618
  rightIndex.length === 1
@@ -1894,61 +1843,7 @@ export class Logic extends Annotatable {
1894
1843
  // 需要类型推导的局部变量/返回值需要调整申明顺序
1895
1844
  const advanceMap: Map<Return | Variable, Assignment | BatchAssignment> = new Map();
1896
1845
  const callFunctionAdvanceMap: Map<Return | Variable, CallFunction> = new Map();
1897
- yield* self.traverseChildrenGenerator(function* traverseChildrenGenerator(el) {
1898
- if (
1899
- el &&
1900
- // 批量赋值
1901
- (asserts.isBatchAssignment(el) ||
1902
- // 赋值
1903
- (asserts.isAssignment(el) && el.left?.name) ||
1904
- // 内置函数对集合类型的推导
1905
- (asserts.isCallFunction(el) && el.derivablecollection?.name))
1906
- ) {
1907
- if (el?.getAncestor('SubLogic')) {
1908
- return;
1909
- }
1910
- if (asserts.isAssignment(el)) {
1911
- const advanceVar = self.variables?.find(
1912
- (variable) => !variable.typeAnnotation && el.left?.name === variable.name,
1913
- );
1914
- if (advanceVar && !advanceMap.get(advanceVar)) {
1915
- advanceMap.set(advanceVar, el);
1916
- }
1917
- const advanceRn = self.returns?.find((ret) => !ret.typeAnnotation && el.left?.name === ret.name);
1918
- if (advanceRn && !advanceMap.get(advanceRn)) {
1919
- advanceMap.set(advanceRn, el);
1920
- }
1921
- } else if (asserts.isCallFunction(el)) {
1922
- // 需要被推导的集合
1923
- const expression = el.derivablecollection;
1924
- // 宽泛意义上的变量(变量+出参)
1925
- const advanceVar = [...(self.variables || []), ...(self.returns || [])].find((variable) => {
1926
- return !variable.typeAnnotation && expression?.name === variable.name;
1927
- });
1928
- if (advanceVar && !callFunctionAdvanceMap.get(advanceVar)) {
1929
- callFunctionAdvanceMap.set(advanceVar, el);
1930
- }
1931
- } else if (asserts.isBatchAssignment(el)) {
1932
- yield* wrapForEach(el.assignmentLines, function* warpForEachGenerator({ leftIndex }) {
1933
- const leftCode =
1934
- leftIndex.length === 1
1935
- ? yield* el.left.expression.toEmbeddedTS(shiftState(state, code, { inline: true }))
1936
- : yield* el.left.members[leftIndex[1]]?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
1937
- returnOrigin('');
1938
- const advanceVar = self.variables?.find(
1939
- (variable) => !variable.typeAnnotation && leftCode === variable.name,
1940
- );
1941
- if (advanceVar && !advanceMap.get(advanceVar)) {
1942
- advanceMap.set(advanceVar, el);
1943
- }
1944
- const advanceRn = self.returns?.find((ret) => !ret.typeAnnotation && leftCode === ret.name);
1945
- if (advanceRn && !advanceMap.get(advanceRn)) {
1946
- advanceMap.set(advanceRn, el);
1947
- }
1948
- });
1949
- }
1950
- }
1951
- });
1846
+ yield* reCollectTyInferCtx(advanceMap, callFunctionAdvanceMap, self);
1952
1847
 
1953
1848
  const needChooseParamTypes = completeTypeParams.filter((typeParam) => typeParam.needChoose);
1954
1849
  // 兼容 return 没有类型情况
@@ -2049,7 +1944,7 @@ export class Logic extends Annotatable {
2049
1944
  leftIndex.length === 1
2050
1945
  ? yield* assignment.left.expression.toEmbeddedTS(shiftState(state, code, { inline: true }))
2051
1946
  : yield* assignment.left.members[leftIndex[1]]?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
2052
- returnOrigin('');
1947
+ returnOrigin('');
2053
1948
  if (leftCode === node.name) {
2054
1949
  const rightNode: any =
2055
1950
  rightIndex.length === 1
@@ -2160,7 +2055,7 @@ export class Logic extends Annotatable {
2160
2055
  && itemNode.typeAnnotation?.typeKind === 'anonymousStructure'
2161
2056
  )
2162
2057
  || (
2163
- (asserts.isNewList(itemNode) || asserts.isNewMap(itemNode))
2058
+ (asserts.isNewList(itemNode) || asserts.isNewMap(itemNode))
2164
2059
  && !(itemNode?.typeAnnotation)
2165
2060
  )
2166
2061
  ) {
@@ -2168,14 +2063,14 @@ export class Logic extends Annotatable {
2168
2063
  itemCode += yield* itemNode?.getInitCode?.(shiftState(state, code, {
2169
2064
  inline: true
2170
2065
  })) ??
2171
- returnOrigin('');
2066
+ returnOrigin('');
2172
2067
  } else if (asserts.isNewComposite(itemNode) && itemNode.typeAnnotation?.typeKind === 'generic') { // new 带泛型的数据结构/实体 进这里
2173
2068
  code += ' = ';
2174
2069
  itemCode += (yield* itemNode?.getNewCompositeCode?.(shiftState(state, code, { inline: true }))) || 'null';
2175
2070
  } else if ((itemNode as any)?.typeAnnotation && !(asserts.isCallQueryComponent(itemNode) && !itemNode.isAutoInfer())) {
2176
2071
  code += ': ';
2177
2072
  code += yield* (itemNode as any)?.typeAnnotation?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
2178
- returnOrigin('');
2073
+ returnOrigin('');
2179
2074
  } else {
2180
2075
  code += ' = ';
2181
2076
  itemCode = yield* itemNode?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
@@ -2294,19 +2189,32 @@ export class Logic extends Annotatable {
2294
2189
  }
2295
2190
 
2296
2191
  code += `(`;
2297
- if (this.parentNode?.concept === 'BindEvent') {
2298
- code += `event`;
2192
+ if (state?.typeMap?.[this.nodePath]) {
2193
+ code += state?.typeMap?.[this.nodePath];
2194
+ } else {
2195
+ if (this.parentNode?.concept === 'BindEvent') {
2196
+ // code += `event`;
2197
+ }
2198
+ this.params.forEach((param, index) => {
2199
+ let curCode = '';
2200
+ if (param.name === 'event') curCode += '';
2201
+ else curCode += param.toNaturalTS(shiftState(state, code, { inline: true }));
2202
+ if (curCode && index !== this.params.length - 1) curCode += ', ';
2203
+ code += curCode;
2204
+ });
2299
2205
  }
2300
- this.params.forEach((param, index) => {
2301
- code += param.toNaturalTS(shiftState(state, code, { inline: true }));
2302
- if (index !== this.params.length - 1) code += ', ';
2303
- });
2304
2206
  code += ')';
2305
2207
 
2306
2208
  // 兼容 return 没有类型情况
2307
- if (this.returns.length && (this.returns[0].typeAnnotation || this.returns[0].__TypeAnnotation)) {
2308
- code += ': ';
2309
- code += this.returns[0].typeAnnotation?.toNaturalTS(shiftState(state, code, { inline: true })) || this.returns[0].__TypeAnnotation?.toNaturalTS(shiftState(state, code, { inline: true }));
2209
+ if (this.returns.length) {
2210
+ if (state?.typeMap?.[this.returns[0]?.nodePath]) {
2211
+ code += ': ';
2212
+ code += state?.typeMap?.[this.returns[0]?.nodePath];
2213
+ } else if (this.returns[0].typeAnnotation || this.returns[0].__TypeAnnotation) {
2214
+ code += ': ';
2215
+ const typeAnnotation = this.returns[0].typeAnnotation || this.returns[0].__TypeAnnotation;
2216
+ code += typeAnnotation?.toNaturalTS(shiftState(state, code, { inline: true }));
2217
+ }
2310
2218
  }
2311
2219
 
2312
2220
  if (state.declaration) {
@@ -2532,8 +2440,8 @@ export class Logic extends Annotatable {
2532
2440
  collectionTSCode === '__IDENTIFIER__'
2533
2441
  ? collectionTSCode
2534
2442
  : callFunction.isLoopMap && index === 0
2535
- ? `${collectionTSCode}.__getKey(0)`
2536
- : `${collectionTSCode}.__get(0)`,
2443
+ ? `${collectionTSCode}.__getKey(0)`
2444
+ : `${collectionTSCode}.__get(0)`,
2537
2445
  );
2538
2446
  }
2539
2447
  });
@@ -2675,9 +2583,8 @@ export class Logic extends Annotatable {
2675
2583
  if (asserts.isFrontendLibrary(this.parentNode)) {
2676
2584
  _path += `/frontends/${this.parentNode.type}`;
2677
2585
  } else if (this.parentNode.concept === 'BindEvent' && this.getAncestor('Frontend')) {
2678
- _path += `/frontendTypes/${this.getAncestor('FrontendType')?.name}/frontends/${
2679
- this.getAncestor('Frontend')?.name
2680
- }/bindEvents/${name}.ts`;
2586
+ _path += `/frontendTypes/${this.getAncestor('FrontendType')?.name}/frontends/${this.getAncestor('Frontend')?.name
2587
+ }/bindEvents/${name}.ts`;
2681
2588
  }
2682
2589
  return `/embedded/${this.getAncestor('App')?.name}${_path}/logics/${name}.ts`;
2683
2590
  }
@@ -2767,9 +2674,9 @@ export class Logic extends Annotatable {
2767
2674
  super.delete();
2768
2675
  this.body.forEach((el) => {
2769
2676
  if (asserts.isCallInterface(el)) {
2770
- el.deleteCallNode()
2677
+ el.deleteCallNode();
2771
2678
  }
2772
- })
2679
+ });
2773
2680
  this.traverseChildren(async (el) => {
2774
2681
  if (el?.concept === 'CallQueryComponent') (el as CallQueryComponent).removeStructure();
2775
2682
  // 仅仅针对 自定义连接器下的 Loigc,其他需要界定边界
@@ -2902,6 +2809,9 @@ export class Logic extends Annotatable {
2902
2809
  subLogics: Array<SubLogic> = [];
2903
2810
 
2904
2811
  getSubLogics() {
2812
+ if (varScopeCtx.isFirstScreen) {
2813
+ return;
2814
+ }
2905
2815
  const subLogics = this.findNaslNodeByBFS((node: BaseNode) => {
2906
2816
  if (node?.concept === 'SubLogic') {
2907
2817
  return true;
@@ -125,7 +125,7 @@ export class MemberExpression extends LogicItem {
125
125
  let elementTag;
126
126
 
127
127
  if (this.object?.namespace?.startsWith('elements.$ce')) {
128
- elementName = this.getAncestor('ViewElement')?.name;
128
+ elementName = this.getAncestor('ViewElement')?.name
129
129
  } else {
130
130
  elementName = this.object.name;
131
131
  }
@@ -173,7 +173,7 @@ export class MemberExpression extends LogicItem {
173
173
  this.object?.object?.name === 'elements' &&
174
174
  this.object?.property?.name === '$ce'
175
175
  ) {
176
- return this.transfromAtrrLogic({ type: 'toVue' });
176
+ return this.transformAtrrLogic({ type: 'toVue' });
177
177
  }
178
178
 
179
179
  const object = String(this.object?.toVue(options)); // undefined 也让正常展示
@@ -302,7 +302,7 @@ export class MemberExpression extends LogicItem {
302
302
  this.object?.object?.name === 'elements' &&
303
303
  this.object?.property?.name === '$ce'
304
304
  ) {
305
- return this.transfromAtrrLogic();
305
+ return this.transformAtrrLogic();
306
306
  }
307
307
 
308
308
  const object: string = this.object?.toJS(state);
@@ -409,10 +409,13 @@ export class MemberExpression extends LogicItem {
409
409
  return value;
410
410
  }
411
411
 
412
- transfromAtrrLogic(options?: { type: 'toVue' | 'toJS' }) {
412
+ transformAtrrLogic(options?: { type: 'toVue' | 'toJS' }) {
413
413
  const { type = 'toJS' } = options || {};
414
414
 
415
- const elementName = this.getAncestor('ViewElement')?.name;
415
+ const elementName = this.getAncestor('ViewElement')?.name
416
+ // varScopeCtx.isFirstScreen
417
+ // ? varScopeCtx.memExprToViewElem.get(this)?.name
418
+ // : this.getAncestor('ViewElement')?.name;
416
419
  let element;
417
420
  let elementTag;
418
421
 
@@ -490,6 +493,17 @@ export class MemberExpression extends LogicItem {
490
493
  *toEmbeddedTS(state = createCompilerState()): TranslatorGenerator {
491
494
  const self = this;
492
495
  let code = '';
496
+
497
+ // 变量提升且是调用逻辑取属性,此时需要翻译为立即执行函数规避 TS 的 BUG
498
+ if (asserts.isCallLogic(self.object) && state.isVariableHost) {
499
+ code += '(() => {\nconst __$1 = ';
500
+ code += `${yield* self.object.toEmbeddedTS(shiftState(state, code, { inline: true }))};\n`
501
+ code += `return __$1.`;
502
+ code += self.property ? yield* self.property.toEmbeddedTS(shiftState(state, code, { inline: true })) : '';
503
+ code += ';})()';
504
+ return code;
505
+ }
506
+
493
507
  const leftCode = self.object
494
508
  ? `${yield* self.object.toEmbeddedTS(shiftState(state, code, { inline: true }))}.`
495
509
  : '';
@@ -516,7 +530,7 @@ export class MemberExpression extends LogicItem {
516
530
  ) {
517
531
  let newCode = '';
518
532
  if (self.object?.namespace?.startsWith('elements.$ce')) {
519
- const elementName = self.getAncestor('ViewElement')?.name;
533
+ const elementName = self.getAncestor('ViewElement')?.name
520
534
  newCode += `__elements['${elementName}']`;
521
535
  if (asserts.isIdentifier(self.property) && self.property?.name) {
522
536
  newCode += `['${self.property?.name}']`;
@@ -537,7 +551,7 @@ export class MemberExpression extends LogicItem {
537
551
  self.object?.property?.name === '$ce'
538
552
  ) {
539
553
  let newCode = '';
540
- const elementName = self.getAncestor('ViewElement')?.name;
554
+ const elementName = self.getAncestor('ViewElement')?.name
541
555
  newCode += `__elements['${elementName}']`;
542
556
  newCode += `.${self.property?.name}`;
543
557
  return newCode;
@@ -16,7 +16,8 @@ import type Identifier from './Identifier__';
16
16
  import type MemberExpression from './MemberExpression__';
17
17
  import type { Entity } from './Entity__';
18
18
  import type { EntityProperty } from './EntityProperty__';
19
- import logicService from '../service/logic';
19
+ import { naslOQLCacheStore } from '../utils/language-cache/nasl';
20
+
20
21
  //================================================================================
21
22
  // 从这里开始到结尾注释之间的代码由 NASL Workbench 自动生成,请不手动修改!
22
23
  // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
@@ -303,8 +304,8 @@ export class OqlQueryComponent extends LogicItem {
303
304
  };
304
305
  }
305
306
 
306
- return http
307
- .post('/api/v1/querydebug/generate/typescript', {
307
+ const query = async () => {
308
+ const params = {
308
309
  appId: 'myAppId',
309
310
  oqlIdentifier: 'myoqlIdentifier',
310
311
  dataSourceName: this.dataSource,
@@ -313,8 +314,31 @@ export class OqlQueryComponent extends LogicItem {
313
314
  dataSourceNasl,
314
315
  typeScriptStartLine: 1,
315
316
  typeScriptStartLineColumn: 1,
316
- })
317
- .then(({ data }: any) => {
317
+ };
318
+ const key = JSON.stringify(params);
319
+ let res = null;
320
+ let canUseCache = false;
321
+ try {
322
+ res = await naslOQLCacheStore.getItem(key);
323
+ canUseCache = true;
324
+ } catch (error) {}
325
+ if (res !== null) {
326
+ return res;
327
+ }
328
+ return http
329
+ .post('/api/v1/querydebug/generate/typescript', params)
330
+ .then(async ({ data }) => {
331
+ if (canUseCache) {
332
+ try {
333
+ await naslOQLCacheStore.setItem(key, data);
334
+ } catch (error) {}
335
+ }
336
+ return data;
337
+ });
338
+ };
339
+
340
+ return query()
341
+ .then((data: any) => {
318
342
  this.codeSourceMap = data.result ?? { typescript: '', lexicalErrorCode: 1001 };
319
343
  })
320
344
  .catch((err) => {
@@ -59,6 +59,7 @@ import Param from './Param__';
59
59
  import Return from './Return__';
60
60
  import Variable from './Variable__';
61
61
  import LogicItem from './LogicItem__';
62
+ import { reCollectTyInferCtx } from '../../../nasl/src/server/semanticData';
62
63
 
63
64
  /**
64
65
  * 覆写逻辑
@@ -1584,61 +1585,8 @@ export class OverriddenLogic extends BaseNode {
1584
1585
  // 需要类型推导的局部变量/返回值需要调整申明顺序
1585
1586
  const advanceMap: Map<Return | Variable, Assignment | BatchAssignment> = new Map();
1586
1587
  const callFunctionAdvanceMap: Map<Return | Variable, CallFunction> = new Map();
1587
- yield* self.traverseChildrenGenerator(function* traverseChildrenGenerator(el) {
1588
- if (
1589
- el &&
1590
- // 批量赋值
1591
- (asserts.isBatchAssignment(el) ||
1592
- // 赋值
1593
- (asserts.isAssignment(el) && el.left?.name) ||
1594
- // 内置函数对集合类型的推导
1595
- (asserts.isCallFunction(el) && el.derivablecollection?.name))
1596
- ) {
1597
- if (el?.getAncestor('SubLogic')) {
1598
- return;
1599
- }
1600
- if (asserts.isAssignment(el)) {
1601
- const advanceVar = self.variables?.find(
1602
- (variable) => !variable.typeAnnotation && el.left?.name === variable.name,
1603
- );
1604
- if (advanceVar && !advanceMap.get(advanceVar)) {
1605
- advanceMap.set(advanceVar, el);
1606
- }
1607
- const advanceRn = self.returns?.find((ret) => !ret.typeAnnotation && el.left?.name === ret.name);
1608
- if (advanceRn && !advanceMap.get(advanceRn)) {
1609
- advanceMap.set(advanceRn, el);
1610
- }
1611
- } else if (asserts.isCallFunction(el)) {
1612
- // 需要被推导的集合
1613
- const expression = el.derivablecollection;
1614
- // 宽泛意义上的变量(变量+出参)
1615
- const advanceVar = [...(self.variables || []), ...(self.returns || [])].find((variable) => {
1616
- return !variable.typeAnnotation && expression?.name === variable.name;
1617
- });
1618
- if (advanceVar && !callFunctionAdvanceMap.get(advanceVar)) {
1619
- callFunctionAdvanceMap.set(advanceVar, el);
1620
- }
1621
- } else if (asserts.isBatchAssignment(el)) {
1622
- yield* wrapForEach(el.assignmentLines, function* warpForEachGenerator({ leftIndex }) {
1623
- const leftCode =
1624
- leftIndex.length === 1
1625
- ? yield* el.left.expression.toEmbeddedTS(shiftState(state, code, { inline: true }))
1626
- : yield* el.left.members[leftIndex[1]]?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
1627
- returnOrigin('');
1628
- const advanceVar = self.variables?.find(
1629
- (variable) => !variable.typeAnnotation && leftCode === variable.name,
1630
- );
1631
- if (advanceVar && !advanceMap.get(advanceVar)) {
1632
- advanceMap.set(advanceVar, el);
1633
- }
1634
- const advanceRn = self.returns?.find((ret) => !ret.typeAnnotation && leftCode === ret.name);
1635
- if (advanceRn && !advanceMap.get(advanceRn)) {
1636
- advanceMap.set(advanceRn, el);
1637
- }
1638
- });
1639
- }
1640
- }
1641
- });
1588
+ yield* reCollectTyInferCtx(advanceMap, callFunctionAdvanceMap, self);
1589
+
1642
1590
  // 兼容 return 没有类型情况
1643
1591
  if (self.returns.length && self.returns[0].typeAnnotation) {
1644
1592
  code += ': ';
@@ -1778,7 +1726,7 @@ export class OverriddenLogic extends BaseNode {
1778
1726
  && itemNode.typeAnnotation?.typeKind === 'anonymousStructure'
1779
1727
  )
1780
1728
  || (
1781
- (asserts.isNewList(itemNode) || asserts.isNewMap(itemNode))
1729
+ (asserts.isNewList(itemNode) || asserts.isNewMap(itemNode))
1782
1730
  && !(itemNode?.typeAnnotation)
1783
1731
  )
1784
1732
  ) {
@@ -329,12 +329,13 @@ export class Param extends BaseNode {
329
329
  if (asserts.isFunction(this.defaultExpression) || asserts.isAnonymousFunction(this.defaultExpression)) {
330
330
  code += this.defaultValue?.expression || this.defaultExpression ? '?: ' : ': ';
331
331
  code += runSync(this.defaultExpression.toEmbeddedTSDefinition(shiftState(state, code)));
332
- } else if (!dontType && this.typeAnnotation) {
332
+ } else if (!dontType && (this.typeAnnotation || this.__TypeAnnotation)) {
333
+ const typeAnnotation = this?.typeAnnotation || this?.__TypeAnnotation;
333
334
  code += ': ';
334
- code += this.typeAnnotation.toNaturalTS(shiftState(state, code));
335
- if (this.typeAnnotation?.typeKind !== 'primitive' && this.defaultValue) {
335
+ code += typeAnnotation?.toNaturalTS(shiftState(state, code));
336
+ if (typeAnnotation?.typeKind !== 'primitive' && this.defaultValue) {
336
337
  if (this.isEnum()) {
337
- code += `= ${this.typeAnnotation.typeKey}['${this.defaultValue}']`;
338
+ code += `= ${typeAnnotation.typeKey}['${this.defaultValue}']`;
338
339
  }
339
340
  }
340
341
  }
@@ -45,6 +45,7 @@ import FlowConditionV2 from './FlowConditionV2__';
45
45
  import Logic from './Logic__';
46
46
  import BindEvent from './BindEvent__';
47
47
  import ApprovalPolicyV2 from './ApprovalPolicyV2__';
48
+ import { varScopeCtx } from '../../../nasl/src/server/semanticData';
48
49
 
49
50
  /**
50
51
  * 流程元素
@@ -1536,6 +1537,9 @@ export class ProcessElementV2 extends BaseNode {
1536
1537
  subLogics: Array<SubLogic> = [];
1537
1538
 
1538
1539
  getSubLogics() {
1540
+ if (varScopeCtx.isFirstScreen) {
1541
+ return;
1542
+ }
1539
1543
  const subLogics = this.findNaslNodeByBFS((node: BaseNode) => {
1540
1544
  if (asserts.isSubLogic(node)) {
1541
1545
  return true;
@@ -43,6 +43,7 @@ import Return from './Return__';
43
43
  import Constant from './Constant__';
44
44
  import BindAttribute from './BindAttribute__';
45
45
  import MultiApprovalPolicy from './MultiApprovalPolicy__';
46
+ import { varScopeCtx } from '../../../nasl/src/server/semanticData';
46
47
 
47
48
  /**
48
49
  * 流程元素
@@ -1733,6 +1734,9 @@ export class ProcessElement extends BaseNode {
1733
1734
  // 只有 AutoTask 才需要在他的节点下找子逻辑
1734
1735
  // 其他直接在 BindEvent 下找
1735
1736
  if (this.type !== 'AutoTask') return [] as SubLogic[];
1737
+ if (varScopeCtx.isFirstScreen) {
1738
+ return;
1739
+ }
1736
1740
  const subLogics = this.findNaslNodeByBFS((node: BaseNode) => {
1737
1741
  if (asserts.isSubLogic(node)) {
1738
1742
  return true;
@@ -28,6 +28,8 @@ import ProcessElementV2 from './ProcessElementV2__';
28
28
  import HistoryProcessV2 from './HistoryProcessV2__';
29
29
  import ProcessBindV2 from './ProcessBindV2__';
30
30
  import BindEvent from './BindEvent__';
31
+ import { varScopeCtx } from '../../../nasl/src/server/semanticData';
32
+
31
33
  /**
32
34
  * 流程
33
35
  */
@@ -1046,6 +1048,9 @@ export class ProcessV2 extends BaseNode {
1046
1048
  subLogics: Array<SubLogic> = [];
1047
1049
 
1048
1050
  getSubLogics() {
1051
+ if (varScopeCtx.isFirstScreen) {
1052
+ return;
1053
+ }
1049
1054
  const subLogics = this.findNaslNodeByBFS((node: BaseNode) => {
1050
1055
  if (asserts.isSubLogic(node)) {
1051
1056
  return true;
@@ -36,6 +36,7 @@ import Param from './Param__';
36
36
  import Return from './Return__';
37
37
  import Constant from './Constant__';
38
38
  import ProcessElement from './ProcessElement__';
39
+ import { varScopeCtx } from '../../../nasl/src/server/semanticData';
39
40
 
40
41
  /**
41
42
  * 流程
@@ -1497,6 +1498,9 @@ export class Process extends BaseNode {
1497
1498
  subLogics: Array<SubLogic> = [];
1498
1499
 
1499
1500
  getSubLogics() {
1501
+ if (varScopeCtx.isFirstScreen) {
1502
+ return;
1503
+ }
1500
1504
  const subLogics = this.findNaslNodeByBFS((node: BaseNode) => {
1501
1505
  if (asserts.isSubLogic(node)) {
1502
1506
  return true;
@@ -114,7 +114,6 @@ export class QueryOrderByExpression extends LogicItem {
114
114
  public static getDefaultOptions() {
115
115
  return {
116
116
  concept: 'QueryOrderByExpression',
117
- label: '查询组件OrderBy元素',
118
117
  orderElement: {
119
118
  concept: 'QueryFieldExpression',
120
119
  },
@@ -573,16 +573,14 @@ export class Structure extends BaseNode {
573
573
  .join(', ')}>`;
574
574
  }
575
575
 
576
- code += ` {`;
577
- if (state.descriptionComment && this.description)
578
- code += `/* ${this.description} */`;
579
- code += '\n';
576
+ code += ` {\n`;
577
+ // if (state.descriptionComment && this.description)
578
+ // code += `/* ${this.description} */`;
579
+ // code += '\n';
580
580
 
581
581
  // code += `${indent(state.tabSize + 1)}__name: '${this.getNamespace()}.${this.name}';\n`;
582
582
  this.properties.forEach((property) => {
583
- code += indent(state.tabSize + 1);
584
- code += property.toNaturalTS(shiftState(state, code, { tabSize: 0 }));
585
- code += ';\n';
583
+ code += `${property.toNaturalTS(shiftState(state, code, { tabSize: state.tabSize + 1 }))};\n`;
586
584
  });
587
585
  code += `${indent(state.tabSize)}}\n`;
588
586
  return code;