@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
@@ -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 '../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 '../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;
@@ -63,6 +63,7 @@ import Param from './Param__';
63
63
  import Return from './Return__';
64
64
  import Variable from './Variable__';
65
65
  import LogicItem from './LogicItem__';
66
+ import { reCollectTyInferCtx, varScopeCtx } from '../server/semanticData';
66
67
 
67
68
  /**
68
69
  * 子逻辑
@@ -1181,61 +1182,7 @@ export class SubLogic extends LogicItem {
1181
1182
  code += ')';
1182
1183
  const advanceMap: Map<Return | Variable, Assignment | BatchAssignment> = new Map();
1183
1184
  const callFunctionAdvanceMap: Map<Return | Variable, CallFunction> = new Map();
1184
- yield* self.traverseChildrenGenerator(function* traverseChildrenGenerator(el) {
1185
- if (
1186
- el &&
1187
- // 批量赋值
1188
- (asserts.isBatchAssignment(el) ||
1189
- // 赋值
1190
- (asserts.isAssignment(el) && el.left?.name) ||
1191
- // 内置函数对集合类型的推导
1192
- (asserts.isCallFunction(el) && el.derivablecollection?.name))
1193
- ) {
1194
- if (el?.getAncestor('SubLogic') !== self) {
1195
- return;
1196
- }
1197
- if (asserts.isAssignment(el)) {
1198
- const advanceVar = self.variables?.find(
1199
- (variable) => !variable.typeAnnotation && el.left?.name === variable.name,
1200
- );
1201
- if (advanceVar && !advanceMap.get(advanceVar)) {
1202
- advanceMap.set(advanceVar, el);
1203
- }
1204
- const advanceRn = self.returns?.find((ret) => !ret.typeAnnotation && el.left?.name === ret.name);
1205
- if (advanceRn && !advanceMap.get(advanceRn)) {
1206
- advanceMap.set(advanceRn, el);
1207
- }
1208
- } else if (asserts.isCallFunction(el)) {
1209
- // 需要被推导的集合
1210
- const expression = el.derivablecollection;
1211
- // 宽泛意义上的变量(变量+出参)
1212
- const advanceVar = [...(self.variables || []), ...(self.returns || [])].find((variable) => {
1213
- return !variable.typeAnnotation && expression?.name === variable.name;
1214
- });
1215
- if (advanceVar && !callFunctionAdvanceMap.get(advanceVar)) {
1216
- callFunctionAdvanceMap.set(advanceVar, el);
1217
- }
1218
- } else if (asserts.isBatchAssignment(el)) {
1219
- yield* wrapForEach(el.assignmentLines, function* warpForEachGenerator({ leftIndex }) {
1220
- const leftCode =
1221
- leftIndex.length === 1
1222
- ? yield* el.left.expression.toEmbeddedTS(shiftState(state, code, { inline: true }))
1223
- : yield* el.left.members[leftIndex[1]]?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
1224
- returnOrigin('');
1225
- const advanceVar = self.variables?.find(
1226
- (variable) => !variable.typeAnnotation && leftCode === variable.name,
1227
- );
1228
- if (advanceVar && !advanceMap.get(advanceVar)) {
1229
- advanceMap.set(advanceVar, el);
1230
- }
1231
- const advanceRn = self.returns?.find((ret) => !ret.typeAnnotation && leftCode === ret.name);
1232
- if (advanceRn && !advanceMap.get(advanceRn)) {
1233
- advanceMap.set(advanceRn, el);
1234
- }
1235
- });
1236
- }
1237
- }
1238
- });
1185
+ yield* reCollectTyInferCtx(advanceMap, callFunctionAdvanceMap, self);
1239
1186
 
1240
1187
  // 兼容 return 没有类型情况
1241
1188
  if (self.returns.length && self.returns[0].typeAnnotation) {
@@ -1508,7 +1455,10 @@ export class SubLogic extends LogicItem {
1508
1455
  subLogics: SubLogic[] = [];
1509
1456
 
1510
1457
  getSubLogics() {
1511
- const subLogics = this.findNaslNodeByBFS((node: BaseNode) => {
1458
+ if (varScopeCtx.isFirstScreen) {
1459
+ return;
1460
+ }
1461
+ const subLogics = this.findNaslNodeByBFS((node) => {
1512
1462
  if (asserts.isSubLogic(node)) {
1513
1463
  return true;
1514
1464
  }
@@ -1253,7 +1253,7 @@ export class TypeAnnotation extends BaseNode {
1253
1253
  'inferred',
1254
1254
  'ruleMap',
1255
1255
  'properties',
1256
- 'name',
1256
+ // 'name',
1257
1257
  'label',
1258
1258
  'description',
1259
1259
  'typeAnnotation',
@@ -46,6 +46,8 @@ const removedViewElementCache: {
46
46
  [key: string]: number | bigint;
47
47
  } = {};
48
48
 
49
+ import { reCollectTyInferCtx, varScopeCtx } from '../server/semanticData';
50
+
49
51
  import { config } from '../config';
50
52
 
51
53
  //================================================================================
@@ -2182,7 +2184,12 @@ export class View extends Annotatable {
2182
2184
  *toEmbeddedTS(state = createCompilerState()): TranslatorGenerator {
2183
2185
  const self = this;
2184
2186
  // 获取所有子节点用于树上填充
2187
+ // const time1 = Date.now();
2185
2188
  self.getSubLogics();
2189
+ // const time2 = Date.now();
2190
+ // if (time2 - time1 > 100) {
2191
+ // console.log('获取 getSubLogics 耗时', (time2 - time1) / 1000, 's');
2192
+ // }
2186
2193
  function chineseTsName(name: string) {
2187
2194
  let tsName = name;
2188
2195
  // 匹配所有特殊字符都转为_
@@ -2209,57 +2216,7 @@ export class View extends Annotatable {
2209
2216
  // 需要类型推导的局部变量/返回值需要调整申明顺序
2210
2217
  const advanceMap: Map<Variable, Assignment | BatchAssignment> = new Map();
2211
2218
  const callFunctionAdvanceMap: Map<Variable, CallFunction> = new Map();
2212
- yield* self.traverseChildrenGenerator(function* traverseChildrenGenerator(el) {
2213
- if (
2214
- el &&
2215
- // 批量赋值
2216
- (asserts.isBatchAssignment(el) ||
2217
- // 赋值
2218
- (asserts.isAssignment(el) && el.left?.name) ||
2219
- // 内置函数对集合类型的推导
2220
- (asserts.isCallFunction(el) && el.derivablecollection?.name))
2221
- ) {
2222
- if (el?.getAncestor('SubLogic')) {
2223
- return;
2224
- }
2225
- // 子页面内部逻辑过滤
2226
- if (el.view !== self) return;
2227
- if (asserts.isAssignment(el)) {
2228
- // 需要被推导的赋值左侧
2229
- const expression = el.left;
2230
- const advanceVar = self.variables?.find((variable) => {
2231
- return !variable.typeAnnotation && expression?.name === variable.name;
2232
- });
2233
- if (advanceVar && !advanceMap.get(advanceVar)) {
2234
- advanceMap.set(advanceVar, el);
2235
- }
2236
- } else if (asserts.isCallFunction(el)) {
2237
- // 需要被推导的集合
2238
- const expression = el.derivablecollection;
2239
- const advanceVar = self.variables?.find((variable) => {
2240
- return !variable.typeAnnotation && expression?.name === variable.name;
2241
- });
2242
- if (advanceVar && !callFunctionAdvanceMap.get(advanceVar)) {
2243
- callFunctionAdvanceMap.set(advanceVar, el);
2244
- }
2245
- } else if (asserts.isBatchAssignment(el)) {
2246
- yield* wrapForEach(el.assignmentLines, function* warpForEachGenerator({ leftIndex }) {
2247
- const leftCode =
2248
- leftIndex.length === 1
2249
- ? yield* el.left?.expression?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
2250
- returnOrigin('')
2251
- : yield* el.left?.members[leftIndex[1]]?.toEmbeddedTS(shiftState(state, code, { inline: true })) ??
2252
- returnOrigin('');
2253
- const advanceVar = self.variables?.find(
2254
- (variable) => !variable.typeAnnotation && leftCode === variable.name,
2255
- );
2256
- if (advanceVar && !advanceMap.get(advanceVar)) {
2257
- advanceMap.set(advanceVar, el);
2258
- }
2259
- });
2260
- }
2261
- }
2262
- });
2219
+ yield* reCollectTyInferCtx(advanceMap, callFunctionAdvanceMap, self);
2263
2220
 
2264
2221
  // 用来储存默认值翻译结构是__IDENTIFIER__或者__IDENTIFIER__()的节点
2265
2222
  const IDENTIFIERMAP = new Set<Variable>();
@@ -2789,8 +2746,8 @@ export class View extends Annotatable {
2789
2746
  this.elements.forEach((item) => {
2790
2747
  utils.traverse(
2791
2748
  (current) => {
2792
- current.node.bindEvents.forEach((bindEvent) => {
2793
- bindEvent.logics.forEach((logic) => {
2749
+ current.node.bindEvents.forEach((bindEvent: BindEvent) => {
2750
+ bindEvent.logics.forEach((logic: Logic) => {
2794
2751
  if (!logic?.name || logic?.name?.startsWith('__')) {
2795
2752
  return;
2796
2753
  }
@@ -3186,7 +3143,10 @@ export class View extends Annotatable {
3186
3143
  subLogics: Array<SubLogic> = [];
3187
3144
 
3188
3145
  getSubLogics() {
3189
- const subLogics = this.findNaslNodeByBFS((node: BaseNode) => {
3146
+ if (varScopeCtx.isFirstScreen) {
3147
+ return;
3148
+ }
3149
+ const subLogics = this.findNaslNodeByBFS((node) => {
3190
3150
  // 仅仅是为了处理数据源中的子逻辑,Logic 下面的,交由Logic 自己处理
3191
3151
  if (node?.concept === 'Logic') {
3192
3152
  return true;
@@ -502,7 +502,7 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
502
502
  if (frontend.globalScaleEnabled) {
503
503
  content += `{
504
504
  // 如果是顶层页面,才使用iframe缩放,否则会死循环
505
- if(window.parent === window){
505
+ if(!window.isScaledFrame){
506
506
  // 顶层页面里有个iframe,用来缩放页面
507
507
  document.body.innerHTML = '<iframe src="' + location.href + '"></iframe>';
508
508
  const iframe = document.querySelector('iframe');
@@ -538,10 +538,10 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
538
538
  document.documentElement.style.setProperty('--scrollbar-size', 0);
539
539
  // 移除 iframe 边框
540
540
  iframe.style.border = 'none';
541
- // 标记全局缩放的顶层,原因:全局缩放页面可能在 iframe 中
542
- window.isGlobalScaleTop = true;
541
+ // 标记全局缩放的iframe,原因:全局缩放页面可能在 iframe 中
542
+ iframe.contentWindow.isScaledFrame = true;
543
543
  return;
544
- } else if(window.parent.isGlobalScaleTop) {
544
+ } else {
545
545
  // 点击跳转到外部页面时,通知顶层页面
546
546
  document.body.addEventListener('click', (e) => {
547
547
  if(!e.target.href) return;
@@ -681,7 +681,7 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
681
681
  if (frontend.globalScaleEnabled) {
682
682
  content += `
683
683
  // 同步逻辑仅在 iframe 内部执行
684
- if(window.parent.isGlobalScaleTop) {
684
+ if(window.isScaledFrame) {
685
685
  /**
686
686
  * iframe 路由同步的几种情况:
687
687
  * 1. 跳转时,iframe 同步到顶层
@@ -332,7 +332,7 @@ export async function genPermissionDataOld(app: App) {
332
332
  if (authVals?.length) {
333
333
  authVals.forEach((item) => {
334
334
  const { key, authValue } = item;
335
- if (key.startsWith('/upload' || '/api/')) {
335
+ if (key.startsWith('/upload') || key.startsWith('/api/')) {
336
336
  logicPageResourceDtoList[`${key}:POST`] = checkPageAndUploadAuth(uploaders, key) ? [[]] : convertArray(authValue);
337
337
  }
338
338
  });
@@ -365,6 +365,14 @@ function createArrayOnAdd<K, V>(k : K, v : V, m: Map<K, Array<V>>) {
365
365
  }
366
366
  }
367
367
 
368
+ function createSetOnAdd<K, V>(k : K, v : V, m: Map<K, Set<V>>) {
369
+ if (m.get(k)) {
370
+ m.get(k).add(v);
371
+ } else {
372
+ m.set(k, new Set([v]));
373
+ }
374
+ }
375
+
368
376
  // 需要区分:前端逻辑、后端逻辑、流程逻辑
369
377
  // 需要的信息:后端逻辑、流程逻辑的 service path;逻辑调用到其定义的映射;
370
378
  // 流程逻辑 call 的 getCallNode() 每次都不同
@@ -418,8 +426,12 @@ export function genPermissionData(app: App): { [key: string]: ResourceNode[][];
418
426
  const urlAttr = nd.bindAttrs.find((item : BindAttribute) => item.name === 'url');
419
427
  const url = urlAttr?.value;
420
428
  if (url) {
421
- if (!uploaders.has(url)) uploaders.set(url, [nd]);
422
- else uploaders.get(url).push(nd);
429
+ if (!uploaders.has(url)) {
430
+ uploaders.set(url, [nd]);
431
+ }
432
+ else {
433
+ uploaders.get(url).push(nd);
434
+ }
423
435
  }
424
436
  }
425
437
  break;
@@ -519,6 +531,7 @@ export function genPermissionData(app: App): { [key: string]: ResourceNode[][];
519
531
  });
520
532
 
521
533
  frontendLogicCallCtx.forEach(({ view, viewElements, thisLogic }) => {
534
+ const visitedCalls = new Map<Logic, Set<CallLogic>>(); // 防止 A 调用 A 自我调用或 A 调用 B,B 又调用 A 等循环调用
522
535
  const findCallBackendLogic = ([kind, l] : ['process' | 'server' | 'front', Logic]) => {
523
536
  if (!l) {
524
537
  return;
@@ -536,7 +549,12 @@ export function genPermissionData(app: App): { [key: string]: ResourceNode[][];
536
549
  }
537
550
  case 'front': {
538
551
  const lgcCalls : Array<CallLogic> = defToCalls.get(l);
539
- lgcCalls?.forEach( call => findCallBackendLogic(call.getCallNodeUsingCache(frontNdCache, serverNdCache, processNdCache)));
552
+ lgcCalls?.forEach(call => {
553
+ if (!visitedCalls.get(l)?.has(call)) {
554
+ createSetOnAdd(l, call, visitedCalls);
555
+ findCallBackendLogic(call.getCallNodeUsingCache(frontNdCache, serverNdCache, processNdCache));
556
+ }
557
+ });
540
558
  break;
541
559
  }
542
560
  default: {
@@ -579,7 +597,7 @@ export function genPermissionData(app: App): { [key: string]: ResourceNode[][];
579
597
  if (authVals?.length) {
580
598
  authVals.forEach((item) => {
581
599
  const { key, authValue } = item;
582
- if (key.startsWith('/upload' || '/api/')) {
600
+ if (key.startsWith('/upload') || (key.startsWith('/api/'))) {
583
601
  logicPageResourceDtoList[`${key}:POST`] =
584
602
  checkPageAndUploadAuth(uploaders, key) ? [[]] : convertArray(authValue);
585
603
  }
@@ -212,7 +212,6 @@ async function mergeBodyData(app: App, opt: InternalReleaseData) {
212
212
  const authReport: ReturnType<typeof getAuthReport> = getAuthReport(app, opt.frontends);
213
213
  await opt.logPublishFunc?.('权限', '分析权限数据成功!');
214
214
  const logicPageResourceDtoList = genPermissionData(app);
215
-
216
215
  // 与老板逻辑权限数据对比
217
216
  // await testWithOldPermissionResult(app, logicPageResourceDtoList);
218
217
  const allFrontends = getFrontendByTypes(app?.frontendTypes);
@@ -68,7 +68,7 @@ function transformParam(node: babelTypes.Identifier): naslTypes.Param {
68
68
  // 处理生命周期函数
69
69
  function transformLifecycle(node: babelTypes.ObjectExpression): Array<naslTypes.BindEvent> {
70
70
  const bindEvents: Array<naslTypes.BindEvent> = [];
71
- node.properties.forEach((property: any) => {
71
+ node.properties?.forEach((property: any) => {
72
72
  const eventName = property?.key?.name?.replace(/^on/, '')?.toLowerCase();
73
73
  const bindEvent = new naslTypes.BindEvent({ name: eventName });
74
74
  property.value.elements.forEach((element: any) => {
@@ -150,7 +150,7 @@ function handleNewExpression(calleeName: String, node: any, type?: string) {
150
150
  if (calleeName === 'NewMap') {
151
151
  const keys: any = [];
152
152
  const values: any = [];
153
- node?.arguments?.[0]?.properties.forEach((arg: any) => {
153
+ node?.arguments?.[0]?.properties?.forEach((arg: any) => {
154
154
  keys.push(transformNode2Expression(arg.key));
155
155
  values.push(transformNode2Expression(arg.value));
156
156
  });
@@ -166,7 +166,7 @@ function handleNewExpression(calleeName: String, node: any, type?: string) {
166
166
  const properties: any = [];
167
167
  const rights: any = [];
168
168
  const assignmentLines: any = [];
169
- node?.arguments?.[0]?.properties.forEach((arg: any, index: number) => {
169
+ node?.arguments?.[0]?.properties?.forEach((arg: any, index: number) => {
170
170
  properties.push(transformNode2Expression(arg.key));
171
171
  if (arg.value.type === 'MemberExpression') {
172
172
  const expression = flatMemberExpression(arg.value);
@@ -223,7 +223,7 @@ function handleNewExpression(calleeName: String, node: any, type?: string) {
223
223
  const properties: any = [];
224
224
  const rights: any = [];
225
225
  const assignmentLines: any = [];
226
- node?.arguments?.[0]?.properties.forEach((arg: any, index: number) => {
226
+ node?.arguments?.[0]?.properties?.forEach((arg: any, index: number) => {
227
227
  properties.push(transformNode2Expression(arg.key));
228
228
  if (arg.value.type === 'MemberExpression') {
229
229
  const expression = flatMemberExpression(arg.value);
@@ -1110,7 +1110,7 @@ function transformNode2ViewElement(node: babelTypes.NewExpression, componentName
1110
1110
  tag,
1111
1111
  name,
1112
1112
  });
1113
- viewNode.properties.forEach((prop: any, propIndex: number) => {
1113
+ viewNode.properties?.forEach((prop: any, propIndex: number) => {
1114
1114
  if (prop?.value?.type === 'ArrayExpression' && ['FunctionExpression', 'ArrowFunctionExpression'].includes(prop?.value?.elements?.[0]?.type)) {
1115
1115
  // 事件逻辑
1116
1116
  const eventName = prop?.key?.name?.replace(/^on/, '')?.toLowerCase();
@@ -178,7 +178,7 @@ function transform2NewExpression(calleeName: String, node: babelTypes.CallExpres
178
178
  if (calleeName === 'NewMap') {
179
179
  const keys: any = [];
180
180
  const values: any = [];
181
- (node?.arguments?.[0] as babelTypes.ObjectExpression)?.properties.forEach((arg: any) => {
181
+ (node?.arguments?.[0] as babelTypes.ObjectExpression)?.properties?.forEach((arg: any) => {
182
182
  keys.push(transform2LogicItem(arg.key, options));
183
183
  values.push(transform2LogicItem(arg.value, options));
184
184
  });
@@ -194,7 +194,7 @@ function transform2NewExpression(calleeName: String, node: babelTypes.CallExpres
194
194
  const properties: any = [];
195
195
  const rights: any = [];
196
196
  const assignmentLines: any = [];
197
- (node?.arguments?.[0] as babelTypes.ObjectExpression)?.properties.forEach((arg: any, index: number) => {
197
+ (node?.arguments?.[0] as babelTypes.ObjectExpression)?.properties?.forEach((arg: any, index: number) => {
198
198
  properties.push(transform2LogicItem(arg.key, options));
199
199
  if (arg.value.type === 'MemberExpression') {
200
200
  const expression = flatMemberExpression(arg.value);
@@ -251,7 +251,7 @@ function transform2NewExpression(calleeName: String, node: babelTypes.CallExpres
251
251
  const properties: any = [];
252
252
  const rights: any = [];
253
253
  const assignmentLines: any = [];
254
- (node?.arguments?.[0] as babelTypes.ObjectExpression)?.properties.forEach((arg: any, index: number) => {
254
+ (node?.arguments?.[0] as babelTypes.ObjectExpression)?.properties?.forEach((arg: any, index: number) => {
255
255
  properties.push(transform2LogicItem(arg.key, options));
256
256
  if (arg.value.type === 'MemberExpression') {
257
257
  const expression = flatMemberExpression(arg.value);
@@ -1222,7 +1222,7 @@ function transformCall2DataQuery(node: babelTypes.CallExpression, calleeName: st
1222
1222
  });
1223
1223
 
1224
1224
  const asNames: Array<string> = [];
1225
- (item.arguments[0] as babelTypes.ObjectExpression).properties.forEach((arg: babelTypes.ObjectProperty) => {
1225
+ (item.arguments[0] as babelTypes.ObjectExpression).properties?.forEach((arg: babelTypes.ObjectProperty) => {
1226
1226
  const selectElement = arg.value.type === 'CallExpression' ? transform2QueryAggregateExpression(arg, { ...options, entityAsNames }) : transform2SelectQueryFieldExpression(arg, { ...options, entityAsNames });
1227
1227
  asNames.push((arg.key as babelTypes.Identifier).name);
1228
1228
 
@@ -1320,7 +1320,7 @@ export function transform2LogicItem(node: babelTypes.Node, options: TransformOpt
1320
1320
  transformManager.registerCallExpression('alert', transformAlert2ShowMessage);
1321
1321
  transformManager.registerCallExpression((node, calleeName) => /^app.dataSources|app.logics/.test(calleeName), transformCall2CallDataSourceLogic);
1322
1322
  transformManager.registerCallExpression((node, calleeName) => /interfaces\./.test(calleeName), transformCall2Interface);
1323
- transformManager.registerCallExpression((node, calleeName) => /connectors\./.test(calleeName), transformCall2Connector);
1323
+ transformManager.registerCallExpression((node, calleeName) => /connector\./.test(calleeName), transformCall2Connector);
1324
1324
  transformManager.registerCallExpression((node, calleeName) => /extensions\./.test(calleeName), transformCall2Extension);
1325
1325
  transformManager.registerCallExpression((node) => node.callee.type === 'ArrowFunctionExpression', transformArrowFunction2Match);
1326
1326
  transformManager.registerCallExpression((node, calleeName) => ['plus', 'minus', 'multiply', 'divide', 'remainder', 'STARTWITH', 'ENDWITH', 'LIKE', 'IN'].includes(calleeName), transformCallExpressionToBinaryExpression);
@@ -123,6 +123,9 @@ import { traverse, FileNode } from '../utils';
123
123
  import { withQueueExecute } from '../decorators';
124
124
  import { getNodeByNodeCallee } from '../automate/engine/utils';
125
125
  import { isApp, isConnection, isConnector, isMsgTriggerEvent, isProcess, isProcessV2, isStrictLogic } from '../concepts/utils/asserts';
126
+ import { waitOqlQueryComponentChildrenFinish } from '../common/utils';
127
+
128
+ import { collectAllSemanticCtx, clearSemanticData, printSemanticDataInfo } from './semanticData';
126
129
 
127
130
  const EmbeddedTSFileLineMap: { [name: string]: number } = {
128
131
  Entity: 3,
@@ -585,6 +588,8 @@ class NaslServer {
585
588
  frontends = []
586
589
  } = module as Module;
587
590
 
591
+ const oqlFinished = waitOqlQueryComponentChildrenFinish(module);
592
+
588
593
  yield* getTsFiles(structures, 'structure');
589
594
  yield* getTsFiles(metadataTypes, 'metadataType');
590
595
 
@@ -619,6 +624,7 @@ class NaslServer {
619
624
  yield* getTsFiles(concat(dataSources, 'entities'), 'dataSource_entity');
620
625
  yield* getTsFiles(interfaces as FileNode[], 'interface');
621
626
  yield* getTsFiles(enums, 'enum');
627
+ yield oqlFinished;
622
628
  yield* getTsFiles(logics, 'logic');
623
629
  yield* getTsFiles(authLogics, 'authLogic', Logic);
624
630
  yield* getTsFiles(authLogicsForCallInterface, 'authLogicForCallInterface', Logic);
@@ -649,6 +655,10 @@ class NaslServer {
649
655
 
650
656
  async openApp(app: App, performance = false, needRegisterCommand = true) {
651
657
  this.logger.time('生成 TS 文件');
658
+ this.logger.time('简单语义分析');
659
+ await utils.runGeneratorSync(collectAllSemanticCtx(app));
660
+ this.logger.timeEnd('简单语义分析');
661
+ // printSemanticDataInfo();
652
662
  invokeCommand('naslServer:startWork');
653
663
 
654
664
  app.naslServer = this;
@@ -677,6 +687,7 @@ class NaslServer {
677
687
  callback();
678
688
  });
679
689
  }
690
+ clearSemanticData();
680
691
  this.logger.timeEnd('生成 TS 文件');
681
692
 
682
693
  function* getAllTsFiles() {
@@ -1121,7 +1132,9 @@ class NaslServer {
1121
1132
  return;
1122
1133
  }
1123
1134
 
1124
- const { node } = record;
1135
+ let { node } = record;
1136
+ // @ts-ignore
1137
+ node = node.__v_raw || node; // 暂时先这样提速
1125
1138
 
1126
1139
  // 先获取原来的节点先清除一下之前有异常的节点,下面重新赋值
1127
1140
  const oldRecord = self.diagnosticManager.getRecord?.(record.id);
@@ -1815,6 +1828,8 @@ class NaslServer {
1815
1828
  */
1816
1829
  private *_attachDiagnosticsWithGenerator(fileNode: BaseNode) {
1817
1830
  // 每次诊断前先清空这个Set
1831
+ // @ts-ignore
1832
+ fileNode = fileNode.__v_raw || fileNode; // 暂时先这样提速
1818
1833
  this.logicSetWithComponentLogic = new Set<string>();
1819
1834
 
1820
1835
  const self = this;
@@ -3197,11 +3212,15 @@ class NaslServer {
3197
3212
  fileNode: FileNode
3198
3213
  ): Generator<void, MinRange> {
3199
3214
  let minRange: MinRange;
3215
+ // @ts-ignore
3216
+ fileNode = fileNode.__v_raw || fileNode; // 暂时先这样提速
3200
3217
  const { sourceMap } = fileNode;
3201
3218
  // 是否找到了行内准确的,是的话,就不走多行的
3202
3219
  let haveLineNode = false;
3203
3220
 
3204
- for (const [node, item] of sourceMap.entries()) {
3221
+ for (let [node, item] of sourceMap.entries()) {
3222
+ // @ts-ignore
3223
+ node = node.__v_raw || node; // 暂时先这样提速
3205
3224
  /**
3206
3225
  * 当前内容的开始行 <= 诊断开始的行 &&
3207
3226
  * 当前内容的结束行 >= 诊断结束的行
@@ -4663,6 +4682,7 @@ class NaslServer {
4663
4682
  }
4664
4683
  if (
4665
4684
  ![
4685
+
4666
4686
  'Identifier',
4667
4687
  'BinaryExpression',
4668
4688
  'CallLogic',
@@ -4775,8 +4795,10 @@ class NaslServer {
4775
4795
  }
4776
4796
  }
4777
4797
  });
4798
+
4778
4799
  yield* utils.wrapIteratorToGenerator(types.entries(), ([node, value]) => {
4779
4800
  try {
4801
+
4780
4802
  // 因为node可能是经过处理的TypeAnnotation
4781
4803
  node.__isCorrectTypeAnnotation = true;
4782
4804
  if (value) {
@@ -5492,6 +5514,7 @@ class NaslServer {
5492
5514
  */
5493
5515
  async handleRename(fileNode: BaseNode, targetNode: BaseNode, result: utils.EmbeddedTSFileResult, oldFilePath?: string) {
5494
5516
  // rename 场景
5517
+
5495
5518
  const outputFiles = [{ file: result.filePath, fileContent: result.code }];
5496
5519
  // 如果是要修改顶级文件名
5497
5520
  // file节点和当前改得是同一节点
@@ -5798,6 +5821,7 @@ class NaslServer {
5798
5821
 
5799
5822
  changeFileNext() {
5800
5823
  if (!this.singleFileChangeIng) {
5824
+ // SHIFT IS O(n) AND SLOW
5801
5825
  const item = this.changeStackList.shift();
5802
5826
  this.receiveHandleChange(item)
5803
5827
  .catch((err) => {