@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.
- package/out/checker.d.ts.map +1 -1
- package/out/checker.js +27 -4
- package/out/checker.js.map +1 -1
- package/out/index.d.ts +1 -1
- package/out/index.d.ts.map +1 -1
- package/out/index.js +5 -3
- package/out/index.js.map +1 -1
- package/out/reference-manager/build-q-name-def.js +2 -2
- package/out/reference-manager/build-q-name-def.js.map +1 -1
- package/out/reference-manager/builtin-q-name.js +2 -2
- package/out/reference-manager/builtin-q-name.js.map +1 -1
- package/out/reference-manager/collect-q-name.d.ts +1 -1
- package/out/reference-manager/collect-q-name.d.ts.map +1 -1
- package/out/reference-manager/collect-q-name.js +58 -24
- package/out/reference-manager/collect-q-name.js.map +1 -1
- package/out/reference-manager/def-key-helpers.d.ts +38 -0
- package/out/reference-manager/def-key-helpers.d.ts.map +1 -0
- package/out/reference-manager/{get-q-name.js → def-key-helpers.js} +176 -29
- package/out/reference-manager/def-key-helpers.js.map +1 -0
- package/out/reference-manager/helper.js +2 -2
- package/out/reference-manager/helper.js.map +1 -1
- package/out/reference-manager/reference-manager.d.ts +24 -52
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +222 -219
- package/out/reference-manager/reference-manager.js.map +1 -1
- package/out/reference-manager/remove-q-name.d.ts +1 -1
- package/out/reference-manager/remove-q-name.d.ts.map +1 -1
- package/out/reference-manager/remove-q-name.js +7 -10
- package/out/reference-manager/remove-q-name.js.map +1 -1
- package/out/reference-manager/rename-q-name.d.ts +26 -26
- package/out/reference-manager/rename-q-name.d.ts.map +1 -1
- package/out/reference-manager/rename-q-name.js +48 -167
- package/out/reference-manager/rename-q-name.js.map +1 -1
- package/out/reference-manager/symbol-type.d.ts +4 -4
- package/out/reference-manager/symbol-type.d.ts.map +1 -1
- package/out/reference-manager/symbol-type.js +1 -1
- package/out/reference-manager/symbol-type.js.map +1 -1
- package/out/reference-manager/update-nasl-fragment.js +4 -4
- package/out/reference-manager/update-nasl-fragment.js.map +1 -1
- package/out/typer/collectGlobalDefs.js +2 -2
- package/out/typer/collectGlobalDefs.js.map +1 -1
- package/out/typer/component-def-manager/component-def-manager.js +2 -2
- package/out/typer/component-def-manager/component-def-manager.js.map +1 -1
- package/out/typer/component-def-manager/utils.d.ts.map +1 -1
- package/out/typer/component-def-manager/utils.js +3 -2
- package/out/typer/component-def-manager/utils.js.map +1 -1
- package/out/typer/dispatch-all.js +2 -2
- package/out/typer/dispatch-all.js.map +1 -1
- package/out/typer/dispatch-call.js +3 -3
- package/out/typer/dispatch-call.js.map +1 -1
- package/out/typer/dispatch-def.js +3 -3
- package/out/typer/dispatch-def.js.map +1 -1
- package/out/typer/dispatch-expr.js +7 -7
- package/out/typer/dispatch-expr.js.map +1 -1
- package/out/typer/dispatch-process.js +3 -3
- package/out/typer/dispatch-process.js.map +1 -1
- package/out/typer/dispatch-view.d.ts.map +1 -1
- package/out/typer/dispatch-view.js +8 -13
- package/out/typer/dispatch-view.js.map +1 -1
- package/out/typer/get-oql-files.js +1 -1
- package/out/typer/get-oql-files.js.map +1 -1
- package/out/typer/incremental-update.js +8 -8
- package/out/typer/incremental-update.js.map +1 -1
- package/out/typer/overload-helper.js +2 -2
- package/out/typer/overload-helper.js.map +1 -1
- package/out/typer/subster.js +4 -4
- package/out/typer/subster.js.map +1 -1
- package/out/typer/topo-sort.js +4 -4
- package/out/typer/topo-sort.js.map +1 -1
- package/out/typer/type-predicate.js +3 -3
- package/out/typer/type-predicate.js.map +1 -1
- package/out/typer/typer.d.ts +2 -2
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +25 -26
- package/out/typer/typer.js.map +1 -1
- package/package.json +5 -5
- package/out/reference-manager/get-q-name.d.ts +0 -14
- package/out/reference-manager/get-q-name.d.ts.map +0 -1
- package/out/reference-manager/get-q-name.js.map +0 -1
- package/out/reference-manager/view-elem-logic.d.ts +0 -44
- package/out/reference-manager/view-elem-logic.d.ts.map +0 -1
- package/out/reference-manager/view-elem-logic.js +0 -181
- 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
|
|
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 和
|
|
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.
|
|
69
|
-
// Accessor methods for
|
|
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.
|
|
71
|
+
return this.globalRefs.get(def);
|
|
73
72
|
};
|
|
74
73
|
this.setSymbolRefs = (__def, refs) => {
|
|
75
74
|
const def = this.normaliseEntityLogic(__def);
|
|
76
|
-
this.
|
|
75
|
+
this.globalRefs.set(def, refs);
|
|
77
76
|
};
|
|
78
77
|
this.deleteSymbolRefs = (__def) => {
|
|
79
78
|
const def = this.normaliseEntityLogic(__def);
|
|
80
|
-
return this.
|
|
79
|
+
return this.globalRefs.delete(def);
|
|
81
80
|
};
|
|
82
|
-
this.
|
|
83
|
-
this.
|
|
81
|
+
this.clearGlobalRefs = () => {
|
|
82
|
+
this.globalRefs.clear();
|
|
84
83
|
};
|
|
85
|
-
this.
|
|
86
|
-
return this.
|
|
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
|
-
/**
|
|
137
|
-
this.
|
|
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)
|
|
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
|
-
|
|
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
|
|
229
|
-
if (!
|
|
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(
|
|
225
|
+
if (seen.has(vKey))
|
|
233
226
|
continue;
|
|
234
|
-
seen.add(
|
|
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,
|
|
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.
|
|
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,
|
|
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
|
-
// 逻辑/页面参数:外部引用在
|
|
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,
|
|
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.
|
|
520
|
-
this.
|
|
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
|
|
525
|
-
const internalRefs = (
|
|
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(
|
|
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,
|
|
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
|
-
|
|
554
|
-
|
|
555
|
-
|
|
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(
|
|
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.
|
|
563
|
-
this.
|
|
564
|
-
|
|
565
|
-
|
|
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
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
res = mnemonist_1.set.union(res ?? new Set(), this.
|
|
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
|
-
|
|
597
|
-
|
|
598
|
-
bsRefsRefs.push(...this.getViewElementRefs(bsInst));
|
|
564
|
+
if (ctxViewLike)
|
|
565
|
+
this.buildLocalRefs(env, ctxViewLike);
|
|
599
566
|
}
|
|
600
|
-
//
|
|
601
|
-
res = mnemonist_1.set.union(res,
|
|
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.
|
|
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
|
|
602
|
+
* @warning 不包括 ViewElement、BindEvent 相关的引用,已合并到 getLocalDefKeys 与 collectedRefs 处理
|
|
636
603
|
* @warning 需要包括 SubLogics
|
|
637
604
|
*/
|
|
638
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
664
|
+
const qName = (0, def_key_helpers_1.getLocalDefKey)(def) ?? (0, def_key_helpers_1.getGlobalDefKey)(def);
|
|
672
665
|
if (qName) {
|
|
673
|
-
this.
|
|
666
|
+
this.localRefs.set(qName, new Set());
|
|
674
667
|
}
|
|
675
668
|
});
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
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
|
-
|
|
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
|
-
// 通过
|
|
833
|
-
const currentQName = (0,
|
|
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,
|
|
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,
|
|
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」重新收集参数引用,把参数引用加进
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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 与
|
|
995
|
+
* Logic/View/BusinessLogic 参数列表变更时同步 gQNameDefs 与 globalRefs。
|
|
995
996
|
* - 仅卸载「已删除」的参数,避免把内部引用清空。
|
|
996
997
|
* - 仍存在的参数:把 refs 从旧 def 迁移到新 def,并更新 gQNameDefs。
|
|
997
998
|
* - 新加参数:只做注册。
|
|
998
|
-
* - 最后对「调用该 Logic/View 的所有 CallLogic」重新收集参数引用,把新参数的引用加进
|
|
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,
|
|
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
|
-
// 只卸载已删除的参数,用
|
|
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,
|
|
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,新增的只注册,用
|
|
1026
|
+
// 对新参数:存在的迁移 refs,新增的只注册,用 getGlobalDefKey(p) 与注册时 key 一致
|
|
1026
1027
|
for (const p of newParams) {
|
|
1027
|
-
const pq = (0,
|
|
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.
|
|
1034
|
+
const refs = oldDef ? this.globalRefs.get(oldDef) : undefined;
|
|
1034
1035
|
if (oldDef)
|
|
1035
|
-
this.
|
|
1036
|
+
this.globalRefs.delete(oldDef);
|
|
1036
1037
|
this.gQNameDefs.set(pq, p);
|
|
1037
1038
|
if (refs?.size)
|
|
1038
|
-
this.
|
|
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,
|
|
1058
|
+
const logicQName = (0, def_key_helpers_1.getGlobalDefKey)(parent);
|
|
1058
1059
|
if (!logicQName)
|
|
1059
1060
|
return;
|
|
1060
|
-
const pq = (0,
|
|
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
|
-
*
|
|
1068
|
+
* 建立「调用处实参」到「Logic/View/BusinessComponent 形参」的引用。
|
|
1069
|
+
* 支持 CallLogic(调用逻辑)、Destination(页面跳转)、ViewElement(业务组件 bindAttrs)等。
|
|
1070
|
+
* 扩充新类型时只需在此处增加分支。
|
|
1068
1071
|
*/
|
|
1069
|
-
this.
|
|
1072
|
+
this.handleCallerParamRefs = (env, nd) => {
|
|
1070
1073
|
if (!this.modeForCollect)
|
|
1071
1074
|
return;
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
const
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
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
|
-
|
|
1105
|
-
for (
|
|
1106
|
-
const
|
|
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,
|
|
1116
|
+
this.handleRefOp(this.modeForCollect, refNode, paramQName);
|
|
1114
1117
|
}
|
|
1115
1118
|
}
|
|
1116
1119
|
};
|
|
1117
1120
|
/**
|
|
1118
|
-
|
|
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
|
|
1171
|
-
(0, fp_macros_1.createOnAdd)(this.
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
1314
|
-
// this.handleRefOp(this.modeForCollect!, nd,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
1773
|
-
: (0,
|
|
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
|
-
|
|
1790
|
+
globalRefs: this.globalRefs, // Exporting private map for serialization
|
|
1786
1791
|
pendingRefsForRecreation: this.pendingRefsForRecreation, // Exporting private map for serialization
|
|
1787
|
-
|
|
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,
|
|
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.
|
|
1851
|
-
refs.size > 0 && this.
|
|
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,
|
|
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
|
|
1908
|
-
const ancestor = !
|
|
1909
|
-
const boundary = (
|
|
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,
|
|
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.
|
|
1962
|
+
this.clearGlobalRefs();
|
|
1958
1963
|
this.gQNameDefs.clear();
|
|
1959
|
-
this.
|
|
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();
|