@lcap/nasl 3.8.3-beta.4 → 3.8.3-beta.6

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 (101) hide show
  1. package/out/common/BaseNode.d.ts +9 -4
  2. package/out/common/BaseNode.js +73 -18
  3. package/out/common/BaseNode.js.map +1 -1
  4. package/out/common/utils.d.ts +5 -1
  5. package/out/common/utils.js +188 -6
  6. package/out/common/utils.js.map +1 -1
  7. package/out/concepts/App__.js +17 -13
  8. package/out/concepts/App__.js.map +1 -1
  9. package/out/concepts/AuthLogicForCallInterface__.js +2 -50
  10. package/out/concepts/AuthLogicForCallInterface__.js.map +1 -1
  11. package/out/concepts/BusinessComponent__.js +2 -42
  12. package/out/concepts/BusinessComponent__.js.map +1 -1
  13. package/out/concepts/BusinessLogic__.js +2 -50
  14. package/out/concepts/BusinessLogic__.js.map +1 -1
  15. package/out/concepts/CallFunction__.d.ts +1 -1
  16. package/out/concepts/CallFunction__.js +1 -1
  17. package/out/concepts/CallLogic__.js +2 -2
  18. package/out/concepts/CallLogic__.js.map +1 -1
  19. package/out/concepts/Identifier__.d.ts +2 -0
  20. package/out/concepts/Identifier__.js +51 -5
  21. package/out/concepts/Identifier__.js.map +1 -1
  22. package/out/concepts/Logic__.js +6 -101
  23. package/out/concepts/Logic__.js.map +1 -1
  24. package/out/concepts/MemberExpression__.d.ts +1 -1
  25. package/out/concepts/MemberExpression__.js +15 -3
  26. package/out/concepts/MemberExpression__.js.map +1 -1
  27. package/out/concepts/OqlQueryComponent__.d.ts +0 -1
  28. package/out/concepts/OqlQueryComponent__.js +0 -70
  29. package/out/concepts/OqlQueryComponent__.js.map +1 -1
  30. package/out/concepts/OverriddenLogic__.js +2 -50
  31. package/out/concepts/OverriddenLogic__.js.map +1 -1
  32. package/out/concepts/ProcessElementV2__.js +4 -0
  33. package/out/concepts/ProcessElementV2__.js.map +1 -1
  34. package/out/concepts/ProcessElement__.js +4 -0
  35. package/out/concepts/ProcessElement__.js.map +1 -1
  36. package/out/concepts/ProcessV2__.js +4 -0
  37. package/out/concepts/ProcessV2__.js.map +1 -1
  38. package/out/concepts/Process__.js +4 -0
  39. package/out/concepts/Process__.js.map +1 -1
  40. package/out/concepts/SubLogic__.js +5 -50
  41. package/out/concepts/SubLogic__.js.map +1 -1
  42. package/out/concepts/TypeAnnotation__.js +1 -1
  43. package/out/concepts/TypeAnnotation__.js.map +1 -1
  44. package/out/concepts/View__.js +10 -49
  45. package/out/concepts/View__.js.map +1 -1
  46. package/out/generator/genBundleFiles.js +5 -5
  47. package/out/generator/permission.js +21 -5
  48. package/out/generator/permission.js.map +1 -1
  49. package/out/generator/release-body/body.js.map +1 -1
  50. package/out/natural/transformTS2UI.js +5 -5
  51. package/out/natural/transformTS2UI.js.map +1 -1
  52. package/out/natural/transforms/transform2LogicItem.js +5 -5
  53. package/out/natural/transforms/transform2LogicItem.js.map +1 -1
  54. package/out/server/naslServer.js +20 -2
  55. package/out/server/naslServer.js.map +1 -1
  56. package/out/server/semanticData.d.ts +32 -0
  57. package/out/server/semanticData.js +371 -0
  58. package/out/server/semanticData.js.map +1 -0
  59. package/out/service/logic/api.d.ts +9 -0
  60. package/out/service/logic/api.js +6 -0
  61. package/out/service/logic/api.js.map +1 -1
  62. package/out/templator/block2nasl/viewMergeBlock.js +2 -1
  63. package/out/templator/block2nasl/viewMergeBlock.js.map +1 -1
  64. package/package.json +1 -1
  65. package/sandbox/stdlib/nasl.collection.ts +3 -3
  66. package/src/common/BaseNode.ts +106 -36
  67. package/src/common/utils.ts +227 -5
  68. package/src/concepts/App__.ts +17 -13
  69. package/src/concepts/AuthLogicForCallInterface__.ts +3 -56
  70. package/src/concepts/BusinessComponent__.ts +6 -51
  71. package/src/concepts/BusinessLogic__.ts +4 -56
  72. package/src/concepts/CallFunction__.ts +1 -1
  73. package/src/concepts/CallLogic__.ts +8 -4
  74. package/src/concepts/Identifier__.ts +57 -6
  75. package/src/concepts/Logic__.ts +9 -111
  76. package/src/concepts/MemberExpression__.ts +21 -7
  77. package/src/concepts/OqlQueryComponent__.ts +1 -74
  78. package/src/concepts/OverriddenLogic__.ts +4 -56
  79. package/src/concepts/ProcessElementV2__.ts +4 -0
  80. package/src/concepts/ProcessElement__.ts +4 -0
  81. package/src/concepts/ProcessV2__.ts +5 -0
  82. package/src/concepts/Process__.ts +4 -0
  83. package/src/concepts/SubLogic__.ts +6 -56
  84. package/src/concepts/TypeAnnotation__.ts +1 -1
  85. package/src/concepts/View__.ts +14 -54
  86. package/src/generator/genBundleFiles.ts +5 -5
  87. package/src/generator/permission.ts +23 -5
  88. package/src/generator/release-body/body.ts +0 -1
  89. package/src/natural/transformTS2UI.ts +5 -5
  90. package/src/natural/transforms/transform2LogicItem.ts +5 -5
  91. package/src/server/naslServer.ts +26 -2
  92. package/src/server/semanticData.ts +447 -0
  93. package/src/service/logic/api.js +6 -0
  94. package/src/templator/block2nasl/viewMergeBlock.ts +2 -1
  95. package/src/translator/utils.ts +1 -1
  96. package/test/concepts/logic/__snapshots__/toEmbeddedTS.spec.ts.snap +182 -0
  97. package/test/concepts/logic/constant.ts +5 -0
  98. package/test/concepts/logic/fixtures/variable-host-call-logic-member-expression.json +267 -0
  99. package/test/concepts/logic/fixtures/variable-host-call-logic-nested-member-expression copy.json +457 -0
  100. package/test/concepts/logic/fixtures/variable-host-call-logic-with-handle-error-member-expression.json +267 -0
  101. package/test/concepts/logic/toEmbeddedTS.spec.ts +15 -0
@@ -0,0 +1,447 @@
1
+ import { App, Identifier, MemberExpression, View, ViewElement, BaseNode, Return, Variable,
2
+ Assignment, BatchAssignment, CallFunction, AuthLogicForCallInterface, BusinessComponent, BusinessLogic,
3
+ Logic, OverriddenLogic, SubLogic,
4
+ Process,
5
+ ProcessV2,
6
+ ProcessElement,
7
+ ProcessElementV2,
8
+ } from '..';
9
+
10
+ import { SyntaxNode } from '../concepts/utils/types';
11
+
12
+ import { createCompilerState, shiftState } from '../translator';
13
+ import { runGeneratorAsync, runGeneratorSync, wrapForEachToGenerator, returnOrigin } from '../utils';
14
+
15
+ type VarScopeCtx = {
16
+ // 优化首屏 getAncestor 热点代码
17
+ app: App;
18
+ isFirstScreen: boolean;
19
+ frontendGlobalVars: Set<string>;
20
+ varInViewOrComponent: Set<string>;
21
+ logicInViewOrComponent: Set<string>;
22
+ idToView: Map<Identifier, View>;
23
+ ctxViewElement: Array<ViewElement>;
24
+ ctxView: Array<View>;
25
+ isInViewOrComponent: boolean;
26
+ memExprToViewElem: Map<MemberExpression, ViewElement>;
27
+ }
28
+
29
+ type TyInferCtx = {
30
+ // 优化首屏 类型推导,变量提升
31
+ inferViaAsgnMap: Map<Return | Variable , Assignment | BatchAssignment | CallFunction>,
32
+ inferViaFnCallMap: Map<Return | Variable , CallFunction>,
33
+ scope: Array<AuthLogicForCallInterface | BusinessComponent | BusinessLogic | Logic | OverriddenLogic | SubLogic | View>,
34
+ // key 用 name 是不精确的,应该用地址。 暂时用 name,后面比较的时候简单点,暂时应该没 bug
35
+ // 全局变量暂不支持推导
36
+ capturedVars: Map<string, Variable | Return>,
37
+ }
38
+
39
+ type SubLogicCtx = {
40
+ // naslNodesCount: number;
41
+ ctx: Logic | Process | ProcessV2 | ProcessElement | ProcessElementV2 | null;
42
+ // 我也不知道为啥 view 这么特殊
43
+ viewSubLogics: Set<SubLogic>;
44
+ }
45
+
46
+ // 前端全局变量很少,一般就十个以内,所以 map 大小可以忽略不计
47
+ export const varScopeCtx : VarScopeCtx = {
48
+ app: null,
49
+ isFirstScreen: false,
50
+ frontendGlobalVars: new Set<string>(),
51
+ // Collect all params, (local) variables, and logic names under business component
52
+ // Note that within a business component, one can only refer to the above variables, and cannot refer to
53
+ // frontend global variables and any other variables under Views; therefore, checking the Name already suffices.
54
+ // 收集业务组件下的所有参数、(局部)变量和逻辑名称,请注意,在业务组件中,只能引用上述变量,
55
+ // 而不能引用前端全局变量和其他任何 “视图 ”下的变量;因此,检查 “Name” 已经足够了。
56
+ varInViewOrComponent: new Set<string>(),
57
+
58
+ logicInViewOrComponent: new Set<string>(),
59
+
60
+ // Collect all params, (local) variables, and logic names under views
61
+ // Actually, frontendGlobalVars U idInView U idInComponent should be the complete set of accessible variables
62
+ // 事实上,frontendGlobalVars 并上 idInView 并上 idInComponent 应该是前端所有能访问到的变量(名的集合)
63
+
64
+ // 赫基 27w 应用,前端 View 下有 2000 个变量名字;56176 个变量引用,内存占用约 1M。
65
+ idToView: new Map<Identifier, View>(),
66
+
67
+ // 路径上的 ViewElement 节点
68
+ ctxViewElement: [],
69
+
70
+ // 路径上的 View 节点
71
+ ctxView: [],
72
+
73
+ isInViewOrComponent: false,
74
+
75
+ memExprToViewElem: new Map<MemberExpression, ViewElement>(),
76
+ };
77
+
78
+ export const tyInferCtx : TyInferCtx = {
79
+ inferViaAsgnMap: new Map(),
80
+ inferViaFnCallMap: new Map(),
81
+ scope: [],
82
+ capturedVars: new Map(),
83
+ }
84
+
85
+ export const subLogicCtx : SubLogicCtx = {
86
+ // naslNodesCount: 0,
87
+ ctx: null, // 当前逻辑
88
+ viewSubLogics : new Set<SubLogic>(), // 隶属于 view 的 SubLogic,需要排除掉隶属于 Logic 的 SubLogic。
89
+ }
90
+
91
+ const last = <T>(arr: Array<T>) => arr[arr.length - 1];
92
+
93
+
94
+ export function *collectAllSemanticCtx(app: App) {
95
+ varScopeCtx.app = app;
96
+ varScopeCtx.isFirstScreen = true;
97
+ const tasks = [
98
+ // collectFrontendVariablesTask, 这样不值得,能快一点还是快一点吧,
99
+ collectVarInViewOrComponentCtxTask,
100
+ collectLogicInViewOrComponentTask,
101
+ // collectMemExprToViewElemCtxTask, // 因为 $ce 的原因,暂时用不了
102
+ collectIdToViewCtxTask,
103
+ collectSubLogicCtxTask,
104
+ collectTyInferCtxTask
105
+ ];
106
+
107
+ const cleanups = [
108
+ collectVarInViewOrComponentCtxCleanup,
109
+ // collectLogicInViewOrComponentCleanup,
110
+ // collectMemExprToViewElemCtxCleanup, // 因为 $ce 的原因,暂时用不了
111
+ collectIdToViewCtxCleanup,
112
+ collectSubLogicCtxCleanup,
113
+ collectTyInferCtxCleanup
114
+ ];
115
+
116
+ runGeneratorSync(collectFrontendVariablesTask(app));
117
+ runGeneratorSync(app.traverseStrictChildrenDoMultiTasks(tasks, cleanups));
118
+ }
119
+
120
+
121
+ function *collectFrontendVariablesTask(app: App) {
122
+ app.frontendTypes.forEach(ft => {
123
+ ft.frontends.forEach(f => {
124
+ f.variables.forEach(v => {
125
+ varScopeCtx.frontendGlobalVars.add(v.name);
126
+ });
127
+ });
128
+ })
129
+ }
130
+
131
+ function *collectVarInViewOrComponentCtxTask(nd: SyntaxNode) {
132
+ switch (nd.concept) {
133
+ case 'Variable': /* FALL THROUGH */
134
+ case 'Param': /* FALL THROUGH */
135
+ case 'Return': {
136
+ if (varScopeCtx.isInViewOrComponent) {
137
+ varScopeCtx.varInViewOrComponent.add(nd.name);
138
+ }
139
+ break;
140
+ }
141
+ case 'View': /* FALL THROUGH */
142
+ case 'BusinessComponent': varScopeCtx.isInViewOrComponent = true; break;
143
+ default: break;
144
+ }
145
+ }
146
+
147
+ function *collectVarInViewOrComponentCtxCleanup(nd: SyntaxNode) {
148
+ if (nd.concept === 'View' || nd.concept === 'BusinessComponent') {
149
+ varScopeCtx.isInViewOrComponent = false;
150
+ }
151
+ }
152
+
153
+
154
+ // component-like:业务组件下的变量引用
155
+ function *collectLogicInViewOrComponentTask(nd: SyntaxNode) {
156
+ if (nd.concept === 'Logic' || nd.concept === 'BusinessComponent') {
157
+ if (varScopeCtx.isInViewOrComponent) {
158
+ varScopeCtx.logicInViewOrComponent.add(nd.name);
159
+ }
160
+ }
161
+ }
162
+ // collectLogicInViewOrComponentCleanup 的事情被 collectVarInViewOrComponentCtxPost 做了
163
+
164
+
165
+ function *collectMemExprToViewElemCtxTask(nd: SyntaxNode) {
166
+ // view 下的 identifier 的 getAncestor 必定有 view
167
+ switch (nd.concept) {
168
+ case 'ViewElement': {
169
+ varScopeCtx.ctxViewElement.push(nd as ViewElement);
170
+ break;
171
+ }
172
+ case 'MemberExpression': {
173
+ if (varScopeCtx.ctxViewElement) {
174
+ varScopeCtx.memExprToViewElem.set(nd as MemberExpression, last(varScopeCtx.ctxViewElement));
175
+ }
176
+ break;
177
+ }
178
+ default: break;
179
+ }
180
+ }
181
+
182
+ function *collectMemExprToViewElemCtxCleanup(nd: SyntaxNode) {
183
+ if (nd.concept === 'ViewElement') {
184
+ varScopeCtx.ctxViewElement.pop();
185
+ }
186
+ }
187
+
188
+
189
+ function *collectIdToViewCtxTask(nd: SyntaxNode) {
190
+ // view 下的 identifier 的 getAncestor 必定有 view
191
+ switch (nd.concept) {
192
+ case 'View': varScopeCtx.ctxView.push(nd); break;
193
+ case 'Identifier': {
194
+ if (varScopeCtx.ctxView.length > 0) {
195
+ varScopeCtx.idToView.set(nd as Identifier, last(varScopeCtx.ctxView));
196
+ }
197
+ break;
198
+ }
199
+ default: break;
200
+ }
201
+ }
202
+
203
+ function *collectIdToViewCtxCleanup(nd: SyntaxNode) {
204
+ switch (nd.concept) {
205
+ case 'View': varScopeCtx.ctxView.pop(); break;
206
+ default: break;
207
+ }
208
+ }
209
+
210
+
211
+ function *collectSubLogicCtxTask(nd : SyntaxNode) {
212
+ switch (nd.concept) {
213
+ case 'Logic': /* FALL THROUGH */
214
+ /* 流程支持子逻辑 */
215
+ /* 流程变量不支持类型推导 */
216
+ case 'Process': /* FALL THROUGH */
217
+ case 'ProcessV2': /* FALL THROUGH */
218
+ case 'ProcessElement': /* FALL THROUGH */
219
+ case 'ProcessElementV2': /* FALL THROUGH */
220
+ case 'BusinessLogic': subLogicCtx.ctx = nd; break;
221
+ case 'SubLogic': {
222
+ // 收集子逻辑
223
+ if (subLogicCtx.ctx) {
224
+ subLogicCtx.ctx.subLogics.push(nd as SubLogic);
225
+ // console.log('逻辑或流程的子逻辑:', subLogicCtx.ctx)
226
+ } else {
227
+ subLogicCtx.viewSubLogics.add(nd as SubLogic);
228
+ }
229
+ break;
230
+ }
231
+ default: break;
232
+ }
233
+ }
234
+
235
+ function *collectSubLogicCtxCleanup(nd : SyntaxNode) {
236
+ switch (nd.concept) {
237
+ /* 流程支持子逻辑 */
238
+ /* 流程变量不支持类型推导 */
239
+ case 'Logic': /* FALL THROUGH */
240
+ case 'Process': /* FALL THROUGH */
241
+ case 'ProcessV2': /* FALL THROUGH */
242
+ case 'ProcessElement': /* FALL THROUGH */
243
+ case 'ProcessElementV2': subLogicCtx.ctx = null; break;
244
+ // 可能是有人忘了给业务组件加 subLogics?
245
+ case 'View': {
246
+ subLogicCtx.viewSubLogics.forEach(sl => { nd.subLogics.push(sl); });
247
+ // console.log('View 的子逻辑:', nd.subLogics)
248
+ subLogicCtx.viewSubLogics.clear();
249
+ break;
250
+ }
251
+ default: break;
252
+ }
253
+ }
254
+
255
+
256
+ const addVars = (nd : Array<Variable> | Array<Return>, s : Map<string, Variable | Return>) => {
257
+ nd.forEach(v => {
258
+ if (!v.typeAnnotation) {
259
+ s.set(v.name, v);
260
+ }
261
+ })
262
+ }
263
+
264
+ const removeVars = (nd : Array<Variable> | Array<Return>, s : Map<string, Variable | Return>) => {
265
+ nd.forEach(v => s.delete(v.name))
266
+ }
267
+
268
+
269
+ // OQL 批量优化优化完成前请勿移除
270
+ // const oqlSet = new Set<string>();
271
+
272
+ function *collectTyInferCtxTask(nd : SyntaxNode) {
273
+ // ++subLogicCtx.naslNodesCount;
274
+ // if (nd.concept === 'OqlQueryComponent') {
275
+ // oqlSet.add(nd.code);
276
+ // }
277
+ switch (nd.concept) {
278
+ case 'Logic': /* FALL THROUGH */
279
+ case 'AuthLogicForCallInterface': /* FALL THROUGH */
280
+ case 'BusinessLogic': /* FALL THROUGH */
281
+ case 'OverriddenLogic': /* FALL THROUGH */
282
+ case 'SubLogic': {
283
+ // 全局变量不支持类型推导;逻辑的变量也不支持跨子逻辑推导
284
+ // addVars(nd.variables, tyInferCtx.capturedVars);
285
+ // addVars(nd.returns, tyInferCtx.capturedVars);
286
+ tyInferCtx.scope.push(nd);
287
+ break;
288
+ }
289
+ case 'View': /* FALL THROUGH */
290
+ case 'BusinessComponent': {
291
+ addVars(nd.variables, tyInferCtx.capturedVars);
292
+ tyInferCtx.scope.push(nd);
293
+ break;
294
+ }
295
+ default: {
296
+ runGeneratorAsync(
297
+ collectAsgn(tyInferCtx.inferViaAsgnMap, tyInferCtx.inferViaFnCallMap, nd));
298
+ break;
299
+ }
300
+ }
301
+ }
302
+
303
+ function *collectTyInferCtxCleanup(nd : SyntaxNode) {
304
+ switch (nd.concept) {
305
+ case 'Logic': /* FALL THROUGH */
306
+ case 'AuthLogicForCallInterface': /* FALL THROUGH */
307
+ case 'BusinessLogic': /* FALL THROUGH */
308
+ case 'OverriddenLogic': /* FALL THROUGH */
309
+ case 'SubLogic': {
310
+ // removeVars(nd.variables, tyInferCtx.capturedVars);
311
+ // removeVars(nd.returns, tyInferCtx.capturedVars);
312
+ tyInferCtx.scope.pop();
313
+ break;
314
+ }
315
+
316
+ case 'View': /* FALL THROUGH */
317
+ case 'BusinessComponent': {
318
+ removeVars(nd.variables, tyInferCtx.capturedVars);
319
+ tyInferCtx.scope.pop();
320
+ break;
321
+ }
322
+ default: break;
323
+ }
324
+ }
325
+
326
+
327
+ type LogicContainer = AuthLogicForCallInterface | BusinessComponent | BusinessLogic | Logic | OverriddenLogic | SubLogic | View;
328
+
329
+ export function *reCollectTyInferCtx(
330
+ inferViaAsgn: Map<Return | Variable, Assignment | BatchAssignment | CallFunction>,
331
+ inferViaFnCall: Map<Return | Variable, CallFunction>,
332
+ self: LogicContainer) {
333
+
334
+ // No (types of) variables to be inferred
335
+ // @ts-ignore
336
+ const preTest = self.variables?.some((v : Variable) => !v.typeAnnotation) || self.returns?.some((v : Variable) => !v.typeAnnotation)
337
+ if (!preTest) {
338
+ return;
339
+ }
340
+
341
+ // 非首次则清空脏 map,重新收集所需上下文
342
+ if (!varScopeCtx.isFirstScreen) {
343
+ tyInferCtx.inferViaAsgnMap.clear();
344
+ tyInferCtx.inferViaFnCallMap.clear();
345
+ yield* self.traverseChildrenGenerator(collectTyInferCtxTask);
346
+ }
347
+
348
+ self.variables.forEach((locVar : Variable) => {
349
+ if (tyInferCtx.inferViaAsgnMap.has(locVar)){
350
+ inferViaAsgn.set(locVar, tyInferCtx.inferViaAsgnMap.get(locVar))
351
+ } else if (tyInferCtx.inferViaFnCallMap.has(locVar)){
352
+ inferViaFnCall.set(locVar, tyInferCtx.inferViaFnCallMap.get(locVar))
353
+ }
354
+ });
355
+ // @ts-ignore
356
+ self.returns?.forEach((locRet : Return) => {
357
+ if (tyInferCtx.inferViaAsgnMap.has(locRet)){
358
+ inferViaAsgn.set(locRet, tyInferCtx.inferViaAsgnMap.get(locRet))
359
+ } else if (tyInferCtx.inferViaFnCallMap.has(locRet)){
360
+ inferViaFnCall.set(locRet, tyInferCtx.inferViaFnCallMap.get(locRet))
361
+ }
362
+ });
363
+ }
364
+
365
+ function *collectAsgn(
366
+ inferViaAsgnMap: Map<Return | Variable, Assignment | BatchAssignment | CallFunction>,
367
+ inferViaBuiltinFnMap: Map<Return | Variable, CallFunction>,
368
+ nd: SyntaxNode) {
369
+ const self = last(tyInferCtx.scope); // 可能是 undefined
370
+ if (!nd || !self) {
371
+ return;
372
+ }
373
+
374
+ if (nd.concept === 'Assignment' && nd.left?.name) {
375
+ if (!self) {
376
+ console.log('nd', nd)
377
+ }
378
+ const hoistVar = self.variables?.find(v => nd.left?.name === v.name && !v.typeAnnotation)
379
+ // View 和 BusinessComponent 没有 returns
380
+ // @ts-ignore
381
+ ?? self.returns?.find(ret => nd.left?.name === ret.name && !ret.typeAnnotation)
382
+ ?? tyInferCtx.capturedVars.get(nd.left.name);
383
+ if (hoistVar && !inferViaAsgnMap.has(hoistVar)) {
384
+ inferViaAsgnMap.set(hoistVar, nd);
385
+ }
386
+ } else if (nd.concept === 'BatchAssignment') {
387
+ yield* wrapForEachToGenerator(nd.assignmentLines, function* warpForEachGenerator({ leftIndex }) {
388
+ const leftCode =
389
+ leftIndex.length === 1
390
+ ? yield* nd.left.expression.toEmbeddedTS(shiftState(createCompilerState(), '', { inline: true }))
391
+ : yield* nd.left.members[leftIndex[1]]?.toEmbeddedTS(shiftState(createCompilerState(), '', { inline: true })) ??
392
+ returnOrigin('');
393
+ const hoistVar = self.variables?.find((v : Variable) => leftCode === v.name && !v.typeAnnotation)
394
+ // View 和 BusinessComponent 没有 returns
395
+ // @ts-ignore
396
+ ?? self.returns?.find(ret => leftCode === ret.name && !ret.typeAnnotation)
397
+ ?? tyInferCtx.capturedVars.get(leftCode);
398
+ if (hoistVar && !inferViaAsgnMap.has(hoistVar)) {
399
+ inferViaAsgnMap.set(hoistVar, nd);
400
+ }
401
+ });
402
+ } else if (nd.concept === 'CallFunction' && nd.derivableCollection?.name) {
403
+ // 需要被推导的集合
404
+ const expr = nd.derivableCollection;
405
+ // 宽泛意义上的变量(变量+出参),View 和 BusinessComponent 没有 returns
406
+ const hoistVar = self.variables.find((v) => expr?.name === v.name && !v.typeAnnotation)
407
+ // @ts-ignore
408
+ ?? self.returns?.find(ret => expr?.name === ret.name && !ret.typeAnnotation)
409
+ ?? tyInferCtx.capturedVars.get(expr.name);
410
+ if (hoistVar && !inferViaBuiltinFnMap.has(hoistVar)) {
411
+ inferViaBuiltinFnMap.set(hoistVar, nd);
412
+ }
413
+ }
414
+ }
415
+
416
+ export const clearSemanticData = () => {
417
+ varScopeCtx.isFirstScreen = false;
418
+ varScopeCtx.frontendGlobalVars.clear();
419
+ varScopeCtx.varInViewOrComponent.clear();
420
+ varScopeCtx.logicInViewOrComponent.clear();
421
+ varScopeCtx.idToView.clear();
422
+ varScopeCtx.ctxViewElement = [];
423
+ varScopeCtx.memExprToViewElem.clear();
424
+ tyInferCtx.inferViaAsgnMap.clear();
425
+ tyInferCtx.inferViaFnCallMap.clear();
426
+ tyInferCtx.scope = [];
427
+ tyInferCtx.capturedVars.clear();
428
+ subLogicCtx.viewSubLogics.clear();
429
+ subLogicCtx.ctx = null;
430
+ }
431
+
432
+ export function printSemanticDataInfo() {
433
+ console.log('frontendGlobalVars', varScopeCtx.frontendGlobalVars)
434
+ console.log('varInViewOrComponent', varScopeCtx.varInViewOrComponent)
435
+ console.log('logicInViewOrComponent', varScopeCtx.logicInViewOrComponent)
436
+ console.log('idToView', varScopeCtx.idToView)
437
+ console.log('memExprToViewElem', varScopeCtx.memExprToViewElem)
438
+ console.log('inferViaAsgnMap', tyInferCtx.inferViaAsgnMap)
439
+ console.log('inferViaFnCallMap', tyInferCtx.inferViaFnCallMap)
440
+ // console.log(oqlSet)
441
+ // console.log('capturedVars', tyInferCtx.capturedVars)
442
+ // console.log('viewSubLogics', subLogicCtx.viewSubLogics)
443
+ // console.log('naslNodesCount', subLogicCtx.naslNodesCount)
444
+ // console.log('ctx', subLogicCtx.ctx)
445
+ // console.log('scope', tyInferCtx.scope)
446
+ // console.log('isFirstScreen', varScopeCtx.isFirstScreen)
447
+ }
@@ -5,4 +5,10 @@ export default {
5
5
  method: 'post',
6
6
  },
7
7
  },
8
+ queryDebugTypescriptBatch: {
9
+ url: {
10
+ path: '/api/v1/querydebug/generate/typescriptBatch',
11
+ method: 'post',
12
+ },
13
+ },
8
14
  };
@@ -37,7 +37,8 @@ export function viewMergeBlock({
37
37
  const naslCode = tryTransformBlock2Nasl(code);
38
38
  const blockView = naslCode.view;
39
39
  // vue2需要对tag进行转换 kebab-case
40
- if(((((view as any)?.parentNode as Frontend))?.parentNode as FrontendType)?.frameworkKind === 'vue2') {
40
+ const frontendType = (view as any)?.getAncestor('FrontendType');
41
+ if((frontendType as any)?.frameworkKind === 'vue2') {
41
42
  traverse(({ node }) => {
42
43
  if (node.concept === 'ViewElement') {
43
44
  node.tag = Camel2kebab(node.tag);
@@ -314,4 +314,4 @@ export function createIdentifierCode(name: string) {
314
314
 
315
315
  export function textualNamespace(name: string) {
316
316
  return name.replace(/\./g, '::');
317
- }
317
+ }
@@ -0,0 +1,182 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`logic:toEmbeddedTS variable-host-call-logic-member-expression 1`] = `
4
+ "export function logic3() {
5
+ // @ts-ignore
6
+ let result = (() => {
7
+ const __$1 = app.logics.logic2();
8
+ return __$1.a;
9
+ })();
10
+
11
+ nasl.core.assign(result, app.logics.logic2().a);
12
+ return result;
13
+ /* -----以下是 returns 的默认值草稿------ */
14
+ }
15
+ "
16
+ `;
17
+
18
+ exports[`logic:toEmbeddedTS variable-host-call-logic-nested-member-expression copy 1`] = `
19
+ "export function logic3() {
20
+ // @ts-ignore
21
+ let result = (() => {
22
+ const __$1 = app.logics.logic4(
23
+ (() => {
24
+ const __$1 = app.logics.logic2();
25
+ return __$1.b;
26
+ })()
27
+ );
28
+ return __$1.a;
29
+ })();
30
+
31
+ nasl.core.assign(result, app.logics.logic4(app.logics.logic2().b).a);
32
+ return result;
33
+ /* -----以下是 returns 的默认值草稿------ */
34
+ }
35
+ "
36
+ `;
37
+
38
+ exports[`logic:toEmbeddedTS variable-host-call-logic-with-handle-error-member-expression 1`] = `
39
+ "export function logic3() {
40
+ // @ts-ignore
41
+ let result = (() => {
42
+ const __$1 = (() => {
43
+ const __wrapper = nasl.util.autoHandleError(app.logics.logic2);
44
+ return __wrapper();
45
+ })();
46
+ return __$1.a;
47
+ })();
48
+
49
+ nasl.core.assign(
50
+ result,
51
+ (() => {
52
+ const __wrapper = nasl.util.autoHandleError(app.logics.logic2);
53
+ return __wrapper();
54
+ })().a
55
+ );
56
+ return result;
57
+ /* -----以下是 returns 的默认值草稿------ */
58
+ }
59
+ "
60
+ `;
61
+
62
+ exports[`logic:toEmbeddedTS variable-host-call-query-conponent 1`] = `
63
+ "export function logic2(): {
64
+ list: nasl.collection.List<{
65
+ entity1: app.dataSources.defaultDS.entities.Entity1;
66
+ __name: \\"AStructure_62305639\\";
67
+ }>;
68
+ total: nasl.core.Long;
69
+ __name: \\"AStructure_7d582107\\";
70
+ } {
71
+ let result: {
72
+ list: nasl.collection.List<{
73
+ entity1: app.dataSources.defaultDS.entities.Entity1;
74
+ __name: \\"AStructure_62305639\\";
75
+ }>;
76
+ total: nasl.core.Long;
77
+ __name: \\"AStructure_7d582107\\";
78
+ };
79
+
80
+ nasl.core.assign(
81
+ result,
82
+ nasl.util.paginateLimit(
83
+ (function (): nasl.collection.List<{
84
+ entity1: app.dataSources.defaultDS.entities.Entity1;
85
+ __name: \\"AStructure_62305639\\";
86
+ }> {
87
+ nasl.langUtil
88
+ .FROM(
89
+ new nasl.langUtil.Collection<
90
+ [app.dataSources.defaultDS.entities.Entity1]
91
+ >()
92
+ )
93
+ .SELECT(() => new app.dataSources.defaultDS.entities.Entity1())
94
+ .ORDER_BY(() => [
95
+ new app.dataSources.defaultDS.entities.Entity1().createdTime,
96
+ new nasl.core.String(\\"StringLiteral\\"),
97
+ ]);
98
+ return;
99
+ })(),
100
+ new nasl.core.Long(10),
101
+ new nasl.core.Long(10)
102
+ )
103
+ );
104
+ return result;
105
+ /* -----以下是 returns 的默认值草稿------ */
106
+ }
107
+ "
108
+ `;
109
+
110
+ exports[`logic:toEmbeddedTS variable-host-call-query-conponent-wrapper 1`] = `
111
+ "export function logic2(): {
112
+ list: nasl.collection.List<{
113
+ entity1: app.dataSources.defaultDS.entities.Entity1;
114
+ __name: \\"AStructure_62305639\\";
115
+ }>;
116
+ total: nasl.core.Long;
117
+ __name: \\"AStructure_7d582107\\";
118
+ } {
119
+ let result: {
120
+ list: nasl.collection.List<{
121
+ entity1: app.dataSources.defaultDS.entities.Entity1;
122
+ __name: \\"AStructure_62305639\\";
123
+ }>;
124
+ total: nasl.core.Long;
125
+ __name: \\"AStructure_7d582107\\";
126
+ };
127
+
128
+ nasl.core.assign(
129
+ result,
130
+ nasl.util.paginateLimit(
131
+ (function (): nasl.collection.List<{
132
+ entity1: app.dataSources.defaultDS.entities.Entity1;
133
+ __name: \\"AStructure_62305639\\";
134
+ }> {
135
+ nasl.langUtil
136
+ .FROM(
137
+ new nasl.langUtil.Collection<
138
+ [app.dataSources.defaultDS.entities.Entity1]
139
+ >()
140
+ )
141
+ .SELECT(() => new app.dataSources.defaultDS.entities.Entity1())
142
+ .ORDER_BY(() => [
143
+ new app.dataSources.defaultDS.entities.Entity1().createdTime,
144
+ new nasl.core.String(\\"StringLiteral\\"),
145
+ ]);
146
+ return;
147
+ })(),
148
+ new nasl.core.Long(10),
149
+ new nasl.core.Long(10)
150
+ )
151
+ );
152
+ return result;
153
+ /* -----以下是 returns 的默认值草稿------ */
154
+ }
155
+ "
156
+ `;
157
+
158
+ exports[`logic:toEmbeddedTS with-annotation 1`] = `
159
+ "export function logic1(param1: nasl.core.String): nasl.core.String {
160
+ let result: nasl.core.String;
161
+
162
+ nasl.core.assign(result, param1);
163
+ return result;
164
+ /* -----以下是 returns 的默认值草稿------ */
165
+ /* -----以下是 params 的默认值草稿------ */
166
+ }
167
+ "
168
+ `;
169
+
170
+ exports[`logic:toEmbeddedTS with-annotation-with-default 1`] = `
171
+ "export function logic1(
172
+ param1: nasl.core.String = new nasl.core.String(\\"StringLiteral\\")
173
+ ): nasl.core.String {
174
+ let result: nasl.core.String;
175
+
176
+ nasl.core.assign(result, param1);
177
+ return result;
178
+ /* -----以下是 returns 的默认值草稿------ */
179
+ /* -----以下是 params 的默认值草稿------ */
180
+ }
181
+ "
182
+ `;
@@ -0,0 +1,5 @@
1
+ import { basename } from 'path';
2
+ import { getCases } from '../utils';
3
+
4
+ export const ConceptName = basename(__dirname);
5
+ export const cases = getCases(ConceptName);