@lcap/nasl-language-server-core 4.1.0-rc.3 → 4.1.0-rc.4
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 +6 -4
- package/out/checker.js.map +1 -1
- package/out/index.d.ts +3 -0
- package/out/index.d.ts.map +1 -1
- package/out/index.js +5 -1
- package/out/index.js.map +1 -1
- package/out/reference-manager/build-q-name-def.d.ts +10 -0
- package/out/reference-manager/build-q-name-def.d.ts.map +1 -0
- package/out/reference-manager/build-q-name-def.js +66 -0
- package/out/reference-manager/build-q-name-def.js.map +1 -0
- package/out/reference-manager/builtin-q-name.js +6 -6
- package/out/reference-manager/builtin-q-name.js.map +1 -1
- package/out/reference-manager/get-q-name.d.ts.map +1 -1
- package/out/reference-manager/get-q-name.js +11 -7
- package/out/reference-manager/get-q-name.js.map +1 -1
- package/out/reference-manager/helper.d.ts +21 -0
- package/out/reference-manager/helper.d.ts.map +1 -0
- package/out/reference-manager/helper.js +92 -0
- package/out/reference-manager/helper.js.map +1 -0
- package/out/reference-manager/reference-manager.d.ts +39 -132
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +200 -481
- package/out/reference-manager/reference-manager.js.map +1 -1
- package/out/reference-manager/special-string-ref.d.ts +7 -0
- package/out/reference-manager/special-string-ref.d.ts.map +1 -0
- package/out/reference-manager/special-string-ref.js +34 -0
- package/out/reference-manager/special-string-ref.js.map +1 -0
- package/out/reference-manager/symbol-type.d.ts +5 -2
- package/out/reference-manager/symbol-type.d.ts.map +1 -1
- package/out/reference-manager/symbol-type.js +22 -2
- package/out/reference-manager/symbol-type.js.map +1 -1
- package/out/reference-manager/update-nasl-fragment.d.ts +1 -4
- package/out/reference-manager/update-nasl-fragment.d.ts.map +1 -1
- package/out/reference-manager/update-nasl-fragment.js +22 -37
- package/out/reference-manager/update-nasl-fragment.js.map +1 -1
- package/out/reference-manager/view-elem-logic.d.ts +44 -0
- package/out/reference-manager/view-elem-logic.d.ts.map +1 -0
- package/out/reference-manager/view-elem-logic.js +164 -0
- package/out/reference-manager/view-elem-logic.js.map +1 -0
- package/out/services/bindable-logic-service.d.ts +64 -0
- package/out/services/bindable-logic-service.d.ts.map +1 -0
- package/out/services/bindable-logic-service.js +186 -0
- package/out/services/bindable-logic-service.js.map +1 -0
- package/out/services/client.d.ts +10 -0
- package/out/services/client.d.ts.map +1 -0
- package/out/services/client.js +21 -0
- package/out/services/client.js.map +1 -0
- package/out/services/contextual-variables-service.d.ts +14 -0
- package/out/services/contextual-variables-service.d.ts.map +1 -0
- package/out/services/contextual-variables-service.js +17 -0
- package/out/services/contextual-variables-service.js.map +1 -0
- package/out/services/event-handler-type-service.d.ts +16 -0
- package/out/services/event-handler-type-service.d.ts.map +1 -0
- package/out/services/event-handler-type-service.js +57 -0
- package/out/services/event-handler-type-service.js.map +1 -0
- package/out/services/index.d.ts +2 -0
- package/out/services/index.d.ts.map +1 -0
- package/out/services/index.js +18 -0
- package/out/services/index.js.map +1 -0
- package/out/services/types/type.d.ts +13 -0
- package/out/services/types/type.d.ts.map +1 -0
- package/out/services/types/type.js +3 -0
- package/out/services/types/type.js.map +1 -0
- package/out/symbol/traverse/concepts/frontend/bind-event.d.ts.map +1 -1
- package/out/symbol/traverse/concepts/frontend/bind-event.js +3 -0
- package/out/symbol/traverse/concepts/frontend/bind-event.js.map +1 -1
- package/out/symbol/traverse/concepts/index.d.ts +1 -1
- package/out/symbol/traverse/concepts/index.d.ts.map +1 -1
- package/out/typer/collectGlobalDefs.js +1 -1
- package/out/typer/collectGlobalDefs.js.map +1 -1
- package/out/typer/dispatch-all.d.ts +1 -1
- package/out/typer/dispatch-all.d.ts.map +1 -1
- package/out/typer/dispatch-all.js +1 -1
- package/out/typer/dispatch-all.js.map +1 -1
- package/out/typer/dispatch-def.d.ts +2 -2
- package/out/typer/dispatch-def.d.ts.map +1 -1
- package/out/typer/dispatch-def.js +11 -16
- package/out/typer/dispatch-def.js.map +1 -1
- package/out/typer/dispatch-expr.js +11 -11
- package/out/typer/dispatch-expr.js.map +1 -1
- package/out/typer/dispatch-process.d.ts.map +1 -1
- package/out/typer/dispatch-process.js +7 -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 +125 -62
- package/out/typer/dispatch-view.js.map +1 -1
- package/out/typer/helper.d.ts +0 -5
- package/out/typer/helper.d.ts.map +1 -1
- package/out/typer/helper.js +1 -21
- package/out/typer/helper.js.map +1 -1
- package/out/typer/incremental-update.d.ts.map +1 -1
- package/out/typer/incremental-update.js +127 -44
- package/out/typer/incremental-update.js.map +1 -1
- package/out/typer/index.d.ts +3 -3
- package/out/typer/index.d.ts.map +1 -1
- package/out/typer/index.js +3 -4
- package/out/typer/index.js.map +1 -1
- package/out/typer/nasl-predicate.d.ts +3 -5
- package/out/typer/nasl-predicate.d.ts.map +1 -1
- package/out/typer/nasl-predicate.js +10 -7
- package/out/typer/nasl-predicate.js.map +1 -1
- package/out/typer/solver.d.ts.map +1 -1
- package/out/typer/solver.js +4 -0
- package/out/typer/solver.js.map +1 -1
- package/out/typer/subster.js +4 -4
- package/out/typer/subster.js.map +1 -1
- package/out/typer/topo-sort.d.ts +1 -1
- package/out/typer/topo-sort.d.ts.map +1 -1
- package/out/typer/topo-sort.js +2 -2
- package/out/typer/topo-sort.js.map +1 -1
- package/out/typer/type-manager.d.ts +1 -1
- package/out/typer/type-manager.d.ts.map +1 -1
- package/out/typer/type-manager.js +5 -7
- package/out/typer/type-manager.js.map +1 -1
- package/out/typer/type-predicate.d.ts.map +1 -1
- package/out/typer/type-predicate.js +21 -7
- package/out/typer/type-predicate.js.map +1 -1
- package/out/typer/typer.d.ts +42 -6
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +127 -17
- package/out/typer/typer.js.map +1 -1
- package/out/typer/unifier.d.ts +0 -1
- package/out/typer/unifier.d.ts.map +1 -1
- package/out/typer/unifier.js +17 -12
- package/out/typer/unifier.js.map +1 -1
- package/out/utils/misc.d.ts +11 -0
- package/out/utils/misc.d.ts.map +1 -0
- package/out/utils/misc.js +29 -0
- package/out/utils/misc.js.map +1 -0
- package/out/utils/traverse-util.d.ts +5 -0
- package/out/utils/traverse-util.d.ts.map +1 -0
- package/out/utils/traverse-util.js +69 -0
- package/out/utils/traverse-util.js.map +1 -0
- package/package.json +5 -5
|
@@ -1,125 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.handleEntityAutoRef = exports.easyGetOldQName = exports.ReferenceManager = void 0;
|
|
4
4
|
const nasl_concepts_1 = require("@lcap/nasl-concepts");
|
|
5
5
|
const mnemonist_1 = require("mnemonist");
|
|
6
6
|
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
|
-
const
|
|
9
|
+
const build_q_name_def_1 = require("./build-q-name-def");
|
|
10
|
+
const get_q_name_1 = require("./get-q-name");
|
|
10
11
|
const typer_1 = require("../typer");
|
|
11
12
|
const type_predicate_1 = require("../typer/type-predicate");
|
|
12
13
|
const helper_1 = require("../typer/helper");
|
|
13
14
|
const component_def_manager_1 = require("../typer/component-def-manager/component-def-manager");
|
|
14
|
-
const get_q_name_1 = require("./get-q-name");
|
|
15
15
|
const string_1 = require("../utils/string");
|
|
16
16
|
const symbol_type_1 = require("./symbol-type");
|
|
17
17
|
const update_nasl_fragment_1 = require("./update-nasl-fragment");
|
|
18
|
-
const
|
|
18
|
+
const special_string_ref_1 = require("./special-string-ref"); /** 页面组件中的字符串引用 */
|
|
19
|
+
const service_1 = require("@lcap/nasl-concepts/service");
|
|
19
20
|
const type_manager_1 = require("../typer/type-manager");
|
|
20
21
|
const oql_1 = require("../utils/oql");
|
|
21
|
-
const parseTsClassType_1 = require("../utils/parseTsClassType");
|
|
22
22
|
const string_2 = require("../utils/string");
|
|
23
|
+
const traverse_util_1 = require("../utils/traverse-util");
|
|
24
|
+
const view_elem_logic_1 = require("./view-elem-logic");
|
|
25
|
+
const helper_2 = require("./helper");
|
|
26
|
+
const misc_1 = require("../utils/misc");
|
|
23
27
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* a 与 b 可能变为 T3.a 和 T4.b 中的引用
|
|
32
|
-
*
|
|
33
|
-
* 因此不能只对 (...) 中的符号做增删,而是需要对整个文件级别的符号做增删
|
|
34
|
-
* 并且 result 类型变化为,所有受牵连的文件也都需要对内部所有符号重新做增删
|
|
35
|
-
*/
|
|
36
|
-
/**
|
|
37
|
-
* 最核心的宗旨:(1)添加的东西可以链接到老的引用,但是新添加的东西里面都没有引用,所以先添加 qName,再做类型检查,再做引用计数
|
|
38
|
-
* (2)删除的东西前,必须先更新引用计数、把里面的引用都删掉,再删 qName,再类型检查,再视情况按新类型添加引用
|
|
39
|
-
* (3)更新时,必须按旧的类型删除引用,再做类型检查,再按新类型添加引用
|
|
40
|
-
*
|
|
41
|
-
* 增量类型检查时序:
|
|
42
|
-
* 对于非 definitions:
|
|
43
|
-
* 1 首先基于操作种类,对 xs 和内部引用符号做增删
|
|
44
|
-
* 2 无论是什么操作,都直接 getFileNodeTransClosure 查到 FileNode 的引用传递闭包,设为 ys
|
|
45
|
-
* 3 对 ys 中的所有引用,在 symbolRefs 中删除
|
|
46
|
-
* 4 类型检查 ys
|
|
47
|
-
* 5 对 ys 中的所有引用,在 symbolRefs 中添加
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* 对于 definitions:
|
|
51
|
-
* Create xs
|
|
52
|
-
* 1 创建 xs 的 qNames
|
|
53
|
-
* 2 尝试 'relink' 到旧的 refs(需要 relink 所有下属定义,如 Structure 下的 StructureProperty)
|
|
54
|
-
* 3 待检查项设为 ys:xs 所在的 FileNode,和 refs 所在的 FileNode 的 transitive closure
|
|
55
|
-
*
|
|
56
|
-
* (一般不需要处理 xs 的下属定义?如 Structure 下的 StructureProperty,
|
|
57
|
-
* 因为引用下属定义前一定会先引用 xs 的 qName,如引用 .prop1 时必定有类似 x: Structure1, x.prop1。
|
|
58
|
-
* 但也不一定,比如 f().prop1 时,只引用了 prop1 而没有 Structure1 的名字)
|
|
59
|
-
*
|
|
60
|
-
* 以下不在 preProcess 中做:
|
|
61
|
-
* 4 拓扑排序 ys 确定类型检查顺序
|
|
62
|
-
* 5 类型检查 ys
|
|
63
|
-
* 6 更新 ys 中对 xs qNames 的引用 symbolRefs
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* Remove xs:
|
|
67
|
-
* 1 扫描 xs 的 qNames
|
|
68
|
-
* 2 确定待检查项 ys:xs 引用的 FileNodes,
|
|
69
|
-
* 3 删除 xs 中对所有全局符号的引用,更新 symbolRefs
|
|
70
|
-
* (1 因为即使通过撤销重做,进来的 refs 对象的内存地址也不一样,无法重用)
|
|
71
|
-
* (2 xs 中其他符号的引用如果还在,查找其他符号时依然会找到"消失的xs",然后再找到 xs 被引用的 FileNode,这样不对)
|
|
72
|
-
* 4 缓存要删除的 qNames qNameDefsToRemove,现在不能删除,因为如果删除了,移除 ys 中的符号时就会报错,例子我不记得了,之后再想想……
|
|
73
|
-
*
|
|
74
|
-
* 以下不在 preProcess 中做:
|
|
75
|
-
* 5 类型检查 ys
|
|
76
|
-
* 6 不需要删除 ys 中对 xs 的引用 refs,所以不需要更新 symbolRefs(为了之后做 'relink')
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* Rename xs:
|
|
80
|
-
* 1 获取要删除的旧的 qNames1
|
|
81
|
-
* 2 获取引用旧的 qNames1 的待检查项 ys
|
|
82
|
-
* 3 获取要增加的新的 qNames2
|
|
83
|
-
* 4 引用转移:qNameDefs 中增加 qNames2,并且把 qNames1 的 symbolRefs 转移到 qNames2,qNameDefs 中删除 qNames1
|
|
84
|
-
* 5 尝试 'relink':改名后,如果新名字已经存在一些存量 refs,也要加进去
|
|
85
|
-
* 6 根据转移的 symbolRefs,获取引用新的 qNames2 的待检查项 zs(比如可能一个以前找不到的名字碰巧连接上了)
|
|
86
|
-
* 7 类型检查 ys 和 zs
|
|
87
|
-
*
|
|
88
|
-
* 其他 update xs:
|
|
89
|
-
* 1 拆成 delete oldObj 和 create newObj
|
|
90
|
-
* 2 查找 xs 的引用, 确定待检查项 ys
|
|
91
|
-
*
|
|
92
|
-
* 3 (基于旧类型)删除 xs 和 ys 中的引用 symbolRefs
|
|
93
|
-
* 4 类型检查 xs 和 ys
|
|
94
|
-
* 5 (基于新类型)更新 xs 和 ys 中的引用 symbolRefs
|
|
95
|
-
*
|
|
96
|
-
* 以上所有的基于旧类型删除 symbolRefs,类型检查,然后基于新类型更新 symbolRefs 的操作,都需要在最后执行。在那之前只处理 def 的 qNames 和 ref 的局部更新等。
|
|
97
|
-
*/
|
|
98
|
-
// 鉴于 NASL AST 设计,本模块没有办法设计得很优雅
|
|
99
|
-
/**
|
|
100
|
-
* 特点:增量更新、惰性
|
|
101
|
-
* 进入应用:扫描所有全局符号
|
|
102
|
-
* 打开页面逻辑、逻辑、页面:啥也不动
|
|
103
|
-
* 更新逻辑:增量更新局部引用、全局引用
|
|
104
|
-
* 查找全局符号:直接返回
|
|
105
|
-
* 查找局部符号:有缓存则从缓存返回结果,如无缓存则局部扫描局部所有符号建立缓存再返回结果
|
|
106
|
-
*/
|
|
107
|
-
/**
|
|
108
|
-
* 不考虑场景:剪切后粘贴并自动重命名等
|
|
109
|
-
*/
|
|
110
|
-
// Type definitions moved to symbol-type.ts
|
|
111
|
-
/**
|
|
112
|
-
* 约定:不要在这里处理任何定义中的 type 删除,这里只管引用。
|
|
113
|
-
* 删除引用时,需要一并移除类型:这里是删除引用的最后的现场,删除引用后类型检查阶段拿到的 NASL 是
|
|
114
|
-
* 不带删除节点的 NASL,所以无法再处理了。(删除定义时,有一个删除定义列表可以处理,引用不在此列表里)。
|
|
115
|
-
* 因为今天永远也不知道 public 方法明天会被什么地方调到,增量更新是时序非常敏感的,很容易出问题
|
|
116
|
-
*/
|
|
117
|
-
/**
|
|
118
|
-
* 一些奇怪的引用或关联关系,特别容易出错的:
|
|
119
|
-
* - BindAttr 的 field、valueField、textField、parentField 字符串暗含的特殊引用
|
|
28
|
+
* 一些非常规引用或关联关系,特别容易出错的:
|
|
29
|
+
* - BindAttr 的
|
|
30
|
+
* field、
|
|
31
|
+
* valueField、
|
|
32
|
+
* textField、
|
|
33
|
+
* parentField 字符串暗含的特殊引用
|
|
34
|
+
* @warning 考虑之后开放一个接口,让组件库开发自己配置字符串引用
|
|
120
35
|
* - QueryFieldExpression、QueryJoinExpression、QueryFromExpression 中的特殊引用,可能是字符串也可能是别的,注意 QueryFromExpression 内部包含 QueryJoinExpression
|
|
121
36
|
* - 触碰到 Logic 时,要同时看看 OverriddenLogic
|
|
122
37
|
* - 触碰到实体时,要看看实体逻辑
|
|
38
|
+
* - __TypeAnnotation 要单独管理,因为重命名不能碰这些推导的没有记录在 NASL 的数据
|
|
39
|
+
* - 页面引用了流程(通过“流程——关联页面”),但可能被页面局部符号 shadow
|
|
123
40
|
*/
|
|
124
41
|
class ReferenceManager {
|
|
125
42
|
static { this.refConcept = symbol_type_1.refConcept; } /** imported */
|
|
@@ -130,65 +47,80 @@ class ReferenceManager {
|
|
|
130
47
|
static { this.connectionNsp = 'app.connections'; }
|
|
131
48
|
// qNameDefs 和 symbolRefs 的构建时机不一样,所以不放在构造器中
|
|
132
49
|
constructor() {
|
|
133
|
-
// qualified names to definition memory address
|
|
134
|
-
this.
|
|
135
|
-
// definition to its references (memory address)
|
|
50
|
+
// qualified names to definition memory address for GLOBAL DEFINITIONS
|
|
51
|
+
this.gQNameDefs = new Map();
|
|
136
52
|
/**
|
|
53
|
+
* @warning g 表示 global,这里基本只存放全局符号的引用
|
|
54
|
+
*
|
|
55
|
+
* 增量语义分析的范围基本由它决定:因为全局符号改动后,接口有变动,引用处需要重新做语义分析
|
|
56
|
+
* 局部符号变动后,仅直接影响所处的全局定义(如实体、逻辑接口类型);其他的定义无法引用局部符号。
|
|
57
|
+
*
|
|
58
|
+
* definition to its references (memory address) for GLOBAL DEFINITIONS
|
|
137
59
|
* 实体 def,11 个实体逻辑构成对其引用吗?
|
|
138
|
-
* 实体逻辑的定义的 params 的 typeAnnotation
|
|
60
|
+
* 实体逻辑的定义的 params 的 typeAnnotation 确实对实体有引用,但那不是用户数据。
|
|
61
|
+
* 如果加上引用,则 rename 时 实体逻辑的 nodePath 直接 invalid ==> "数据不同步强制刷新"
|
|
62
|
+
*
|
|
139
63
|
* 实体逻辑对其不够成引用 ==> rename 时额外加上 11 个实体逻辑的引用
|
|
140
64
|
*
|
|
141
65
|
* 将实体看成 namespace,所有引用实体逻辑的地方也算引用了实体?
|
|
142
66
|
*/
|
|
143
|
-
this.
|
|
67
|
+
this.gSymbolRefs = new Map; // 手动管理,小心内存泄漏
|
|
144
68
|
// Accessor methods for symbolRefs to normalize input later
|
|
145
69
|
this.getSymbolRefs = (__def) => {
|
|
146
70
|
const def = this.normaliseEntityLogic(__def);
|
|
147
|
-
return this.
|
|
71
|
+
return this.gSymbolRefs.get(def);
|
|
148
72
|
};
|
|
149
73
|
this.setSymbolRefs = (__def, refs) => {
|
|
150
74
|
const def = this.normaliseEntityLogic(__def);
|
|
151
|
-
this.
|
|
75
|
+
this.gSymbolRefs.set(def, refs);
|
|
152
76
|
};
|
|
153
77
|
this.deleteSymbolRefs = (__def) => {
|
|
154
78
|
const def = this.normaliseEntityLogic(__def);
|
|
155
|
-
return this.
|
|
79
|
+
return this.gSymbolRefs.delete(def);
|
|
156
80
|
};
|
|
157
81
|
this.clearSymbolRefs = () => {
|
|
158
|
-
this.
|
|
82
|
+
this.gSymbolRefs.clear();
|
|
159
83
|
};
|
|
160
84
|
this.getSymbolRefsSize = () => {
|
|
161
|
-
return this.
|
|
85
|
+
return this.gSymbolRefs.size;
|
|
162
86
|
};
|
|
87
|
+
// 辅助 map
|
|
88
|
+
this.veQNameDefs = new Map();
|
|
89
|
+
/**
|
|
90
|
+
* @warning ViewElement 和 Logic 都是局部符号,可以重名,qName 重复时会出错,不要搞这种例子谢谢
|
|
91
|
+
* key 是 memory addr 而不是 string 的原因:点查找引用时,不好高效获取 qName(如 Logic 没有 namespace 但调用处其实有,对的就是 elements.)
|
|
92
|
+
*/
|
|
93
|
+
this.veRefs = new Map();
|
|
163
94
|
// 当前的 collectRefs 是增加还是删除引用。先这样吧,没时间重构了……
|
|
164
95
|
this.modeForCollect = null;
|
|
165
96
|
/**
|
|
166
97
|
* 非用户选择的"隐式引用",如推导出的类型
|
|
167
98
|
* 用于存储来自 __TypeAnnotation 字段的隐式引用
|
|
168
99
|
*/
|
|
169
|
-
this.
|
|
100
|
+
this.gSymbolImplicitRefs = new WeakMap();
|
|
170
101
|
this.setSymbolImplicitRef = (def, ref) => {
|
|
171
102
|
// 该功能目前仅为这三个类型提供
|
|
172
103
|
if (def.concept !== 'Entity' && def.concept !== 'Structure' && def.concept !== 'Enum' && def.concept !== 'BackendVariable') {
|
|
173
104
|
return;
|
|
174
105
|
}
|
|
175
|
-
(0, fp_macros_1.createOnAddWeakMap)(this.
|
|
106
|
+
(0, fp_macros_1.createOnAddWeakMap)(this.gSymbolImplicitRefs, def, ref);
|
|
176
107
|
};
|
|
177
108
|
this.getImplicitReferences = (__nd) => {
|
|
178
|
-
let nd = toRaw(__nd);
|
|
109
|
+
let nd = (0, misc_1.toRaw)(__nd);
|
|
179
110
|
const emptySet = new Set();
|
|
180
111
|
if (nd.concept !== 'Entity' && nd.concept !== 'Structure' && nd.concept !== 'Enum') {
|
|
181
112
|
return emptySet;
|
|
182
113
|
}
|
|
183
114
|
// 暂无"局部类型",所以简化处理:
|
|
184
|
-
return this.
|
|
115
|
+
return this.gSymbolImplicitRefs.get(nd) ?? emptySet;
|
|
185
116
|
};
|
|
186
117
|
// 删除一个 def 时,缓存其 qName 到引用符号的关系,为了方便之后还能 relink 恢复
|
|
187
|
-
this.
|
|
118
|
+
this.gCachedQNameSymbolRefs = new Map();
|
|
119
|
+
this.compDefMgr = new component_def_manager_1.ComponentDefManager();
|
|
188
120
|
// 上一次查找引用局部符号建立的 cache
|
|
189
121
|
this.lastBoundary = undefined;
|
|
190
122
|
this.isLocalCacheValid = true;
|
|
191
|
-
this.
|
|
123
|
+
this.lQNameRefs = new Map();
|
|
192
124
|
// 当前文件节点
|
|
193
125
|
this.curFileNode = undefined;
|
|
194
126
|
// 约 20 万节点 200ms
|
|
@@ -254,16 +186,16 @@ class ReferenceManager {
|
|
|
254
186
|
if (!ref) {
|
|
255
187
|
return;
|
|
256
188
|
}
|
|
257
|
-
const def = this.
|
|
189
|
+
const def = this.gQNameDefs.get(qName);
|
|
258
190
|
if (def) {
|
|
259
191
|
// Add reference to existing definition
|
|
260
|
-
(0, helper_1.createSetOnPush)(this.
|
|
192
|
+
(0, helper_1.createSetOnPush)(this.gSymbolRefs, def, ref);
|
|
261
193
|
}
|
|
262
194
|
else {
|
|
263
195
|
// Cache reference for future relinking
|
|
264
196
|
// FIXME:这里有问题,脏脏的,比如局部变量、入参等都扔到这里面了,虽然暂时可能没有太大的正确性问题,但有内存泄漏
|
|
265
|
-
if (!(0,
|
|
266
|
-
(0, helper_1.createSetOnPush)(this.
|
|
197
|
+
if (!(0, helper_2.cheapTestLocalSymbol)(qName)) {
|
|
198
|
+
(0, helper_1.createSetOnPush)(this.gCachedQNameSymbolRefs, qName, ref);
|
|
267
199
|
}
|
|
268
200
|
}
|
|
269
201
|
});
|
|
@@ -293,60 +225,13 @@ class ReferenceManager {
|
|
|
293
225
|
}
|
|
294
226
|
this.modeForCollect = null;
|
|
295
227
|
};
|
|
296
|
-
this.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
// Build builtin types
|
|
303
|
-
(0, builtin_q_name_1.buildBuiltinTypeQNameDefs)(this.qNameDefs);
|
|
304
|
-
for (const fn of parseTsClassType_1.overloadedBuiltinFns) {
|
|
305
|
-
const def = (0, builtin_q_name_1.createDefaultOverloadedFnDef)(fn, 'nasl.util');
|
|
306
|
-
this.addQNameDef(def.name, def); // name 已经带了 namespace
|
|
307
|
-
}
|
|
308
|
-
for (const fn of parseTsClassType_1.overloadedSqlFns) {
|
|
309
|
-
const def = (0, builtin_q_name_1.createDefaultOverloadedFnDef)(fn, 'nasl.sqlFunction');
|
|
310
|
-
this.addQNameDef(def.name, def); // name 已经带了 namespace
|
|
311
|
-
}
|
|
312
|
-
// Process enums
|
|
313
|
-
const processEnumCollection = (0, collect_q_name_1.adhocBuildProcessEnum)();
|
|
314
|
-
processEnumCollection.forEach(([qName, def]) => {
|
|
315
|
-
this.addQNameDef(qName, def);
|
|
316
|
-
});
|
|
317
|
-
// I18N enums
|
|
318
|
-
const i18nEnumCollection = (0, collect_q_name_1.adhocBuildI18NEnum)();
|
|
319
|
-
i18nEnumCollection.forEach(([qName, def]) => {
|
|
320
|
-
this.addQNameDef(qName, def);
|
|
321
|
-
});
|
|
322
|
-
// 更多的 error structures
|
|
323
|
-
const stdNamespace = (0, nasl_concepts_1.getStdlibNamespace)();
|
|
324
|
-
const errorNamespace = stdNamespace.findChild("error");
|
|
325
|
-
errorNamespace.structures.forEach((structure) => {
|
|
326
|
-
(0, collect_q_name_1.collectStructure)('nasl')(structure);
|
|
327
|
-
});
|
|
328
|
-
};
|
|
329
|
-
// Update the addQNameDefs method to use the new collection functions
|
|
330
|
-
/**
|
|
331
|
-
* FIXME wudengke rename this to collectFullDefs
|
|
332
|
-
* @param app
|
|
333
|
-
*/
|
|
334
|
-
this.addQNameDefs = (app) => {
|
|
335
|
-
if (app) {
|
|
336
|
-
const qNameDefs = (0, collect_q_name_1.collectAllQNames)('')(app);
|
|
337
|
-
qNameDefs.forEach(([qName, def]) => {
|
|
338
|
-
if ((0, component_def_manager_1.isGeneralViewElementDefinition)(def)) {
|
|
339
|
-
this.compDefMgr.add(def, 'referenceManager#addQNameDefs');
|
|
340
|
-
}
|
|
341
|
-
this.addQNameDef(qName, def);
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
};
|
|
345
|
-
this.addQNameDef = (qName, def) => {
|
|
346
|
-
this.qNameDefs.set(qName, def);
|
|
347
|
-
};
|
|
228
|
+
this.addQNameDefs = (0, build_q_name_def_1.mkAddQNameDefs)(this.gQNameDefs, this.compDefMgr);
|
|
229
|
+
/** 注释见具体实现 */
|
|
230
|
+
this.addViewElementLogicQNameDefs = (0, view_elem_logic_1.mkAddViewElementLogicQNameDefs)(this.veQNameDefs, this.gQNameDefs);
|
|
231
|
+
/** 注释见具体实现 */
|
|
232
|
+
this.addViewElementLogicRefs = (0, view_elem_logic_1.mkAddViewElementBindLogicRefs)(this.veQNameDefs, this.veRefs);
|
|
348
233
|
this.queryQNameDef = (qName) => {
|
|
349
|
-
const res = this.
|
|
234
|
+
const res = this.gQNameDefs.get(qName);
|
|
350
235
|
if (!res) {
|
|
351
236
|
console.log(`queryQNameDef: ${qName} not found`);
|
|
352
237
|
}
|
|
@@ -397,7 +282,7 @@ class ReferenceManager {
|
|
|
397
282
|
}
|
|
398
283
|
else {
|
|
399
284
|
// @ts-expect-error
|
|
400
|
-
return this.
|
|
285
|
+
return this.gQNameDefs.get(`${ty.typeNamespace}.${ty.typeName}`);
|
|
401
286
|
}
|
|
402
287
|
};
|
|
403
288
|
/**
|
|
@@ -407,7 +292,7 @@ class ReferenceManager {
|
|
|
407
292
|
*/
|
|
408
293
|
this.getNodeDef = (ref) => {
|
|
409
294
|
const qName = (0, get_q_name_1.getTokenQualifiedName)(ref);
|
|
410
|
-
return qName ? this.
|
|
295
|
+
return qName ? this.gQNameDefs.get(qName) : undefined;
|
|
411
296
|
};
|
|
412
297
|
/**
|
|
413
298
|
* 对外接口,指用户点击 "查找引用",只返回用户手动指定的引用
|
|
@@ -415,49 +300,74 @@ class ReferenceManager {
|
|
|
415
300
|
* @returns 所有引用处
|
|
416
301
|
*/
|
|
417
302
|
this.getReferences = (env, __nd) => {
|
|
418
|
-
let nd = this.normaliseEntityLogic(toRaw(__nd));
|
|
419
|
-
let res;
|
|
303
|
+
let nd = this.normaliseEntityLogic((0, misc_1.toRaw)(__nd));
|
|
304
|
+
let res = new Set();
|
|
420
305
|
// 比如 OverriddenLogic 和对应的 Logic 名字一样,但引用挂在 Logic 上
|
|
421
306
|
// 比如 实体对应的实体逻辑可能有多份内存地址,归结到现存的一份上
|
|
422
307
|
// nd = this.qNameDefs.get(getTokenQualifiedName(nd)!)!;
|
|
423
308
|
// ==> 好像也不行,很多依赖库逻辑调用又挂了,这也不行,那也不行
|
|
424
309
|
// 全局符号直接查找
|
|
425
|
-
if (isGlobalDef(nd)) {
|
|
426
|
-
res = this.getSymbolRefs(nd) ?? new Set();
|
|
427
|
-
if (nd.concept === 'Entity') {
|
|
428
|
-
// 加上所有实体逻辑调用的引用(实体逻辑可看做无定义,但要修改调用处的 namespace:实体名是 namespace 的一部分)
|
|
429
|
-
for (const l of nd.logics) {
|
|
430
|
-
res = mnemonist_1.set.union(res, this.getSymbolRefs(l) ?? new Set());
|
|
431
|
-
}
|
|
432
|
-
}
|
|
310
|
+
if ((0, symbol_type_1.isGlobalDef)(nd)) {
|
|
311
|
+
res = mnemonist_1.set.union(res, this.getSymbolRefs(nd) ?? new Set());
|
|
433
312
|
}
|
|
434
|
-
else {
|
|
435
|
-
|
|
313
|
+
else {
|
|
314
|
+
// 局部符号需要即时获取
|
|
315
|
+
const boundary = (0, misc_1.toRaw)((0, helper_2.getBoundary)(nd));
|
|
316
|
+
// 从缓存中获取
|
|
436
317
|
if (this.lastBoundary === boundary && this.isLocalCacheValid) {
|
|
437
|
-
res = this.
|
|
318
|
+
res = this.lQNameRefs.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? new Set();
|
|
319
|
+
// 此处的 Logic 必然不是全局逻辑
|
|
320
|
+
// @ts-expect-error 目前的 AST 设计,ViewElement 既是引用又是定义
|
|
321
|
+
if (nd.concept === 'ViewElement' || nd.concept === 'Logic' || nd.concept === 'BusinessLogic') {
|
|
322
|
+
res = mnemonist_1.set.union(res, this.getViewElementRefs(nd));
|
|
323
|
+
}
|
|
438
324
|
}
|
|
439
325
|
else {
|
|
440
326
|
// 局部扫描,建立所有局部引用
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
327
|
+
this.lQNameRefs.clear();
|
|
328
|
+
this.veQNameDefs.clear();
|
|
329
|
+
this.veRefs.clear();
|
|
330
|
+
this.timeAndLog('Get reference: collect local refs', this.buildMinimalLocalQNameRefs, env, nd);
|
|
331
|
+
res = mnemonist_1.set.union(res, this.lQNameRefs.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? new Set());
|
|
332
|
+
// @ts-expect-error 同上,并且虽然 BindEvent 本身没引用但是要触发对 view 建立引用
|
|
333
|
+
if (nd.concept === 'ViewElement' || nd.concept === 'Logic' || nd.concept === 'BusinessLogic' || nd.concept === 'BindEvent') {
|
|
334
|
+
const ctxViewLike = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
335
|
+
this.timeAndLog('Get reference: build view element logic qName defs cache', this.addViewElementLogicQNameDefs, ctxViewLike);
|
|
336
|
+
this.timeAndLog('Get reference: build view element refs cache', this.addViewElementLogicRefs, ctxViewLike);
|
|
337
|
+
// @ts-expect-error get 出来一个 undefined 无所谓
|
|
338
|
+
res = mnemonist_1.set.union(res ?? new Set(), this.getViewElementRefs(nd));
|
|
339
|
+
}
|
|
445
340
|
}
|
|
446
341
|
}
|
|
447
|
-
//
|
|
342
|
+
// 这些逻辑不要移到上面,因为放上面的话 局部引用 cache 可能还没建立
|
|
343
|
+
/** 这个东西很特殊……查三代
|
|
344
|
+
* 这玩意跟全局逻辑不一样,全局逻辑名字是固定的。
|
|
345
|
+
* 业务逻辑在页面调用的时候,名字前缀是随着业务组件实例名字而变化的,几乎是全应用查找……
|
|
346
|
+
*/
|
|
448
347
|
if (nd.concept === 'BusinessLogic') {
|
|
449
348
|
// 上面已经找到了业务组件内部对业务组件逻辑的内用
|
|
450
349
|
// 现在再找出所有 业务组件逻辑 所属的业务组件的外部引用
|
|
451
|
-
const bs = toRaw((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
350
|
+
const bs = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
452
351
|
if (bs?.concept === 'BusinessComponent') {
|
|
453
352
|
const bsRefs = this.getSymbolRefs(bs) ?? new Set();
|
|
454
353
|
let bsRefsRefs = new Array(); // 业务组件(在页面的引用)的引用
|
|
455
|
-
|
|
354
|
+
/**
|
|
355
|
+
* 再对每个实例找到所有引用
|
|
356
|
+
* @warning 造孽,引用业务组件的每个 view 都要扫描一遍,应该很慢
|
|
357
|
+
*/
|
|
358
|
+
const startTime = Date.now();
|
|
456
359
|
for (const bsInst of bsRefs) {
|
|
457
|
-
|
|
360
|
+
const ctxViewLike = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxViewLike)(bsInst));
|
|
361
|
+
this.addViewElementLogicQNameDefs(ctxViewLike);
|
|
362
|
+
this.addViewElementLogicRefs(ctxViewLike);
|
|
363
|
+
bsRefsRefs.push(...this.getViewElementRefs(bsInst));
|
|
458
364
|
}
|
|
459
365
|
// 再从引用中过滤出找到当前业务逻辑的调用
|
|
460
366
|
res = mnemonist_1.set.union(res, new Set(bsRefsRefs.filter(r => r.concept === 'CallLogic' && r.calleeName === nd.name))); // amazing!
|
|
367
|
+
const endTime = Date.now();
|
|
368
|
+
if (endTime - startTime > 200) {
|
|
369
|
+
console.log(`Get reference: complex business logic took ${endTime - startTime}ms`);
|
|
370
|
+
}
|
|
461
371
|
}
|
|
462
372
|
}
|
|
463
373
|
// 这个东西很特殊……查三代
|
|
@@ -468,63 +378,78 @@ class ReferenceManager {
|
|
|
468
378
|
res = mnemonist_1.set.union(res ?? new Set(), new Set(this.getReferences(env, l)));
|
|
469
379
|
}
|
|
470
380
|
}
|
|
381
|
+
// 加上所有实体逻辑调用的引用(实体逻辑可看做无定义,但要修改调用处的 namespace:实体名是 namespace 的一部分)
|
|
382
|
+
if (nd.concept === 'Entity') {
|
|
383
|
+
for (const l of nd.logics) {
|
|
384
|
+
res = mnemonist_1.set.union(res, this.getSymbolRefs(l) ?? new Set());
|
|
385
|
+
}
|
|
386
|
+
}
|
|
471
387
|
return res ? Array.from(res) : [];
|
|
472
388
|
};
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
389
|
+
this.timeAndLog = (label, fn, ...args) => {
|
|
390
|
+
const startTime = Date.now();
|
|
391
|
+
fn(...args);
|
|
392
|
+
const endTime = Date.now();
|
|
393
|
+
if (endTime - startTime > 200) {
|
|
394
|
+
console.log(`${label}: ${endTime - startTime}ms`);
|
|
395
|
+
}
|
|
477
396
|
};
|
|
478
397
|
// 给类似 FileNode 级别的定义建立局部索引
|
|
479
|
-
|
|
480
|
-
this.buildLocalQNameRefs = (env, __nd) => {
|
|
398
|
+
this.buildMinimalLocalQNameRefs = (env, __nd) => {
|
|
481
399
|
this.modeForCollect = "create" /* Operation.Create */;
|
|
482
|
-
const nd = toRaw(__nd);
|
|
400
|
+
const nd = (0, misc_1.toRaw)(__nd);
|
|
483
401
|
let logicVars = new Array();
|
|
484
402
|
let viewVars = new Array();
|
|
485
403
|
let processVars = new Array();
|
|
486
|
-
|
|
487
|
-
|
|
404
|
+
/**
|
|
405
|
+
* @warning v4.1 开始,逻辑不在这里处理,在 veQNameRefs 那里处理
|
|
406
|
+
*/
|
|
407
|
+
// let logics = new Array<DefConcept>();
|
|
408
|
+
let isViewLike = false;
|
|
409
|
+
const boundary = (0, helper_2.getBoundary)(nd);
|
|
488
410
|
if (!boundary) {
|
|
489
411
|
return new Set();
|
|
490
412
|
}
|
|
491
413
|
if (boundary.concept === 'View' || boundary.concept === 'BusinessComponent') {
|
|
492
|
-
viewVars = (0, nasl_concepts_1.getViewVars)(nd).map(toRaw);
|
|
414
|
+
viewVars = (0, nasl_concepts_1.getViewVars)(nd).map(misc_1.toRaw);
|
|
493
415
|
const ctxLogic = (0, nasl_concepts_1.getCtxLogicLike)(nd);
|
|
494
416
|
if (ctxLogic && 'variables' in ctxLogic) {
|
|
495
|
-
logicVars.push(...ctxLogic.variables?.map(toRaw) ?? []);
|
|
417
|
+
logicVars.push(...ctxLogic.variables?.map(misc_1.toRaw) ?? []);
|
|
496
418
|
}
|
|
497
|
-
logics =
|
|
419
|
+
// logics = getViewLikeLogics(nd).map(toRaw);
|
|
420
|
+
isViewLike = true;
|
|
498
421
|
}
|
|
499
422
|
else if (boundary.concept === 'ProcessDefinitionV2') {
|
|
500
|
-
processVars = (0, nasl_concepts_1.getProcessVars)(nd).map(toRaw);
|
|
423
|
+
processVars = (0, nasl_concepts_1.getProcessVars)(nd).map(misc_1.toRaw);
|
|
501
424
|
const ctxLogic = (0, nasl_concepts_1.getCtxLogicLike)(nd);
|
|
502
425
|
if (ctxLogic && 'variables' in ctxLogic) {
|
|
503
|
-
logicVars.push(...ctxLogic.variables?.map(toRaw) ?? []);
|
|
426
|
+
logicVars.push(...ctxLogic.variables?.map(misc_1.toRaw) ?? []);
|
|
504
427
|
}
|
|
505
|
-
logics =
|
|
428
|
+
// logics = getProcessLikeLogics(nd).map(toRaw);
|
|
506
429
|
}
|
|
507
|
-
else if ((0,
|
|
508
|
-
logicVars = (0, nasl_concepts_1.getLogicVars)(nd).map(toRaw);
|
|
430
|
+
else if ((0, service_1.isCallableNaslLogic)(boundary) || (0, service_1.isCallableNaslInterface)(boundary)) {
|
|
431
|
+
logicVars = (0, nasl_concepts_1.getLogicVars)(nd).map(misc_1.toRaw);
|
|
509
432
|
}
|
|
510
433
|
let allVars = logicVars.concat(processVars).concat(viewVars);
|
|
434
|
+
// should also get view element definitions
|
|
435
|
+
if (isViewLike) {
|
|
436
|
+
}
|
|
511
437
|
// initialize local cache
|
|
512
|
-
[...allVars, ...logics].forEach(def => {
|
|
438
|
+
[...allVars, /** ...logics */].forEach(def => {
|
|
513
439
|
const qName = (0, get_q_name_1.getTokenQualifiedName)(def);
|
|
514
440
|
if (qName) {
|
|
515
|
-
this.
|
|
441
|
+
this.lQNameRefs.set(qName, new Set());
|
|
516
442
|
}
|
|
517
443
|
});
|
|
518
444
|
let subRefs = this.collectRefs(env, boundary, true);
|
|
519
445
|
this.lastBoundary = boundary;
|
|
520
446
|
subRefs?.forEach(([rf, qName]) => {
|
|
521
447
|
// 不存在则表示不是局部符号
|
|
522
|
-
this.
|
|
448
|
+
this.lQNameRefs.get(qName)?.add(rf);
|
|
523
449
|
});
|
|
524
450
|
// Note: 暂不支持 BindAttr、BindDirective 里的变量的查找引用
|
|
525
451
|
this.isLocalCacheValid = true;
|
|
526
452
|
this.modeForCollect = null;
|
|
527
|
-
return this.localQNameRefs.get((0, get_q_name_1.getTokenQualifiedName)(nd));
|
|
528
453
|
};
|
|
529
454
|
/**
|
|
530
455
|
* References to view elements are calls of component logic and access of properties
|
|
@@ -536,38 +461,7 @@ class ReferenceManager {
|
|
|
536
461
|
* "name": "uLinearLayout1",
|
|
537
462
|
*
|
|
538
463
|
*/
|
|
539
|
-
this.getViewElementRefs = (
|
|
540
|
-
const result = new Array();
|
|
541
|
-
if (!__nd) {
|
|
542
|
-
return result;
|
|
543
|
-
}
|
|
544
|
-
const nd = toRaw(__nd);
|
|
545
|
-
if (nd.concept === 'ViewElement') {
|
|
546
|
-
const veQName = (0, get_q_name_1.getTokenQualifiedName)(nd);
|
|
547
|
-
const veLocalName = veQName ? veQName.substring(veQName.lastIndexOf('.') + 1) : '';
|
|
548
|
-
const ctxViewLike = toRaw((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
549
|
-
const lam = (n) => {
|
|
550
|
-
if (n.concept === 'CallLogic') {
|
|
551
|
-
const qName = (0, get_q_name_1.getTokenQualifiedName)(n);
|
|
552
|
-
if (qName?.startsWith('elements.')) {
|
|
553
|
-
const elementName = qName.substring('elements.'.length, qName.indexOf('.', 'elements.'.length));
|
|
554
|
-
if (elementName === veLocalName) {
|
|
555
|
-
result.push(n);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
if (n.concept === 'Identifier') {
|
|
560
|
-
if (n.namespace?.startsWith('elements.')) {
|
|
561
|
-
if (n.name === veLocalName) {
|
|
562
|
-
result.push(n);
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
};
|
|
567
|
-
visitChildrenWith(ctxViewLike, lam);
|
|
568
|
-
}
|
|
569
|
-
return result;
|
|
570
|
-
};
|
|
464
|
+
this.getViewElementRefs = (nd) => !nd ? new Set() : this.veRefs.get(nd) ?? new Set();
|
|
571
465
|
/**
|
|
572
466
|
* 非常危险,但是先这样吧
|
|
573
467
|
*/
|
|
@@ -576,8 +470,8 @@ class ReferenceManager {
|
|
|
576
470
|
if (!__nd) {
|
|
577
471
|
return result;
|
|
578
472
|
}
|
|
579
|
-
const nd = toRaw(__nd);
|
|
580
|
-
const ctxProcLike = toRaw((0, nasl_concepts_1.getCtxProcessLike)(nd));
|
|
473
|
+
const nd = (0, misc_1.toRaw)(__nd);
|
|
474
|
+
const ctxProcLike = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxProcessLike)(nd));
|
|
581
475
|
if (!ctxProcLike) {
|
|
582
476
|
return result;
|
|
583
477
|
}
|
|
@@ -594,7 +488,7 @@ class ReferenceManager {
|
|
|
594
488
|
}
|
|
595
489
|
}
|
|
596
490
|
};
|
|
597
|
-
visitChildrenWith(ctxProcLike, lam);
|
|
491
|
+
(0, traverse_util_1.visitChildrenWith)(ctxProcLike, lam);
|
|
598
492
|
// 重命名时不需要处理 sourceRef targetRef,好像其他逻辑已经处理掉了
|
|
599
493
|
return result;
|
|
600
494
|
};
|
|
@@ -613,38 +507,37 @@ class ReferenceManager {
|
|
|
613
507
|
this.transferQNameDef = (oldQName, newQName, mode) => {
|
|
614
508
|
if (!oldQName || !newQName)
|
|
615
509
|
return;
|
|
616
|
-
const oldDef = this.
|
|
510
|
+
const oldDef = this.gQNameDefs.get(oldQName);
|
|
617
511
|
if (!oldDef)
|
|
618
512
|
return;
|
|
619
513
|
// 1. 删除 oldQName,建立 newQName,def 地址不变
|
|
620
|
-
this.
|
|
621
|
-
this.
|
|
514
|
+
this.gQNameDefs.delete(oldQName);
|
|
515
|
+
this.gQNameDefs.set(newQName, oldDef);
|
|
622
516
|
// 2. 处理引用集合
|
|
623
517
|
if (mode === 'update') {
|
|
624
518
|
// 获取 oldQName 的既存引用
|
|
625
|
-
const oldRefs = this.
|
|
519
|
+
const oldRefs = this.gSymbolRefs.get(oldDef) ?? new Set();
|
|
626
520
|
// 获取 newQName 在缓存中的引用
|
|
627
|
-
const newCachedRefs = this.
|
|
521
|
+
const newCachedRefs = this.gCachedQNameSymbolRefs.get(newQName) ?? new Set();
|
|
628
522
|
// 合并引用集合
|
|
629
523
|
const mergedRefs = mnemonist_1.set.union(oldRefs, newCachedRefs);
|
|
630
524
|
// 设置新名字的引用集合
|
|
631
525
|
mergedRefs.size > 0 && this.setSymbolRefs(oldDef, mergedRefs);
|
|
632
526
|
// 删除 newQName 在缓存中的引用
|
|
633
|
-
this.
|
|
527
|
+
this.gCachedQNameSymbolRefs.delete(newQName);
|
|
634
528
|
}
|
|
635
529
|
else {
|
|
636
530
|
// 不是 update,直接取 newQName 在缓存中的引用
|
|
637
|
-
const newCachedRefs = this.
|
|
531
|
+
const newCachedRefs = this.gCachedQNameSymbolRefs.get(newQName) ?? new Set();
|
|
638
532
|
this.setSymbolRefs(oldDef, newCachedRefs);
|
|
639
533
|
// oldQName 的引用集合被放入 cachedQNameSymbolRefs
|
|
640
|
-
const oldRefs = this.
|
|
641
|
-
oldRefs.size > 0 && this.
|
|
534
|
+
const oldRefs = this.gSymbolRefs.get(oldDef) ?? new Set();
|
|
535
|
+
oldRefs.size > 0 && this.gCachedQNameSymbolRefs.set(oldQName, oldRefs);
|
|
642
536
|
// 删除 newQName 在缓存中的引用
|
|
643
|
-
this.
|
|
537
|
+
this.gCachedQNameSymbolRefs.delete(newQName);
|
|
644
538
|
}
|
|
645
539
|
};
|
|
646
540
|
this.updateRefsInNaslFragment = update_nasl_fragment_1.updateRefsInNaslFragment;
|
|
647
|
-
this.cacheRemovedConnectors = update_nasl_fragment_1.cacheRemovedConnectors;
|
|
648
541
|
/**
|
|
649
542
|
* @warning Only handle global symbols
|
|
650
543
|
*/
|
|
@@ -652,31 +545,31 @@ class ReferenceManager {
|
|
|
652
545
|
switch (mode) {
|
|
653
546
|
// 目前的策略是 re-link:删除 logic1 后,不会删除引用。新建一个 logic1 后,自动关联到老的引用上
|
|
654
547
|
case "create" /* Operation.Create */: {
|
|
655
|
-
if (symbol_type_1.
|
|
548
|
+
if (!(0, symbol_type_1.isGlobalDef)(defNode)) {
|
|
656
549
|
this.isLocalCacheValid = false;
|
|
657
550
|
}
|
|
658
551
|
else {
|
|
659
552
|
// 可以链接回旧的引用,类似于 rename
|
|
660
|
-
const oldRefs = this.
|
|
553
|
+
const oldRefs = this.gCachedQNameSymbolRefs.get(qName);
|
|
661
554
|
oldRefs && this.setSymbolRefs(defNode, oldRefs);
|
|
662
555
|
// qName 链接到新的 defNode 的 mem addr
|
|
663
|
-
this.
|
|
556
|
+
this.gQNameDefs.set(qName, defNode);
|
|
664
557
|
if ((0, component_def_manager_1.isGeneralViewElementDefinition)(defNode)) {
|
|
665
558
|
this.compDefMgr.add(defNode, 'handleDefOp');
|
|
666
559
|
}
|
|
667
560
|
// 删除缓存
|
|
668
|
-
this.
|
|
561
|
+
this.gCachedQNameSymbolRefs.delete(qName);
|
|
669
562
|
}
|
|
670
563
|
break;
|
|
671
564
|
}
|
|
672
565
|
case "delete" /* Operation.Remove */: { // 连根拔起,但缓存
|
|
673
|
-
if (symbol_type_1.
|
|
566
|
+
if (!(0, symbol_type_1.isGlobalDef)(defNode)) {
|
|
674
567
|
this.isLocalCacheValid = false;
|
|
675
568
|
}
|
|
676
569
|
else {
|
|
677
570
|
const refs = this.getSymbolRefs(defNode);
|
|
678
|
-
refs && this.
|
|
679
|
-
this.
|
|
571
|
+
refs && this.gCachedQNameSymbolRefs.set(qName, refs);
|
|
572
|
+
this.gQNameDefs.delete(qName);
|
|
680
573
|
if ((0, component_def_manager_1.isGeneralViewElementDefinition)(defNode)) {
|
|
681
574
|
this.compDefMgr.removeComponentGroup(defNode);
|
|
682
575
|
}
|
|
@@ -690,13 +583,13 @@ class ReferenceManager {
|
|
|
690
583
|
* @warning Only handle global symbols
|
|
691
584
|
*/
|
|
692
585
|
this.handleRefOp = (env, mode, refNd, qName) => {
|
|
693
|
-
const def = this.
|
|
586
|
+
const def = this.gQNameDefs.get(qName);
|
|
694
587
|
if (def) {
|
|
695
588
|
switch (mode) {
|
|
696
589
|
case "create" /* Operation.Create */: {
|
|
697
590
|
// Route reference to the appropriate map based on whether it's explicit or implicit
|
|
698
591
|
// Explicit references go to symbolRefs
|
|
699
|
-
(0, fp_macros_1.createOnAdd)(this.
|
|
592
|
+
(0, fp_macros_1.createOnAdd)(this.gSymbolRefs, def, refNd);
|
|
700
593
|
break;
|
|
701
594
|
}
|
|
702
595
|
case "delete" /* Operation.Remove */: {
|
|
@@ -710,11 +603,11 @@ class ReferenceManager {
|
|
|
710
603
|
// cache 里的也要处理……
|
|
711
604
|
switch (mode) {
|
|
712
605
|
case "create" /* Operation.Create */: {
|
|
713
|
-
(0, fp_macros_1.createOnAdd)(this.
|
|
606
|
+
(0, fp_macros_1.createOnAdd)(this.gCachedQNameSymbolRefs, qName, refNd);
|
|
714
607
|
break;
|
|
715
608
|
}
|
|
716
609
|
case "delete" /* Operation.Remove */: {
|
|
717
|
-
this.
|
|
610
|
+
this.gCachedQNameSymbolRefs.get(qName)?.delete(refNd);
|
|
718
611
|
break;
|
|
719
612
|
}
|
|
720
613
|
}
|
|
@@ -744,7 +637,7 @@ class ReferenceManager {
|
|
|
744
637
|
this.setSymbolImplicitRef(tyDef, nd);
|
|
745
638
|
}
|
|
746
639
|
else if (this.modeForCollect === "delete" /* Operation.Remove */) {
|
|
747
|
-
this.
|
|
640
|
+
this.gSymbolImplicitRefs.get(tyDef)?.delete(nd);
|
|
748
641
|
}
|
|
749
642
|
}
|
|
750
643
|
else {
|
|
@@ -761,7 +654,7 @@ class ReferenceManager {
|
|
|
761
654
|
this.setSymbolImplicitRef(tyDef, nd);
|
|
762
655
|
}
|
|
763
656
|
else if (this.modeForCollect === "delete" /* Operation.Remove */) {
|
|
764
|
-
this.
|
|
657
|
+
this.gSymbolImplicitRefs.get(tyDef)?.delete(nd);
|
|
765
658
|
}
|
|
766
659
|
}
|
|
767
660
|
}
|
|
@@ -884,7 +777,7 @@ class ReferenceManager {
|
|
|
884
777
|
// extract views
|
|
885
778
|
const views = new Array();
|
|
886
779
|
nd.concept === 'View' && views.push(nd);
|
|
887
|
-
!skipSubView && views.push(...(0,
|
|
780
|
+
!skipSubView && views.push(...(0, misc_1.getSubViews)(nd));
|
|
888
781
|
if (nd.concept === 'View' || nd.concept === 'BusinessComponent') {
|
|
889
782
|
this.curFileNode = nd;
|
|
890
783
|
env.viewAssocProcess = env.processV2ViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? null;
|
|
@@ -971,7 +864,7 @@ class ReferenceManager {
|
|
|
971
864
|
const lastCurFileNode = this.curFileNode;
|
|
972
865
|
this.curFileNode = v;
|
|
973
866
|
// @ts-expect-error contra-variance errors
|
|
974
|
-
visitChildrenWith(v, normalCb, compositeNodePred, compositeNodeCb);
|
|
867
|
+
(0, traverse_util_1.visitChildrenWith)(v, normalCb, compositeNodePred, compositeNodeCb);
|
|
975
868
|
this.curFileNode = lastCurFileNode;
|
|
976
869
|
env.viewAssocProcess = lastViewAssocProcess;
|
|
977
870
|
}
|
|
@@ -979,7 +872,7 @@ class ReferenceManager {
|
|
|
979
872
|
else {
|
|
980
873
|
// 处理非页面
|
|
981
874
|
// @ts-expect-error contra-variance errors
|
|
982
|
-
visitChildrenWith(nd, normalCb, compositeNodePred, compositeNodeCb);
|
|
875
|
+
(0, traverse_util_1.visitChildrenWith)(nd, normalCb, compositeNodePred, compositeNodeCb);
|
|
983
876
|
}
|
|
984
877
|
// QFE 实在是没办法一致性处理
|
|
985
878
|
if (nd.concept !== 'QueryFieldExpression') {
|
|
@@ -1014,12 +907,12 @@ class ReferenceManager {
|
|
|
1014
907
|
// 清理绑定属性中的 string 暗含的特殊引用,哇哦
|
|
1015
908
|
if (rmNd.concept === 'View' || rmNd.concept === 'BusinessComponent') {
|
|
1016
909
|
rmNd.traverseStrictChildren((nd) => {
|
|
1017
|
-
if (nd.concept === 'BindAttribute' && !nd.expression &&
|
|
910
|
+
if (nd.concept === 'BindAttribute' && !nd.expression && special_string_ref_1.specialStringRefs.includes(nd.name)) {
|
|
1018
911
|
(0, update_nasl_fragment_1.removeBindAttrRef)(this, nd);
|
|
1019
912
|
}
|
|
1020
913
|
}); // @ts-expect-error
|
|
1021
914
|
}
|
|
1022
|
-
else if (rmNd.concept === 'BindAttribute' && !rmNd.expression &&
|
|
915
|
+
else if (rmNd.concept === 'BindAttribute' && !rmNd.expression && special_string_ref_1.specialStringRefs.includes(rmNd.name)) {
|
|
1023
916
|
(0, update_nasl_fragment_1.removeBindAttrRef)(this, rmNd);
|
|
1024
917
|
}
|
|
1025
918
|
env.processAssocEntity = null;
|
|
@@ -1039,7 +932,7 @@ class ReferenceManager {
|
|
|
1039
932
|
const refAndQNames = this.collectRefs(env, nd, skipSubView);
|
|
1040
933
|
const localVars = env.localVars.get(nd) ?? [];
|
|
1041
934
|
for (const [ref, qName] of refAndQNames) {
|
|
1042
|
-
if (localVars.includes(qName) || (0,
|
|
935
|
+
if (localVars.includes(qName) || (0, helper_2.cheapTestLocalSymbol)(qName)) {
|
|
1043
936
|
continue;
|
|
1044
937
|
}
|
|
1045
938
|
this.handleRefOp(env, "create" /* Operation.Create */, ref, qName);
|
|
@@ -1051,6 +944,9 @@ class ReferenceManager {
|
|
|
1051
944
|
this.invalidateLocalSymCache = () => {
|
|
1052
945
|
this.isLocalCacheValid = false;
|
|
1053
946
|
};
|
|
947
|
+
this.getLocalCacheState = () => {
|
|
948
|
+
return this.isLocalCacheValid;
|
|
949
|
+
};
|
|
1054
950
|
/**
|
|
1055
951
|
* 干的事太多了,只能改名 hack 了
|
|
1056
952
|
* 假设 a:A, b:B, c:C, d:D,a.b.c.d 拆解为
|
|
@@ -1109,8 +1005,8 @@ class ReferenceManager {
|
|
|
1109
1005
|
if (qName) {
|
|
1110
1006
|
// Handle process reference in view
|
|
1111
1007
|
if (env.viewAssocProcess && env.viewAssocProcess.name === ids[0].name) {
|
|
1112
|
-
const ctxLogic = toRaw((0, nasl_concepts_1.getCtxLogicLike)(nd));
|
|
1113
|
-
const ctxViewLike = toRaw((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
1008
|
+
const ctxLogic = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxLogicLike)(nd));
|
|
1009
|
+
const ctxViewLike = (0, misc_1.toRaw)((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
1114
1010
|
const logicVars = env.localVars.get(ctxLogic);
|
|
1115
1011
|
const viewVars = env.localVars.get(ctxViewLike);
|
|
1116
1012
|
// 哇,是 Process.data.XXX 特殊引用 && avoid shadowing
|
|
@@ -1225,7 +1121,7 @@ class ReferenceManager {
|
|
|
1225
1121
|
const getEntityProp = (prop, def) => def.properties.find(p => p.name === prop);
|
|
1226
1122
|
if (eNsp && eAsName) {
|
|
1227
1123
|
const entityQName = `${eNsp}.${eAsName}`; // namespace eNsp already contains '.entities'
|
|
1228
|
-
const entityDef = this.
|
|
1124
|
+
const entityDef = this.gQNameDefs.get(`${eNsp}.${eAsName}`);
|
|
1229
1125
|
entityDef && res.push([nd, entityQName]);
|
|
1230
1126
|
if (entityDef && pName) {
|
|
1231
1127
|
const propQName = (0, string_2.getPropQName)(entityQName, pName, 'Entity');
|
|
@@ -1269,10 +1165,10 @@ class ReferenceManager {
|
|
|
1269
1165
|
*/
|
|
1270
1166
|
this.getMemoryStats = () => {
|
|
1271
1167
|
const stats = {
|
|
1272
|
-
qNameDefs: this.
|
|
1273
|
-
symbolRefs: this.
|
|
1274
|
-
cachedQNameSymbolRefs: this.
|
|
1275
|
-
localQNameRefs: this.
|
|
1168
|
+
qNameDefs: this.gQNameDefs,
|
|
1169
|
+
symbolRefs: this.gSymbolRefs, // Exporting private map for serialization
|
|
1170
|
+
cachedQNameSymbolRefs: this.gCachedQNameSymbolRefs,
|
|
1171
|
+
localQNameRefs: this.lQNameRefs,
|
|
1276
1172
|
compDefMgr: this.compDefMgr,
|
|
1277
1173
|
};
|
|
1278
1174
|
const result = {
|
|
@@ -1321,36 +1217,35 @@ class ReferenceManager {
|
|
|
1321
1217
|
return result;
|
|
1322
1218
|
};
|
|
1323
1219
|
this.normaliseEntityLogic = (nd) => {
|
|
1324
|
-
if (!(0,
|
|
1220
|
+
if (!(0, helper_2.isEntityLogic)(nd)) {
|
|
1325
1221
|
return nd;
|
|
1326
1222
|
}
|
|
1327
1223
|
const qName = (0, get_q_name_1.getTokenQualifiedName)(nd);
|
|
1328
1224
|
if (!qName) {
|
|
1329
1225
|
throw new Error('The entity logic does not have namespace');
|
|
1330
1226
|
}
|
|
1331
|
-
const def = this.
|
|
1227
|
+
const def = this.gQNameDefs.get(qName);
|
|
1332
1228
|
if (!def) {
|
|
1333
1229
|
return nd;
|
|
1334
1230
|
}
|
|
1335
|
-
//
|
|
1231
|
+
// 同步跟新引用管理器,跟上实体逻辑内存地址变化的节奏
|
|
1336
1232
|
if (nd !== def) {
|
|
1337
|
-
this.
|
|
1338
|
-
const refs = mnemonist_1.set.union(this.
|
|
1339
|
-
refs.size > 0 && this.
|
|
1233
|
+
this.gQNameDefs.set(qName, nd);
|
|
1234
|
+
const refs = mnemonist_1.set.union(this.gSymbolRefs.get(def) ?? new Set(), this.gSymbolRefs.get(nd) ?? new Set());
|
|
1235
|
+
refs.size > 0 && this.gSymbolRefs.set(nd, refs);
|
|
1340
1236
|
}
|
|
1341
1237
|
return nd;
|
|
1342
1238
|
};
|
|
1343
|
-
this.compDefMgr = new component_def_manager_1.ComponentDefManager();
|
|
1344
1239
|
}
|
|
1345
1240
|
buildQNameDefsForApp(app) {
|
|
1346
1241
|
console.time('\x1b[44m\x1b[97m Reference manager: Build Qualified Name to Definition Map \x1b[0m');
|
|
1347
|
-
this.
|
|
1242
|
+
(0, build_q_name_def_1.mkBuildQNameDefs)(this.gQNameDefs, this.compDefMgr)((0, misc_1.toRaw)(app));
|
|
1348
1243
|
console.timeEnd('\x1b[44m\x1b[97m Reference manager: Build Qualified Name to Definition Map \x1b[0m');
|
|
1349
1244
|
}
|
|
1350
1245
|
buildSymbolRefsForApp(env, app) {
|
|
1351
1246
|
console.time('\x1b[44m\x1b[97m Reference manager: Build Symbol to Reference Map \x1b[0m');
|
|
1352
1247
|
// symbolGraph && this.buildSymbolRefsFromSymbolGraph(symbolGraph); // 方舟的,后面可能不好修 bug 和维护
|
|
1353
|
-
app && this.slowBuildSymbolRefsForApp(env, toRaw(app));
|
|
1248
|
+
app && this.slowBuildSymbolRefsForApp(env, (0, misc_1.toRaw)(app));
|
|
1354
1249
|
console.timeEnd('\x1b[44m\x1b[97m Reference manager: Build Symbol to Reference Map \x1b[0m');
|
|
1355
1250
|
}
|
|
1356
1251
|
// 属性名 p + 类型名 T,获取 T.p EntityProperty | StructureProperty | Enum
|
|
@@ -1378,87 +1273,19 @@ class ReferenceManager {
|
|
|
1378
1273
|
}
|
|
1379
1274
|
clearAll() {
|
|
1380
1275
|
this.clearSymbolRefs();
|
|
1381
|
-
this.
|
|
1382
|
-
this.
|
|
1383
|
-
this.
|
|
1276
|
+
this.gQNameDefs.clear();
|
|
1277
|
+
this.gCachedQNameSymbolRefs.clear();
|
|
1278
|
+
this.lQNameRefs.clear();
|
|
1279
|
+
this.veQNameDefs.clear();
|
|
1280
|
+
this.veRefs.clear();
|
|
1384
1281
|
this.compDefMgr.clearAll();
|
|
1385
|
-
this.
|
|
1282
|
+
this.gSymbolImplicitRefs = new WeakMap();
|
|
1386
1283
|
}
|
|
1387
1284
|
}
|
|
1388
1285
|
exports.ReferenceManager = ReferenceManager;
|
|
1389
|
-
// prependStr moved to get-q-name.ts
|
|
1390
|
-
// getTokenQualifiedName moved to get-q-name.ts
|
|
1391
|
-
// getTokenQualifiedNameForMatchedExpr moved to get-q-name.ts
|
|
1392
|
-
// handleLogic moved to get-q-name.ts
|
|
1393
|
-
// handleFVar moved to get-q-name.ts
|
|
1394
|
-
// 是否是个全局定义呢?
|
|
1395
|
-
const isGlobalDef = (nd) => {
|
|
1396
|
-
if (!symbol_type_1.globalDefConcept.includes(nd.concept)) {
|
|
1397
|
-
return false;
|
|
1398
|
-
}
|
|
1399
|
-
if (nd.concept === 'View' || nd.concept === 'BusinessComponent' || nd.concept === 'ProcessV2') {
|
|
1400
|
-
return true;
|
|
1401
|
-
}
|
|
1402
|
-
else if (nd.getAncestorRaw('View') ?? nd.getAncestorRaw('BusinessComponent')) {
|
|
1403
|
-
// 但页面逻辑的 concept 也是 Logic,还需剔除
|
|
1404
|
-
return false;
|
|
1405
|
-
}
|
|
1406
|
-
return true;
|
|
1407
|
-
};
|
|
1408
1286
|
// 获取语义类型
|
|
1409
1287
|
// @ts-ignore
|
|
1410
1288
|
const getSemTy = (nd, env) => env.getType(nd) ?? nd.typeAnnotation; // Fallback to typeAnnotation using type assertion
|
|
1411
|
-
const toRaw = (nd) => {
|
|
1412
|
-
// @ts-ignore
|
|
1413
|
-
return nd?.__v_raw ?? nd;
|
|
1414
|
-
};
|
|
1415
|
-
const visitChildrenWith = (start, cb, pred, predCb) => {
|
|
1416
|
-
const traverse = (node) => {
|
|
1417
|
-
if (!(node.concept?.length)) {
|
|
1418
|
-
return;
|
|
1419
|
-
}
|
|
1420
|
-
const { childProperties, childrenProperties } = (0, nasl_concepts_1.getConceptMeta)(node.concept);
|
|
1421
|
-
for (const key of childProperties) {
|
|
1422
|
-
const child = node[key];
|
|
1423
|
-
if (!child || !(child.concept?.length)) {
|
|
1424
|
-
continue;
|
|
1425
|
-
}
|
|
1426
|
-
if (pred && pred(child)) {
|
|
1427
|
-
predCb(child); // 短路,不访问子节点
|
|
1428
|
-
}
|
|
1429
|
-
else {
|
|
1430
|
-
cb(child);
|
|
1431
|
-
traverse(child);
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
for (const key of childrenProperties) {
|
|
1435
|
-
const children = node[key];
|
|
1436
|
-
if (!Array.isArray(children)) {
|
|
1437
|
-
continue;
|
|
1438
|
-
}
|
|
1439
|
-
for (const child of children) {
|
|
1440
|
-
if (!child || !child.concept?.length) {
|
|
1441
|
-
continue;
|
|
1442
|
-
}
|
|
1443
|
-
if (pred && pred(child)) {
|
|
1444
|
-
predCb(child); // 短路,不访问子节点
|
|
1445
|
-
}
|
|
1446
|
-
else {
|
|
1447
|
-
cb(child);
|
|
1448
|
-
traverse(child);
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
// 不遍历 __TypeAnnotation,防止造成未知错误。例如 a.b.c 中每个节点都有 __TypeAnnotation,类型改名时查到这里可能都是无效的 nodePath
|
|
1453
|
-
};
|
|
1454
|
-
if (pred && pred(start)) {
|
|
1455
|
-
predCb(start);
|
|
1456
|
-
}
|
|
1457
|
-
else {
|
|
1458
|
-
cb(start);
|
|
1459
|
-
traverse(start);
|
|
1460
|
-
}
|
|
1461
|
-
};
|
|
1462
1289
|
// 都用这个方法,安全些
|
|
1463
1290
|
// getPropQName moved to get-q-name.ts
|
|
1464
1291
|
const easyGetOldQName = (qName, oldName) => {
|
|
@@ -1480,20 +1307,6 @@ exports.easyGetOldQName = easyGetOldQName;
|
|
|
1480
1307
|
- 页面的引用处只有 页面跳转
|
|
1481
1308
|
- 放过的定义:App
|
|
1482
1309
|
*/
|
|
1483
|
-
/**
|
|
1484
|
-
* 判断字符串是否以 '.entities.X.logics' 结尾,其中 X 是任意字符串
|
|
1485
|
-
* @param str 需要判断的字符串
|
|
1486
|
-
* @returns 是否符合条件
|
|
1487
|
-
*/
|
|
1488
|
-
const isEntitiesLogicsPath = (str) => {
|
|
1489
|
-
// 使用正则表达式匹配以 .entities.任意字符串.logics 结尾的字符串
|
|
1490
|
-
return /\.entities\.[^.]+\.logics$/.test(str);
|
|
1491
|
-
};
|
|
1492
|
-
/**
|
|
1493
|
-
* 今后大概率会改成 isNonUserNode,实体逻辑只是其中之一。比如文件夹应该也是 nonUserNode 吧
|
|
1494
|
-
*/
|
|
1495
|
-
const isEntityLogic = (nd) => nd?.concept === 'Logic' && nd.getNamespace && isEntitiesLogicsPath(nd.getNamespace());
|
|
1496
|
-
exports.isEntityLogic = isEntityLogic;
|
|
1497
1310
|
/**
|
|
1498
1311
|
* 处理 CodeWave 编译器的一些连带的自动化行为,如自动生成 { abc: Abc } 这样的匿名结构体。
|
|
1499
1312
|
* 这里实质上是否是引用?这里不是直接引用,但是 entityX 这个名字是从 EntityX 自动生成的,也可以看作是间接引用
|
|
@@ -1510,98 +1323,4 @@ const handleEntityAutoRef = (ty, nextProp, ident) => {
|
|
|
1510
1323
|
return undefined;
|
|
1511
1324
|
};
|
|
1512
1325
|
exports.handleEntityAutoRef = handleEntityAutoRef;
|
|
1513
|
-
// Helper function to determine boundary according to custom rules
|
|
1514
|
-
const getBoundary = (nd) => {
|
|
1515
|
-
if (!nd) {
|
|
1516
|
-
return undefined;
|
|
1517
|
-
}
|
|
1518
|
-
const ctxViewLike = toRaw((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
1519
|
-
const ctxLogicLike = toRaw((0, nasl_concepts_1.getCtxLogicLike)(nd));
|
|
1520
|
-
const ctxProcessLike = toRaw((0, nasl_concepts_1.getCtxProcessLike)(nd));
|
|
1521
|
-
// 1. 存在 ctxProcessLike,本身是逻辑,返回 ctxProcessLike
|
|
1522
|
-
if (ctxProcessLike && ((0, nasl_predicate_1.isCallableNaslLogic)(nd) || (0, nasl_predicate_1.isCallableNaslInterface)(nd))) {
|
|
1523
|
-
return ctxProcessLike;
|
|
1524
|
-
}
|
|
1525
|
-
// 2. 存在 ctxProcessLike,不存在 ctxLogicLike,返回 ctxProcessLike
|
|
1526
|
-
if (ctxProcessLike && !ctxLogicLike) {
|
|
1527
|
-
return ctxProcessLike;
|
|
1528
|
-
}
|
|
1529
|
-
// 3. 存在 ctxViewLike,本身是逻辑,返回 ctxViewLike
|
|
1530
|
-
if (ctxViewLike && ((0, nasl_predicate_1.isCallableNaslLogic)(nd) || (0, nasl_predicate_1.isCallableNaslInterface)(nd))) {
|
|
1531
|
-
return ctxViewLike;
|
|
1532
|
-
}
|
|
1533
|
-
// 4. 存在 ctxViewLike,不存在 ctxLogicLike,返回 ctxViewLike
|
|
1534
|
-
if (ctxViewLike && !ctxLogicLike) {
|
|
1535
|
-
return ctxViewLike;
|
|
1536
|
-
}
|
|
1537
|
-
// 5. 存在 ctxLogicLike(但本身不是逻辑),返回 ctxLogicLike
|
|
1538
|
-
// backend logics or variables inside logic
|
|
1539
|
-
if (ctxLogicLike && !(0, nasl_predicate_1.isCallableNaslLogic)(nd) && !(0, nasl_predicate_1.isCallableNaslInterface)(nd)) {
|
|
1540
|
-
return ctxLogicLike;
|
|
1541
|
-
}
|
|
1542
|
-
return undefined;
|
|
1543
|
-
};
|
|
1544
|
-
const getDatasourceQName = (eNsp) => eNsp.lastIndexOf('.') !== -1
|
|
1545
|
-
? eNsp.substring(0, eNsp.lastIndexOf('.'))
|
|
1546
|
-
: eNsp;
|
|
1547
|
-
exports.getDatasourceQName = getDatasourceQName;
|
|
1548
|
-
/**
|
|
1549
|
-
* 移除 nsp 中最后一个 . 之后的内容,
|
|
1550
|
-
* 如 app.logics 只保留 app,
|
|
1551
|
-
* extensions.encrypt_tool.logics 只保留 extensions.encrypt_tool
|
|
1552
|
-
* xxx.entities 只保留 xxx
|
|
1553
|
-
*/
|
|
1554
|
-
const getNamespaceWithoutLast = (def) => {
|
|
1555
|
-
// 你敢信,concept:Return 也没有 getNamespace() 方法,直接 throw 了,强无敌
|
|
1556
|
-
const qName = (0, get_q_name_1.getTokenQualifiedName)(def) ?? '';
|
|
1557
|
-
const lastDotIndex0 = qName.lastIndexOf('.');
|
|
1558
|
-
const res0 = lastDotIndex0 !== -1 ? qName.slice(0, lastDotIndex0) : '';
|
|
1559
|
-
// 枚举是 Identifier, namespace + name 是 app.enums.X,只保留 app.enums
|
|
1560
|
-
// if (def.concept === 'Enum') {
|
|
1561
|
-
// return res0;
|
|
1562
|
-
// }
|
|
1563
|
-
// 其他都是 type,有 typeNamespace + typeName,都是 app.structure.properties.X 这种形式
|
|
1564
|
-
const lastDotIndex1 = res0.lastIndexOf('.');
|
|
1565
|
-
const res1 = lastDotIndex1 !== -1 ? res0.slice(0, lastDotIndex1) : '';
|
|
1566
|
-
return res1;
|
|
1567
|
-
};
|
|
1568
|
-
exports.getNamespaceWithoutLast = getNamespaceWithoutLast;
|
|
1569
|
-
// 最好是与 typing 合成一个步骤,那里有 local nameBindings
|
|
1570
|
-
// 暂时用有没有 .、a、Tp 粗略判断吧,hack,对速度有点影响
|
|
1571
|
-
const cheapTestLocalSymbol = (qName) => {
|
|
1572
|
-
if (qName.startsWith('a+') || qName.startsWith('Tp+') ||
|
|
1573
|
-
qName.startsWith('nasl.core') || qName.startsWith('elements.') ||
|
|
1574
|
-
qName.startsWith('nasl.util') ||
|
|
1575
|
-
qName.startsWith('nasl.collection')) {
|
|
1576
|
-
return true;
|
|
1577
|
-
}
|
|
1578
|
-
// 页面下引用的 Process 的 qName,一般是 Process_uniqueKey 的 hash
|
|
1579
|
-
if (qName.startsWith('Process_')) {
|
|
1580
|
-
return false;
|
|
1581
|
-
}
|
|
1582
|
-
if (qName.indexOf('.') === -1) {
|
|
1583
|
-
return true;
|
|
1584
|
-
}
|
|
1585
|
-
return false;
|
|
1586
|
-
};
|
|
1587
|
-
exports.cheapTestLocalSymbol = cheapTestLocalSymbol;
|
|
1588
|
-
/**
|
|
1589
|
-
* 一个 FileNode 下面还可以有其他 FileNode 哦,其实没什么神秘的。
|
|
1590
|
-
* @warning 只会返回下属的 FileNode,不包含自己
|
|
1591
|
-
* @param node
|
|
1592
|
-
* @returns 下属 FileNodes,不包含自己
|
|
1593
|
-
*/
|
|
1594
|
-
const getSubViews = (node) => {
|
|
1595
|
-
const result = [];
|
|
1596
|
-
if (node.concept === 'View') {
|
|
1597
|
-
node.children?.forEach((nd) => {
|
|
1598
|
-
if (nd.concept === 'View') {
|
|
1599
|
-
result.push(nd);
|
|
1600
|
-
result.push(...(0, exports.getSubViews)(nd));
|
|
1601
|
-
}
|
|
1602
|
-
});
|
|
1603
|
-
}
|
|
1604
|
-
return result;
|
|
1605
|
-
};
|
|
1606
|
-
exports.getSubViews = getSubViews;
|
|
1607
1326
|
//# sourceMappingURL=reference-manager.js.map
|