@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.
- package/out/common/BaseNode.d.ts +9 -4
- package/out/common/BaseNode.js +73 -18
- package/out/common/BaseNode.js.map +1 -1
- package/out/common/utils.d.ts +5 -1
- package/out/common/utils.js +188 -6
- package/out/common/utils.js.map +1 -1
- package/out/concepts/App__.js +17 -13
- package/out/concepts/App__.js.map +1 -1
- package/out/concepts/AuthLogicForCallInterface__.js +2 -50
- package/out/concepts/AuthLogicForCallInterface__.js.map +1 -1
- package/out/concepts/BusinessComponent__.js +2 -42
- package/out/concepts/BusinessComponent__.js.map +1 -1
- package/out/concepts/BusinessLogic__.js +2 -50
- package/out/concepts/BusinessLogic__.js.map +1 -1
- package/out/concepts/CallFunction__.d.ts +1 -1
- package/out/concepts/CallFunction__.js +1 -1
- package/out/concepts/CallLogic__.js +2 -2
- package/out/concepts/CallLogic__.js.map +1 -1
- package/out/concepts/Identifier__.d.ts +2 -0
- package/out/concepts/Identifier__.js +51 -5
- package/out/concepts/Identifier__.js.map +1 -1
- package/out/concepts/Logic__.js +6 -101
- package/out/concepts/Logic__.js.map +1 -1
- package/out/concepts/MemberExpression__.d.ts +1 -1
- package/out/concepts/MemberExpression__.js +15 -3
- package/out/concepts/MemberExpression__.js.map +1 -1
- package/out/concepts/OqlQueryComponent__.d.ts +0 -1
- package/out/concepts/OqlQueryComponent__.js +0 -70
- package/out/concepts/OqlQueryComponent__.js.map +1 -1
- package/out/concepts/OverriddenLogic__.js +2 -50
- package/out/concepts/OverriddenLogic__.js.map +1 -1
- package/out/concepts/ProcessElementV2__.js +4 -0
- package/out/concepts/ProcessElementV2__.js.map +1 -1
- package/out/concepts/ProcessElement__.js +4 -0
- package/out/concepts/ProcessElement__.js.map +1 -1
- package/out/concepts/ProcessV2__.js +4 -0
- package/out/concepts/ProcessV2__.js.map +1 -1
- package/out/concepts/Process__.js +4 -0
- package/out/concepts/Process__.js.map +1 -1
- package/out/concepts/SubLogic__.js +5 -50
- package/out/concepts/SubLogic__.js.map +1 -1
- package/out/concepts/TypeAnnotation__.js +1 -1
- package/out/concepts/TypeAnnotation__.js.map +1 -1
- package/out/concepts/View__.js +10 -49
- package/out/concepts/View__.js.map +1 -1
- package/out/generator/genBundleFiles.js +5 -5
- package/out/generator/permission.js +21 -5
- package/out/generator/permission.js.map +1 -1
- package/out/generator/release-body/body.js.map +1 -1
- package/out/natural/transformTS2UI.js +5 -5
- package/out/natural/transformTS2UI.js.map +1 -1
- package/out/natural/transforms/transform2LogicItem.js +5 -5
- package/out/natural/transforms/transform2LogicItem.js.map +1 -1
- package/out/server/naslServer.js +20 -2
- package/out/server/naslServer.js.map +1 -1
- package/out/server/semanticData.d.ts +32 -0
- package/out/server/semanticData.js +371 -0
- package/out/server/semanticData.js.map +1 -0
- package/out/service/logic/api.d.ts +9 -0
- package/out/service/logic/api.js +6 -0
- package/out/service/logic/api.js.map +1 -1
- package/out/templator/block2nasl/viewMergeBlock.js +2 -1
- package/out/templator/block2nasl/viewMergeBlock.js.map +1 -1
- package/package.json +1 -1
- package/sandbox/stdlib/nasl.collection.ts +3 -3
- package/src/common/BaseNode.ts +106 -36
- package/src/common/utils.ts +227 -5
- package/src/concepts/App__.ts +17 -13
- package/src/concepts/AuthLogicForCallInterface__.ts +3 -56
- package/src/concepts/BusinessComponent__.ts +6 -51
- package/src/concepts/BusinessLogic__.ts +4 -56
- package/src/concepts/CallFunction__.ts +1 -1
- package/src/concepts/CallLogic__.ts +8 -4
- package/src/concepts/Identifier__.ts +57 -6
- package/src/concepts/Logic__.ts +9 -111
- package/src/concepts/MemberExpression__.ts +21 -7
- package/src/concepts/OqlQueryComponent__.ts +1 -74
- package/src/concepts/OverriddenLogic__.ts +4 -56
- package/src/concepts/ProcessElementV2__.ts +4 -0
- package/src/concepts/ProcessElement__.ts +4 -0
- package/src/concepts/ProcessV2__.ts +5 -0
- package/src/concepts/Process__.ts +4 -0
- package/src/concepts/SubLogic__.ts +6 -56
- package/src/concepts/TypeAnnotation__.ts +1 -1
- package/src/concepts/View__.ts +14 -54
- package/src/generator/genBundleFiles.ts +5 -5
- package/src/generator/permission.ts +23 -5
- package/src/generator/release-body/body.ts +0 -1
- package/src/natural/transformTS2UI.ts +5 -5
- package/src/natural/transforms/transform2LogicItem.ts +5 -5
- package/src/server/naslServer.ts +26 -2
- package/src/server/semanticData.ts +447 -0
- package/src/service/logic/api.js +6 -0
- package/src/templator/block2nasl/viewMergeBlock.ts +2 -1
- package/src/translator/utils.ts +1 -1
- package/test/concepts/logic/__snapshots__/toEmbeddedTS.spec.ts.snap +182 -0
- package/test/concepts/logic/constant.ts +5 -0
- package/test/concepts/logic/fixtures/variable-host-call-logic-member-expression.json +267 -0
- package/test/concepts/logic/fixtures/variable-host-call-logic-nested-member-expression copy.json +457 -0
- package/test/concepts/logic/fixtures/variable-host-call-logic-with-handle-error-member-expression.json +267 -0
- 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
|
+
}
|
package/src/service/logic/api.js
CHANGED
|
@@ -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
|
-
|
|
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);
|
package/src/translator/utils.ts
CHANGED
|
@@ -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
|
+
`;
|