@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.
Files changed (135) hide show
  1. package/out/checker.d.ts.map +1 -1
  2. package/out/checker.js +6 -4
  3. package/out/checker.js.map +1 -1
  4. package/out/index.d.ts +3 -0
  5. package/out/index.d.ts.map +1 -1
  6. package/out/index.js +5 -1
  7. package/out/index.js.map +1 -1
  8. package/out/reference-manager/build-q-name-def.d.ts +10 -0
  9. package/out/reference-manager/build-q-name-def.d.ts.map +1 -0
  10. package/out/reference-manager/build-q-name-def.js +66 -0
  11. package/out/reference-manager/build-q-name-def.js.map +1 -0
  12. package/out/reference-manager/builtin-q-name.js +6 -6
  13. package/out/reference-manager/builtin-q-name.js.map +1 -1
  14. package/out/reference-manager/get-q-name.d.ts.map +1 -1
  15. package/out/reference-manager/get-q-name.js +11 -7
  16. package/out/reference-manager/get-q-name.js.map +1 -1
  17. package/out/reference-manager/helper.d.ts +21 -0
  18. package/out/reference-manager/helper.d.ts.map +1 -0
  19. package/out/reference-manager/helper.js +92 -0
  20. package/out/reference-manager/helper.js.map +1 -0
  21. package/out/reference-manager/reference-manager.d.ts +39 -132
  22. package/out/reference-manager/reference-manager.d.ts.map +1 -1
  23. package/out/reference-manager/reference-manager.js +200 -481
  24. package/out/reference-manager/reference-manager.js.map +1 -1
  25. package/out/reference-manager/special-string-ref.d.ts +7 -0
  26. package/out/reference-manager/special-string-ref.d.ts.map +1 -0
  27. package/out/reference-manager/special-string-ref.js +34 -0
  28. package/out/reference-manager/special-string-ref.js.map +1 -0
  29. package/out/reference-manager/symbol-type.d.ts +5 -2
  30. package/out/reference-manager/symbol-type.d.ts.map +1 -1
  31. package/out/reference-manager/symbol-type.js +22 -2
  32. package/out/reference-manager/symbol-type.js.map +1 -1
  33. package/out/reference-manager/update-nasl-fragment.d.ts +1 -4
  34. package/out/reference-manager/update-nasl-fragment.d.ts.map +1 -1
  35. package/out/reference-manager/update-nasl-fragment.js +22 -37
  36. package/out/reference-manager/update-nasl-fragment.js.map +1 -1
  37. package/out/reference-manager/view-elem-logic.d.ts +44 -0
  38. package/out/reference-manager/view-elem-logic.d.ts.map +1 -0
  39. package/out/reference-manager/view-elem-logic.js +164 -0
  40. package/out/reference-manager/view-elem-logic.js.map +1 -0
  41. package/out/services/bindable-logic-service.d.ts +64 -0
  42. package/out/services/bindable-logic-service.d.ts.map +1 -0
  43. package/out/services/bindable-logic-service.js +186 -0
  44. package/out/services/bindable-logic-service.js.map +1 -0
  45. package/out/services/client.d.ts +10 -0
  46. package/out/services/client.d.ts.map +1 -0
  47. package/out/services/client.js +21 -0
  48. package/out/services/client.js.map +1 -0
  49. package/out/services/contextual-variables-service.d.ts +14 -0
  50. package/out/services/contextual-variables-service.d.ts.map +1 -0
  51. package/out/services/contextual-variables-service.js +17 -0
  52. package/out/services/contextual-variables-service.js.map +1 -0
  53. package/out/services/event-handler-type-service.d.ts +16 -0
  54. package/out/services/event-handler-type-service.d.ts.map +1 -0
  55. package/out/services/event-handler-type-service.js +57 -0
  56. package/out/services/event-handler-type-service.js.map +1 -0
  57. package/out/services/index.d.ts +2 -0
  58. package/out/services/index.d.ts.map +1 -0
  59. package/out/services/index.js +18 -0
  60. package/out/services/index.js.map +1 -0
  61. package/out/services/types/type.d.ts +13 -0
  62. package/out/services/types/type.d.ts.map +1 -0
  63. package/out/services/types/type.js +3 -0
  64. package/out/services/types/type.js.map +1 -0
  65. package/out/symbol/traverse/concepts/frontend/bind-event.d.ts.map +1 -1
  66. package/out/symbol/traverse/concepts/frontend/bind-event.js +3 -0
  67. package/out/symbol/traverse/concepts/frontend/bind-event.js.map +1 -1
  68. package/out/symbol/traverse/concepts/index.d.ts +1 -1
  69. package/out/symbol/traverse/concepts/index.d.ts.map +1 -1
  70. package/out/typer/collectGlobalDefs.js +1 -1
  71. package/out/typer/collectGlobalDefs.js.map +1 -1
  72. package/out/typer/dispatch-all.d.ts +1 -1
  73. package/out/typer/dispatch-all.d.ts.map +1 -1
  74. package/out/typer/dispatch-all.js +1 -1
  75. package/out/typer/dispatch-all.js.map +1 -1
  76. package/out/typer/dispatch-def.d.ts +2 -2
  77. package/out/typer/dispatch-def.d.ts.map +1 -1
  78. package/out/typer/dispatch-def.js +11 -16
  79. package/out/typer/dispatch-def.js.map +1 -1
  80. package/out/typer/dispatch-expr.js +11 -11
  81. package/out/typer/dispatch-expr.js.map +1 -1
  82. package/out/typer/dispatch-process.d.ts.map +1 -1
  83. package/out/typer/dispatch-process.js +7 -3
  84. package/out/typer/dispatch-process.js.map +1 -1
  85. package/out/typer/dispatch-view.d.ts.map +1 -1
  86. package/out/typer/dispatch-view.js +125 -62
  87. package/out/typer/dispatch-view.js.map +1 -1
  88. package/out/typer/helper.d.ts +0 -5
  89. package/out/typer/helper.d.ts.map +1 -1
  90. package/out/typer/helper.js +1 -21
  91. package/out/typer/helper.js.map +1 -1
  92. package/out/typer/incremental-update.d.ts.map +1 -1
  93. package/out/typer/incremental-update.js +127 -44
  94. package/out/typer/incremental-update.js.map +1 -1
  95. package/out/typer/index.d.ts +3 -3
  96. package/out/typer/index.d.ts.map +1 -1
  97. package/out/typer/index.js +3 -4
  98. package/out/typer/index.js.map +1 -1
  99. package/out/typer/nasl-predicate.d.ts +3 -5
  100. package/out/typer/nasl-predicate.d.ts.map +1 -1
  101. package/out/typer/nasl-predicate.js +10 -7
  102. package/out/typer/nasl-predicate.js.map +1 -1
  103. package/out/typer/solver.d.ts.map +1 -1
  104. package/out/typer/solver.js +4 -0
  105. package/out/typer/solver.js.map +1 -1
  106. package/out/typer/subster.js +4 -4
  107. package/out/typer/subster.js.map +1 -1
  108. package/out/typer/topo-sort.d.ts +1 -1
  109. package/out/typer/topo-sort.d.ts.map +1 -1
  110. package/out/typer/topo-sort.js +2 -2
  111. package/out/typer/topo-sort.js.map +1 -1
  112. package/out/typer/type-manager.d.ts +1 -1
  113. package/out/typer/type-manager.d.ts.map +1 -1
  114. package/out/typer/type-manager.js +5 -7
  115. package/out/typer/type-manager.js.map +1 -1
  116. package/out/typer/type-predicate.d.ts.map +1 -1
  117. package/out/typer/type-predicate.js +21 -7
  118. package/out/typer/type-predicate.js.map +1 -1
  119. package/out/typer/typer.d.ts +42 -6
  120. package/out/typer/typer.d.ts.map +1 -1
  121. package/out/typer/typer.js +127 -17
  122. package/out/typer/typer.js.map +1 -1
  123. package/out/typer/unifier.d.ts +0 -1
  124. package/out/typer/unifier.d.ts.map +1 -1
  125. package/out/typer/unifier.js +17 -12
  126. package/out/typer/unifier.js.map +1 -1
  127. package/out/utils/misc.d.ts +11 -0
  128. package/out/utils/misc.d.ts.map +1 -0
  129. package/out/utils/misc.js +29 -0
  130. package/out/utils/misc.js.map +1 -0
  131. package/out/utils/traverse-util.d.ts +5 -0
  132. package/out/utils/traverse-util.d.ts.map +1 -0
  133. package/out/utils/traverse-util.js +69 -0
  134. package/out/utils/traverse-util.js.map +1 -0
  135. package/package.json +5 -5
@@ -1,125 +1,42 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSubViews = exports.cheapTestLocalSymbol = exports.getNamespaceWithoutLast = exports.getDatasourceQName = exports.handleEntityAutoRef = exports.isEntityLogic = exports.easyGetOldQName = exports.ReferenceManager = void 0;
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 collect_q_name_1 = require("./collect-q-name");
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 nasl_predicate_1 = require("../typer/nasl-predicate");
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
- * x = f(...)
26
- * result = x.a.b
27
- *
28
- * a 与 b 可能本来是 T1.a 和 T2.b 中的引用
29
- *
30
- * 用户修改 f(...) 后
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.qNameDefs = new Map;
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 确实对实体有引用,但那不是用户数据。加上引用 ==> rename 时 实体逻辑的 nodePath 直接 invalid ==> "数据不同步强制刷新"
60
+ * 实体逻辑的定义的 params 的 typeAnnotation 确实对实体有引用,但那不是用户数据。
61
+ * 如果加上引用,则 rename 时 实体逻辑的 nodePath 直接 invalid ==> "数据不同步强制刷新"
62
+ *
139
63
  * 实体逻辑对其不够成引用 ==> rename 时额外加上 11 个实体逻辑的引用
140
64
  *
141
65
  * 将实体看成 namespace,所有引用实体逻辑的地方也算引用了实体?
142
66
  */
143
- this.symbolRefs = new Map; // Map 可就要小心内存泄漏咯 - 保存显式引用 (.typeAnnotation 字段)
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.symbolRefs.get(def);
71
+ return this.gSymbolRefs.get(def);
148
72
  };
149
73
  this.setSymbolRefs = (__def, refs) => {
150
74
  const def = this.normaliseEntityLogic(__def);
151
- this.symbolRefs.set(def, refs);
75
+ this.gSymbolRefs.set(def, refs);
152
76
  };
153
77
  this.deleteSymbolRefs = (__def) => {
154
78
  const def = this.normaliseEntityLogic(__def);
155
- return this.symbolRefs.delete(def);
79
+ return this.gSymbolRefs.delete(def);
156
80
  };
157
81
  this.clearSymbolRefs = () => {
158
- this.symbolRefs.clear();
82
+ this.gSymbolRefs.clear();
159
83
  };
160
84
  this.getSymbolRefsSize = () => {
161
- return this.symbolRefs.size;
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.symbolImplicitRefs = new WeakMap;
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.symbolImplicitRefs, def, ref);
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.symbolImplicitRefs.get(nd) ?? emptySet;
115
+ return this.gSymbolImplicitRefs.get(nd) ?? emptySet;
185
116
  };
186
117
  // 删除一个 def 时,缓存其 qName 到引用符号的关系,为了方便之后还能 relink 恢复
187
- this.cachedQNameSymbolRefs = new Map();
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.localQNameRefs = new Map();
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.qNameDefs.get(qName);
189
+ const def = this.gQNameDefs.get(qName);
258
190
  if (def) {
259
191
  // Add reference to existing definition
260
- (0, helper_1.createSetOnPush)(this.symbolRefs, def, ref);
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, exports.cheapTestLocalSymbol)(qName)) {
266
- (0, helper_1.createSetOnPush)(this.cachedQNameSymbolRefs, qName, ref);
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.fastBuildQNameDefs = (app) => {
297
- this.qNameDefs = new Map();
298
- this.compDefMgr.clearAll();
299
- if (app) {
300
- this.addQNameDefs(app);
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.qNameDefs.get(qName);
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.qNameDefs.get(`${ty.typeNamespace}.${ty.typeName}`);
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.qNameDefs.get(qName) : undefined;
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
- const boundary = toRaw(getBoundary(nd));
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.localQNameRefs.get((0, get_q_name_1.getTokenQualifiedName)(nd));
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
- const startTime = Date.now();
442
- res = this.clearRebuildLocalCache(env, nd);
443
- const endTime = Date.now();
444
- (endTime - startTime > 200) && console.log(`Get reference: all time: ${endTime - startTime}ms`);
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
- bsRefsRefs.push(...this.getViewElementRefs(env, bsInst));
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
- this.clearRebuildLocalCache = (env, nd_) => {
475
- this.localQNameRefs.clear();
476
- return this.buildLocalQNameRefs(env, toRaw(nd_)) ?? new Set();
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
- // 修改后:不写入 env map 了,不做缓存,直接返回数据
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
- let logics = new Array();
487
- const boundary = getBoundary(nd);
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 = (0, nasl_concepts_1.getViewLikeLogics)(nd).map(toRaw);
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 = (0, nasl_concepts_1.getProcessLikeLogics)(nd).map(toRaw);
428
+ // logics = getProcessLikeLogics(nd).map(toRaw);
506
429
  }
507
- else if ((0, nasl_predicate_1.isCallableNaslLogic)(boundary) || (0, nasl_predicate_1.isCallableNaslInterface)(boundary)) {
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.localQNameRefs.set(qName, new Set());
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.localQNameRefs.get(qName)?.add(rf);
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 = (env, __nd) => {
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.qNameDefs.get(oldQName);
510
+ const oldDef = this.gQNameDefs.get(oldQName);
617
511
  if (!oldDef)
618
512
  return;
619
513
  // 1. 删除 oldQName,建立 newQName,def 地址不变
620
- this.qNameDefs.delete(oldQName);
621
- this.qNameDefs.set(newQName, oldDef);
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.symbolRefs.get(oldDef) ?? new Set();
519
+ const oldRefs = this.gSymbolRefs.get(oldDef) ?? new Set();
626
520
  // 获取 newQName 在缓存中的引用
627
- const newCachedRefs = this.cachedQNameSymbolRefs.get(newQName) ?? new Set();
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.cachedQNameSymbolRefs.delete(newQName);
527
+ this.gCachedQNameSymbolRefs.delete(newQName);
634
528
  }
635
529
  else {
636
530
  // 不是 update,直接取 newQName 在缓存中的引用
637
- const newCachedRefs = this.cachedQNameSymbolRefs.get(newQName) ?? new Set();
531
+ const newCachedRefs = this.gCachedQNameSymbolRefs.get(newQName) ?? new Set();
638
532
  this.setSymbolRefs(oldDef, newCachedRefs);
639
533
  // oldQName 的引用集合被放入 cachedQNameSymbolRefs
640
- const oldRefs = this.symbolRefs.get(oldDef) ?? new Set();
641
- oldRefs.size > 0 && this.cachedQNameSymbolRefs.set(oldQName, oldRefs);
534
+ const oldRefs = this.gSymbolRefs.get(oldDef) ?? new Set();
535
+ oldRefs.size > 0 && this.gCachedQNameSymbolRefs.set(oldQName, oldRefs);
642
536
  // 删除 newQName 在缓存中的引用
643
- this.cachedQNameSymbolRefs.delete(newQName);
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.localDefConcept.includes(defNode.concept)) {
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.cachedQNameSymbolRefs.get(qName);
553
+ const oldRefs = this.gCachedQNameSymbolRefs.get(qName);
661
554
  oldRefs && this.setSymbolRefs(defNode, oldRefs);
662
555
  // qName 链接到新的 defNode 的 mem addr
663
- this.addQNameDef(qName, defNode);
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.cachedQNameSymbolRefs.delete(qName);
561
+ this.gCachedQNameSymbolRefs.delete(qName);
669
562
  }
670
563
  break;
671
564
  }
672
565
  case "delete" /* Operation.Remove */: { // 连根拔起,但缓存
673
- if (symbol_type_1.localDefConcept.includes(defNode.concept)) {
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.cachedQNameSymbolRefs.set(qName, refs);
679
- this.qNameDefs.delete(qName);
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.qNameDefs.get(qName);
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.symbolRefs, def, refNd);
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.cachedQNameSymbolRefs, qName, refNd);
606
+ (0, fp_macros_1.createOnAdd)(this.gCachedQNameSymbolRefs, qName, refNd);
714
607
  break;
715
608
  }
716
609
  case "delete" /* Operation.Remove */: {
717
- this.cachedQNameSymbolRefs.get(qName)?.delete(refNd);
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.symbolImplicitRefs.get(tyDef)?.delete(nd);
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.symbolImplicitRefs.get(tyDef)?.delete(nd);
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, exports.getSubViews)(nd));
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 && (0, update_nasl_fragment_1.isSpecialStringRefField)(nd.name)) {
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 && (0, update_nasl_fragment_1.isSpecialStringRefField)(rmNd.name)) {
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, exports.cheapTestLocalSymbol)(qName)) {
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.qNameDefs.get(`${eNsp}.${eAsName}`);
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.qNameDefs,
1273
- symbolRefs: this.symbolRefs, // Exporting private map for serialization
1274
- cachedQNameSymbolRefs: this.cachedQNameSymbolRefs,
1275
- localQNameRefs: this.localQNameRefs,
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, exports.isEntityLogic)(nd)) {
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.qNameDefs.get(qName);
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.qNameDefs.set(qName, nd);
1338
- const refs = mnemonist_1.set.union(this.symbolRefs.get(def) ?? new Set(), this.symbolRefs.get(nd) ?? new Set());
1339
- refs.size > 0 && this.symbolRefs.set(nd, refs);
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.fastBuildQNameDefs(toRaw(app));
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.qNameDefs.clear();
1382
- this.cachedQNameSymbolRefs.clear();
1383
- this.localQNameRefs.clear();
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.symbolImplicitRefs = new WeakMap();
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