arkanalyzer 1.0.94 → 2.0.0-beta1

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 (291) hide show
  1. package/lib/Config.d.ts +7 -0
  2. package/lib/Config.d.ts.map +1 -1
  3. package/lib/Scene.d.ts +134 -170
  4. package/lib/Scene.d.ts.map +1 -1
  5. package/lib/Scene.js +412 -976
  6. package/lib/callgraph/algorithm/AbstractAnalysis.js +3 -2
  7. package/lib/callgraph/algorithm/RapidTypeAnalysis.js +1 -1
  8. package/lib/callgraph/model/CallGraph.js +1 -1
  9. package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts +1 -3
  10. package/lib/callgraph/pointerAnalysis/PTAUtils.d.ts.map +1 -1
  11. package/lib/callgraph/pointerAnalysis/PTAUtils.js +17 -7
  12. package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
  13. package/lib/callgraph/pointerAnalysis/Pag.js +4 -14
  14. package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
  15. package/lib/callgraph/pointerAnalysis/PagBuilder.js +2 -1
  16. package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
  17. package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +1 -2
  18. package/lib/callgraph/pointerAnalysis/plugins/WorkerPlugin.d.ts.map +1 -1
  19. package/lib/callgraph/pointerAnalysis/plugins/WorkerPlugin.js +0 -1
  20. package/lib/cli/commands/cg.d.ts +1 -0
  21. package/lib/cli/commands/cg.d.ts.map +1 -1
  22. package/lib/cli/commands/cg.js +22 -18
  23. package/lib/cli/commands/ir.d.ts +1 -0
  24. package/lib/cli/commands/ir.d.ts.map +1 -1
  25. package/lib/cli/commands/ir.js +5 -2
  26. package/lib/core/base/Constant.d.ts +5 -5
  27. package/lib/core/base/Constant.d.ts.map +1 -1
  28. package/lib/core/base/Constant.js +12 -9
  29. package/lib/core/base/Expr.d.ts +36 -20
  30. package/lib/core/base/Expr.d.ts.map +1 -1
  31. package/lib/core/base/Expr.js +206 -94
  32. package/lib/core/base/Local.d.ts +10 -20
  33. package/lib/core/base/Local.d.ts.map +1 -1
  34. package/lib/core/base/Local.js +25 -28
  35. package/lib/core/base/Position.d.ts +6 -0
  36. package/lib/core/base/Position.d.ts.map +1 -1
  37. package/lib/core/base/Position.js +37 -11
  38. package/lib/core/base/Ref.d.ts +45 -33
  39. package/lib/core/base/Ref.d.ts.map +1 -1
  40. package/lib/core/base/Ref.js +225 -51
  41. package/lib/core/base/Stmt.d.ts +19 -9
  42. package/lib/core/base/Stmt.d.ts.map +1 -1
  43. package/lib/core/base/Stmt.js +135 -52
  44. package/lib/core/base/Type.d.ts +67 -4
  45. package/lib/core/base/Type.d.ts.map +1 -1
  46. package/lib/core/base/Type.js +391 -20
  47. package/lib/core/base/TypeExpr.d.ts +6 -4
  48. package/lib/core/base/TypeExpr.d.ts.map +1 -1
  49. package/lib/core/base/TypeExpr.js +34 -10
  50. package/lib/core/base/Value.d.ts +20 -2
  51. package/lib/core/base/Value.d.ts.map +1 -1
  52. package/lib/core/base/Value.js +12 -0
  53. package/lib/core/common/ArkIRTransformer.d.ts +18 -0
  54. package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
  55. package/lib/core/common/ArkIRTransformer.js +94 -75
  56. package/lib/core/common/ArkValueTransformer.d.ts +21 -3
  57. package/lib/core/common/ArkValueTransformer.d.ts.map +1 -1
  58. package/lib/core/common/ArkValueTransformer.js +455 -265
  59. package/lib/core/common/Builtin.d.ts +48 -24
  60. package/lib/core/common/Builtin.d.ts.map +1 -1
  61. package/lib/core/common/Builtin.js +90 -52
  62. package/lib/core/common/CanonicalizerValidator.d.ts +308 -0
  63. package/lib/core/common/CanonicalizerValidator.d.ts.map +1 -0
  64. package/lib/core/common/CanonicalizerValidator.js +888 -0
  65. package/lib/core/common/Const.d.ts +3 -3
  66. package/lib/core/common/Const.d.ts.map +1 -1
  67. package/lib/core/common/Const.js +3 -3
  68. package/lib/core/common/DummyMainCreater.d.ts +2 -21
  69. package/lib/core/common/DummyMainCreater.d.ts.map +1 -1
  70. package/lib/core/common/DummyMainCreater.js +8 -105
  71. package/lib/core/common/IRInference.d.ts +55 -3
  72. package/lib/core/common/IRInference.d.ts.map +1 -1
  73. package/lib/core/common/IRInference.js +407 -126
  74. package/lib/core/common/IRUtils.d.ts +1 -0
  75. package/lib/core/common/IRUtils.d.ts.map +1 -1
  76. package/lib/core/common/IRUtils.js +44 -13
  77. package/lib/core/common/ModelUtils.d.ts +44 -20
  78. package/lib/core/common/ModelUtils.d.ts.map +1 -1
  79. package/lib/core/common/ModelUtils.js +378 -208
  80. package/lib/core/common/SdkUtils.d.ts +35 -5
  81. package/lib/core/common/SdkUtils.d.ts.map +1 -1
  82. package/lib/core/common/SdkUtils.js +181 -53
  83. package/lib/core/common/SignatureCanonicalizer.d.ts +95 -0
  84. package/lib/core/common/SignatureCanonicalizer.d.ts.map +1 -0
  85. package/lib/core/common/SignatureCanonicalizer.js +116 -0
  86. package/lib/core/common/SignatureCanonicalizerRegistry.d.ts +176 -0
  87. package/lib/core/common/SignatureCanonicalizerRegistry.d.ts.map +1 -0
  88. package/lib/core/common/SignatureCanonicalizerRegistry.js +343 -0
  89. package/lib/core/common/SignatureModelCanonicalizer.d.ts +69 -0
  90. package/lib/core/common/SignatureModelCanonicalizer.d.ts.map +1 -0
  91. package/lib/core/common/SignatureModelCanonicalizer.js +109 -0
  92. package/lib/core/common/StmtUseReplacer.d.ts +1 -0
  93. package/lib/core/common/StmtUseReplacer.d.ts.map +1 -1
  94. package/lib/core/common/StmtUseReplacer.js +9 -0
  95. package/lib/core/common/StringUtils.d.ts +12 -1
  96. package/lib/core/common/StringUtils.d.ts.map +1 -1
  97. package/lib/core/common/StringUtils.js +36 -17
  98. package/lib/core/common/TempSignatureCanonicalizer.d.ts +82 -0
  99. package/lib/core/common/TempSignatureCanonicalizer.d.ts.map +1 -0
  100. package/lib/core/common/TempSignatureCanonicalizer.js +177 -0
  101. package/lib/core/common/TypeInference.d.ts +24 -6
  102. package/lib/core/common/TypeInference.d.ts.map +1 -1
  103. package/lib/core/common/TypeInference.js +243 -117
  104. package/lib/core/common/ValueUtil.d.ts +2 -1
  105. package/lib/core/common/ValueUtil.d.ts.map +1 -1
  106. package/lib/core/common/ValueUtil.js +4 -1
  107. package/lib/core/graph/Cfg.d.ts.map +1 -1
  108. package/lib/core/graph/Cfg.js +21 -6
  109. package/lib/core/graph/builder/CfgBuilder.d.ts.map +1 -1
  110. package/lib/core/graph/builder/CfgBuilder.js +46 -33
  111. package/lib/core/graph/builder/IfBuilder.d.ts.map +1 -1
  112. package/lib/core/graph/builder/IfBuilder.js +6 -2
  113. package/lib/core/graph/builder/ViewTreeBuilder.d.ts.map +1 -1
  114. package/lib/core/graph/builder/ViewTreeBuilder.js +6 -2
  115. package/lib/core/inference/ModelInference.d.ts +24 -4
  116. package/lib/core/inference/ModelInference.d.ts.map +1 -1
  117. package/lib/core/inference/ModelInference.js +273 -79
  118. package/lib/core/inference/ValueInference.d.ts +3 -2
  119. package/lib/core/inference/ValueInference.d.ts.map +1 -1
  120. package/lib/core/inference/ValueInference.js +90 -40
  121. package/lib/core/inference/abc/AbcInference.d.ts.map +1 -1
  122. package/lib/core/inference/abc/AbcInference.js +28 -15
  123. package/lib/core/inference/arkts/ArkTsInference.d.ts +9 -3
  124. package/lib/core/inference/arkts/ArkTsInference.d.ts.map +1 -1
  125. package/lib/core/inference/arkts/ArkTsInference.js +54 -16
  126. package/lib/core/model/ArkClass.d.ts +192 -18
  127. package/lib/core/model/ArkClass.d.ts.map +1 -1
  128. package/lib/core/model/ArkClass.js +852 -122
  129. package/lib/core/model/ArkExport.d.ts.map +1 -1
  130. package/lib/core/model/ArkExport.js +1 -2
  131. package/lib/core/model/ArkField.d.ts +34 -2
  132. package/lib/core/model/ArkField.d.ts.map +1 -1
  133. package/lib/core/model/ArkField.js +89 -14
  134. package/lib/core/model/ArkFile.d.ts +72 -12
  135. package/lib/core/model/ArkFile.d.ts.map +1 -1
  136. package/lib/core/model/ArkFile.js +275 -65
  137. package/lib/core/model/ArkImport.d.ts.map +1 -1
  138. package/lib/core/model/ArkImport.js +1 -2
  139. package/lib/core/model/ArkMethod.d.ts +101 -15
  140. package/lib/core/model/ArkMethod.d.ts.map +1 -1
  141. package/lib/core/model/ArkMethod.js +252 -39
  142. package/lib/core/model/ArkModule.d.ts +1 -1
  143. package/lib/core/model/ArkModule.js +1 -1
  144. package/lib/core/model/ArkNamespace.d.ts +80 -10
  145. package/lib/core/model/ArkNamespace.d.ts.map +1 -1
  146. package/lib/core/model/ArkNamespace.js +309 -76
  147. package/lib/core/model/ArkSignature.d.ts +242 -18
  148. package/lib/core/model/ArkSignature.d.ts.map +1 -1
  149. package/lib/core/model/ArkSignature.js +725 -95
  150. package/lib/core/model/builder/ArkClassBuilder.d.ts +6 -3
  151. package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -1
  152. package/lib/core/model/builder/ArkClassBuilder.js +116 -71
  153. package/lib/core/model/builder/ArkExportBuilder.d.ts +1 -1
  154. package/lib/core/model/builder/ArkExportBuilder.d.ts.map +1 -1
  155. package/lib/core/model/builder/ArkExportBuilder.js +1 -1
  156. package/lib/core/model/builder/ArkFieldBuilder.d.ts +0 -2
  157. package/lib/core/model/builder/ArkFieldBuilder.d.ts.map +1 -1
  158. package/lib/core/model/builder/ArkFieldBuilder.js +9 -43
  159. package/lib/core/model/builder/ArkFileBuilder.d.ts.map +1 -1
  160. package/lib/core/model/builder/ArkFileBuilder.js +32 -33
  161. package/lib/core/model/builder/ArkMethodBuilder.d.ts +10 -3
  162. package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
  163. package/lib/core/model/builder/ArkMethodBuilder.js +40 -26
  164. package/lib/core/model/builder/ArkNamespaceBuilder.d.ts +3 -2
  165. package/lib/core/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
  166. package/lib/core/model/builder/ArkNamespaceBuilder.js +45 -77
  167. package/lib/core/model/builder/ArkSignatureBuilder.d.ts +9 -0
  168. package/lib/core/model/builder/ArkSignatureBuilder.d.ts.map +1 -1
  169. package/lib/core/model/builder/ArkSignatureBuilder.js +26 -3
  170. package/lib/core/model/builder/BodyBuilder.d.ts +1 -0
  171. package/lib/core/model/builder/BodyBuilder.d.ts.map +1 -1
  172. package/lib/core/model/builder/BodyBuilder.js +37 -11
  173. package/lib/core/model/builder/builderUtils.d.ts +11 -1
  174. package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
  175. package/lib/core/model/builder/builderUtils.js +124 -90
  176. package/lib/frontend/FrontendBuilder.d.ts +10 -6
  177. package/lib/frontend/FrontendBuilder.d.ts.map +1 -1
  178. package/lib/frontend/FrontendBuilder.js +19 -45
  179. package/lib/frontend/ModuleScene.d.ts +43 -0
  180. package/lib/frontend/ModuleScene.d.ts.map +1 -0
  181. package/lib/frontend/ModuleScene.js +143 -0
  182. package/lib/frontend/SceneBuildStage.d.ts +15 -0
  183. package/lib/frontend/SceneBuildStage.d.ts.map +1 -0
  184. package/lib/frontend/SceneBuildStage.js +32 -0
  185. package/lib/frontend/SceneBuilder.d.ts +153 -0
  186. package/lib/frontend/SceneBuilder.d.ts.map +1 -0
  187. package/lib/frontend/SceneBuilder.js +859 -0
  188. package/lib/frontend/arktsFrontend/ArktsFrontend.d.ts +0 -2
  189. package/lib/frontend/arktsFrontend/ArktsFrontend.d.ts.map +1 -1
  190. package/lib/frontend/arktsFrontend/ArktsFrontend.js +0 -18
  191. package/lib/frontend/arktsFrontend/FileBodyRemount.d.ts +17 -0
  192. package/lib/frontend/arktsFrontend/FileBodyRemount.d.ts.map +1 -0
  193. package/lib/frontend/arktsFrontend/FileBodyRemount.js +187 -0
  194. package/lib/frontend/common/ModuleBuilder.d.ts +4 -2
  195. package/lib/frontend/common/ModuleBuilder.d.ts.map +1 -1
  196. package/lib/frontend/common/ModuleBuilder.js +19 -9
  197. package/lib/frontend/cppFrontend/CppFrontend.d.ts +0 -6
  198. package/lib/frontend/cppFrontend/CppFrontend.d.ts.map +1 -1
  199. package/lib/frontend/cppFrontend/CppFrontend.js +0 -56
  200. package/lib/frontend/cppFrontend/base/Type.d.ts +7 -0
  201. package/lib/frontend/cppFrontend/base/Type.d.ts.map +1 -1
  202. package/lib/frontend/cppFrontend/base/Type.js +29 -0
  203. package/lib/frontend/cppFrontend/common/ArkIRTransformer.d.ts.map +1 -1
  204. package/lib/frontend/cppFrontend/common/ArkIRTransformer.js +56 -56
  205. package/lib/frontend/cppFrontend/common/ArkValueTransformer.d.ts +1 -1
  206. package/lib/frontend/cppFrontend/common/ArkValueTransformer.d.ts.map +1 -1
  207. package/lib/frontend/cppFrontend/common/ArkValueTransformer.js +124 -113
  208. package/lib/frontend/cppFrontend/common/Builtin.d.ts +29 -19
  209. package/lib/frontend/cppFrontend/common/Builtin.d.ts.map +1 -1
  210. package/lib/frontend/cppFrontend/common/Builtin.js +56 -35
  211. package/lib/frontend/cppFrontend/common/IRInference.d.ts +7 -2
  212. package/lib/frontend/cppFrontend/common/IRInference.d.ts.map +1 -1
  213. package/lib/frontend/cppFrontend/common/IRInference.js +61 -28
  214. package/lib/frontend/cppFrontend/common/IRUtils.d.ts +1 -0
  215. package/lib/frontend/cppFrontend/common/IRUtils.d.ts.map +1 -1
  216. package/lib/frontend/cppFrontend/common/IRUtils.js +22 -10
  217. package/lib/frontend/cppFrontend/common/ModelUtils.d.ts +19 -0
  218. package/lib/frontend/cppFrontend/common/ModelUtils.d.ts.map +1 -1
  219. package/lib/frontend/cppFrontend/common/ModelUtils.js +84 -3
  220. package/lib/frontend/cppFrontend/common/TypeInference.d.ts.map +1 -1
  221. package/lib/frontend/cppFrontend/common/TypeInference.js +44 -54
  222. package/lib/frontend/cppFrontend/graph/builder/CfgBuilder.d.ts.map +1 -1
  223. package/lib/frontend/cppFrontend/graph/builder/CfgBuilder.js +2 -1
  224. package/lib/frontend/cppFrontend/inference/CxxModelInference.d.ts +1 -1
  225. package/lib/frontend/cppFrontend/inference/CxxModelInference.d.ts.map +1 -1
  226. package/lib/frontend/cppFrontend/inference/CxxValueInference.d.ts.map +1 -1
  227. package/lib/frontend/cppFrontend/inference/CxxValueInference.js +41 -5
  228. package/lib/frontend/cppFrontend/model/builder/ArkClassBuilder.d.ts.map +1 -1
  229. package/lib/frontend/cppFrontend/model/builder/ArkClassBuilder.js +18 -28
  230. package/lib/frontend/cppFrontend/model/builder/ArkFieldBuilder.d.ts.map +1 -1
  231. package/lib/frontend/cppFrontend/model/builder/ArkFieldBuilder.js +2 -3
  232. package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.d.ts +2 -2
  233. package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.d.ts.map +1 -1
  234. package/lib/frontend/cppFrontend/model/builder/ArkFileBuilder.js +31 -24
  235. package/lib/frontend/cppFrontend/model/builder/ArkMethodBuilder.d.ts.map +1 -1
  236. package/lib/frontend/cppFrontend/model/builder/ArkMethodBuilder.js +10 -16
  237. package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.d.ts +0 -2
  238. package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
  239. package/lib/frontend/cppFrontend/model/builder/ArkNamespaceBuilder.js +19 -37
  240. package/lib/frontend/cppFrontend/model/builder/BodyBuilder.d.ts +1 -0
  241. package/lib/frontend/cppFrontend/model/builder/BodyBuilder.d.ts.map +1 -1
  242. package/lib/frontend/cppFrontend/model/builder/BodyBuilder.js +30 -3
  243. package/lib/frontend/cppFrontend/model/builder/builderUtils.d.ts.map +1 -1
  244. package/lib/frontend/cppFrontend/model/builder/builderUtils.js +8 -4
  245. package/lib/index.d.ts +3 -0
  246. package/lib/index.d.ts.map +1 -1
  247. package/lib/index.js +10 -2
  248. package/lib/save/json/JsonSerialization.js +2 -2
  249. package/lib/save/source/SourceStmt.js +1 -1
  250. package/lib/save/source/SourceTransformer.d.ts.map +1 -1
  251. package/lib/save/source/SourceTransformer.js +0 -9
  252. package/lib/statistics/StageStatistics.d.ts +195 -0
  253. package/lib/statistics/StageStatistics.d.ts.map +1 -0
  254. package/lib/statistics/StageStatistics.js +346 -0
  255. package/lib/statistics/StageStatisticsReporter.d.ts +58 -0
  256. package/lib/statistics/StageStatisticsReporter.d.ts.map +1 -0
  257. package/lib/statistics/StageStatisticsReporter.js +255 -0
  258. package/lib/utils/Canonicalizer.d.ts +9 -2
  259. package/lib/utils/Canonicalizer.d.ts.map +1 -1
  260. package/lib/utils/Canonicalizer.js +19 -2
  261. package/lib/utils/CxxSceneUtils.d.ts +7 -0
  262. package/lib/utils/CxxSceneUtils.d.ts.map +1 -1
  263. package/lib/utils/CxxSceneUtils.js +10 -1
  264. package/lib/utils/FileUtils.d.ts +0 -1
  265. package/lib/utils/FileUtils.d.ts.map +1 -1
  266. package/lib/utils/FileUtils.js +1 -9
  267. package/lib/utils/HashUtils.d.ts +9 -0
  268. package/lib/utils/HashUtils.d.ts.map +1 -0
  269. package/lib/utils/HashUtils.js +65 -0
  270. package/lib/utils/ModuleUtils.d.ts.map +1 -1
  271. package/lib/utils/ModuleUtils.js +24 -5
  272. package/lib/utils/VisitedSegment.d.ts +23 -0
  273. package/lib/utils/VisitedSegment.d.ts.map +1 -0
  274. package/lib/utils/VisitedSegment.js +64 -0
  275. package/lib/utils/callGraphUtils.d.ts.map +1 -1
  276. package/lib/utils/callGraphUtils.js +7 -7
  277. package/lib/utils/getAllFiles.d.ts.map +1 -1
  278. package/lib/utils/getAllFiles.js +11 -8
  279. package/lib/utils/logger.d.ts +4 -0
  280. package/lib/utils/logger.d.ts.map +1 -1
  281. package/lib/utils/logger.js +16 -0
  282. package/lib/utils/parseArkSourceFile.d.ts +33 -0
  283. package/lib/utils/parseArkSourceFile.d.ts.map +1 -0
  284. package/lib/utils/parseArkSourceFile.js +131 -0
  285. package/package.json +1 -1
  286. package/lib/utils/DependenciesSort.d.ts +0 -3
  287. package/lib/utils/DependenciesSort.d.ts.map +0 -1
  288. package/lib/utils/DependenciesSort.js +0 -72
  289. package/lib/utils/crypto_utils.d.ts +0 -6
  290. package/lib/utils/crypto_utils.d.ts.map +0 -1
  291. package/lib/utils/crypto_utils.js +0 -57
@@ -0,0 +1,888 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Huawei Device Co., Ltd.
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.CanonicalizerValidator = void 0;
41
+ const SignatureCanonicalizerRegistry_1 = require("./SignatureCanonicalizerRegistry");
42
+ const ArkSignature_1 = require("../model/ArkSignature");
43
+ const Type_1 = require("../base/Type");
44
+ const Expr_1 = require("../base/Expr");
45
+ const Ref_1 = require("../base/Ref");
46
+ const logger_1 = __importStar(require("../../utils/logger"));
47
+ const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'CanonicalizerValidator');
48
+ /**
49
+ * 签名 canonicalizer 的内部结构校验器(仅开发调试用)。
50
+ *
51
+ * 每个 formal 空间的校验规则互不相同(class 空间存在别名折叠语义、method 空间存在
52
+ * declare-only 合法无 model 条目等),因此各空间独立实现各自的 validateXxxSpace,
53
+ * 不做统一泛型模板;待多个空间落地后若出现真实重复,再抽取公共部分。
54
+ *
55
+ * 通过 `SceneOptions.validateCanonicalizers` 开启(默认关闭)。
56
+ */
57
+ class CanonicalizerValidator {
58
+ /**
59
+ * 校验 formal file 空间的结构不变量,规则如下:
60
+ *
61
+ * R1a DEFAULT 保留位契约(正向断言):ID 0 必须存在 DEFAULT 签名条目。
62
+ * 缺失说明 registry 初始化损坏(internDefaults 未执行或被破坏)。
63
+ *
64
+ * R1b DEFAULT 保留位契约(正向断言):ID 0 的 model 必须为 undefined。
65
+ * models[0] 设计上永久空置(registerFile 有 id > 0 守卫);若被绕过守卫
66
+ * 直接 setModel(0, ...) 挂载,视为保留位被侵占。
67
+ *
68
+ * R2 ID 稠密性:[1, size) 内每个 ID 都必须有签名条目。
69
+ * 出现空洞说明条目结构损坏(理论上不可达,防御性检查)。
70
+ *
71
+ * R3 model 完备性:[1, size) 内每个 ID 必须有对应的 ArkFile model。
72
+ * 两种可能来路:① disposeModule 驱逐态(removeFile 删 model 留 sig,合法、
73
+ * 可 reload 自愈);② 新代码引入的空洞(bug)。本工具不区分二者,
74
+ * 全部报告,由开发者结合场景判断。
75
+ *
76
+ * R4 model 回指一致性:挂载在 ID i 的 ArkFile,其 getFileSigID() 必须等于 i。
77
+ * 回指不一致会导致查询路径走 stale 兜底(error 日志 + 返回 DEFAULT)。
78
+ *
79
+ * R5 签名值唯一性:任意两个不同 ID 不得持有 equals() 相等的签名。
80
+ * canonicalizer 本身按 hash+equals 去重,正常情况下同值必同 ID;本规则
81
+ * 违规当且仅当 hash/equals 契约破裂(如给 FileSignature 加字段进了 equals
82
+ * 忘了进 hash)。契约保证"equals 相等 → hash 相等",故违规对必落在同一
83
+ * hash 分组内,按 hashCode 分组后组内两两比较即可,均摊 O(n)。
84
+ * ID 0 的 DEFAULT 签名参与分组比较——这是值域坍缩不变量的守卫:所有用
85
+ * UNKNOWN 常量(%unk/%unk)构造的签名必须 intern 到 ID 0,不得出现第二个。
86
+ *
87
+ * R6 model 挂载唯一性:同一 ArkFile 实例不得挂载于多个 ID。
88
+ * 双挂载意味着模型索引错乱,Scene.getFile 查询结果将不一致。
89
+ *
90
+ * R7 project/SDK ID 边界一致性(仅边界已设置时检查,见
91
+ * SignatureCanonicalizerRegistry.markProjectFileBoundary):
92
+ * [1, first) 内有 model 的 ID,其 isProjectFile() 必须为 false;
93
+ * [first, size) 内有 model 的 ID,其 isProjectFile() 必须为 true。
94
+ * 违反说明构建时序回归(如边界设置后仍有 SDK 文件注册)或 ArkFile 的
95
+ * projectFile 标志被误标。ID 0(DEFAULT)不参与本规则。
96
+ *
97
+ * 执行语义:所有规则全量执行、任何违规不中断;违规逐条收集(规则号 + ID +
98
+ * 签名描述),一次性汇总报告——无论违规多少都给出完整清单。全部规则均为
99
+ * error 级:任何一条违规即意味着某项不变量被打破。
100
+ *
101
+ * @returns 全部违规描述(空数组 = 空间干净)。
102
+ */
103
+ static validateFileSpace() {
104
+ const violations = [];
105
+ const reg = SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
106
+ const canonicalizer = reg.fileSigCanonicalizer;
107
+ // R5 辅助结构:按缓存的 hashCode 分组签名。
108
+ const byHash = new Map();
109
+ // R6 辅助结构:已见过的 model 实例,用于检测双挂载。
110
+ const seenModels = new Set();
111
+ this.checkDefaultSlot(violations, 'file', 'R1a', 'R1b', canonicalizer, byHash);
112
+ const size = canonicalizer.size();
113
+ // R7 边界:循环外取一次。
114
+ const boundary = reg.getFirstProjectFileSigID();
115
+ for (let id = 1; id < size; id++) {
116
+ this.checkFileEntry(violations, canonicalizer, id, canonicalizer.get(id), size, byHash, seenModels, boundary);
117
+ }
118
+ this.checkSignatureValueUniqueness(violations, byHash, 'file', 'R5');
119
+ return violations;
120
+ }
121
+ /** R2–R7:单 ID 条目级校验(R5 仅累积分组,组内比较在 {@link checkSignatureValueUniqueness})。 */
122
+ static checkFileEntry(violations, canonicalizer, id, sig, size, byHash, seenModels, boundary) {
123
+ if (sig === undefined) {
124
+ // R2
125
+ violations.push(`[file] R2: ID ${id} is inside [0, size=${size}) but has no signature entry`);
126
+ return;
127
+ }
128
+ // R5(累积)
129
+ let group = byHash.get(sig.getHashCode());
130
+ if (group === undefined) {
131
+ group = [];
132
+ byHash.set(sig.getHashCode(), group);
133
+ }
134
+ group.push({ id, sig });
135
+ const model = canonicalizer.getModel(id);
136
+ if (model === undefined) {
137
+ // R3
138
+ violations.push(`[file] R3: ID ${id} (${sig.toString()}) has no model`);
139
+ return;
140
+ }
141
+ // R4
142
+ const back = model.getFileSigID();
143
+ if (back !== id) {
144
+ violations.push(`[file] R4: model at ID ${id} (${sig.toString()}) back-points to ${back}`);
145
+ }
146
+ // R6
147
+ if (seenModels.has(model)) {
148
+ violations.push(`[file] R6: model at ID ${id} (${sig.toString()}) is mounted at more than one ID`);
149
+ }
150
+ else {
151
+ seenModels.add(model);
152
+ }
153
+ // R7
154
+ if (boundary !== -1) {
155
+ const expectedProject = id >= boundary;
156
+ if (model.isProjectFile() !== expectedProject) {
157
+ violations.push(`[file] R7: ID ${id} (${sig.toString()}) is ${model.isProjectFile() ? 'a project file' : 'an SDK file'} ` +
158
+ `but sits ${expectedProject ? 'at/after' : 'before'} the project/SDK boundary ${boundary}`);
159
+ }
160
+ }
161
+ }
162
+ /**
163
+ * 校验 formal namespace 空间的结构不变量,规则如下:
164
+ *
165
+ * N1a DEFAULT 保留位契约(正向断言):ID 0 必须存在 DEFAULT 签名条目。
166
+ *
167
+ * N1b DEFAULT 保留位契约(正向断言):ID 0 的 model 必须为 undefined。
168
+ *
169
+ * N2 ID 稠密性:[1, size) 内每个 ID 都必须有签名条目。
170
+ *
171
+ * N3 model 完备性:[1, size) 内每个 ID 必须有对应的 ArkNamespace model。
172
+ * 两种可能来路:① disposeModule 驱逐态(removeNamespace 删 model 留 sig,
173
+ * 合法、可 reload 自愈);② 签名值仅被惰性 intern(NamespaceSignature.
174
+ * getNamespaceSigID)而无真实 ArkNamespace 注册——ArkNamespace.setSignature
175
+ * 已带自愈补挂,出现即为新路径逃逸。全部报告,由开发者结合场景判断。
176
+ *
177
+ * N4 model 回指一致性:挂载在 ID i 的 ArkNamespace,其 getNamespaceSigID()
178
+ * 必须等于 i。
179
+ *
180
+ * N5 签名值唯一性:任意两个不同 ID 不得持有 equals() 相等的签名(守卫
181
+ * hash/equals 契约与 DEFAULT 值域坍缩;原理同 file 空间 R5)。
182
+ *
183
+ * N6 model 挂载唯一性:同一 ArkNamespace 实例不得挂载于多个 ID。
184
+ *
185
+ * N7 链完整性(仅对 model 存活的条目检查;驱逐态条目的链检查跳过——N3 已
186
+ * 报告其驱逐,父/子链完整性以存活侧为准):
187
+ * N7a 嵌套 ns:declaringNamespaceSigID 非 undefined 时,父 namespace 的
188
+ * model 必须存在(disposeModule 同文件整树驱逐,父驱逐子存活 = 驱逐
189
+ * 不完整或手工构造逃逸);
190
+ * N7b 嵌套 ns:父 model 的 top 列表必须含本 ID(父子互联正确);
191
+ * N7c 顶层 ns:declaringNamespaceSigID 为 undefined 时,declaring file
192
+ * 的 model 必须存在且其 top 列表含本 ID(file 侧互联正确)。
193
+ *
194
+ * 执行语义:所有规则全量执行、任何违规不中断;违规逐条收集(规则号 + ID +
195
+ * 签名描述),一次性汇总报告。全部规则均为 error 级。
196
+ *
197
+ * @returns 全部违规描述(空数组 = 空间干净)。
198
+ */
199
+ static validateNamespaceSpace() {
200
+ const violations = [];
201
+ const reg = SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
202
+ const canonicalizer = reg.namespaceSigCanonicalizer;
203
+ // N5 辅助结构:按缓存的 hashCode 分组签名。
204
+ const byHash = new Map();
205
+ // N6 辅助结构:已见过的 model 实例,用于检测双挂载。
206
+ const seenModels = new Set();
207
+ this.checkDefaultSlot(violations, 'namespace', 'N1a', 'N1b', canonicalizer, byHash);
208
+ const size = canonicalizer.size();
209
+ for (let id = 1; id < size; id++) {
210
+ this.checkNamespaceEntry(violations, reg, id, canonicalizer.get(id), size, byHash, seenModels);
211
+ }
212
+ this.checkSignatureValueUniqueness(violations, byHash, 'namespace', 'N5');
213
+ return violations;
214
+ }
215
+ /** N2–N7:单 ID 条目级校验(N5 仅累积分组,组内比较在 {@link checkSignatureValueUniqueness})。 */
216
+ static checkNamespaceEntry(violations, reg, id, sig, size, byHash, seenModels) {
217
+ if (sig === undefined) {
218
+ // N2
219
+ violations.push(`[namespace] N2: ID ${id} is inside [0, size=${size}) but has no signature entry`);
220
+ return;
221
+ }
222
+ // N5(累积)
223
+ let group = byHash.get(sig.getHashCode());
224
+ if (group === undefined) {
225
+ group = [];
226
+ byHash.set(sig.getHashCode(), group);
227
+ }
228
+ group.push({ id, sig });
229
+ const model = reg.namespaceSigCanonicalizer.getModel(id);
230
+ if (model === undefined) {
231
+ // N3
232
+ violations.push(`[namespace] N3: ID ${id} (${sig.toString()}) has no model`);
233
+ return;
234
+ }
235
+ // N4
236
+ const back = model.getNamespaceSigID();
237
+ if (back !== id) {
238
+ violations.push(`[namespace] N4: model at ID ${id} (${sig.toString()}) back-points to ${back}`);
239
+ }
240
+ // N6
241
+ if (seenModels.has(model)) {
242
+ violations.push(`[namespace] N6: model at ID ${id} (${sig.toString()}) is mounted at more than one ID`);
243
+ }
244
+ else {
245
+ seenModels.add(model);
246
+ }
247
+ this.checkNamespaceChain(violations, reg, id, sig);
248
+ }
249
+ /** N7a/N7b/N7c:挂载链完整性(仅存活条目;嵌套 ns 查父链,顶层 ns 查 declaring file 链)。 */
250
+ static checkNamespaceChain(violations, reg, id, sig) {
251
+ const parentSigID = sig.getDeclaringNamespaceSigID();
252
+ if (parentSigID !== undefined) {
253
+ const parentModel = reg.namespaceSigCanonicalizer.getModel(parentSigID);
254
+ if (parentModel === undefined) {
255
+ // N7a
256
+ violations.push(`[namespace] N7a: ID ${id} (${sig.toString()}) has parent SigID ${parentSigID} with no model`);
257
+ }
258
+ else if (!parentModel.hasTopNamespaceWithID(id)) {
259
+ // N7b
260
+ violations.push(`[namespace] N7b: ID ${id} (${sig.toString()}) is not in parent ${parentSigID}'s top-namespace list`);
261
+ }
262
+ }
263
+ else {
264
+ const fileModel = reg.fileSigCanonicalizer.getModel(sig.getDeclaringFileSigID());
265
+ if (fileModel === undefined) {
266
+ // N7c
267
+ violations.push(`[namespace] N7c: top-level ID ${id} (${sig.toString()}) has declaring file SigID ${sig.getDeclaringFileSigID()} with no model`);
268
+ }
269
+ else if (!fileModel.hasTopNamespaceWithID(id)) {
270
+ // N7c
271
+ violations.push(`[namespace] N7c: top-level ID ${id} (${sig.toString()}) is not in its declaring file's top-namespace list`);
272
+ }
273
+ }
274
+ }
275
+ /**
276
+ * 校验 formal class 空间的结构不变量,规则如下:
277
+ *
278
+ * C1a DEFAULT 保留位契约(正向断言):ID 0 必须存在 DEFAULT 签名条目。
279
+ *
280
+ * C1b DEFAULT 保留位契约(正向断言):ID 0 的 model 必须为 undefined。
281
+ *
282
+ * C2 ID 稠密性:[1, size) 内每个 ID 都必须有签名条目(防御性检查)。
283
+ *
284
+ * C3 model 完备性:[1, size) 内每个 ID 必须有对应的 ArkClass model。
285
+ * 两种可能来路:① disposeModule 驱逐态(removeClassModel 删 model 留 sig,合法、可 reload 自愈);② 显式 getId intern 无 model——生产路径不产生
286
+ * 此形态(formal 只读命中 / temp 弱注册兜底,写入点收敛为 internDefaults + ArkClass.setSignature),出现即为 tests 手工构造或未来新代码逃逸
287
+ * (ArkClass.setSignature 的 existing≥0 分支不注册语义由本规则持续守护)。全部报告,开发者判别。
288
+ *
289
+ * C4 model 回指一致性:挂载在 ID i 的 ArkClass,其 getClassSigID() 必须
290
+ * 等于 i。
291
+ *
292
+ * C5 签名值唯一性:任意两个不同 ID 不得持有 equals() 相等的签名(守卫
293
+ * hash/equals 契约与 DEFAULT 值域坍缩;原理同 file R5)。
294
+ * 注:display 归一化后 AliasClassSignature 的 aliasName **参与** equals/hash——alias 是独立 formal 条目(同 aliasName+同 origin 维度折叠、异名/
295
+ * 与 origin 互不相等),本规则即守护该独立 ID 语义(两个 alias ID 值相等 = 契约破坏)。
296
+ *
297
+ * C6 model 挂载唯一性:同一 ArkClass 实例不得挂载于多个 ID。
298
+ *
299
+ * C7 挂载链完整性(仅对 model 存活条目检查;驱逐态条目链检查跳过——C3 已
300
+ * 报告其驱逐,链完整性以存活侧为准;单 Scene 单次构建生命周期声明覆盖):
301
+ * C7a 嵌套类:declaringNamespaceSigID 非 undefined 时,父 namespace
302
+ * 的 model 必须存在(父驱逐子存活 = 驱逐不完整或手工构造逃逸);
303
+ * C7b 嵌套类:父 ns 的 topClass 列表必须含本 ID(hasTopClassWithID);
304
+ * C7c 顶层类:declaring file 的 model 必须存在且其 topClass 列表
305
+ * 含本 ID。
306
+ *
307
+ * 执行语义:所有规则全量执行、任何违规不中断;违规逐条收集(规则号 + ID +
308
+ * 签名描述),一次性汇总报告。全部规则均为 error 级。
309
+ *
310
+ * @returns 全部违规描述(空数组 = 空间干净)。
311
+ */
312
+ static validateClassSpace() {
313
+ const violations = [];
314
+ const reg = SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
315
+ const canonicalizer = reg.classSigCanonicalizer;
316
+ // C5 辅助结构:按缓存的 hashCode 分组签名。
317
+ const byHash = new Map();
318
+ // C6 辅助结构:已见过的 model 实例,用于检测双挂载。
319
+ const seenModels = new Set();
320
+ this.checkDefaultSlot(violations, 'class', 'C1a', 'C1b', canonicalizer, byHash);
321
+ const size = canonicalizer.size();
322
+ for (let id = 1; id < size; id++) {
323
+ this.checkClassEntry(violations, reg, id, canonicalizer.get(id), size, byHash, seenModels);
324
+ }
325
+ this.checkSignatureValueUniqueness(violations, byHash, 'class', 'C5');
326
+ return violations;
327
+ }
328
+ /** C2–C7:单 ID 条目级校验(C5 仅累积分组,组内比较在 {@link checkSignatureValueUniqueness};alias 条目豁免 C4/C6/链检查)。 */
329
+ static checkClassEntry(violations, reg, id, sig, size, byHash, seenModels) {
330
+ if (sig === undefined) {
331
+ // C2
332
+ violations.push(`[class] C2: ID ${id} is inside [0, size=${size}) but has no signature entry`);
333
+ return;
334
+ }
335
+ // C5(累积)
336
+ let group = byHash.get(sig.getHashCode());
337
+ if (group === undefined) {
338
+ group = [];
339
+ byHash.set(sig.getHashCode(), group);
340
+ }
341
+ group.push({ id, sig });
342
+ const model = reg.classSigCanonicalizer.getModel(id);
343
+ if (model === undefined) {
344
+ // C3
345
+ violations.push(`[class] C3: ID ${id} (${sig.toString()}) has no model`);
346
+ return;
347
+ }
348
+ const isAliasEntry = sig instanceof ArkSignature_1.AliasClassSignature;
349
+ // C4
350
+ const back = model.getClassSigID();
351
+ if (!isAliasEntry && back !== id) {
352
+ violations.push(`[class] C4: model at ID ${id} (${sig.toString()}) back-points to ${back}`);
353
+ }
354
+ // C6
355
+ if (!isAliasEntry) {
356
+ if (seenModels.has(model)) {
357
+ violations.push(`[class] C6: model at ID ${id} (${sig.toString()}) is mounted at more than one ID`);
358
+ }
359
+ else {
360
+ seenModels.add(model);
361
+ }
362
+ }
363
+ this.checkClassChain(violations, reg, id, sig, isAliasEntry);
364
+ }
365
+ /** C7a/C7b/C7c:挂载链完整性(仅存活条目;alias 条目豁免——挂载链以 origin 条目为准)。 */
366
+ static checkClassChain(violations, reg, id, sig, isAliasEntry) {
367
+ const parentSigID = sig.getDeclaringNamespaceSigID();
368
+ if (!isAliasEntry && parentSigID !== undefined) {
369
+ const parentModel = reg.namespaceSigCanonicalizer.getModel(parentSigID);
370
+ if (parentModel === undefined) {
371
+ // C7a
372
+ violations.push(`[class] C7a: ID ${id} (${sig.toString()}) has declaring namespace SigID ${parentSigID} with no model`);
373
+ }
374
+ else if (!parentModel.hasTopClassWithID(id)) {
375
+ // C7b
376
+ violations.push(`[class] C7b: ID ${id} (${sig.toString()}) is not in parent namespace ${parentSigID}'s top-class list`);
377
+ }
378
+ }
379
+ else if (!isAliasEntry) {
380
+ const fileModel = reg.fileSigCanonicalizer.getModel(sig.getDeclaringFileSigID());
381
+ if (fileModel === undefined) {
382
+ // C7c
383
+ violations.push(`[class] C7c: top-level ID ${id} (${sig.toString()}) has declaring file SigID ${sig.getDeclaringFileSigID()} with no model`);
384
+ }
385
+ else if (!fileModel.hasTopClassWithID(id)) {
386
+ // C7c
387
+ violations.push(`[class] C7c: top-level ID ${id} (${sig.toString()}) is not in its declaring file's top-class list`);
388
+ }
389
+ }
390
+ }
391
+ /**
392
+ * 校验 formal field 空间的结构不变量,规则如下:
393
+ *
394
+ * F1a DEFAULT 保留位契约(正向断言):ID 0 必须存在 DEFAULT 签名条目。
395
+ *
396
+ * F1b DEFAULT 保留位契约(正向断言):ID 0 的 model 必须为 undefined。
397
+ *
398
+ * F2 ID 稠密性:[1, size) 内每个 ID 都必须有签名条目(防御性检查)。
399
+ *
400
+ * F3 model 完备性:[1, size) 内每个 ID 必须有对应的 ArkField model。
401
+ * 两种可能来路:① 驱逐态(disposeModule / pruneNonKeptClasses 的
402
+ * removeField 删 model 留 sig,合法、reload 由 addField 兜底自愈——
403
+ * 窗口期报告属预期);② 引用侧 namespace 声明签名(genFieldSignature
404
+ * 等构造的 ns 重载,无 ArkField model,值语义合法形态)及未来新代码
405
+ * 逃逸。全部报告,由开发者结合场景判断。
406
+ *
407
+ * F4 model 回指一致性:挂载在 ID i 的 ArkField,其 getFieldSigID() 必须
408
+ * 等于 i(field 单轨——无 method 空间的 impl/declare 双槽复杂度)。
409
+ *
410
+ * F4b 双侧声明类一致性:model.getDeclaringClassID() 必须等于
411
+ * sig.getDeclaringClassSigID()(ArkField 与 FieldSignature 独立维护
412
+ * 两处 declaring ClassSigID,能抓 builder 不一致 bug)。
413
+ * 注意 breakInternalReferences 将 declaringClassID 置 -1 的窗口形态
414
+ * (unload 后半,model 残留期)——该形态同时被 F3(若 model 已删)
415
+ * 或本规则(model 仍在但 ID=-1)捕获,属驱逐窗口预期报告。
416
+ *
417
+ * F5 签名值唯一性:任意两个不同 ID 不得持有 equals() 相等的签名
418
+ * (hash 分组 + 组内两两比较;ID 0 种入守卫 DEFAULT 值域坍缩)。
419
+ * 注记:type 不参与身份(equals/hashCode 只含 fieldName + staticFlag +
420
+ * 四个 declaring SigID);setType/setStaticFlag 可在 intern 后原地改值
421
+ * 且不重算 hash(hash-equal 是 equals-equal 的合法超集,算法不受影响)。
422
+ *
423
+ * F6 model 挂载唯一性:同一 ArkField 实例不得挂载于多个 ID(按 model 槽
424
+ * 唯一口径——AbcInference 同名重复推断产生的非 model 别名实例是值语义
425
+ * 合法形态,不属违规)。
426
+ *
427
+ * F7 挂载链完整性(仅对 model 存活条目检查):
428
+ * F7a declaring class 的 model 必须存在(class 驱逐后 field 存活 =
429
+ * 驱逐不完整——P0 修复后此形态应仅出现在合法驱逐窗口之外);
430
+ * F7b 该 class 的字段索引必须含本 ID:hasTopFieldWithID(i) ||
431
+ * hasTopStaticFieldWithID(i)——联合判定(不区分数组):index
432
+ * signature 存在签名 staticFlag=true 但按 modifier tag 挂实例
433
+ * 数组的既有不一致形态,联合判定免误报。
434
+ * 注记:model 侧不存在 namespace 声明的 ArkField(ns 声明签名仅在引用侧,无 F7 的 ns 分支);查询走 sig.getDeclaringClassSigID() formal 直查
435
+ * (不经 declaringSignatureDisplay——display 归一化后 declaringClass 为 AliasClassSignature 时 SigID 是独立的 alias ID,formal 直查命中 alias 条目,
436
+ * display 仅影响展示)。
437
+ *
438
+ * 执行语义:所有规则全量执行、任何违规不中断;违规逐条收集(规则号 + ID +
439
+ * 签名描述),一次性汇总报告。全部规则均为 error 级。
440
+ *
441
+ * @returns 全部违规描述(空数组 = 空间干净)。
442
+ */
443
+ static validateFieldSpace() {
444
+ const violations = [];
445
+ const reg = SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
446
+ const canonicalizer = reg.fieldSigCanonicalizer;
447
+ // F5 辅助结构:按缓存的 hashCode 分组签名。
448
+ const byHash = new Map();
449
+ // F6 辅助结构:已见过的 model 实例,用于检测双挂载。
450
+ const seenModels = new Set();
451
+ this.checkDefaultSlot(violations, 'field', 'F1a', 'F1b', canonicalizer, byHash);
452
+ const size = canonicalizer.size();
453
+ for (let id = 1; id < size; id++) {
454
+ this.checkFieldEntry(violations, reg, id, canonicalizer.get(id), size, byHash, seenModels);
455
+ }
456
+ this.checkSignatureValueUniqueness(violations, byHash, 'field', 'F5');
457
+ return violations;
458
+ }
459
+ /** F2–F7:单 ID 条目级校验(F5 仅累积分组,组内比较在 {@link checkSignatureValueUniqueness})。 */
460
+ static checkFieldEntry(violations, reg, id, sig, size, byHash, seenModels) {
461
+ if (sig === undefined) {
462
+ // F2
463
+ violations.push(`[field] F2: ID ${id} is inside [0, size=${size}) but has no signature entry`);
464
+ return;
465
+ }
466
+ // F5(累积)
467
+ let group = byHash.get(sig.getHashCode());
468
+ if (group === undefined) {
469
+ group = [];
470
+ byHash.set(sig.getHashCode(), group);
471
+ }
472
+ group.push({ id, sig });
473
+ const model = reg.fieldSigCanonicalizer.getModel(id);
474
+ if (model === undefined) {
475
+ // F3
476
+ violations.push(`[field] F3: ID ${id} (${sig.toString()}) has no model`);
477
+ return;
478
+ }
479
+ // F4
480
+ const back = model.getFieldSigID();
481
+ if (back !== id) {
482
+ violations.push(`[field] F4: model at ID ${id} (${sig.toString()}) back-points to ${back}`);
483
+ }
484
+ // F4b
485
+ const modelDeclClassID = model.getDeclaringClassID();
486
+ const sigDeclClassID = sig.getDeclaringClassSigID();
487
+ if (modelDeclClassID !== sigDeclClassID) {
488
+ violations.push(`[field] F4b: model at ID ${id} (${sig.toString()}) has declaringClassID ${modelDeclClassID} ` + `but the signature declares ${sigDeclClassID}`);
489
+ }
490
+ // F6
491
+ if (seenModels.has(model)) {
492
+ violations.push(`[field] F6: model at ID ${id} (${sig.toString()}) is mounted at more than one ID`);
493
+ }
494
+ else {
495
+ seenModels.add(model);
496
+ }
497
+ this.checkFieldChain(violations, reg, id, sig, sigDeclClassID);
498
+ }
499
+ /** F7a/F7b:挂载链完整性(仅存活条目——declaring class model 存在 + 类字段索引联合判定)。 */
500
+ static checkFieldChain(violations, reg, id, sig, sigDeclClassID) {
501
+ const classModel = reg.classSigCanonicalizer.getModel(sigDeclClassID !== null && sigDeclClassID !== void 0 ? sigDeclClassID : -1);
502
+ if (classModel === undefined) {
503
+ // F7a(含 sigDeclClassID 为 undefined/-1 的非法 model 侧形态:
504
+ // model 侧 field 一律 class 声明,ns/unclear 声明不该出现。)
505
+ violations.push(`[field] F7a: ID ${id} (${sig.toString()}) has declaring class SigID ${sigDeclClassID} with no model`);
506
+ }
507
+ else if (!classModel.hasTopFieldWithID(id) && !classModel.hasTopStaticFieldWithID(id)) {
508
+ // F7b(联合判定,见函数头注记)
509
+ violations.push(`[field] F7b: ID ${id} (${sig.toString()}) is in neither of declaring class ${sigDeclClassID}'s field indexes`);
510
+ }
511
+ }
512
+ /**
513
+ * 校验 formal method 空间的结构不变量,规则如下:
514
+ *
515
+ * 前置设计契约(闭包双签名,BodyBuilder.updateNestedMethodWithClosures 的
516
+ * 终态为设计行为):重签后 model[id1]=M(旧签名,类索引锚定——枚举入口)
517
+ * 与 model[id2]=M(新签名含闭包参数——invoke expr 消费面)双注册合法,
518
+ * topMethodSigIDs 持 id1 不变、id2 不入索引(保证 getMethods 枚举唯一,
519
+ * 实测 ENUM-DUP=0)。
520
+ *
521
+ * M1a DEFAULT 保留位契约(正向断言):ID 0 必须存在 DEFAULT 签名条目。
522
+ *
523
+ * M1b DEFAULT 保留位契约(正向断言):ID 0 的 model 必须为 undefined。
524
+ *
525
+ * M2 ID 稠密性:[1, size) 内每个 ID 都必须有签名条目(防御性检查)。
526
+ *
527
+ * M3 model 完备性:无 model 的条目按 declaring class 存活判定分类——declaring class 的 model 存活 → 视为 declare-only 合法态跳过(实证:SDK 接口
528
+ * overload 声明条目(如 ObjectConstructor.create/freeze 的非首声明)与闭包 declare 重签产物均为此形态,单资源达千条量级,属构建常态而非洞);
529
+ * declaring class 不明(-1/0)或 class model 已删(驱逐窗口外)→ 报告。驱逐窗口内的条目随 reload 由 addMethod 兜底自愈。
530
+ *
531
+ * M4 挂载槽一致性(方法级三方持有,闭包双签名适配):model[i] 存在时,
532
+ * i === M.getMethodSigID() ∨ M.declareSigIDs ∋ i ∨ 某存活类方法索引
533
+ * ∋ i。闭包 id1 经索引持有 ✓、id2 经 self-id ✓;违规 = 孤儿挂载
534
+ * (无任何持有方的 model 残留,如驱逐窗口 legacy 槽)。
535
+ *
536
+ * M4b 双侧声明类一致:model.getDeclaringClassID() === sig 的
537
+ * declaringClassSigID(独立双维护点,抓 builder 不同步)。copyMembers
538
+ * 跨类挂载双侧同指 from 类 → 不误报 ✓。
539
+ *
540
+ * M5 签名值唯一(hash 分组 + 组内两两 equals,ID 0 种入守卫值域坍缩)。
541
+ * 注记:declaringClassTempSigID 参与 equals——temp 版与 formal 版是
542
+ * 合法分裂条目非重复;returnType 进 equals 不进 hash(仅返回类型不同
543
+ * 的重载合法分 ID)。
544
+ *
545
+ * M6 反向链检查(非实例唯一——闭包双挂载已合法化):存活类方法索引
546
+ * (含 default/init 三个旁路 ID 字段)的每个条目 ID 必须有 model
547
+ * (抓索引断链:驱逐 desync、索引损坏)。
548
+ *
549
+ * M7 declaring class model 存在(sig 侧 -1 temp / 0 跳过并注记;
550
+ * class 驱逐后 method 存活 = 驱逐不完整形态)。
551
+ *
552
+ * 执行语义:所有规则全量执行、任何违规不中断;违规逐条收集(规则号 + ID +
553
+ * 签名描述),一次性汇总报告。全部规则均为 error 级。
554
+ *
555
+ * @returns 全部违规描述(空数组 = 空间干净)。
556
+ */
557
+ static validateMethodSpace() {
558
+ const violations = [];
559
+ const reg = SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
560
+ const canonicalizer = reg.methodSigCanonicalizer;
561
+ // M5 辅助结构:按缓存的 hashCode 分组签名。
562
+ const byHash = new Map();
563
+ this.checkDefaultSlot(violations, 'method', 'M1a', 'M1b', canonicalizer, byHash);
564
+ const { indexHeld, indexEntries } = this.collectMethodIndexHolders(reg);
565
+ const size = canonicalizer.size();
566
+ for (let id = 1; id < size; id++) {
567
+ this.checkMethodEntry(violations, reg, id, canonicalizer.get(id), size, byHash, indexHeld);
568
+ }
569
+ this.checkMethodIndexBackLinks(violations, canonicalizer, indexEntries);
570
+ this.checkSignatureValueUniqueness(violations, byHash, 'method', 'M5');
571
+ return violations;
572
+ }
573
+ /** M4/M6 辅助结构(单遍构建):索引持有集(存活类方法索引 + default/init 旁路 ID)与索引条目清单。 */
574
+ static collectMethodIndexHolders(reg) {
575
+ var _a, _b, _c, _d;
576
+ const indexHeld = new Set();
577
+ const indexEntries = [];
578
+ for (let clsID = 1; clsID < reg.classSigCanonicalizer.size(); clsID++) {
579
+ const cls = reg.classSigCanonicalizer.getModel(clsID);
580
+ if (cls === undefined) {
581
+ continue;
582
+ }
583
+ for (const ids of (_b = (_a = cls.getMethodNameIndex()) === null || _a === void 0 ? void 0 : _a.values()) !== null && _b !== void 0 ? _b : []) {
584
+ for (const id of ids) {
585
+ indexHeld.add(id);
586
+ indexEntries.push({ clsID, id });
587
+ }
588
+ }
589
+ for (const ids of (_d = (_c = cls.getStaticMethodNameIndex()) === null || _c === void 0 ? void 0 : _c.values()) !== null && _d !== void 0 ? _d : []) {
590
+ for (const id of ids) {
591
+ indexHeld.add(id);
592
+ indexEntries.push({ clsID, id });
593
+ }
594
+ }
595
+ }
596
+ return { indexHeld, indexEntries };
597
+ }
598
+ /** M2–M7:单 ID 条目级校验(M5 仅累积分组,组内比较在 {@link checkSignatureValueUniqueness})。 */
599
+ static checkMethodEntry(violations, reg, id, sig, size, byHash, indexHeld) {
600
+ var _a;
601
+ if (sig === undefined) {
602
+ // M2
603
+ violations.push(`[method] M2: ID ${id} is inside [0, size=${size}) but has no signature entry`);
604
+ return;
605
+ }
606
+ // M5(累积)
607
+ let group = byHash.get(sig.getHashCode());
608
+ if (group === undefined) {
609
+ group = [];
610
+ byHash.set(sig.getHashCode(), group);
611
+ }
612
+ group.push({ id, sig });
613
+ const model = reg.methodSigCanonicalizer.getModel(id);
614
+ if (model === undefined) {
615
+ // M3:declaring class 存活 → declare-only 合法跳过。
616
+ const declClassID = sig.getDeclaringClassSigID();
617
+ if (declClassID === undefined || declClassID <= 0 || reg.classSigCanonicalizer.getModel(declClassID) === undefined) {
618
+ violations.push(`[method] M3: ID ${id} (${sig.toString()}) has no model and its declaring class is not alive`);
619
+ }
620
+ return;
621
+ }
622
+ // M4(三方持有)
623
+ const selfID = model.getMethodSigID();
624
+ const declareHeld = ((_a = model.getDeclareSigIDs()) !== null && _a !== void 0 ? _a : []).includes(id);
625
+ const sigDeclClassForAlias = sig.getDeclaringClassSigID();
626
+ const isAliasEntry = sigDeclClassForAlias > 0 && reg.classSigCanonicalizer.get(sigDeclClassForAlias) instanceof ArkSignature_1.AliasClassSignature;
627
+ if (!isAliasEntry && id !== selfID && !declareHeld && !indexHeld.has(id)) {
628
+ violations.push(`[method] M4: model at ID ${id} (${sig.toString()}) is held by no one (not self/declare/index)`);
629
+ }
630
+ // M4b(alias 条目跳过:sig 的 declaringClassSigID 是 alias ID,与 origin
631
+ // model 的 declaringClassID 必然不同——双注册的设计内形态)
632
+ const modelDeclClassID = model.getDeclaringClassID();
633
+ const sigDeclClassID = sig.getDeclaringClassSigID();
634
+ if (!isAliasEntry && modelDeclClassID !== sigDeclClassID) {
635
+ violations.push(`[method] M4b: model at ID ${id} (${sig.toString()}) has declaringClassID ${modelDeclClassID} ` + `but the signature declares ${sigDeclClassID}`);
636
+ }
637
+ // M7(declaring class model 存在;-1 temp / 0 跳过)
638
+ if (sigDeclClassID !== undefined && sigDeclClassID > 0 && reg.classSigCanonicalizer.getModel(sigDeclClassID) === undefined) {
639
+ violations.push(`[method] M7: ID ${id} (${sig.toString()}) has declaring class SigID ${sigDeclClassID} with no model`);
640
+ }
641
+ }
642
+ /** M6(反向链):存活类方法索引的每个条目 ID 必须有 model。 */
643
+ static checkMethodIndexBackLinks(violations, canonicalizer, indexEntries) {
644
+ for (const { clsID, id } of indexEntries) {
645
+ if (canonicalizer.getModel(id) === undefined) {
646
+ violations.push(`[method] M6: class ${clsID}'s method index holds ID ${id} with no model`);
647
+ }
648
+ }
649
+ }
650
+ // ---------------------------------------------------------------------
651
+ // Temp weak-registry spaces validation
652
+ // ---------------------------------------------------------------------
653
+ /**
654
+ * 校验三个 temp 弱注册空间(class/method/field)的结构不变量,规则如下:
655
+ *
656
+ * T1 非陈旧性:非空 slot 的值不得已存在于 formal 空间。temp 注册的前提是
657
+ * formal miss;若后来同值签名进入 formal(真实模型注册),该 slot 即
658
+ * 过期——消费方已可从 formal 解析,成为"可迁移未迁移"的陈旧残留
659
+ * (持有者下次重路由 formal 命中时经 retireWithReplacement 置空)。
660
+ * (注意:不做"全部 unclear"强断言——ClassType/FunctionType/Ref 等注册源
661
+ * 的条件是 formal miss,clear-but-unregistered 条目为设计内合法形态。)
662
+ *
663
+ * T2 register 幂等守护:槽位 ID ↔ 实例自带 symbol ID 双向一致。register 按
664
+ * 对象恒等幂等分配 ID(同实例复用、新实例新 ID),同一实例出现在两个
665
+ * 槽位(或实例自带 ID 与槽位不符)意味着 symbol 标记被破坏。
666
+ *
667
+ * T3 持有者 ID 有效性:持有结构上声明的 temp SigID
668
+ * 必须指向非空 slot(未迁移)或有替换记录的已置空 slot(已迁移,惰性
669
+ * 物化痕迹态 formalID≥0 && tempSigID≠undefined 亦经此规则覆盖)。
670
+ * 两者皆无 = stale(Registry clear/dispose 后的残留)或从未注册的 ID
671
+ * (构造 bug)。持有结构(判据一律用注册标记字段 getTempSigID /
672
+ * getDeclaringClassTempSigID):
673
+ * - tempClass:ClassType(getTempSigID)、FieldSignature/MethodSignature
674
+ * 的 declaringClassTempSigID
675
+ * - tempMethod:FunctionType/LexicalEnvType/AbstractInvokeExpr(getTempSigID)
676
+ * - tempField:EnumValueType、AbstractFieldRef 即 ArkInstanceFieldRef/
677
+ * ArkStaticFieldRef(getTempSigID)
678
+ *
679
+ * T4 持有可达性——不设此规则:索引表 slot 强持有下,"存活但无持有者"的 GC 驱动判定失去意义(slot 本身就是持有者,全保留是设计决策——推导中间垃圾
680
+ * 钉活到 dispose 属知情权衡)。若引入 prune,再按需新建对应审计规则。
681
+ *
682
+ * 执行语义:所有规则全量执行、任何违规不中断;全部为 error 级。
683
+ *
684
+ * @returns 全部违规描述(空数组 = 三个空间干净)。
685
+ */
686
+ static validateTempSpaces() {
687
+ return this.runTempSpaceValidation();
688
+ }
689
+ static runTempSpaceValidation() {
690
+ const reg = SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
691
+ const violations = [];
692
+ violations.push(...this.validateTempSpaceEntries('class', reg.tempClassSigCanonicalizer, reg.classSigCanonicalizer));
693
+ violations.push(...this.validateTempSpaceEntries('method', reg.tempMethodSigCanonicalizer, reg.methodSigCanonicalizer));
694
+ violations.push(...this.validateTempSpaceEntries('field', reg.tempFieldSigCanonicalizer, reg.fieldSigCanonicalizer));
695
+ this.checkTempHolderIDs(violations);
696
+ return violations;
697
+ }
698
+ /** T1 + T2:单空间的条目级校验。 */
699
+ static validateTempSpaceEntries(space, temp, formal) {
700
+ const violations = [];
701
+ for (const id of temp.registeredIds()) {
702
+ const sig = temp.get(id);
703
+ if (sig === undefined) {
704
+ continue;
705
+ }
706
+ // T1: the value must not have landed in formal after the temp registration.
707
+ const formalId = formal.getExistingId(sig);
708
+ if (formalId !== -1) {
709
+ violations.push(`[temp-${space}] T1: live entry ${id} (${sig.toString()}) also exists in formal (ID ${formalId}) — stale temp registration`);
710
+ }
711
+ // T2: register idempotency — the instance's self-carried temp ID must equal its slot.
712
+ const selfId = temp.getExistingTempId(sig);
713
+ if (selfId !== id) {
714
+ violations.push(`[temp-${space}] T2: slot ${id} (${sig.toString()}) holds an instance whose self-carried temp ID is ${selfId === -1 ? 'unregistered' : selfId} — register idempotency broken`);
715
+ }
716
+ }
717
+ return violations;
718
+ }
719
+ static checkTempHolderIDs(violations) {
720
+ var _a;
721
+ const reg = SignatureCanonicalizerRegistry_1.SignatureCanonicalizerRegistry.getInstance();
722
+ const visitedTypes = new Set();
723
+ for (const cls of reg.classSigCanonicalizer.getModels()) {
724
+ if (cls === undefined) {
725
+ continue;
726
+ }
727
+ const classDesc = `class ${cls.getName()}`;
728
+ for (const rt of (_a = cls.getRealTypes()) !== null && _a !== void 0 ? _a : []) {
729
+ this.visitTypeHolders(rt, classDesc, violations, visitedTypes, reg);
730
+ }
731
+ for (const method of cls.getMethods()) {
732
+ this.checkMethodHolderEntries(method, classDesc, violations, visitedTypes, reg);
733
+ }
734
+ for (const field of cls.getFields()) {
735
+ const fieldSig = field.getSignature();
736
+ const fieldDesc = `${classDesc} field ${field.getName()}`;
737
+ this.checkTempHolderID(violations, reg, 'class', fieldSig.getDeclaringClassTempSigID(), `${fieldDesc} (FieldSignature declaring)`);
738
+ this.visitTypeHolders(fieldSig.getType(), fieldDesc, violations, visitedTypes, reg);
739
+ }
740
+ }
741
+ }
742
+ /** T3(方法粒度):方法签名 declaring/返回类型/参数类型 + 方法体(locals/usedGlobals/语句 def&uses)。 */
743
+ static checkMethodHolderEntries(method, classDesc, violations, visitedTypes, reg) {
744
+ const methodSig = method.getSignature();
745
+ const methodDesc = `${classDesc} method ${method.getName()}`;
746
+ this.checkTempHolderID(violations, reg, 'class', methodSig.getDeclaringClassTempSigID(), `${methodDesc} (MethodSignature declaring)`);
747
+ this.visitTypeHolders(methodSig.getMethodSubSignature().getReturnType(), methodDesc, violations, visitedTypes, reg);
748
+ for (const param of methodSig.getMethodSubSignature().getParameters()) {
749
+ this.visitTypeHolders(param.getType(), methodDesc, violations, visitedTypes, reg);
750
+ }
751
+ const body = method.getBody();
752
+ if (body === undefined) {
753
+ return;
754
+ }
755
+ for (const local of body.getLocals().values()) {
756
+ this.visitTypeHolders(local.getType(), methodDesc, violations, visitedTypes, reg);
757
+ }
758
+ const usedGlobals = body.getUsedGlobals();
759
+ if (usedGlobals !== undefined) {
760
+ for (const gv of usedGlobals.values()) {
761
+ this.visitValueHolders(gv, methodDesc, violations, visitedTypes, reg);
762
+ }
763
+ }
764
+ for (const stmt of body.getCfg().getStmts()) {
765
+ for (const v of stmt.getDefAndUses()) {
766
+ this.visitValueHolders(v, methodDesc, violations, visitedTypes, reg);
767
+ }
768
+ }
769
+ }
770
+ /** T3 判定:声明的 temp SigID 必须指向非空 slot(未迁移)或有替换记录的已置空 slot(已迁移)。 */
771
+ static checkTempHolderID(violations, reg, space, tempSigID, holderDesc) {
772
+ if (tempSigID === undefined) {
773
+ return;
774
+ }
775
+ const temp = space === 'class' ? reg.tempClassSigCanonicalizer : space === 'method' ? reg.tempMethodSigCanonicalizer : reg.tempFieldSigCanonicalizer;
776
+ const slotLive = temp.get(tempSigID) !== undefined;
777
+ const hasReplacement = temp.getReplacement(tempSigID) !== -1;
778
+ if (!slotLive && !hasReplacement) {
779
+ violations.push(`[temp-${space}] T3: ${holderDesc} declares temp SigID ${tempSigID} that is neither a live slot nor has a replacement record — stale or unregistered ID`);
780
+ }
781
+ }
782
+ /** T3 类型遍历:按类型形态分发持有检查(容器递归共享 visited 防环)。 */
783
+ static visitTypeHolders(type, holderDesc, violations, visitedTypes, reg) {
784
+ var _a, _b;
785
+ if (type === undefined || type === null || visitedTypes.has(type)) {
786
+ return;
787
+ }
788
+ visitedTypes.add(type);
789
+ if (type instanceof Type_1.ClassType) {
790
+ this.checkTempHolderID(violations, reg, 'class', type.getTempSigID(), `${holderDesc} (ClassType)`);
791
+ for (const gt of (_a = type.getRealGenericTypes()) !== null && _a !== void 0 ? _a : []) {
792
+ this.visitTypeHolders(gt, holderDesc, violations, visitedTypes, reg);
793
+ }
794
+ }
795
+ else if (type instanceof Type_1.FunctionType) {
796
+ this.checkTempHolderID(violations, reg, 'method', type.getTempSigID(), `${holderDesc} (FunctionType)`);
797
+ for (const gt of (_b = type.getRealGenericTypes()) !== null && _b !== void 0 ? _b : []) {
798
+ this.visitTypeHolders(gt, holderDesc, violations, visitedTypes, reg);
799
+ }
800
+ }
801
+ else if (type instanceof Type_1.LexicalEnvType) {
802
+ this.checkTempHolderID(violations, reg, 'method', type.getTempSigID(), `${holderDesc} (LexicalEnvType)`);
803
+ for (const closure of type.getClosures()) {
804
+ this.visitTypeHolders(closure.getType(), holderDesc, violations, visitedTypes, reg);
805
+ }
806
+ }
807
+ else if (type instanceof Type_1.EnumValueType) {
808
+ this.checkTempHolderID(violations, reg, 'field', type.getTempSigID(), `${holderDesc} (EnumValueType)`);
809
+ }
810
+ else if (type instanceof Type_1.UnionType || type instanceof Type_1.IntersectionType || type instanceof Type_1.TupleType) {
811
+ for (const t of type.getTypes()) {
812
+ this.visitTypeHolders(t, holderDesc, violations, visitedTypes, reg);
813
+ }
814
+ }
815
+ else if (type instanceof Type_1.ArrayType) {
816
+ this.visitTypeHolders(type.getBaseType(), holderDesc, violations, visitedTypes, reg);
817
+ }
818
+ else if (type instanceof Type_1.AliasType) {
819
+ this.visitTypeHolders(type.getOriginalType(), holderDesc, violations, visitedTypes, reg);
820
+ }
821
+ }
822
+ /** T3 值遍历:invoke expr / field ref / GlobalRef 的 temp 声明与嵌套遍历。 */
823
+ static visitValueHolders(value, holderDesc, violations, visitedTypes, reg) {
824
+ if (value instanceof Expr_1.AbstractInvokeExpr) {
825
+ this.checkTempHolderID(violations, reg, 'method', value.getTempSigID(), `${holderDesc} (invoke expr)`);
826
+ for (const arg of value.getArgs()) {
827
+ this.visitValueHolders(arg, holderDesc, violations, visitedTypes, reg);
828
+ }
829
+ this.visitTypeHolders(value.getType(), holderDesc, violations, visitedTypes, reg);
830
+ }
831
+ else if (value instanceof Ref_1.AbstractFieldRef) {
832
+ this.checkTempHolderID(violations, reg, 'field', value.getTempSigID(), `${holderDesc} (field ref)`);
833
+ this.visitTypeHolders(value.getType(), holderDesc, violations, visitedTypes, reg);
834
+ }
835
+ else if (value instanceof Ref_1.GlobalRef) {
836
+ this.visitValueHolders(value.getRef(), holderDesc, violations, visitedTypes, reg);
837
+ }
838
+ }
839
+ // ---------------------------------------------------------------------
840
+ // Shared formal-space rule helpers
841
+ // ---------------------------------------------------------------------
842
+ /** X1a/X1b:DEFAULT reserved-slot contract (entry exists + model empty), seeding ID 0 into the value-uniqueness groups. */
843
+ static checkDefaultSlot(violations, space, rule1a, rule1b, canonicalizer, byHash) {
844
+ const defaultSig = canonicalizer.get(0);
845
+ if (defaultSig === undefined) {
846
+ violations.push(`[${space}] ${rule1a}: ID 0 has no signature entry — the DEFAULT reserved slot is missing`);
847
+ return;
848
+ }
849
+ if (canonicalizer.getModel(0) !== undefined) {
850
+ violations.push(`[${space}] ${rule1b}: ID 0 (DEFAULT slot) unexpectedly holds a model`);
851
+ }
852
+ byHash.set(defaultSig.getHashCode(), [{ id: 0, sig: defaultSig }]);
853
+ }
854
+ /** X5(检查):组内两两 equals——hash/equals 契约与 DEFAULT 值域坍缩守卫。分组大小几乎恒为 1,均摊 O(n)。 */
855
+ static checkSignatureValueUniqueness(violations, byHash, space, rule) {
856
+ for (const group of byHash.values()) {
857
+ for (let i = 0; i < group.length; i++) {
858
+ for (let j = i + 1; j < group.length; j++) {
859
+ if (group[i].sig.equals(group[j].sig)) {
860
+ violations.push(`[${space}] ${rule}: IDs ${group[i].id} and ${group[j].id} hold equal signatures ` +
861
+ `(${group[i].sig.toString()}) — hash/equals contract broken`);
862
+ }
863
+ }
864
+ }
865
+ }
866
+ }
867
+ /**
868
+ * 校验全部已注册空间,输出一份合并汇总(完整全貌,绝不截断)。
869
+ * @returns 全部空间干净时返回 true。
870
+ */
871
+ static validateAll() {
872
+ const violations = [
873
+ ...this.validateFileSpace(),
874
+ ...this.validateNamespaceSpace(),
875
+ ...this.validateClassSpace(),
876
+ ...this.validateFieldSpace(),
877
+ ...this.validateMethodSpace(),
878
+ ...this.validateTempSpaces(),
879
+ ];
880
+ if (violations.length > 0) {
881
+ logger.error(`Canonicalizer validation failed with ${violations.length} violation(s):\n - ${violations.join('\n - ')}`);
882
+ return false;
883
+ }
884
+ logger.info('Canonicalizer validation successes, everything is ok.');
885
+ return true;
886
+ }
887
+ }
888
+ exports.CanonicalizerValidator = CanonicalizerValidator;