@lcap/nasl-language-server-core 4.0.1-rc.1 → 4.0.1-rc.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 (113) hide show
  1. package/out/checker.d.ts +1 -1
  2. package/out/checker.d.ts.map +1 -1
  3. package/out/checker.js +24 -3
  4. package/out/checker.js.map +1 -1
  5. package/out/index.d.ts +2 -1
  6. package/out/index.d.ts.map +1 -1
  7. package/out/index.js +4 -1
  8. package/out/index.js.map +1 -1
  9. package/out/reference-manager/builtin-q-name.d.ts +1 -1
  10. package/out/reference-manager/builtin-q-name.d.ts.map +1 -1
  11. package/out/reference-manager/builtin-q-name.js +14 -10
  12. package/out/reference-manager/builtin-q-name.js.map +1 -1
  13. package/out/reference-manager/collect-q-name.d.ts +2 -3
  14. package/out/reference-manager/collect-q-name.d.ts.map +1 -1
  15. package/out/reference-manager/collect-q-name.js +29 -28
  16. package/out/reference-manager/collect-q-name.js.map +1 -1
  17. package/out/reference-manager/get-q-name.d.ts +0 -2
  18. package/out/reference-manager/get-q-name.d.ts.map +1 -1
  19. package/out/reference-manager/get-q-name.js +56 -57
  20. package/out/reference-manager/get-q-name.js.map +1 -1
  21. package/out/reference-manager/reference-manager.d.ts +21 -11
  22. package/out/reference-manager/reference-manager.d.ts.map +1 -1
  23. package/out/reference-manager/reference-manager.js +192 -101
  24. package/out/reference-manager/reference-manager.js.map +1 -1
  25. package/out/reference-manager/remove-q-name.d.ts +1 -2
  26. package/out/reference-manager/remove-q-name.d.ts.map +1 -1
  27. package/out/reference-manager/remove-q-name.js +33 -29
  28. package/out/reference-manager/remove-q-name.js.map +1 -1
  29. package/out/reference-manager/rename-q-name.d.ts +2 -1
  30. package/out/reference-manager/rename-q-name.d.ts.map +1 -1
  31. package/out/reference-manager/rename-q-name.js +13 -3
  32. package/out/reference-manager/rename-q-name.js.map +1 -1
  33. package/out/reference-manager/symbol-type.d.ts +5 -3
  34. package/out/reference-manager/symbol-type.d.ts.map +1 -1
  35. package/out/reference-manager/symbol-type.js +8 -3
  36. package/out/reference-manager/symbol-type.js.map +1 -1
  37. package/out/reference-manager/update-nasl-fragment.d.ts.map +1 -1
  38. package/out/reference-manager/update-nasl-fragment.js +4 -4
  39. package/out/reference-manager/update-nasl-fragment.js.map +1 -1
  40. package/out/typer/collectGlobalDefs.d.ts +1 -1
  41. package/out/typer/collectGlobalDefs.d.ts.map +1 -1
  42. package/out/typer/collectGlobalDefs.js +2 -2
  43. package/out/typer/collectGlobalDefs.js.map +1 -1
  44. package/out/typer/component-def-manager/component-def-manager.js +2 -2
  45. package/out/typer/component-def-manager/component-def-manager.js.map +1 -1
  46. package/out/typer/dispatch-all.d.ts +1 -1
  47. package/out/typer/dispatch-all.d.ts.map +1 -1
  48. package/out/typer/dispatch-all.js +2 -2
  49. package/out/typer/dispatch-all.js.map +1 -1
  50. package/out/typer/dispatch-def.d.ts.map +1 -1
  51. package/out/typer/dispatch-def.js +3 -0
  52. package/out/typer/dispatch-def.js.map +1 -1
  53. package/out/typer/dispatch-expr.d.ts.map +1 -1
  54. package/out/typer/dispatch-expr.js +135 -100
  55. package/out/typer/dispatch-expr.js.map +1 -1
  56. package/out/typer/dispatch-process.d.ts.map +1 -1
  57. package/out/typer/dispatch-process.js +17 -5
  58. package/out/typer/dispatch-process.js.map +1 -1
  59. package/out/typer/dispatch-view.d.ts +1 -1
  60. package/out/typer/dispatch-view.d.ts.map +1 -1
  61. package/out/typer/dispatch-view.js +15 -11
  62. package/out/typer/dispatch-view.js.map +1 -1
  63. package/out/typer/incremental-update.d.ts.map +1 -1
  64. package/out/typer/incremental-update.js +28 -44
  65. package/out/typer/incremental-update.js.map +1 -1
  66. package/out/typer/index.d.ts +2 -1
  67. package/out/typer/index.d.ts.map +1 -1
  68. package/out/typer/index.js +3 -1
  69. package/out/typer/index.js.map +1 -1
  70. package/out/typer/nasl-predicate.d.ts +1 -2
  71. package/out/typer/nasl-predicate.d.ts.map +1 -1
  72. package/out/typer/overload-helper.d.ts +12 -0
  73. package/out/typer/overload-helper.d.ts.map +1 -0
  74. package/out/typer/overload-helper.js +110 -0
  75. package/out/typer/overload-helper.js.map +1 -0
  76. package/out/typer/sem-diag.d.ts +4 -0
  77. package/out/typer/sem-diag.d.ts.map +1 -1
  78. package/out/typer/sem-diag.js +9 -1
  79. package/out/typer/sem-diag.js.map +1 -1
  80. package/out/typer/solver.d.ts +2 -2
  81. package/out/typer/solver.d.ts.map +1 -1
  82. package/out/typer/solver.js +17 -19
  83. package/out/typer/solver.js.map +1 -1
  84. package/out/typer/subster.d.ts.map +1 -1
  85. package/out/typer/subster.js +10 -5
  86. package/out/typer/subster.js.map +1 -1
  87. package/out/typer/type-hint-manager/type-hint-manager.d.ts +1 -1
  88. package/out/typer/type-hint-manager/type-hint-manager.d.ts.map +1 -1
  89. package/out/typer/type-manager.d.ts.map +1 -1
  90. package/out/typer/type-manager.js +3 -3
  91. package/out/typer/type-manager.js.map +1 -1
  92. package/out/typer/type-predicate.js +5 -5
  93. package/out/typer/type-predicate.js.map +1 -1
  94. package/out/typer/typer.d.ts +7 -4
  95. package/out/typer/typer.d.ts.map +1 -1
  96. package/out/typer/typer.js +24 -17
  97. package/out/typer/typer.js.map +1 -1
  98. package/out/typer/unifier.d.ts.map +1 -1
  99. package/out/typer/unifier.js +10 -4
  100. package/out/typer/unifier.js.map +1 -1
  101. package/out/utils/parseTsClassType.d.ts +2 -3
  102. package/out/utils/parseTsClassType.d.ts.map +1 -1
  103. package/out/utils/parseTsClassType.js +25 -58
  104. package/out/utils/parseTsClassType.js.map +1 -1
  105. package/out/utils/string.d.ts +4 -0
  106. package/out/utils/string.d.ts.map +1 -0
  107. package/out/utils/string.js +29 -0
  108. package/out/utils/string.js.map +1 -0
  109. package/out/utils/type-operator.d.ts +1 -1
  110. package/out/utils/type-operator.d.ts.map +1 -1
  111. package/out/utils/type-operator.js +12 -12
  112. package/out/utils/type-operator.js.map +1 -1
  113. package/package.json +9 -6
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNamespaceWithoutLast = exports.getDatasourceQName = exports.handleEntityAutoRef = exports.lowercaseFirstChar = exports.isEntityLogic = exports.easyGetOldQName = exports.ReferenceManager = exports.prependStr = exports.getPropQName = exports.getTokenQualifiedNameForMatchedExpr = exports.getTokenQualifiedName = void 0;
3
+ exports.getSubViews = exports.cheapTestLocalSymbol = exports.getNamespaceWithoutLast = exports.getDatasourceQName = exports.handleEntityAutoRef = exports.isEntityLogic = exports.easyGetOldQName = exports.ReferenceManager = void 0;
4
4
  const nasl_concepts_1 = require("@lcap/nasl-concepts");
5
+ const mnemonist_1 = require("mnemonist");
5
6
  const fp_macros_1 = require("../utils/fp-macros");
6
7
  const console_1 = require("console");
7
8
  const builtin_q_name_1 = require("./builtin-q-name");
@@ -11,17 +12,14 @@ const type_predicate_1 = require("../typer/type-predicate");
11
12
  const helper_1 = require("../typer/helper");
12
13
  const component_def_manager_1 = require("../typer/component-def-manager/component-def-manager");
13
14
  const get_q_name_1 = require("./get-q-name");
14
- Object.defineProperty(exports, "getTokenQualifiedName", { enumerable: true, get: function () { return get_q_name_1.getTokenQualifiedName; } });
15
- Object.defineProperty(exports, "getTokenQualifiedNameForMatchedExpr", { enumerable: true, get: function () { return get_q_name_1.getTokenQualifiedNameForMatchedExpr; } });
16
- Object.defineProperty(exports, "getPropQName", { enumerable: true, get: function () { return get_q_name_1.getPropQName; } });
17
- Object.defineProperty(exports, "prependStr", { enumerable: true, get: function () { return get_q_name_1.prependNonEmptyStr; } });
15
+ const string_1 = require("../utils/string");
18
16
  const symbol_type_1 = require("./symbol-type");
19
17
  const update_nasl_fragment_1 = require("./update-nasl-fragment");
20
18
  const nasl_predicate_1 = require("../typer/nasl-predicate");
21
19
  const type_manager_1 = require("../typer/type-manager");
22
20
  const oql_1 = require("../utils/oql");
23
21
  const parseTsClassType_1 = require("../utils/parseTsClassType");
24
- const mnemonist_1 = require("mnemonist");
22
+ const string_2 = require("../utils/string");
25
23
  /**
26
24
  * 考虑这样一个例子:
27
25
  * x = f(...)
@@ -193,12 +191,6 @@ class ReferenceManager {
193
191
  this.localQNameRefs = new Map();
194
192
  // 当前文件节点
195
193
  this.curFileNode = undefined;
196
- this.buildSymbolRefsFromSymbolGraph = (symbolGraph) => {
197
- const m = this.symbolRefs; // Using private property directly for internal function
198
- Array.from(symbolGraph.getSymbols()).forEach(sym => sym.declaration
199
- && symbol_type_1.globalDefConcept.includes(sym.declaration.concept)
200
- && m.set(sym.declaration, new Set(sym.references)));
201
- };
202
194
  // 约 20 万节点 200ms
203
195
  this.slowBuildSymbolRefsForApp = (env, app) => {
204
196
  this.modeForCollect = "create" /* Operation.Create */;
@@ -256,8 +248,8 @@ class ReferenceManager {
256
248
  // for (const preference of app.preferenceMap) {
257
249
  // allRefs.push(...this.collectRefs(env, preference as any as ValidExtInp));
258
250
  // }
259
- app.integration && allRefs.push(...this.collectRefs(env, app.integration));
260
- app.backend && allRefs.push(...this.collectRefs(env, app.backend));
251
+ app.integration && allRefs.push(...this.collectRefs(env, app.integration, false));
252
+ app.backend && allRefs.push(...this.collectRefs(env, app.backend, false));
261
253
  allRefs.forEach(([ref, qName]) => {
262
254
  if (!ref) {
263
255
  return;
@@ -270,24 +262,11 @@ class ReferenceManager {
270
262
  else {
271
263
  // Cache reference for future relinking
272
264
  // FIXME:这里有问题,脏脏的,比如局部变量、入参等都扔到这里面了,虽然暂时可能没有太大的正确性问题,但有内存泄漏
273
- if (!cheapTestLocalSymbol(qName)) {
265
+ if (!(0, exports.cheapTestLocalSymbol)(qName)) {
274
266
  (0, helper_1.createSetOnPush)(this.cachedQNameSymbolRefs, qName, ref);
275
267
  }
276
268
  }
277
269
  });
278
- // 如果 QA 说查找引用要能看到实体逻辑里的类型啥的,再给注释去掉
279
- // 处理一下实体逻辑
280
- // app.dataSources.forEach(ds => {
281
- // ds.entities.forEach(e => {
282
- // e.logics.forEach((l: Logic) => {
283
- // const refsInLogic = this.collectRefs(env, l);
284
- // refsInLogic.forEach((qName, ref) => {
285
- // console.log('xx')
286
- // allRefs.set(ref, qName);
287
- // });
288
- // });
289
- // });
290
- // });
291
270
  // 暂时特殊处理一下流程,应该不会太慢
292
271
  for (const p of app.processV2s) {
293
272
  this.addRefsForGlobalSym(env, p);
@@ -301,7 +280,8 @@ class ReferenceManager {
301
280
  }
302
281
  for (const fe of fet.frontends) {
303
282
  for (const v of fe.views) {
304
- this.addRefsForGlobalSym(env, v);
283
+ // 包括子页面
284
+ this.addRefsForGlobalSym(env, v, false);
305
285
  }
306
286
  for (const be of fe.bindEvents) {
307
287
  this.addRefsForGlobalSym(env, be);
@@ -442,10 +422,14 @@ class ReferenceManager {
442
422
  // nd = this.qNameDefs.get(getTokenQualifiedName(nd)!)!;
443
423
  // ==> 好像也不行,很多依赖库逻辑调用又挂了,这也不行,那也不行
444
424
  // 全局符号直接查找
445
- // if (nd.concept === 'ProcessV2') {
446
- // } else
447
425
  if (isGlobalDef(nd)) {
448
- res = this.getSymbolRefs(nd);
426
+ res = this.getSymbolRefs(nd) ?? new Set();
427
+ if (nd.concept === 'Entity') {
428
+ // 加上所有实体逻辑调用的引用(实体逻辑可看做无定义,但要修改调用处的 namespace:实体名是 namespace 的一部分)
429
+ for (const l of nd.logics) {
430
+ res = mnemonist_1.set.union(res, this.getSymbolRefs(l) ?? new Set());
431
+ }
432
+ }
449
433
  }
450
434
  else { // 局部符号才需要即时获取
451
435
  const boundary = toRaw(getBoundary(nd));
@@ -460,12 +444,36 @@ class ReferenceManager {
460
444
  (endTime - startTime > 200) && console.log(`Get reference: all time: ${endTime - startTime}ms`);
461
445
  }
462
446
  }
447
+ // 这个东西很特殊……查三代
448
+ if (nd.concept === 'BusinessLogic') {
449
+ // 上面已经找到了业务组件内部对业务组件逻辑的内用
450
+ // 现在再找出所有 业务组件逻辑 所属的业务组件的外部引用
451
+ const bs = toRaw((0, nasl_concepts_1.getCtxViewLike)(nd));
452
+ if (bs?.concept === 'BusinessComponent') {
453
+ const bsRefs = this.getSymbolRefs(bs) ?? new Set();
454
+ let bsRefsRefs = new Array(); // 业务组件(在页面的引用)的引用
455
+ // 再对每个实例找到所有引用
456
+ for (const bsInst of bsRefs) {
457
+ bsRefsRefs.push(...this.getViewElementRefs(env, bsInst));
458
+ }
459
+ // 再从引用中过滤出找到当前业务逻辑的调用
460
+ res = mnemonist_1.set.union(res, new Set(bsRefsRefs.filter(r => r.concept === 'CallLogic' && r.calleeName === nd.name))); // amazing!
461
+ }
462
+ }
463
+ // 这个东西很特殊……查三代
464
+ if (nd.concept === 'Connection') {
465
+ const conn = nd.connector;
466
+ const allLogics = [...conn.logics, ...conn.namespaces.flatMap(nsp => nsp.logics)];
467
+ for (const l of allLogics) {
468
+ res = mnemonist_1.set.union(res ?? new Set(), new Set(this.getReferences(env, l)));
469
+ }
470
+ }
463
471
  return res ? Array.from(res) : [];
464
472
  };
465
473
  // 建立所有局部引用,先处理上一次的缓存
466
474
  this.clearRebuildLocalCache = (env, nd_) => {
467
475
  this.localQNameRefs.clear();
468
- return this.buildLocalQNameRefs(env, toRaw(nd_));
476
+ return this.buildLocalQNameRefs(env, toRaw(nd_)) ?? new Set();
469
477
  };
470
478
  // 给类似 FileNode 级别的定义建立局部索引
471
479
  // 修改后:不写入 env map 了,不做缓存,直接返回数据
@@ -482,12 +490,12 @@ class ReferenceManager {
482
490
  }
483
491
  if (boundary.concept === 'View' || boundary.concept === 'BusinessComponent') {
484
492
  viewVars = (0, nasl_concepts_1.getViewVars)(nd).map(toRaw);
485
- logicVars = (0, nasl_concepts_1.getViewLikeLogics)(nd).map(toRaw);
493
+ logicVars.push(...(0, nasl_concepts_1.getCtxLogicLike)(nd)?.variables?.map(toRaw) ?? []);
486
494
  logics = (0, nasl_concepts_1.getViewLikeLogics)(nd).map(toRaw);
487
495
  }
488
496
  else if (boundary.concept === 'ProcessDefinitionV2') {
489
497
  processVars = (0, nasl_concepts_1.getProcessVars)(nd).map(toRaw);
490
- logicVars = (0, nasl_concepts_1.getProcessLikeLogics)(nd).map(toRaw);
498
+ logicVars.push(...(0, nasl_concepts_1.getCtxLogicLike)(nd)?.variables?.map(toRaw) ?? []);
491
499
  logics = (0, nasl_concepts_1.getProcessLikeLogics)(nd).map(toRaw);
492
500
  }
493
501
  else if ((0, nasl_predicate_1.isCallableNaslLogic)(boundary) || (0, nasl_predicate_1.isCallableNaslInterface)(boundary)) {
@@ -501,7 +509,7 @@ class ReferenceManager {
501
509
  this.localQNameRefs.set(qName, new Set());
502
510
  }
503
511
  });
504
- let subRefs = this.collectRefs(env, boundary);
512
+ let subRefs = this.collectRefs(env, boundary, true);
505
513
  this.lastBoundary = boundary;
506
514
  subRefs?.forEach(([rf, qName]) => {
507
515
  // 不存在则表示不是局部符号
@@ -563,7 +571,7 @@ class ReferenceManager {
563
571
  return result;
564
572
  }
565
573
  const nd = toRaw(__nd);
566
- const ctxProcLike = (0, nasl_concepts_1.getCtxProcessLike)(nd);
574
+ const ctxProcLike = toRaw((0, nasl_concepts_1.getCtxProcessLike)(nd));
567
575
  if (!ctxProcLike) {
568
576
  return result;
569
577
  }
@@ -581,6 +589,7 @@ class ReferenceManager {
581
589
  }
582
590
  };
583
591
  visitChildrenWith(ctxProcLike, lam);
592
+ // 重命名时不需要处理 sourceRef targetRef,好像其他逻辑已经处理掉了
584
593
  return result;
585
594
  };
586
595
  /**
@@ -767,7 +776,7 @@ class ReferenceManager {
767
776
  res.push([typeAnnotation, tyQName]);
768
777
  const parentConcept = (0, type_predicate_1.isEntityTy)(typeAnnotation) ? 'Entity' : 'Structure';
769
778
  for (const prop of nd.properties) {
770
- const propQName = (0, get_q_name_1.getPropQName)(tyQName, prop.name, parentConcept);
779
+ const propQName = (0, string_2.getPropQName)(tyQName, prop.name, parentConcept);
771
780
  res.push([prop, propQName]);
772
781
  }
773
782
  };
@@ -784,7 +793,7 @@ class ReferenceManager {
784
793
  }
785
794
  const relEntityQName = `${relNsp}.${relEntity}`;
786
795
  this.handleRefOp(env, this.modeForCollect, nd, relEntityQName);
787
- const relPropQName = (0, get_q_name_1.getPropQName)(`${relNsp}.${relEntity}`, `${relProperty}`, 'Entity');
796
+ const relPropQName = (0, string_2.getPropQName)(`${relNsp}.${relEntity}`, `${relProperty}`, 'Entity');
788
797
  this.handleRefOp(env, this.modeForCollect, nd, relPropQName);
789
798
  };
790
799
  this.handleBusinessComponentRefs = (env, nd) => {
@@ -797,6 +806,54 @@ class ReferenceManager {
797
806
  }
798
807
  this.handleRefOp(env, this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(bsDef));
799
808
  };
809
+ this.handleBindRoles = (env, nd) => {
810
+ for (const roleName of nd.bindRoles ?? nd.roles) {
811
+ const qName = `${symbol_type_1.roleNsp}.${roleName}`;
812
+ this.handleRefOp(env, this.modeForCollect, nd, qName);
813
+ }
814
+ };
815
+ this.handleAuthLogicRef = (env, nd) => {
816
+ let parent = nd.parentNode;
817
+ while (parent) {
818
+ if (parent.concept === 'App' ||
819
+ parent.concept === 'Connector' ||
820
+ parent.concept === 'Module' ||
821
+ parent.concept === 'Namespace') {
822
+ // Found the desired ancestor, stop searching
823
+ break;
824
+ }
825
+ parent = parent.parentNode;
826
+ }
827
+ if (!parent?.concept) {
828
+ return;
829
+ }
830
+ // @ts-expect-error
831
+ parent?.interfaceDependencies?.forEach(dep => {
832
+ dep.interfaces.forEach(itfc => {
833
+ if (itfc.concept === 'AuthInterface' && itfc.name === nd.calleeName) {
834
+ // this.handleRefOp(env, this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
835
+ const authName = itfc.authLogic;
836
+ parent?.authLogicsForCallInterface?.forEach(l => {
837
+ if (l.name === authName) {
838
+ this.handleRefOp(env, this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(l));
839
+ }
840
+ });
841
+ }
842
+ });
843
+ });
844
+ parent.interfaces?.forEach(itfc => {
845
+ if (itfc.concept === 'AuthInterface' && itfc.name === nd.calleeName) {
846
+ // this.handleRefOp(env, this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
847
+ // this.handleRefOp(env, this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
848
+ const authName = itfc.authLogic;
849
+ parent?.authLogics?.forEach(l => {
850
+ if (l.name === authName) {
851
+ this.handleRefOp(env, this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(l));
852
+ }
853
+ });
854
+ }
855
+ });
856
+ };
800
857
  /**
801
858
  * 无论根节点是 ref 还是 def,都要递归收集下层所有的引用节点
802
859
  * 会打散 a.b.c、A | B、x.a.b 等结构,并记录必要的信息
@@ -810,16 +867,35 @@ class ReferenceManager {
810
867
  * @warning 此过程收集所有引用,包括全局符号和局部符号的,不会做过滤
811
868
  * @param env semantic environment
812
869
  * @param nd start node to collect sub refs
870
+ * @param skipSubView whether skip the collection for sub views
813
871
  * @returns [ref, qName]
814
872
  */
815
- this.collectRefs = (env, nd) => {
873
+ this.collectRefs = (env, nd, skipSubView = true) => {
874
+ // 有的 nd 没实例化,上面没有 traverseStrictChildren 方法,比如 ApplyAnnotation 大哥
875
+ if (nd.traverseStrictChildren === undefined) {
876
+ return [];
877
+ }
878
+ // extract views
879
+ const views = new Array();
880
+ nd.concept === 'View' && views.push(nd);
881
+ !skipSubView && views.push(...(0, exports.getSubViews)(nd));
882
+ if (nd.concept === 'View' || nd.concept === 'BusinessComponent') {
883
+ this.curFileNode = nd;
884
+ env.viewAssocProcess = env.processV2ViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? null;
885
+ }
816
886
  const res = new Array(); // 使用数组而不是 Map
817
887
  // specialization for speeding up
818
888
  const normalCb = (n) => {
819
889
  // 隐式引用 - 来自 __TypeAnnotation
820
890
  this.handleSymbolImplicitRefs(n);
821
- n.concept === 'ViewElement' && n.tag.startsWith('bs-') && this.handleBusinessComponentRefs(env, n);
891
+ if (n.concept === 'ViewElement') {
892
+ n.tag.startsWith('bs-') && this.handleBusinessComponentRefs(env, n);
893
+ n.bindRoles.length && this.handleBindRoles(env, n);
894
+ }
895
+ // 都特殊,样样都特殊
822
896
  n.concept === 'EntityProperty' && this.handleForeignKeyRef(env, n);
897
+ n.concept === 'AssigneeV2' && this.handleBindRoles(env, n);
898
+ n.concept === 'CallAuthInterface' && this.handleAuthLogicRef(env, n);
823
899
  if (!symbol_type_1.refConcept.includes(n.concept)) {
824
900
  return;
825
901
  }
@@ -837,7 +913,9 @@ class ReferenceManager {
837
913
  n.concept === 'OqlQueryComponent' ||
838
914
  n.concept === 'FieldPermissionV2' ||
839
915
  // @ts-expect-error 临时 hack,下个版本应该把左侧 concept 改一改
840
- n.concept === 'NewComposite';
916
+ n.concept === 'NewComposite' ||
917
+ // 跳过子页面,但不能跳过自己
918
+ (skipSubView && n.concept === 'View' && n !== nd);
841
919
  // 会终止子树迭代
842
920
  const compositeNodeCb = (n) => {
843
921
  let qNameRefs = new Array();
@@ -857,7 +935,7 @@ class ReferenceManager {
857
935
  this.handleNewCompositeNode(n, res);
858
936
  // 右侧构成的引用
859
937
  qNameRefs = n.rights
860
- .flatMap(r => this.collectRefs(env, r));
938
+ .flatMap(r => this.collectRefs(env, r, true));
861
939
  break;
862
940
  case 'OqlQueryComponent':
863
941
  for (const qName of (0, oql_1.extractSymbolsFromOqlQueryComponent)(n)) {
@@ -878,8 +956,25 @@ class ReferenceManager {
878
956
  res.push([ref, qName]);
879
957
  }
880
958
  };
881
- // @ts-expect-error contra-variance errors
882
- visitChildrenWith(nd, normalCb, compositeNodePred, compositeNodeCb);
959
+ // 逐个处理嵌套的页面
960
+ if (views.length > 0) {
961
+ for (const v of views) {
962
+ v.bindRoles.length && this.handleBindRoles(env, v);
963
+ const lastViewAssocProcess = env.viewAssocProcess;
964
+ env.viewAssocProcess = env.processV2ViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(v)) ?? null;
965
+ const lastCurFileNode = this.curFileNode;
966
+ this.curFileNode = v;
967
+ // @ts-expect-error contra-variance errors
968
+ visitChildrenWith(v, normalCb, compositeNodePred, compositeNodeCb);
969
+ this.curFileNode = lastCurFileNode;
970
+ env.viewAssocProcess = lastViewAssocProcess;
971
+ }
972
+ }
973
+ else {
974
+ // 处理非页面
975
+ // @ts-expect-error contra-variance errors
976
+ visitChildrenWith(nd, normalCb, compositeNodePred, compositeNodeCb);
977
+ }
883
978
  // QFE 实在是没办法一致性处理
884
979
  if (nd.concept !== 'QueryFieldExpression') {
885
980
  // 过滤掉根节点
@@ -887,38 +982,20 @@ class ReferenceManager {
887
982
  }
888
983
  return res;
889
984
  };
890
- this.collectGlobalSubDefs = (nd) => {
891
- const res = new Map();
892
- res.set(nd, (0, get_q_name_1.getTokenQualifiedName)(nd));
893
- const cb = (n) => {
894
- if (!symbol_type_1.globalDefConcept.includes(n.concept)) {
895
- return;
896
- }
897
- const qName = (0, get_q_name_1.getTokenQualifiedName)(n);
898
- if (!qName) {
899
- return;
900
- }
901
- res.set(n, qName);
902
- };
903
- visitChildrenWith(nd, cb);
904
- return res;
905
- };
906
985
  /**
907
986
  * @warning Only handle global symbols
908
987
  * 仅清除全局符号的引用。外部优先调用此接口,不要直接调用 collectRefs
909
988
  * 不是说输入是 global symbol,而是说对于任何输入,只移除内部对 global symbol 的引用
989
+ * @param skipSubView 是否跳过子页面,增量场景调用较多,增量场景默认跳过
910
990
  */
911
- this.removeRefsForGlobalSym = (env, rmNd) => {
991
+ this.removeRefsForGlobalSym = (env, rmNd, skipSubView = true) => {
912
992
  this.curFileNode = rmNd;
913
993
  this.modeForCollect = "delete" /* Operation.Remove */;
914
- if (rmNd.concept === 'View' || rmNd.concept === 'BusinessComponent') {
915
- env.viewAssocProcess = env.processViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(rmNd)) ?? null;
916
- }
917
994
  if (rmNd.concept === 'ProcessV2') {
918
- env.processAssocBind = rmNd.bind;
995
+ env.processAssocEntity = rmNd.bind;
919
996
  }
920
997
  // const localVars = env.localVars.get(rmNd as any) ?? [];
921
- const refAndQNames = this.collectRefs(env, rmNd);
998
+ const refAndQNames = this.collectRefs(env, rmNd, skipSubView);
922
999
  for (const [ref, qName] of refAndQNames) {
923
1000
  // if (localVars.includes(qName) || cheapTestLocalSymbol(qName)) {
924
1001
  // continue;
@@ -939,36 +1016,31 @@ class ReferenceManager {
939
1016
  else if (rmNd.concept === 'BindAttribute' && !rmNd.expression && (0, update_nasl_fragment_1.isSpecialStringRefField)(rmNd.name)) {
940
1017
  (0, update_nasl_fragment_1.removeBindAttrRef)(this, rmNd);
941
1018
  }
942
- env.viewAssocProcess = null;
943
- env.processAssocBind = null;
1019
+ env.processAssocEntity = null;
944
1020
  };
945
1021
  /**
946
1022
  * @warning Only handle global symbols
947
1023
  * 仅收集全局符号的引用。外部优先调用此接口,不要直接调用 collectRefs
948
1024
  * 不是说输入是 global symbol,而是说对于任何输入,只收集内部对 global symbol 的引用
1025
+ * @param skipSubView 是否跳过子页面,增量场景调用较多,增量场景默认跳过
949
1026
  */
950
- this.addRefsForGlobalSym = (env, nd) => {
1027
+ this.addRefsForGlobalSym = (env, nd, skipSubView = true) => {
951
1028
  this.curFileNode = nd;
952
1029
  this.modeForCollect = "create" /* Operation.Create */;
953
- if (nd.concept === 'View' || nd.concept === 'BusinessComponent') {
954
- // 如果是 null,则设置为 null,否则会报错
955
- env.viewAssocProcess = env.processViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? null;
956
- }
957
1030
  if (nd.concept === 'ProcessV2') {
958
- env.processAssocBind = nd.bind;
1031
+ env.processAssocEntity = nd.bind;
959
1032
  }
960
- const refAndQNames = this.collectRefs(env, nd);
1033
+ const refAndQNames = this.collectRefs(env, nd, skipSubView);
961
1034
  const localVars = env.localVars.get(nd) ?? [];
962
1035
  for (const [ref, qName] of refAndQNames) {
963
- if (localVars.includes(qName) || cheapTestLocalSymbol(qName)) {
1036
+ if (localVars.includes(qName) || (0, exports.cheapTestLocalSymbol)(qName)) {
964
1037
  continue;
965
1038
  }
966
1039
  this.handleRefOp(env, "create" /* Operation.Create */, ref, qName);
967
1040
  }
968
1041
  this.modeForCollect = null;
969
1042
  this.curFileNode = undefined;
970
- env.viewAssocProcess = null;
971
- env.processAssocBind = null;
1043
+ env.processAssocEntity = null;
972
1044
  };
973
1045
  this.invalidateLocalSymCache = () => {
974
1046
  this.isLocalCacheValid = false;
@@ -1031,8 +1103,8 @@ class ReferenceManager {
1031
1103
  if (qName) {
1032
1104
  // Handle process reference in view
1033
1105
  if (env.viewAssocProcess && env.viewAssocProcess.name === ids[0].name) {
1034
- const ctxLogic = (0, nasl_concepts_1.getCtxLogicLike)(nd);
1035
- const ctxViewLike = (0, nasl_concepts_1.getCtxViewLike)(nd);
1106
+ const ctxLogic = toRaw((0, nasl_concepts_1.getCtxLogicLike)(nd));
1107
+ const ctxViewLike = toRaw((0, nasl_concepts_1.getCtxViewLike)(nd));
1036
1108
  const logicVars = env.localVars.get(ctxLogic);
1037
1109
  const viewVars = env.localVars.get(ctxViewLike);
1038
1110
  // 哇,是 Process.data.XXX 特殊引用 && avoid shadowing
@@ -1052,7 +1124,7 @@ class ReferenceManager {
1052
1124
  }
1053
1125
  }
1054
1126
  }
1055
- const objDefQNames = this.collectRefs(env, id0); // 第一个可能是复杂表达式,再收集一次
1127
+ const objDefQNames = this.collectRefs(env, id0, false); // 第一个可能是复杂表达式,再收集一次
1056
1128
  objDefQNames.forEach(([ref, qName]) => {
1057
1129
  // @ts-expect-error
1058
1130
  res.push([ref, qName]);
@@ -1067,12 +1139,15 @@ class ReferenceManager {
1067
1139
  // 是这样的,为了兼容 processVariable.variable1,前面的是匿名数据结构,只需要 variable1 的引用就行了
1068
1140
  let ndDef = this.getNodeDef(ty);
1069
1141
  if (ndDef && (ndDef.concept === 'Entity' || ndDef.concept === 'Structure' || ndDef.concept === 'Enum')) {
1070
- const propQName = (0, get_q_name_1.getPropQName)(`${ty.typeNamespace}.${ty.typeName}`, ids[i + 1].name, 'Entity');
1142
+ const propQName = (0, string_2.getPropQName)(`${ty.typeNamespace}.${ty.typeName}`, ids[i + 1].name, 'Entity');
1071
1143
  res.push([ids[i + 1], propQName]); // type reference
1072
1144
  }
1073
1145
  else {
1074
- const propQName = (0, get_q_name_1.prependNonEmptyStr)((0, get_q_name_1.prependNonEmptyStr)(ty.typeNamespace, ty.typeName), ids[i + 1].name);
1075
- res.push([ids[i + 1], propQName]);
1146
+ // 局部无 namespace 的定义应该不可能通过 a.x.y 这种成员访问引用到
1147
+ if (ty.typeNamespace && ty.typeName) {
1148
+ const propQName = (0, string_1.prependNonEmptyStr)((0, string_1.prependNonEmptyStr)(ty.typeNamespace, ty.typeName), ids[i + 1].name);
1149
+ res.push([ids[i + 1], propQName]);
1150
+ }
1076
1151
  }
1077
1152
  // update next ty and nextProp name
1078
1153
  let nextProp = undefined;
@@ -1147,7 +1222,7 @@ class ReferenceManager {
1147
1222
  const entityDef = this.qNameDefs.get(`${eNsp}.${eAsName}`);
1148
1223
  entityDef && res.push([nd, entityQName]);
1149
1224
  if (entityDef && pName) {
1150
- const propQName = (0, get_q_name_1.getPropQName)(entityQName, pName, 'Entity');
1225
+ const propQName = (0, string_2.getPropQName)(entityQName, pName, 'Entity');
1151
1226
  const prop = getEntityProp(pName, entityDef);
1152
1227
  prop && res.push([nd, propQName]);
1153
1228
  }
@@ -1162,9 +1237,12 @@ class ReferenceManager {
1162
1237
  }
1163
1238
  return res;
1164
1239
  };
1240
+ /**
1241
+ * FieldPermissionV2 是对 Entity 和其属性的特殊引用
1242
+ */
1165
1243
  this.splitFieldPermissionV2 = (env, nd) => {
1166
1244
  const res = [];
1167
- const bind = env.processAssocBind;
1245
+ const bind = env.processAssocEntity;
1168
1246
  if (!bind) {
1169
1247
  return res;
1170
1248
  }
@@ -1176,7 +1254,7 @@ class ReferenceManager {
1176
1254
  ? (0, get_q_name_1.getTokenQualifiedName)(entityRef.typeAnnotation) // data 是 Entity
1177
1255
  : (0, get_q_name_1.getTokenQualifiedName)(entityRef.typeAnnotation.typeArguments[0]); // relation_data 是 List<Entity>
1178
1256
  for (const sub of nd.subFieldPermissions) {
1179
- res.push([sub, (0, get_q_name_1.getPropQName)(entityQName, sub.propertyName, 'Entity')]);
1257
+ res.push([sub, (0, string_2.getPropQName)(entityQName, sub.propertyName, 'Entity')]);
1180
1258
  }
1181
1259
  return res;
1182
1260
  };
@@ -1263,7 +1341,7 @@ class ReferenceManager {
1263
1341
  this.fastBuildQNameDefs(toRaw(app));
1264
1342
  console.timeEnd('\x1b[44m\x1b[97m Reference manager: Build Qualified Name to Definition Map \x1b[0m');
1265
1343
  }
1266
- buildSymbolRefsForApp(env, app, symbolGraph) {
1344
+ buildSymbolRefsForApp(env, app) {
1267
1345
  console.time('\x1b[44m\x1b[97m Reference manager: Build Symbol to Reference Map \x1b[0m');
1268
1346
  // symbolGraph && this.buildSymbolRefsFromSymbolGraph(symbolGraph); // 方舟的,后面可能不好修 bug 和维护
1269
1347
  app && this.slowBuildSymbolRefsForApp(env, toRaw(app));
@@ -1410,13 +1488,6 @@ const isEntitiesLogicsPath = (str) => {
1410
1488
  */
1411
1489
  const isEntityLogic = (nd) => nd?.concept === 'Logic' && nd.getNamespace && isEntitiesLogicsPath(nd.getNamespace());
1412
1490
  exports.isEntityLogic = isEntityLogic;
1413
- const lowercaseFirstChar = (str) => {
1414
- if (str.length === 0) {
1415
- return str; // Return an empty string if the input is empty
1416
- }
1417
- return str.charAt(0).toLowerCase() + str.slice(1);
1418
- };
1419
- exports.lowercaseFirstChar = lowercaseFirstChar;
1420
1491
  /**
1421
1492
  * 处理 CodeWave 编译器的一些连带的自动化行为,如自动生成 { abc: Abc } 这样的匿名结构体。
1422
1493
  * 这里实质上是否是引用?这里不是直接引用,但是 entityX 这个名字是从 EntityX 自动生成的,也可以看作是间接引用
@@ -1426,7 +1497,7 @@ exports.lowercaseFirstChar = lowercaseFirstChar;
1426
1497
  const handleEntityAutoRef = (ty, nextProp, ident) => {
1427
1498
  const nextTy = nextProp?.typeAnnotation;
1428
1499
  if (ty.typeKind === 'anonymousStructure' &&
1429
- nextProp?.name === (0, exports.lowercaseFirstChar)(nextTy?.typeName ?? '')) {
1500
+ nextProp?.name === (0, string_1.lowercaseFirstChar)(nextTy?.typeName ?? '')) {
1430
1501
  const entityQName = `${nextTy?.typeNamespace}.${nextTy?.typeName}`;
1431
1502
  return [ident, entityQName];
1432
1503
  }
@@ -1498,13 +1569,33 @@ const cheapTestLocalSymbol = (qName) => {
1498
1569
  qName.startsWith('nasl.collection')) {
1499
1570
  return true;
1500
1571
  }
1501
- // 页面下引用的 Process 的 qName
1502
- // if (qName.startsWith('Process_')) {
1503
- // return false;
1504
- // }
1572
+ // 页面下引用的 Process 的 qName,一般是 Process_uniqueKey 的 hash
1573
+ if (qName.startsWith('Process_')) {
1574
+ return false;
1575
+ }
1505
1576
  if (qName.indexOf('.') === -1) {
1506
1577
  return true;
1507
1578
  }
1508
1579
  return false;
1509
1580
  };
1581
+ exports.cheapTestLocalSymbol = cheapTestLocalSymbol;
1582
+ /**
1583
+ * 一个 FileNode 下面还可以有其他 FileNode 哦,其实没什么神秘的。
1584
+ * @warning 只会返回下属的 FileNode,不包含自己
1585
+ * @param node
1586
+ * @returns 下属 FileNodes,不包含自己
1587
+ */
1588
+ const getSubViews = (node) => {
1589
+ const result = [];
1590
+ if (node.concept === 'View') {
1591
+ node.children?.forEach((nd) => {
1592
+ if (nd.concept === 'View') {
1593
+ result.push(nd);
1594
+ result.push(...(0, exports.getSubViews)(nd));
1595
+ }
1596
+ });
1597
+ }
1598
+ return result;
1599
+ };
1600
+ exports.getSubViews = getSubViews;
1510
1601
  //# sourceMappingURL=reference-manager.js.map