@lcap/nasl-language-server-core 4.4.0-beta.19 → 4.4.0-beta.21

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 (83) hide show
  1. package/out/checker.d.ts.map +1 -1
  2. package/out/checker.js +27 -4
  3. package/out/checker.js.map +1 -1
  4. package/out/index.d.ts +1 -1
  5. package/out/index.d.ts.map +1 -1
  6. package/out/index.js +5 -3
  7. package/out/index.js.map +1 -1
  8. package/out/reference-manager/build-q-name-def.js +2 -2
  9. package/out/reference-manager/build-q-name-def.js.map +1 -1
  10. package/out/reference-manager/builtin-q-name.js +2 -2
  11. package/out/reference-manager/builtin-q-name.js.map +1 -1
  12. package/out/reference-manager/collect-q-name.d.ts +1 -1
  13. package/out/reference-manager/collect-q-name.d.ts.map +1 -1
  14. package/out/reference-manager/collect-q-name.js +58 -24
  15. package/out/reference-manager/collect-q-name.js.map +1 -1
  16. package/out/reference-manager/def-key-helpers.d.ts +38 -0
  17. package/out/reference-manager/def-key-helpers.d.ts.map +1 -0
  18. package/out/reference-manager/{get-q-name.js → def-key-helpers.js} +176 -29
  19. package/out/reference-manager/def-key-helpers.js.map +1 -0
  20. package/out/reference-manager/helper.js +2 -2
  21. package/out/reference-manager/helper.js.map +1 -1
  22. package/out/reference-manager/reference-manager.d.ts +24 -52
  23. package/out/reference-manager/reference-manager.d.ts.map +1 -1
  24. package/out/reference-manager/reference-manager.js +222 -219
  25. package/out/reference-manager/reference-manager.js.map +1 -1
  26. package/out/reference-manager/remove-q-name.d.ts +1 -1
  27. package/out/reference-manager/remove-q-name.d.ts.map +1 -1
  28. package/out/reference-manager/remove-q-name.js +7 -10
  29. package/out/reference-manager/remove-q-name.js.map +1 -1
  30. package/out/reference-manager/rename-q-name.d.ts +26 -26
  31. package/out/reference-manager/rename-q-name.d.ts.map +1 -1
  32. package/out/reference-manager/rename-q-name.js +48 -167
  33. package/out/reference-manager/rename-q-name.js.map +1 -1
  34. package/out/reference-manager/symbol-type.d.ts +4 -4
  35. package/out/reference-manager/symbol-type.d.ts.map +1 -1
  36. package/out/reference-manager/symbol-type.js +1 -1
  37. package/out/reference-manager/symbol-type.js.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.js +2 -2
  41. package/out/typer/collectGlobalDefs.js.map +1 -1
  42. package/out/typer/component-def-manager/component-def-manager.js +2 -2
  43. package/out/typer/component-def-manager/component-def-manager.js.map +1 -1
  44. package/out/typer/component-def-manager/utils.d.ts.map +1 -1
  45. package/out/typer/component-def-manager/utils.js +3 -2
  46. package/out/typer/component-def-manager/utils.js.map +1 -1
  47. package/out/typer/dispatch-all.js +2 -2
  48. package/out/typer/dispatch-all.js.map +1 -1
  49. package/out/typer/dispatch-call.js +3 -3
  50. package/out/typer/dispatch-call.js.map +1 -1
  51. package/out/typer/dispatch-def.js +3 -3
  52. package/out/typer/dispatch-def.js.map +1 -1
  53. package/out/typer/dispatch-expr.js +7 -7
  54. package/out/typer/dispatch-expr.js.map +1 -1
  55. package/out/typer/dispatch-process.js +3 -3
  56. package/out/typer/dispatch-process.js.map +1 -1
  57. package/out/typer/dispatch-view.d.ts.map +1 -1
  58. package/out/typer/dispatch-view.js +8 -13
  59. package/out/typer/dispatch-view.js.map +1 -1
  60. package/out/typer/get-oql-files.js +1 -1
  61. package/out/typer/get-oql-files.js.map +1 -1
  62. package/out/typer/incremental-update.js +8 -8
  63. package/out/typer/incremental-update.js.map +1 -1
  64. package/out/typer/overload-helper.js +2 -2
  65. package/out/typer/overload-helper.js.map +1 -1
  66. package/out/typer/subster.js +4 -4
  67. package/out/typer/subster.js.map +1 -1
  68. package/out/typer/topo-sort.js +4 -4
  69. package/out/typer/topo-sort.js.map +1 -1
  70. package/out/typer/type-predicate.js +3 -3
  71. package/out/typer/type-predicate.js.map +1 -1
  72. package/out/typer/typer.d.ts +2 -2
  73. package/out/typer/typer.d.ts.map +1 -1
  74. package/out/typer/typer.js +25 -26
  75. package/out/typer/typer.js.map +1 -1
  76. package/package.json +5 -5
  77. package/out/reference-manager/get-q-name.d.ts +0 -14
  78. package/out/reference-manager/get-q-name.d.ts.map +0 -1
  79. package/out/reference-manager/get-q-name.js.map +0 -1
  80. package/out/reference-manager/view-elem-logic.d.ts +0 -44
  81. package/out/reference-manager/view-elem-logic.d.ts.map +0 -1
  82. package/out/reference-manager/view-elem-logic.js +0 -181
  83. package/out/reference-manager/view-elem-logic.js.map +0 -1
@@ -7,7 +7,7 @@ const fp_macros_1 = require("../utils/fp-macros");
7
7
  const console_1 = require("console");
8
8
  const builtin_q_name_1 = require("./builtin-q-name");
9
9
  const build_q_name_def_1 = require("./build-q-name-def");
10
- const get_q_name_1 = require("./get-q-name");
10
+ const def_key_helpers_1 = require("./def-key-helpers");
11
11
  const typer_1 = require("../typer");
12
12
  const type_predicate_1 = require("../typer/type-predicate");
13
13
  const helper_1 = require("../typer/helper");
@@ -21,7 +21,6 @@ const type_manager_1 = require("../typer/type-manager");
21
21
  const oql_1 = require("../utils/oql");
22
22
  const string_2 = require("../utils/string");
23
23
  const traverse_util_1 = require("../utils/traverse-util");
24
- const view_elem_logic_1 = require("./view-elem-logic");
25
24
  const helper_2 = require("./helper");
26
25
  const misc_1 = require("../utils/misc");
27
26
  const asserts_1 = require("@lcap/nasl-concepts/asserts");
@@ -46,7 +45,7 @@ class ReferenceManager {
46
45
  static { this.defConcept = symbol_type_1.defConcept; } /** imported */
47
46
  static { this.compositeNodeConcept = symbol_type_1.compositeNodeConcept; } /** imported */
48
47
  static { this.connectionNsp = 'app.connections'; }
49
- // gQNameDefs 和 symbolRefs 的构建时机不一样,所以不放在构造器中
48
+ // gQNameDefs 和 globalRefs 的构建时机不一样,所以不放在构造器中
50
49
  constructor() {
51
50
  // qualified names to definition memory address for GLOBAL DEFINITIONS
52
51
  this.gQNameDefs = new Map();
@@ -65,33 +64,26 @@ class ReferenceManager {
65
64
  *
66
65
  * 将实体看成 namespace,所有引用实体逻辑的地方也算引用了实体?
67
66
  */
68
- this.gSymbolRefs = new Map; // 手动管理,小心内存泄漏
69
- // Accessor methods for symbolRefs to normalize input later
67
+ this.globalRefs = new Map; // 手动管理,小心内存泄漏
68
+ // Accessor methods for globalRefs to normalize input later
70
69
  this.getSymbolRefs = (__def) => {
71
70
  const def = this.normaliseEntityLogic(__def);
72
- return this.gSymbolRefs.get(def);
71
+ return this.globalRefs.get(def);
73
72
  };
74
73
  this.setSymbolRefs = (__def, refs) => {
75
74
  const def = this.normaliseEntityLogic(__def);
76
- this.gSymbolRefs.set(def, refs);
75
+ this.globalRefs.set(def, refs);
77
76
  };
78
77
  this.deleteSymbolRefs = (__def) => {
79
78
  const def = this.normaliseEntityLogic(__def);
80
- return this.gSymbolRefs.delete(def);
79
+ return this.globalRefs.delete(def);
81
80
  };
82
- this.clearSymbolRefs = () => {
83
- this.gSymbolRefs.clear();
81
+ this.clearGlobalRefs = () => {
82
+ this.globalRefs.clear();
84
83
  };
85
- this.getSymbolRefsSize = () => {
86
- return this.gSymbolRefs.size;
84
+ this.getGlobalRefsSize = () => {
85
+ return this.globalRefs.size;
87
86
  };
88
- // 辅助 map
89
- this.veQNameDefs = new Map();
90
- /**
91
- * @warning ViewElement 和 Logic 都是局部符号,可以重名,qName 重复时会出错,不要搞这种例子谢谢
92
- * key 是 memory addr 而不是 string 的原因:点查找引用时,不好高效获取 qName(如 Logic 没有 namespace 但调用处其实有,对的就是 elements.)
93
- */
94
- this.veRefs = new Map();
95
87
  // 当前的 collectRefs 是增加还是删除引用。先这样吧,没时间重构了……
96
88
  this.modeForCollect = null;
97
89
  /**
@@ -133,8 +125,8 @@ class ReferenceManager {
133
125
  // 上一次查找引用局部符号建立的 cache
134
126
  this.lastBoundary = undefined;
135
127
  this.isLocalCacheValid = true;
136
- /** local qName refs 局部符号的引用 */
137
- this.lQNameRefs = new Map();
128
+ /** 局部符号的引用,key getLocalDefKey 返回值(作用域内简单名或完整路径) */
129
+ this.localRefs = new Map();
138
130
  // 当前文件节点
139
131
  this.curFileNode = undefined;
140
132
  /**
@@ -191,7 +183,7 @@ class ReferenceManager {
191
183
  * declaration for each variable name is returned (nearest-first ordering).
192
184
  *
193
185
  * Implementation notes:
194
- * - We intentionally DO NOT depend on the (ephemeral) lexicalVarStacks in SemEnv so
186
+ * - We intentionally DO NOT depend on the (ephemeral) localDefStacks in SemEnv so
195
187
  * this works post-typing (e.g. in reference / rename / hover providers) without
196
188
  * re-running the typer.
197
189
  * - Order:
@@ -218,20 +210,21 @@ class ReferenceManager {
218
210
  const localSyms = this.getVisibleLocalSyms(node, options);
219
211
  const localVars = localSyms.filter(service_1.isLocalVar);
220
212
  const collected = Array.from(localVars);
221
- const seen = new Set(localSyms.map(v => (0, get_q_name_1.getTokenQualifiedName)(v)));
213
+ // 用于 shadowing 去重,需用 getLocalDefKey 与引用时的 key 一致
214
+ const seen = new Set(localSyms.map(v => (0, def_key_helpers_1.getLocalDefKey)(v) ?? (0, def_key_helpers_1.getGlobalDefKey)(v)));
222
215
  const seenNames = new Set(localVars.map(v => v?.name).filter(Boolean));
223
216
  // View-specific: stitch in process variables allocated during typing
224
217
  this.stitchProcessVarsForView(node, env, includeShadowed, predicate, collected, seenNames);
225
218
  this.stitchValidationVarsForView(node, env, includeShadowed, predicate, collected, seenNames);
226
219
  const feVars = getNearestFrontendVars(node);
227
220
  for (const v of feVars) {
228
- const vQName = (0, get_q_name_1.getTokenQualifiedName)(v);
229
- if (!vQName)
221
+ const vKey = (0, def_key_helpers_1.getLocalDefKey)(v) ?? (0, def_key_helpers_1.getGlobalDefKey)(v);
222
+ if (!vKey)
230
223
  continue;
231
224
  if (!includeShadowed) {
232
- if (seen.has(vQName))
225
+ if (seen.has(vKey))
233
226
  continue;
234
- seen.add(vQName);
227
+ seen.add(vKey);
235
228
  }
236
229
  if (predicate && !predicate(v))
237
230
  continue;
@@ -290,7 +283,7 @@ class ReferenceManager {
290
283
  const vars = this.localSymBindings.get(cur);
291
284
  if (vars && vars.length > 0) {
292
285
  for (const v of vars) {
293
- const vQName = (0, get_q_name_1.getTokenQualifiedName)(v);
286
+ const vQName = (0, def_key_helpers_1.getGlobalDefKey)(v);
294
287
  if (!vQName)
295
288
  continue;
296
289
  if (!includeShadowed) {
@@ -373,7 +366,7 @@ class ReferenceManager {
373
366
  const def = this.gQNameDefs.get(qName);
374
367
  if (def) {
375
368
  // Add reference to existing definition
376
- (0, helper_1.createSetOnPush)(this.gSymbolRefs, def, ref);
369
+ (0, helper_1.createSetOnPush)(this.globalRefs, def, ref);
377
370
  }
378
371
  else {
379
372
  // Cache reference for future relinking
@@ -411,10 +404,6 @@ class ReferenceManager {
411
404
  this.modeForCollect = null;
412
405
  };
413
406
  this.addQNameDefs = (0, build_q_name_def_1.mkAddQNameDefs)(this.gQNameDefs, this.compDefMgr);
414
- /** 注释见具体实现 */
415
- this.addViewElementLogicQNameDefs = (0, view_elem_logic_1.mkAddViewElementLogicQNameDefs)(this.veQNameDefs, this.gQNameDefs);
416
- /** 注释见具体实现 */
417
- this.addViewElementLogicRefs = (0, view_elem_logic_1.mkAddViewElementBindLogicRefs)(this.veQNameDefs, this.veRefs);
418
407
  this.queryQNameDef = (qName) => {
419
408
  const res = this.gQNameDefs.get(qName);
420
409
  if (!res) {
@@ -474,31 +463,12 @@ class ReferenceManager {
474
463
  }
475
464
  };
476
465
  /**
477
- * 重要对外接口,查找符号的定义
478
- * @param ref
479
- * @returns
466
+ * 查找符号的定义(含全局符号、View/BC 内 logics 等,均已在 gQNameDefs 中注册)
480
467
  */
481
468
  this.getNodeDef = (ref) => {
482
- const qName = (0, get_q_name_1.getTokenQualifiedName)(ref);
469
+ const qName = (0, def_key_helpers_1.getGlobalDefKey)(ref);
483
470
  return qName ? this.gQNameDefs.get(qName) : undefined;
484
471
  };
485
- /**
486
- * 查找符号的定义,同时查找全局定义和 View 级别的定义
487
- * 用于构建调用图时查找 View 级别的 logics
488
- * @param ref
489
- * @returns
490
- */
491
- this.getNodeDefIncludingView = (ref) => {
492
- const qName = (0, get_q_name_1.getTokenQualifiedName)(ref);
493
- if (!qName)
494
- return undefined;
495
- // 先查找全局定义
496
- const globalDef = this.gQNameDefs.get(qName);
497
- if (globalDef)
498
- return globalDef;
499
- // 再查找 View 级别的定义
500
- return this.veQNameDefs.get(qName);
501
- };
502
472
  /**
503
473
  * @warning 对外接口,指用户点击 "查找引用",只返回用户手动指定的引用
504
474
  * @param __nd 要查找引用的定义
@@ -507,28 +477,25 @@ class ReferenceManager {
507
477
  this.getReferences = (env, __nd) => {
508
478
  let nd = this.normaliseEntityLogic((0, misc_1.toRaw)(__nd));
509
479
  let res = new Set();
510
- // 逻辑/页面参数:外部引用在 gSymbolRefs(CallLogic 实参),内部引用在 lQNameRefs(Logic 体内同名标识符)
511
- // 仅当 parent 为 Logic/View/BusinessLogic 时才用 gQNameDefs 查外部引用,否则 getParamDefQName 只返回 nd.name,会误匹配其它 def
480
+ // 逻辑/页面参数:外部引用在 globalRefs(CallLogic 实参),内部引用在 localRefs(Logic 体内同名标识符)
512
481
  if (nd.concept === 'Param' || nd.concept === 'ParamWithGroup') {
513
- const paramQName = (0, get_q_name_1.getParamDefQName)(nd);
482
+ const paramQName = (0, def_key_helpers_1.getGlobalDefKey)(nd);
514
483
  const isParamOfLogicOrView = (0, symbol_type_1.isLogicViewLike)(nd.parentNode);
515
484
  const def = isParamOfLogicOrView && paramQName ? this.gQNameDefs.get(paramQName) : undefined;
516
485
  const externalRefs = def ? this.getSymbolRefs(def) ?? new Set() : new Set();
517
486
  const boundary = (0, helper_2.getBoundary)(nd);
518
487
  if (boundary && (this.lastBoundary !== boundary || !this.isLocalCacheValid)) {
519
- this.lQNameRefs.clear();
520
- this.veQNameDefs.clear();
521
- this.veRefs.clear();
522
- this.timeAndLog('Get reference: collect local refs for Param', this.buildMinimalLocalQNameRefs, env, nd);
488
+ this.localRefs.clear();
489
+ this.timeAndLog('Get reference: collect local refs for Param', this.buildLocalRefs, env, nd);
523
490
  }
524
- const localQName = nd.name;
525
- const internalRefs = (localQName && this.lQNameRefs.get(localQName)) ?? new Set();
491
+ const localKey = (0, def_key_helpers_1.getLocalDefKey)(nd) ?? nd.name;
492
+ const internalRefs = (localKey && this.localRefs.get(localKey)) ?? new Set();
526
493
  res = mnemonist_1.set.union(externalRefs, internalRefs);
527
494
  return Array.from(res);
528
495
  }
529
496
  // 比如 OverriddenLogic 和对应的 Logic 名字一样,但引用挂在 Logic 上
530
497
  // 比如 实体对应的实体逻辑可能有多份内存地址,归结到现存的一份上
531
- // nd = this.gQNameDefs.get(getTokenQualifiedName(nd)!)!;
498
+ // nd = this.gQNameDefs.get(getGlobalDefKey(nd)!)!;
532
499
  // ==> 好像也不行,很多依赖库逻辑调用又挂了
533
500
  const boundary = (0, helper_2.getBoundary)(nd);
534
501
  // 全局符号直接查找
@@ -539,7 +506,7 @@ class ReferenceManager {
539
506
  if (pConn && boundary) {
540
507
  // 那么它也就是个连接器下的局部符号
541
508
  const qNameRefs = this.collectRefs(env, boundary); // 注意,从 boundary 开始就行,不是从 connector 开始
542
- const ndQName = (0, get_q_name_1.getTokenQualifiedName)(nd);
509
+ const ndQName = (0, def_key_helpers_1.getGlobalDefKey)(nd);
543
510
  for (const [ref, qName] of qNameRefs) {
544
511
  qName === ndQName && res.add(ref);
545
512
  }
@@ -550,27 +517,28 @@ class ReferenceManager {
550
517
  // 局部符号需要即时获取
551
518
  // 从缓存中获取
552
519
  if (this.lastBoundary === boundary && this.isLocalCacheValid) {
553
- res = this.lQNameRefs.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? new Set();
554
- // 此处的 Logic 必然不是全局逻辑
555
- // @ts-expect-error 目前的 AST 设计,ViewElement 既是引用又是定义
520
+ const localKey = (0, def_key_helpers_1.getLocalDefKey)(nd) ?? (0, def_key_helpers_1.getGlobalDefKey)(nd);
521
+ const lRefs = localKey ? (this.localRefs.get(localKey) ?? new Set()) : new Set();
522
+ const gRefs = this.getSymbolRefs(nd) ?? new Set();
556
523
  if (nd.concept === 'ViewElement' || nd.concept === 'Logic' || nd.concept === 'BusinessLogic' || nd.concept === 'Event') {
557
- res = mnemonist_1.set.union(res, this.getViewElementRefs(nd));
524
+ res = mnemonist_1.set.union(lRefs, gRefs);
525
+ }
526
+ else {
527
+ res = lRefs;
558
528
  }
559
529
  }
560
530
  else {
561
531
  // 局部扫描,建立所有局部引用
562
- this.lQNameRefs.clear();
563
- this.veQNameDefs.clear();
564
- this.veRefs.clear();
565
- this.timeAndLog('Get reference: collect local refs', this.buildMinimalLocalQNameRefs, env, nd);
566
- res = mnemonist_1.set.union(res, this.lQNameRefs.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? new Set());
567
- // @ts-expect-error 同上,并且虽然 BindEvent 本身没引用但是要触发对 view 建立引用
532
+ this.localRefs.clear();
533
+ this.timeAndLog('Get reference: collect local refs', this.buildLocalRefs, env, nd);
534
+ const localKey = (0, def_key_helpers_1.getLocalDefKey)(nd) ?? (0, def_key_helpers_1.getGlobalDefKey)(nd);
535
+ res = mnemonist_1.set.union(res, (localKey ? (this.localRefs.get(localKey) ?? new Set()) : new Set()));
568
536
  if (nd.concept === 'ViewElement' || nd.concept === 'Logic' || nd.concept === 'BusinessLogic' || nd.concept === 'BindEvent' || nd.concept === 'Event') {
569
537
  const ctxViewLike = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxViewLike)(nd));
570
- this.timeAndLog('Get reference: build view element logic qName defs cache', this.addViewElementLogicQNameDefs, ctxViewLike);
571
- this.timeAndLog('Get reference: build view element refs cache', this.addViewElementLogicRefs, ctxViewLike);
572
- // @ts-expect-error get 出来一个 undefined 无所谓
573
- res = mnemonist_1.set.union(res ?? new Set(), this.getViewElementRefs(nd));
538
+ if (ctxViewLike) {
539
+ this.timeAndLog('Get reference: build view element refs cache', this.buildLocalRefs, env, ctxViewLike);
540
+ }
541
+ res = mnemonist_1.set.union(res ?? new Set(), this.getSymbolRefs(nd) ?? new Set());
574
542
  }
575
543
  }
576
544
  }
@@ -580,25 +548,24 @@ class ReferenceManager {
580
548
  * 业务逻辑在页面调用的时候,名字前缀是随着业务组件实例名字而变化的,几乎是全应用查找……
581
549
  */
582
550
  if (nd.concept === 'BusinessLogic') {
583
- // 上面已经找到了业务组件内部对业务组件逻辑的内用
551
+ // 上面已经找到了业务组件内部对业务组件逻辑的引用(localRefs)
584
552
  // 现在再找出所有 业务组件逻辑 所属的业务组件的外部引用
553
+ // buildLocalRefs 会把页面中 elements.bs-xxx.logics.myLogic 的调用写入 globalRefs(BusinessLogic)
585
554
  const bs = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxViewLike)(nd));
586
555
  if (bs?.concept === 'BusinessComponent') {
587
556
  const bsRefs = this.getSymbolRefs(bs) ?? new Set();
588
- let bsRefsRefs = new Array(); // 业务组件(在页面的引用)的引用
589
557
  /**
590
- * 再对每个实例找到所有引用
558
+ * 对每个 BC 实例所在的页面扫描,buildLocalRefs 会把外部引用写入 globalRefs(nd)
591
559
  * @warning 造孽,引用业务组件的每个 view 都要扫描一遍,应该很慢
592
560
  */
593
561
  const startTime = Date.now();
594
562
  for (const bsInst of bsRefs) {
595
563
  const ctxViewLike = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxViewLike)(bsInst));
596
- this.addViewElementLogicQNameDefs(ctxViewLike);
597
- this.addViewElementLogicRefs(ctxViewLike);
598
- bsRefsRefs.push(...this.getViewElementRefs(bsInst));
564
+ if (ctxViewLike)
565
+ this.buildLocalRefs(env, ctxViewLike);
599
566
  }
600
- // 再从引用中过滤出找到当前业务逻辑的调用
601
- res = mnemonist_1.set.union(res, new Set(bsRefsRefs.filter(r => r.concept === 'CallLogic' && r.calleeName === nd.name))); // amazing!
567
+ // 外部引用已写入 globalRefs(BusinessLogic),直接取
568
+ res = mnemonist_1.set.union(res, this.getSymbolRefs(nd) ?? new Set());
602
569
  const endTime = Date.now();
603
570
  if (endTime - startTime > 200) {
604
571
  console.log(`Get reference: complex business logic took ${endTime - startTime}ms`);
@@ -611,7 +578,7 @@ class ReferenceManager {
611
578
  const allLogics = [...conn.logics, ...conn.namespaces.flatMap(nsp => nsp.logics)];
612
579
  for (const l of allLogics) {
613
580
  // ConnectorLogic,发布态的连接器里外都有调用,真是里外不是人啊。
614
- res = mnemonist_1.set.union(res, this.gSymbolRefs.get(l) ?? new Set());
581
+ res = mnemonist_1.set.union(res, this.globalRefs.get(l) ?? new Set());
615
582
  }
616
583
  }
617
584
  // 加上所有实体逻辑调用的引用(实体逻辑可看做无定义,但要修改调用处的 namespace:实体名是 namespace 的一部分)
@@ -632,17 +599,15 @@ class ReferenceManager {
632
599
  };
633
600
  /**
634
601
  * 给类似 FileNode 级别的定义建立局部引用记录
635
- * @warning 不包括 ViewElement、BindEvent 相关的引用,那个在 @link addViewElementLogicRefs
602
+ * @warning 不包括 ViewElement、BindEvent 相关的引用,已合并到 getLocalDefKeys 与 collectedRefs 处理
636
603
  * @warning 需要包括 SubLogics
637
604
  */
638
- this.buildMinimalLocalQNameRefs = (env, __nd) => {
605
+ this.buildLocalRefs = (env, __nd) => {
639
606
  this.modeForCollect = "create" /* Operation.Create */;
640
607
  const nd = (0, misc_1.toRaw)(__nd);
641
608
  let logicVars = new Array();
642
609
  let viewVars = new Array();
643
610
  let processVars = new Array();
644
- /** @warning v4.1 开始,view logics 不在这里处理,在 @link veQNameRefs 那里处理 */
645
- let isViewLike = false;
646
611
  const boundary = (0, helper_2.getBoundary)(nd);
647
612
  if (!boundary) {
648
613
  return new Set();
@@ -653,7 +618,33 @@ class ReferenceManager {
653
618
  if (ctxLogic && 'variables' in ctxLogic) {
654
619
  logicVars.push(...ctxLogic.variables?.map(misc_1.toRaw) ?? []);
655
620
  }
656
- isViewLike = true;
621
+ // View/BC 内 logics、events、elements 的引用走 localRefs,需预先初始化 key
622
+ const viewLike = boundary;
623
+ const viewQ = (0, def_key_helpers_1.getGlobalDefKey)(viewLike);
624
+ (viewLike.logics ?? []).forEach((l) => {
625
+ const q = (0, def_key_helpers_1.getLocalDefKey)(l) ?? (0, def_key_helpers_1.getGlobalDefKey)(l);
626
+ q && this.localRefs.set(q, new Set());
627
+ });
628
+ (viewLike.events ?? []).forEach((e) => {
629
+ const q = (0, def_key_helpers_1.getLocalDefKey)(e) ?? (0, def_key_helpers_1.getGlobalDefKey)(e);
630
+ q && this.localRefs.set(q, new Set());
631
+ });
632
+ for (const be of viewLike.bindEvents ?? []) {
633
+ for (const l of be.logics ?? []) {
634
+ this.localRefs.set(`${viewQ}.bindEvents.${be.name}.logics.${l.name}`, new Set());
635
+ }
636
+ }
637
+ const initElemKeys = (ve, parentNsp, parentKey = 'elements') => {
638
+ const elemKey = `${parentNsp}.${parentKey}.${ve.name}`;
639
+ this.localRefs.set(elemKey, new Set());
640
+ for (const be of ve.bindEvents ?? []) {
641
+ for (const l of be.logics ?? []) {
642
+ this.localRefs.set(`${elemKey}.bindEvents.${be.name}.logics.${l.name}`, new Set());
643
+ }
644
+ }
645
+ ve.children?.forEach((c) => initElemKeys(c, elemKey, 'children'));
646
+ };
647
+ (viewLike.elements ?? []).forEach((ve) => initElemKeys(ve, viewQ, 'elements'));
657
648
  }
658
649
  else if (boundary.concept === 'ProcessDefinitionV2') {
659
650
  processVars = (0, nasl_concepts_1.getProcessVars)(nd).map(misc_1.toRaw);
@@ -666,34 +657,47 @@ class ReferenceManager {
666
657
  logicVars = (0, nasl_concepts_1.getLogicVars)(nd).map(misc_1.toRaw);
667
658
  }
668
659
  let allVars = logicVars.concat(processVars).concat(viewVars);
669
- // initialize local cache
660
+ let collectedRefs = this.collectRefs(env, boundary, true);
661
+ this.lastBoundary = boundary;
662
+ // initialize local cache: 局部变量用 getLocalDefKey;Entity/Structure 属性用 collectRefs 返回的 qName(全局 key)
670
663
  allVars.forEach(def => {
671
- const qName = (0, get_q_name_1.getTokenQualifiedName)(def);
664
+ const qName = (0, def_key_helpers_1.getLocalDefKey)(def) ?? (0, def_key_helpers_1.getGlobalDefKey)(def);
672
665
  if (qName) {
673
- this.lQNameRefs.set(qName, new Set());
666
+ this.localRefs.set(qName, new Set());
674
667
  }
675
668
  });
676
- let subRefs = this.collectRefs(env, boundary, true);
677
- this.lastBoundary = boundary;
678
- subRefs?.forEach(([rf, qName]) => {
679
- // 不存在则表示不是局部符号
680
- this.lQNameRefs.get(qName)?.add(rf);
669
+ collectedRefs?.forEach(([rf, qName]) => {
670
+ if (rf.concept === 'Identifier' && qName.includes('.properties.')) {
671
+ this.localRefs.set(qName, this.localRefs.get(qName) ?? new Set());
672
+ }
673
+ });
674
+ collectedRefs?.forEach(([rf, qName]) => {
675
+ const isEntityOrStructPropRef = rf.concept === 'Identifier' && qName.includes('.properties.');
676
+ const keys = (0, def_key_helpers_1.getLocalDefKeys)(rf);
677
+ const keysToUse = isEntityOrStructPropRef ? [qName] : (keys.length > 0 ? keys : [qName]);
678
+ for (const key of keysToUse) {
679
+ // 简单名 key 不加入属性名 Identifier(NewComposite/BatchAssignment 等)
680
+ if (!key.includes('.') && (0, def_key_helpers_1.isIdentifierAsPropertyName)(rf))
681
+ continue;
682
+ this.localRefs.get(key)?.add(rf);
683
+ }
684
+ // 页面调用 BC 逻辑:外部引用 -> globalRefs
685
+ if (rf.concept === 'CallLogic' && rf.calleeNamespace?.startsWith('elements.') && rf.calleeNamespace?.endsWith('.logics')) {
686
+ const def = this.gQNameDefs.get(qName);
687
+ def && (0, fp_macros_1.createOnAdd)(this.globalRefs, def, rf);
688
+ }
689
+ // Entity/Structure 属性引用 -> globalRefs
690
+ if (isEntityOrStructPropRef) {
691
+ const def = this.gQNameDefs.get(qName);
692
+ def && (0, fp_macros_1.createOnAdd)(this.globalRefs, def, rf);
693
+ }
681
694
  });
682
695
  // Note: 暂不支持 BindAttr、BindDirective 里的变量的查找引用
683
696
  this.isLocalCacheValid = true;
684
697
  this.modeForCollect = null;
685
698
  };
686
- /**
687
- * References to view elements are calls of component logic and access of properties
688
- * 'elements.uLinearLayout1.logics.openLoading'
689
- *
690
- * 'elements.uLinearLayout1.property.uLinearLayout1._if._if'
691
- * "concept": "Identifier",
692
- * "namespace": "elements.uLinearLayout1.property",
693
- * "name": "uLinearLayout1",
694
- *
695
- */
696
- this.getViewElementRefs = (nd) => !nd ? new Set() : this.veRefs.get(nd) ?? new Set();
699
+ /** @deprecated 使用 getSymbolRefs,保留仅为兼容 */
700
+ this.getViewElementRefs = (nd) => !nd ? new Set() : this.getSymbolRefs(nd) ?? new Set();
697
701
  /**
698
702
  * 非常危险,但是先这样吧
699
703
  */
@@ -829,8 +833,8 @@ class ReferenceManager {
829
833
  */
830
834
  this.isRefStillReferencingQName = (ref, qName) => {
831
835
  try {
832
- // 通过 getTokenQualifiedName 获取引用节点当前引用的 qName
833
- const currentQName = (0, get_q_name_1.getTokenQualifiedName)(ref);
836
+ // 通过 getGlobalDefKey 获取引用节点当前引用的 qName
837
+ const currentQName = (0, def_key_helpers_1.getGlobalDefKey)(ref);
834
838
  // 检查是否还引用原来的 qName
835
839
  return currentQName === qName;
836
840
  }
@@ -930,7 +934,7 @@ class ReferenceManager {
930
934
  return;
931
935
  }
932
936
  for (const p of nd.params) {
933
- const pq = (0, get_q_name_1.getParamDefQName)(p);
937
+ const pq = (0, def_key_helpers_1.getGlobalDefKey)(p);
934
938
  if (pq) {
935
939
  this.gQNameDefs.set(pq, p);
936
940
  }
@@ -945,7 +949,7 @@ class ReferenceManager {
945
949
  return;
946
950
  }
947
951
  for (const p of nd.params) {
948
- const pq = (0, get_q_name_1.getParamDefQName)(p);
952
+ const pq = (0, def_key_helpers_1.getGlobalDefKey)(p);
949
953
  if (pq) {
950
954
  this.gQNameDefs.delete(pq);
951
955
  this.deleteSymbolRefs(p);
@@ -953,25 +957,22 @@ class ReferenceManager {
953
957
  }
954
958
  };
955
959
  /**
956
- * 对「调用该 Logic/View 的所有 CallLogic/Destination」重新收集参数引用,把参数引用加进 gSymbolRefs
960
+ * 对「调用该 Logic/View/BusinessComponent 的所有 CallLogic/Destination/ViewElement」重新收集参数引用,把参数引用加进 globalRefs
957
961
  * syncParamsOfLogicOrView 与 registerNewParamAndRecollectRefs 共用,避免重复逻辑。
962
+ * 所有 callers 均在 globalRefs。
958
963
  */
959
964
  this.recollectParamRefsForCallers = (env, logicQName) => {
960
965
  const logicDef = this.gQNameDefs.get(logicQName);
961
- if (!logicDef)
962
- return;
963
- const callers = this.getSymbolRefs(logicDef);
966
+ const callers = logicDef ? this.getSymbolRefs(logicDef) : undefined;
964
967
  if (!callers?.size)
965
968
  return;
966
969
  const prevMode = this.modeForCollect;
967
970
  this.modeForCollect = "create" /* Operation.Create */;
968
971
  try {
969
972
  for (const ref of callers) {
970
- if (ref.concept === 'CallLogic') {
971
- this.handleCallLogicParamRefs(env, ref);
972
- }
973
- else if (ref.concept === 'Destination') {
974
- this.handleDestinationParamRefs(env, ref);
973
+ if (ref.concept === 'CallLogic' || ref.concept === 'Destination'
974
+ || (ref.concept === 'ViewElement' && ref.tag?.startsWith('bs-'))) {
975
+ this.handleCallerParamRefs(env, ref);
975
976
  }
976
977
  }
977
978
  }
@@ -986,35 +987,35 @@ class ReferenceManager {
986
987
  this.recollectParamRefsForDef = (env, defNode) => {
987
988
  if (!(0, symbol_type_1.isLogicViewLike)(defNode))
988
989
  return;
989
- const qName = (0, get_q_name_1.getTokenQualifiedName)(defNode);
990
+ const qName = (0, def_key_helpers_1.getGlobalDefKey)(defNode);
990
991
  if (qName)
991
992
  this.recollectParamRefsForCallers(env, qName);
992
993
  };
993
994
  /**
994
- * Logic/View/BusinessLogic 参数列表变更时同步 gQNameDefs 与 gSymbolRefs
995
+ * Logic/View/BusinessLogic 参数列表变更时同步 gQNameDefs 与 globalRefs
995
996
  * - 仅卸载「已删除」的参数,避免把内部引用清空。
996
997
  * - 仍存在的参数:把 refs 从旧 def 迁移到新 def,并更新 gQNameDefs。
997
998
  * - 新加参数:只做注册。
998
- * - 最后对「调用该 Logic/View 的所有 CallLogic」重新收集参数引用,把新参数的引用加进 gSymbolRefs
999
+ * - 最后对「调用该 Logic/View 的所有 CallLogic」重新收集参数引用,把新参数的引用加进 globalRefs
999
1000
  */
1000
1001
  this.syncParamsOfLogicOrView = (env, updatedDefNode, oldDefNode) => {
1001
1002
  const updated = updatedDefNode;
1002
1003
  const old = oldDefNode;
1003
1004
  if (!(0, symbol_type_1.isLogicViewLike)(updated))
1004
1005
  return;
1005
- const logicQName = (0, get_q_name_1.getTokenQualifiedName)(updatedDefNode);
1006
+ const logicQName = (0, def_key_helpers_1.getGlobalDefKey)(updatedDefNode);
1006
1007
  if (!logicQName)
1007
1008
  return;
1008
1009
  const oldParams = old.params ?? [];
1009
1010
  const newParams = updated.params ?? [];
1010
1011
  const newParamNames = new Set(newParams.map((p) => p?.name));
1011
1012
  const oldParamNames = new Set(oldParams.map((p) => p?.name));
1012
- // 只卸载已删除的参数,用 getParamDefQName(p) 与注册时 key 一致,避免 name 为空时 key 不一致
1013
+ // 只卸载已删除的参数,用 getGlobalDefKey(p) 与注册时 key 一致
1013
1014
  for (const p of oldParams) {
1014
1015
  const name = p?.name;
1015
1016
  if (newParamNames.has(name))
1016
1017
  continue;
1017
- const pq = (0, get_q_name_1.getParamDefQName)(p);
1018
+ const pq = (0, def_key_helpers_1.getGlobalDefKey)(p);
1018
1019
  if (!pq)
1019
1020
  continue;
1020
1021
  const def = this.gQNameDefs.get(pq);
@@ -1022,20 +1023,20 @@ class ReferenceManager {
1022
1023
  this.deleteSymbolRefs(def);
1023
1024
  this.gQNameDefs.delete(pq);
1024
1025
  }
1025
- // 对新参数:存在的迁移 refs,新增的只注册,用 getParamDefQName(p) 与注册时 key 一致
1026
+ // 对新参数:存在的迁移 refs,新增的只注册,用 getGlobalDefKey(p) 与注册时 key 一致
1026
1027
  for (const p of newParams) {
1027
- const pq = (0, get_q_name_1.getParamDefQName)(p);
1028
+ const pq = (0, def_key_helpers_1.getGlobalDefKey)(p);
1028
1029
  if (!pq)
1029
1030
  continue;
1030
1031
  const name = p?.name;
1031
1032
  if (oldParamNames.has(name)) {
1032
1033
  const oldDef = this.gQNameDefs.get(pq);
1033
- const refs = oldDef ? this.gSymbolRefs.get(oldDef) : undefined;
1034
+ const refs = oldDef ? this.globalRefs.get(oldDef) : undefined;
1034
1035
  if (oldDef)
1035
- this.gSymbolRefs.delete(oldDef);
1036
+ this.globalRefs.delete(oldDef);
1036
1037
  this.gQNameDefs.set(pq, p);
1037
1038
  if (refs?.size)
1038
- this.gSymbolRefs.set(p, refs);
1039
+ this.globalRefs.set(p, refs);
1039
1040
  }
1040
1041
  else {
1041
1042
  this.gQNameDefs.set(pq, p);
@@ -1054,69 +1055,72 @@ class ReferenceManager {
1054
1055
  const parent = nd.parentNode;
1055
1056
  if (!(0, symbol_type_1.isLogicViewLike)(parent))
1056
1057
  return;
1057
- const logicQName = (0, get_q_name_1.getTokenQualifiedName)(parent);
1058
+ const logicQName = (0, def_key_helpers_1.getGlobalDefKey)(parent);
1058
1059
  if (!logicQName)
1059
1060
  return;
1060
- const pq = (0, get_q_name_1.getParamDefQName)(nd);
1061
+ const pq = (0, def_key_helpers_1.getGlobalDefKey)(nd);
1061
1062
  if (!pq)
1062
1063
  return;
1063
1064
  this.gQNameDefs.set(pq, nd);
1064
1065
  this.recollectParamRefsForCallers(env, logicQName);
1065
1066
  };
1066
1067
  /**
1067
- * 建立「调用逻辑的参数」到「逻辑的参数」的引用:对 CallLogic 的每个 Argument,按 keyword/顺序匹配到 Logic 的 Param,并 handleRefOp
1068
+ * 建立「调用处实参」到「Logic/View/BusinessComponent 形参」的引用。
1069
+ * 支持 CallLogic(调用逻辑)、Destination(页面跳转)、ViewElement(业务组件 bindAttrs)等。
1070
+ * 扩充新类型时只需在此处增加分支。
1068
1071
  */
1069
- this.handleCallLogicParamRefs = (env, nd) => {
1072
+ this.handleCallerParamRefs = (env, nd) => {
1070
1073
  if (!this.modeForCollect)
1071
1074
  return;
1072
- const logicQName = (0, get_q_name_1.getTokenQualifiedName)(nd);
1073
- if (!logicQName)
1074
- return;
1075
- const logic = this.gQNameDefs.get(logicQName);
1076
- if (!logic?.params?.length)
1077
- return;
1078
- const args = nd.arguments ?? [];
1079
- for (let i = 0; i < args.length; i++) {
1080
- const arg = args[i];
1081
- const param = logic.params.find((p) => p.name === arg.keyword)
1082
- ?? logic.params[i];
1083
- if (!param)
1084
- continue;
1085
- const paramQName = (0, get_q_name_1.getParamDefQName)(param);
1086
- if (paramQName) {
1087
- this.handleRefOp(this.modeForCollect, arg, paramQName);
1088
- }
1075
+ let callee;
1076
+ let bindings;
1077
+ if (nd.concept === 'CallLogic' || nd.concept === 'Destination') {
1078
+ const calleeQName = (0, def_key_helpers_1.getGlobalDefKey)(nd);
1079
+ if (!calleeQName)
1080
+ return;
1081
+ callee = this.gQNameDefs.get(calleeQName);
1082
+ if (!callee?.params?.length)
1083
+ return;
1084
+ const args = nd.arguments ?? [];
1085
+ bindings = args
1086
+ .map((arg, i) => {
1087
+ const param = callee.params.find((p) => p.name === arg.keyword)
1088
+ ?? callee.params[i];
1089
+ return param ? { refNode: arg, param } : null;
1090
+ })
1091
+ .filter((x) => !!x);
1092
+ }
1093
+ else if (nd.concept === 'ViewElement' && nd.tag.startsWith('bs-')) {
1094
+ // 无 bindAttrs 则无需注册实参→形参引用,直接跳过,避免 frontendType/businessComponents 查找
1095
+ if (!nd.bindAttrs?.length)
1096
+ return;
1097
+ const bsName = nd.tag.split('bs-')[1];
1098
+ const fet = nd.frontendType;
1099
+ const bsDef = fet?.businessComponents?.find((bc) => bc.name === bsName);
1100
+ if (!bsDef?.params?.length)
1101
+ return;
1102
+ callee = bsDef;
1103
+ bindings = nd.bindAttrs
1104
+ .map((attr) => {
1105
+ const param = bsDef.params.find((p) => p.name === attr.name);
1106
+ return param ? { refNode: attr, param } : null;
1107
+ })
1108
+ .filter((x) => !!x);
1089
1109
  }
1090
- };
1091
- /**
1092
- * 建立「页面跳转的参数」到「页面的参数」的引用:对 Destination 的每个 Argument,按 keyword/顺序匹配到 View 的 Param,并 handleRefOp。
1093
- * 与 handleCallLogicParamRefs 对称,页面入参的查找引用需包含跳转处的实参。
1094
- */
1095
- this.handleDestinationParamRefs = (env, nd) => {
1096
- if (!this.modeForCollect)
1097
- return;
1098
- const viewQName = (0, get_q_name_1.getTokenQualifiedName)(nd);
1099
- if (!viewQName)
1100
- return;
1101
- const view = this.gQNameDefs.get(viewQName);
1102
- if (!view?.params?.length)
1110
+ else {
1103
1111
  return;
1104
- const args = nd.arguments ?? [];
1105
- for (let i = 0; i < args.length; i++) {
1106
- const arg = args[i];
1107
- const param = view.params.find((p) => p.name === arg.keyword)
1108
- ?? view.params[i];
1109
- if (!param)
1110
- continue;
1111
- const paramQName = (0, get_q_name_1.getParamDefQName)(param);
1112
+ }
1113
+ for (const { refNode, param } of bindings) {
1114
+ const paramQName = (0, def_key_helpers_1.getGlobalDefKey)(param);
1112
1115
  if (paramQName) {
1113
- this.handleRefOp(this.modeForCollect, arg, paramQName);
1116
+ this.handleRefOp(this.modeForCollect, refNode, paramQName);
1114
1117
  }
1115
1118
  }
1116
1119
  };
1117
1120
  /**
1118
- * @warning Only handle global symbols
1119
- */
1121
+ * 处理「定义」的增删
1122
+ * @warning Only handle global symbols
1123
+ **/
1120
1124
  this.handleDefOp = (mode, defNode, qName) => {
1121
1125
  switch (mode) {
1122
1126
  // 目前的策略是 re-link:删除 logic1 后,不会删除引用。新建一个 logic1 后,自动关联到老的引用上
@@ -1159,16 +1163,17 @@ class ReferenceManager {
1159
1163
  }
1160
1164
  };
1161
1165
  /**
1166
+ * 处理「引用」的增删
1162
1167
  * @warning Only handle global symbols
1163
- */
1168
+ **/
1164
1169
  this.handleRefOp = (mode, refNd, qName) => {
1165
1170
  const def = this.gQNameDefs.get(qName);
1166
1171
  if (def) {
1167
1172
  switch (mode) {
1168
1173
  case "create" /* Operation.Create */: {
1169
1174
  // Route reference to the appropriate map based on whether it's explicit or implicit
1170
- // Explicit references go to symbolRefs
1171
- (0, fp_macros_1.createOnAdd)(this.gSymbolRefs, def, refNd);
1175
+ // Explicit references go to globalRefs
1176
+ (0, fp_macros_1.createOnAdd)(this.globalRefs, def, refNd);
1172
1177
  break;
1173
1178
  }
1174
1179
  case "delete" /* Operation.Remove */: {
@@ -1236,7 +1241,7 @@ class ReferenceManager {
1236
1241
  if (!(0, type_predicate_1.isEntityTy)(typeAnnotation) && !(0, type_predicate_1.isStructureTy)(typeAnnotation)) {
1237
1242
  return;
1238
1243
  }
1239
- const tyQName = (0, get_q_name_1.getTokenQualifiedName)(typeAnnotation);
1244
+ const tyQName = (0, def_key_helpers_1.getGlobalDefKey)(typeAnnotation);
1240
1245
  if (!tyQName) {
1241
1246
  return;
1242
1247
  }
@@ -1271,7 +1276,7 @@ class ReferenceManager {
1271
1276
  if (!bsDef) {
1272
1277
  return;
1273
1278
  }
1274
- this.handleRefOp(this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(bsDef));
1279
+ this.handleRefOp(this.modeForCollect, nd, (0, def_key_helpers_1.getGlobalDefKey)(bsDef));
1275
1280
  };
1276
1281
  this.handleBindRoles = (env, nd) => {
1277
1282
  for (const roleName of nd.bindRoles ?? nd.roles) {
@@ -1298,11 +1303,11 @@ class ReferenceManager {
1298
1303
  parent?.interfaceDependencies?.forEach(dep => {
1299
1304
  dep.interfaces.forEach(itfc => {
1300
1305
  if (itfc.concept === 'AuthInterface' && itfc.name === nd.calleeName) {
1301
- // this.handleRefOp(this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
1306
+ // this.handleRefOp(this.modeForCollect!, nd, getGlobalDefKey(itfc)!);
1302
1307
  const authName = itfc.authLogic;
1303
1308
  parent?.authLogicsForCallInterface?.forEach(l => {
1304
1309
  if (l.name === authName) {
1305
- this.handleRefOp(this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(l));
1310
+ this.handleRefOp(this.modeForCollect, nd, (0, def_key_helpers_1.getGlobalDefKey)(l));
1306
1311
  }
1307
1312
  });
1308
1313
  }
@@ -1310,12 +1315,12 @@ class ReferenceManager {
1310
1315
  });
1311
1316
  parent.interfaces?.forEach(itfc => {
1312
1317
  if (itfc.concept === 'AuthInterface' && itfc.name === nd.calleeName) {
1313
- // this.handleRefOp(this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
1314
- // this.handleRefOp(this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
1318
+ // this.handleRefOp(this.modeForCollect!, nd, getGlobalDefKey(itfc)!);
1319
+ // this.handleRefOp(this.modeForCollect!, nd, getGlobalDefKey(itfc)!);
1315
1320
  const authName = itfc.authLogic;
1316
1321
  parent?.authLogics?.forEach(l => {
1317
1322
  if (l.name === authName) {
1318
- this.handleRefOp(this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(l));
1323
+ this.handleRefOp(this.modeForCollect, nd, (0, def_key_helpers_1.getGlobalDefKey)(l));
1319
1324
  }
1320
1325
  });
1321
1326
  }
@@ -1360,7 +1365,7 @@ class ReferenceManager {
1360
1365
  !skipSubView && views.push(...(0, misc_1.getSubViews)(nd));
1361
1366
  if (nd.concept === 'View' || nd.concept === 'BusinessComponent') {
1362
1367
  this.curFileNode = nd;
1363
- env.viewAssocProcess = env.processV2ViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? null;
1368
+ env.viewAssocProcess = env.processV2ViewBindings.get((0, def_key_helpers_1.getGlobalDefKey)(nd)) ?? null;
1364
1369
  }
1365
1370
  const res = new Array(); // 使用数组而不是 Map
1366
1371
  // specialization for speeding up
@@ -1377,14 +1382,14 @@ class ReferenceManager {
1377
1382
  n.concept === 'CallAuthInterface' && this.handleAuthLogicRef(env, n);
1378
1383
  // 处理流程子流程引用
1379
1384
  n.concept === 'ProcessElementV2' && this.handleProcessSubProcessRef(env, n);
1380
- // 建立「调用逻辑的参数」到「逻辑的参数」的引用
1381
- n.concept === 'CallLogic' && this.handleCallLogicParamRefs(env, n);
1382
- // 建立「页面跳转的参数」到「页面的参数」的引用
1383
- n.concept === 'Destination' && this.handleDestinationParamRefs(env, n);
1385
+ // 处理 CallLogic、Destination、ViewElement 的调用处实参到形参的引用
1386
+ if (['CallLogic', 'Destination', 'ViewElement'].includes(n.concept)) {
1387
+ this.handleCallerParamRefs(env, n);
1388
+ }
1384
1389
  if (!symbol_type_1.refConcept.includes(n.concept)) {
1385
1390
  return;
1386
1391
  }
1387
- const qName = (0, get_q_name_1.getTokenQualifiedName)(n); // 太慢,后续应该需要优化速度
1392
+ const qName = (0, def_key_helpers_1.getGlobalDefKey)(n); // 太慢,后续应该需要优化速度
1388
1393
  if (!qName) {
1389
1394
  return;
1390
1395
  }
@@ -1411,7 +1416,7 @@ class ReferenceManager {
1411
1416
  case 'TypeAnnotation':
1412
1417
  const refs = this.splitPolyType(n);
1413
1418
  for (const ref of refs) {
1414
- const qName = (0, get_q_name_1.getTokenQualifiedName)(ref);
1419
+ const qName = (0, def_key_helpers_1.getGlobalDefKey)(ref);
1415
1420
  qName && qNameRefs.push([ref, qName]);
1416
1421
  }
1417
1422
  break;
@@ -1446,7 +1451,7 @@ class ReferenceManager {
1446
1451
  for (const v of views) {
1447
1452
  v.bindRoles.length && this.handleBindRoles(env, v);
1448
1453
  const lastViewAssocProcess = env.viewAssocProcess;
1449
- env.viewAssocProcess = env.processV2ViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(v)) ?? null;
1454
+ env.viewAssocProcess = env.processV2ViewBindings.get((0, def_key_helpers_1.getGlobalDefKey)(v)) ?? null;
1450
1455
  const lastCurFileNode = this.curFileNode;
1451
1456
  this.curFileNode = v;
1452
1457
  // @ts-expect-error contra-variance errors
@@ -1461,7 +1466,7 @@ class ReferenceManager {
1461
1466
  (0, traverse_util_1.visitChildrenWith)(nd, normalCb, compositeNodePred, compositeNodeCb);
1462
1467
  }
1463
1468
  if (nd.concept === 'McpInterface') {
1464
- const qName = nd.originLogic && (0, get_q_name_1.getTokenQualifiedName)(nd.originLogic);
1469
+ const qName = nd.originLogic && (0, def_key_helpers_1.getGlobalDefKey)(nd.originLogic);
1465
1470
  qName && res.push([nd, qName]);
1466
1471
  }
1467
1472
  else if (nd.concept !== 'QueryFieldExpression') {
@@ -1523,7 +1528,7 @@ class ReferenceManager {
1523
1528
  const visibleLocalSyms = this.getVisibleLocalSyms(nd);
1524
1529
  const localQNameSet = new Set();
1525
1530
  for (const s of visibleLocalSyms) {
1526
- const q = (0, get_q_name_1.getTokenQualifiedName)(s);
1531
+ const q = (0, def_key_helpers_1.getGlobalDefKey)(s);
1527
1532
  q && localQNameSet.add(q);
1528
1533
  }
1529
1534
  for (const [ref, qName] of refAndQNames) {
@@ -1603,7 +1608,7 @@ class ReferenceManager {
1603
1608
  }
1604
1609
  }
1605
1610
  else if (symbol_type_1.refConcept.includes(id0.concept)) {
1606
- const qName = (0, get_q_name_1.getTokenQualifiedName)(id0);
1611
+ const qName = (0, def_key_helpers_1.getGlobalDefKey)(id0);
1607
1612
  let isProcessRef = false;
1608
1613
  if (qName) {
1609
1614
  // Handle process reference in view
@@ -1622,7 +1627,7 @@ class ReferenceManager {
1622
1627
  }
1623
1628
  if (isProcessRef) {
1624
1629
  const processDef = env.viewAssocProcess;
1625
- const pId = (0, get_q_name_1.getTokenQualifiedName)(processDef);
1630
+ const pId = (0, def_key_helpers_1.getGlobalDefKey)(processDef);
1626
1631
  res.push([ids[0], pId]);
1627
1632
  const processBindDataTy = (0, type_manager_1.createTypeofBindData)(pId, env);
1628
1633
  env.setType(ids[0], processBindDataTy);
@@ -1769,8 +1774,8 @@ class ReferenceManager {
1769
1774
  return res;
1770
1775
  }
1771
1776
  const entityQName = nd.propertyName === 'data'
1772
- ? (0, get_q_name_1.getTokenQualifiedName)(entityRef.typeAnnotation) // data 是 Entity
1773
- : (0, get_q_name_1.getTokenQualifiedName)(entityRef.typeAnnotation.typeArguments[0]); // relation_data 是 List<Entity>
1777
+ ? (0, def_key_helpers_1.getGlobalDefKey)(entityRef.typeAnnotation) // data 是 Entity
1778
+ : (0, def_key_helpers_1.getGlobalDefKey)(entityRef.typeAnnotation.typeArguments[0]); // relation_data 是 List<Entity>
1774
1779
  for (const sub of nd.subFieldPermissions) {
1775
1780
  res.push([sub, (0, string_2.getPropQName)(entityQName, sub.propertyName, 'Entity')]);
1776
1781
  }
@@ -1782,9 +1787,9 @@ class ReferenceManager {
1782
1787
  this.getMemoryStats = () => {
1783
1788
  const stats = {
1784
1789
  gQNameDefs: this.gQNameDefs,
1785
- symbolRefs: this.gSymbolRefs, // Exporting private map for serialization
1790
+ globalRefs: this.globalRefs, // Exporting private map for serialization
1786
1791
  pendingRefsForRecreation: this.pendingRefsForRecreation, // Exporting private map for serialization
1787
- localQNameRefs: this.lQNameRefs,
1792
+ localRefs: this.localRefs,
1788
1793
  compDefMgr: this.compDefMgr,
1789
1794
  };
1790
1795
  const result = {
@@ -1836,7 +1841,7 @@ class ReferenceManager {
1836
1841
  if (!(0, helper_2.isEntityLogic)(nd)) {
1837
1842
  return nd;
1838
1843
  }
1839
- const qName = (0, get_q_name_1.getTokenQualifiedName)(nd);
1844
+ const qName = (0, def_key_helpers_1.getGlobalDefKey)(nd);
1840
1845
  if (!qName) {
1841
1846
  throw new Error('The entity logic does not have namespace');
1842
1847
  }
@@ -1847,8 +1852,8 @@ class ReferenceManager {
1847
1852
  // 同步跟新引用管理器,跟上实体逻辑内存地址变化的节奏
1848
1853
  if (nd !== def) {
1849
1854
  this.gQNameDefs.set(qName, nd);
1850
- const refs = mnemonist_1.set.union(this.gSymbolRefs.get(def) ?? new Set(), this.gSymbolRefs.get(nd) ?? new Set());
1851
- refs.size > 0 && this.gSymbolRefs.set(nd, refs);
1855
+ const refs = mnemonist_1.set.union(this.globalRefs.get(def) ?? new Set(), this.globalRefs.get(nd) ?? new Set());
1856
+ refs.size > 0 && this.globalRefs.set(nd, refs);
1852
1857
  }
1853
1858
  return nd;
1854
1859
  };
@@ -1867,7 +1872,7 @@ class ReferenceManager {
1867
1872
  if (!(ctxViewLike && (ctxViewLike.concept === 'View' || ctxViewLike.concept === 'BusinessComponent'))) {
1868
1873
  return;
1869
1874
  }
1870
- const ctxQName = (0, get_q_name_1.getTokenQualifiedName)(ctxViewLike);
1875
+ const ctxQName = (0, def_key_helpers_1.getGlobalDefKey)(ctxViewLike);
1871
1876
  if (!ctxQName)
1872
1877
  return;
1873
1878
  const assocProc = env.processV2ViewBindings.get(ctxQName);
@@ -1904,9 +1909,9 @@ class ReferenceManager {
1904
1909
  if (!ctxViewElement) {
1905
1910
  return;
1906
1911
  }
1907
- const macthed = node.concept === 'BindAttribute';
1908
- const ancestor = !macthed && node.getAncestorRaw('BindAttribute');
1909
- const boundary = (macthed ? node : ancestor);
1912
+ const matched = node.concept === 'BindAttribute';
1913
+ const ancestor = !matched && node.getAncestorRaw('BindAttribute');
1914
+ const boundary = (matched ? node : ancestor);
1910
1915
  if (boundary?.name !== 'rules') {
1911
1916
  return;
1912
1917
  }
@@ -1946,7 +1951,7 @@ class ReferenceManager {
1946
1951
  }
1947
1952
  }; }
1948
1953
  static getEntityLogicQNames(nd) {
1949
- const qName = (0, get_q_name_1.getTokenQualifiedName)(nd);
1954
+ const qName = (0, def_key_helpers_1.getGlobalDefKey)(nd);
1950
1955
  const res = new Array();
1951
1956
  for (const l of nd.logics) {
1952
1957
  res.push(`${qName}.logics.${l.name}`);
@@ -1954,11 +1959,9 @@ class ReferenceManager {
1954
1959
  return res;
1955
1960
  }
1956
1961
  clearAll() {
1957
- this.clearSymbolRefs();
1962
+ this.clearGlobalRefs();
1958
1963
  this.gQNameDefs.clear();
1959
- this.lQNameRefs.clear();
1960
- this.veQNameDefs.clear();
1961
- this.veRefs.clear();
1964
+ this.localRefs.clear();
1962
1965
  this.compDefMgr.clearAll();
1963
1966
  this.clearPendingRefsCache(); // 清除待恢复引用缓存
1964
1967
  this.gSymbolImplicitRefs = new WeakMap();