@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/README.md +3 -1
  2. package/THIRD_PARTY_NOTICES.md +27 -0
  3. package/dist/bin/mapper-connection.js +2 -1
  4. package/dist/bin/node-host.js +24 -5
  5. package/dist/src/alias-chain.js +35 -9
  6. package/dist/src/amd.js +81 -0
  7. package/dist/src/analysis.js +274 -496
  8. package/dist/src/augmentations.js +64 -3
  9. package/dist/src/automatic-types.js +10 -29
  10. package/dist/src/bindings.js +382 -0
  11. package/dist/src/commands/held.js +499 -0
  12. package/dist/src/commands/read.js +161 -0
  13. package/dist/src/commands/shell.js +169 -0
  14. package/dist/src/commands/tools.js +1847 -0
  15. package/dist/src/component-files.js +3 -2
  16. package/dist/src/component-layer.js +4 -2
  17. package/dist/src/config.js +6 -82
  18. package/dist/src/conformance-record.js +2 -2
  19. package/dist/src/consumers.js +10 -38
  20. package/dist/src/contextual-uses.js +57 -26
  21. package/dist/src/contract/config.generated.js +561 -0
  22. package/dist/src/contract/contract.generated.js +1370 -0
  23. package/dist/src/contract/report.generated.js +866 -0
  24. package/dist/src/dependencies.js +165 -122
  25. package/dist/src/destructuring.js +1 -19
  26. package/dist/src/edges.js +38 -122
  27. package/dist/src/element-access.js +181 -168
  28. package/dist/src/entries/build-scripts.js +222 -0
  29. package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
  30. package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
  31. package/dist/src/entries/conventions.js +740 -0
  32. package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
  33. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
  34. package/dist/src/entries/run-directories.js +77 -0
  35. package/dist/src/entries/sources.js +144 -0
  36. package/dist/src/entries/static-module.js +670 -0
  37. package/dist/src/entries/test-runners.js +650 -0
  38. package/dist/src/entries/workflow-steps.js +345 -0
  39. package/dist/src/exemptions/argument-places.js +131 -0
  40. package/dist/src/exemptions/calls.js +338 -0
  41. package/dist/src/exemptions/classes.js +13 -0
  42. package/dist/src/{decorator.js → exemptions/decorator.js} +19 -30
  43. package/dist/src/exemptions/detectors.js +48 -0
  44. package/dist/src/{enum-group.js → exemptions/enum-group.js} +9 -16
  45. package/dist/src/{erased-stores.js → exemptions/erased-stores.js} +7 -11
  46. package/dist/src/{framework-lifecycle.js → exemptions/framework-lifecycle.js} +76 -54
  47. package/dist/src/exemptions/generated-file.js +241 -0
  48. package/dist/src/{injection-container.js → exemptions/injection-container.js} +20 -26
  49. package/dist/src/exemptions/installed-globals.js +173 -0
  50. package/dist/src/{interface-satisfaction.js → exemptions/interface-satisfaction.js} +52 -121
  51. package/dist/src/exemptions/lifecycle.js +150 -0
  52. package/dist/src/{reflective-lookup.js → exemptions/reflective-lookup.js} +3 -3
  53. package/dist/src/exemptions/serialization-contract.js +1276 -0
  54. package/dist/src/exemptions/sites.js +182 -0
  55. package/dist/src/{template-field.js → exemptions/template-field.js} +13 -23
  56. package/dist/src/{value-reach.js → exemptions/value-reach.js} +14 -7
  57. package/dist/src/exposure.js +400 -0
  58. package/dist/src/extensions.js +37 -0
  59. package/dist/src/facts.js +38 -0
  60. package/dist/src/failure.js +36 -0
  61. package/dist/src/file-facts.js +3 -26
  62. package/dist/src/findings/completion.js +109 -56
  63. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  64. package/dist/src/findings/emitters.js +27 -41
  65. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  66. package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
  67. package/dist/src/findings/interfaces.js +4 -5
  68. package/dist/src/findings/intra-function.js +16 -13
  69. package/dist/src/findings/non-code-artifacts.js +17 -12
  70. package/dist/src/findings/reads-and-writes.js +86 -27
  71. package/dist/src/findings/self-check.js +44 -30
  72. package/dist/src/findings/unused-declarations.js +29 -45
  73. package/dist/src/findings/visibility-narrowing.js +23 -31
  74. package/dist/src/findings-pass.js +13 -21
  75. package/dist/src/fs/document.js +52 -0
  76. package/dist/src/fs/manifest.js +67 -0
  77. package/dist/src/fs/tree.js +88 -0
  78. package/dist/src/git-ignore.js +39 -26
  79. package/dist/src/import-bindings.js +73 -28
  80. package/dist/src/index/sites.js +557 -0
  81. package/dist/src/index/values.js +124 -0
  82. package/dist/src/index.js +2 -2
  83. package/dist/src/indexed-access.js +523 -478
  84. package/dist/src/intra-function-parts.js +63 -43
  85. package/dist/src/inventory/commonjs.js +507 -0
  86. package/dist/src/inventory/enumerate.js +167 -0
  87. package/dist/src/inventory/syntax.js +236 -0
  88. package/dist/src/inventory.js +323 -724
  89. package/dist/src/javascript-file.js +48 -0
  90. package/dist/src/json-document.js +198 -67
  91. package/dist/src/keyof-comparisons.js +126 -107
  92. package/dist/src/kinds.js +3 -366
  93. package/dist/src/{components.js → liveness/components.js} +2 -3
  94. package/dist/src/{graph.js → liveness/graph.js} +52 -28
  95. package/dist/src/liveness/matrix.js +99 -0
  96. package/dist/src/liveness/sweep.js +558 -0
  97. package/dist/src/load/classify.js +289 -0
  98. package/dist/src/load/diagnostics.js +87 -0
  99. package/dist/src/load/discover.js +285 -0
  100. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  101. package/dist/src/load/expected-module.js +136 -0
  102. package/dist/src/load/load.js +27 -0
  103. package/dist/src/load/module-lookup.js +37 -0
  104. package/dist/src/load/package-scope.js +56 -0
  105. package/dist/src/load/plan.js +313 -0
  106. package/dist/src/load/specifiers.js +113 -0
  107. package/dist/src/load/synthesize.js +152 -0
  108. package/dist/src/load/test-globals.js +207 -0
  109. package/dist/src/load/test-joins.js +82 -0
  110. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  111. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  112. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
  113. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  114. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  115. package/dist/src/module-declarations.js +70 -85
  116. package/dist/src/overrides.js +134 -112
  117. package/dist/src/partial.js +2 -1
  118. package/dist/src/paths.js +82 -16
  119. package/dist/src/platform-calls.js +78 -0
  120. package/dist/src/platform-symbols.js +134 -0
  121. package/dist/src/position.js +43 -1
  122. package/dist/src/print.js +11 -79
  123. package/dist/src/product.js +13 -0
  124. package/dist/src/query.js +95 -0
  125. package/dist/src/ref.js +12 -20
  126. package/dist/src/references/read-rule.js +1 -0
  127. package/dist/src/references/read-rules.js +48 -0
  128. package/dist/src/references/sink.js +237 -0
  129. package/dist/src/references/sources.js +450 -0
  130. package/dist/src/references.js +117 -1074
  131. package/dist/src/report-schema.js +51 -0
  132. package/dist/src/report.js +57 -41
  133. package/dist/src/reporters/annotations.js +15 -8
  134. package/dist/src/reporters/sarif.js +16 -10
  135. package/dist/src/reporters/template.js +4 -19
  136. package/dist/src/resolve.js +246 -730
  137. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
  138. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
  139. package/dist/src/roots/manifest.js +216 -0
  140. package/dist/src/roots/published-reach.js +412 -0
  141. package/dist/src/roots/root-set.js +487 -0
  142. package/dist/src/roots/unseen-loads.js +236 -0
  143. package/dist/src/run.js +66 -77
  144. package/dist/src/schema.js +320 -343
  145. package/dist/src/scope.js +38 -115
  146. package/dist/src/session.js +37 -29
  147. package/dist/src/source-files.js +6 -10
  148. package/dist/src/stores.js +4 -2
  149. package/dist/src/suppress-file.js +25 -28
  150. package/dist/src/suppress-inline.js +36 -83
  151. package/dist/src/suppress.js +50 -71
  152. package/dist/src/symbol-keys.js +92 -88
  153. package/dist/src/tests/file-class.js +76 -0
  154. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  155. package/dist/src/{test-support.js → tests/support.js} +5 -12
  156. package/dist/src/text/compare.js +26 -0
  157. package/dist/src/text/glob.js +194 -0
  158. package/dist/src/text/named-files.js +298 -0
  159. package/dist/src/text/yaml.js +684 -0
  160. package/dist/src/type-errors.js +11 -232
  161. package/dist/src/type-parameter-reads.js +178 -139
  162. package/dist/src/unimplemented-callees.js +262 -242
  163. package/dist/src/unwrap.js +23 -0
  164. package/dist/src/usage.js +10 -0
  165. package/dist/src/vendor/unbash/ansi-c.js +132 -0
  166. package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
  167. package/dist/src/vendor/unbash/arithmetic.js +591 -0
  168. package/dist/src/vendor/unbash/assignment.js +131 -0
  169. package/dist/src/vendor/unbash/chars.js +48 -0
  170. package/dist/src/vendor/unbash/command.js +41 -0
  171. package/dist/src/vendor/unbash/expansion.js +80 -0
  172. package/dist/src/vendor/unbash/glob.js +268 -0
  173. package/dist/src/vendor/unbash/heredoc.js +27 -0
  174. package/dist/src/vendor/unbash/internal-types.js +1 -0
  175. package/dist/src/vendor/unbash/lexer.js +4274 -0
  176. package/dist/src/vendor/unbash/limits.js +3 -0
  177. package/dist/src/vendor/unbash/parser.js +1366 -0
  178. package/dist/src/vendor/unbash/parts.js +57 -0
  179. package/dist/src/vendor/unbash/substitution-context.js +8 -0
  180. package/dist/src/vendor/unbash/traversal.js +212 -0
  181. package/dist/src/vendor/unbash/types.js +1 -0
  182. package/dist/src/vendor/unbash/word-value.js +61 -0
  183. package/dist/src/vendor/unbash/word.js +40 -0
  184. package/dist/src/verbs/analyze.js +194 -127
  185. package/dist/src/verbs/describe.js +13 -18
  186. package/dist/src/verbs/explain.js +85 -139
  187. package/dist/src/verbs/print-config.js +2 -1
  188. package/dist/src/verbs/print-projects.js +6 -4
  189. package/dist/src/verbs/print-retained.js +30 -6
  190. package/dist/src/verbs/print-roots.js +4 -2
  191. package/dist/src/verbs/verb.js +1 -5
  192. package/dist/src/verbs/version.js +14 -3
  193. package/jsr.json +2 -1
  194. package/package.json +14 -8
  195. package/src/alias-chain.ts +40 -11
  196. package/src/amd.ts +130 -0
  197. package/src/analysis.ts +426 -733
  198. package/src/augmentations.ts +93 -4
  199. package/src/automatic-types.ts +12 -30
  200. package/src/bindings.ts +460 -0
  201. package/src/commands/held.ts +632 -0
  202. package/src/commands/read.ts +242 -0
  203. package/src/commands/shell.ts +228 -0
  204. package/src/commands/tools.ts +2382 -0
  205. package/src/component-files.ts +4 -2
  206. package/src/component-layer.ts +4 -2
  207. package/src/config.ts +31 -302
  208. package/src/conformance-record.ts +2 -2
  209. package/src/consumers.ts +16 -66
  210. package/src/contextual-uses.ts +66 -34
  211. package/src/contract/config.generated.ts +821 -0
  212. package/src/contract/contract.generated.ts +1453 -0
  213. package/src/contract/report.generated.ts +1241 -0
  214. package/src/dependencies.ts +223 -128
  215. package/src/destructuring.ts +1 -31
  216. package/src/edges.ts +41 -140
  217. package/src/element-access.ts +190 -187
  218. package/src/entries/build-scripts.ts +292 -0
  219. package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
  220. package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
  221. package/src/{conventions.ts → entries/conventions.ts} +367 -583
  222. package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
  223. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
  224. package/src/entries/run-directories.ts +108 -0
  225. package/src/entries/sources.ts +266 -0
  226. package/src/entries/static-module.ts +858 -0
  227. package/src/entries/test-runners.ts +835 -0
  228. package/src/entries/workflow-steps.ts +432 -0
  229. package/src/exemptions/argument-places.ts +198 -0
  230. package/src/exemptions/calls.ts +483 -0
  231. package/src/exemptions/classes.ts +49 -0
  232. package/src/exemptions/decorator.ts +56 -0
  233. package/src/exemptions/detectors.ts +75 -0
  234. package/src/{enum-group.ts → exemptions/enum-group.ts} +10 -19
  235. package/src/{erased-stores.ts → exemptions/erased-stores.ts} +7 -14
  236. package/src/{framework-lifecycle.ts → exemptions/framework-lifecycle.ts} +85 -66
  237. package/src/exemptions/generated-file.ts +318 -0
  238. package/src/{injection-container.ts → exemptions/injection-container.ts} +29 -34
  239. package/src/exemptions/installed-globals.ts +255 -0
  240. package/src/{interface-satisfaction.ts → exemptions/interface-satisfaction.ts} +69 -160
  241. package/src/exemptions/lifecycle.ts +286 -0
  242. package/src/{reflective-lookup.ts → exemptions/reflective-lookup.ts} +5 -5
  243. package/src/exemptions/serialization-contract.ts +1729 -0
  244. package/src/exemptions/sites.ts +293 -0
  245. package/src/{template-field.ts → exemptions/template-field.ts} +22 -32
  246. package/src/{value-reach.ts → exemptions/value-reach.ts} +16 -8
  247. package/src/exposure.ts +492 -0
  248. package/src/extensions.ts +45 -0
  249. package/src/facts.ts +46 -0
  250. package/src/failure.ts +63 -0
  251. package/src/file-facts.ts +15 -25
  252. package/src/finding.ts +10 -10
  253. package/src/findings/boundary.ts +11 -0
  254. package/src/findings/completion.ts +133 -64
  255. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  256. package/src/findings/emitter.ts +9 -10
  257. package/src/findings/emitters.ts +38 -52
  258. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  259. package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
  260. package/src/findings/interfaces.ts +7 -9
  261. package/src/findings/intra-function.ts +16 -14
  262. package/src/findings/non-code-artifacts.ts +24 -15
  263. package/src/findings/reads-and-writes.ts +118 -41
  264. package/src/findings/self-check.ts +51 -38
  265. package/src/findings/unused-declarations.ts +31 -49
  266. package/src/findings/visibility-narrowing.ts +36 -40
  267. package/src/findings-pass.ts +15 -31
  268. package/src/fs/document.ts +70 -0
  269. package/src/fs/manifest.ts +96 -0
  270. package/src/fs/tree.ts +110 -0
  271. package/src/git-ignore.ts +50 -26
  272. package/src/host.ts +12 -5
  273. package/src/import-bindings.ts +98 -29
  274. package/src/index/sites.ts +781 -0
  275. package/src/index/values.ts +170 -0
  276. package/src/index.ts +2 -2
  277. package/src/indexed-access.ts +570 -527
  278. package/src/intra-function-parts.ts +73 -44
  279. package/src/inventory/commonjs.ts +696 -0
  280. package/src/inventory/enumerate.ts +203 -0
  281. package/src/inventory/syntax.ts +311 -0
  282. package/src/inventory.ts +442 -895
  283. package/src/javascript-file.ts +54 -0
  284. package/src/json-document.ts +241 -76
  285. package/src/keyof-comparisons.ts +133 -122
  286. package/src/kinds.ts +5 -413
  287. package/src/{components.ts → liveness/components.ts} +4 -6
  288. package/src/{graph.ts → liveness/graph.ts} +100 -35
  289. package/src/liveness/matrix.ts +162 -0
  290. package/src/liveness/sweep.ts +855 -0
  291. package/src/load/classify.ts +433 -0
  292. package/src/load/diagnostics.ts +154 -0
  293. package/src/load/discover.ts +471 -0
  294. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  295. package/src/load/expected-module.ts +194 -0
  296. package/src/load/load.ts +73 -0
  297. package/src/load/module-lookup.ts +50 -0
  298. package/src/load/package-scope.ts +74 -0
  299. package/src/load/plan.ts +513 -0
  300. package/src/load/specifiers.ts +171 -0
  301. package/src/load/synthesize.ts +230 -0
  302. package/src/load/test-globals.ts +251 -0
  303. package/src/load/test-joins.ts +98 -0
  304. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  305. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  306. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
  307. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  308. package/src/{workspace.ts → load/workspace.ts} +90 -134
  309. package/src/module-declarations.ts +74 -98
  310. package/src/overrides.ts +162 -134
  311. package/src/partial.ts +3 -2
  312. package/src/paths.ts +92 -16
  313. package/src/platform-calls.ts +119 -0
  314. package/src/platform-symbols.ts +189 -0
  315. package/src/position.ts +44 -1
  316. package/src/print.ts +12 -92
  317. package/src/product.ts +18 -0
  318. package/src/query.ts +201 -10
  319. package/src/ref.ts +12 -20
  320. package/src/references/read-rule.ts +60 -0
  321. package/src/references/read-rules.ts +55 -0
  322. package/src/references/sink.ts +314 -0
  323. package/src/references/sources.ts +632 -0
  324. package/src/references.ts +187 -1450
  325. package/src/report-schema.ts +68 -0
  326. package/src/report.ts +103 -226
  327. package/src/reporters/annotations.ts +22 -11
  328. package/src/reporters/json.ts +1 -1
  329. package/src/reporters/reporter.ts +2 -4
  330. package/src/reporters/reporters.ts +1 -1
  331. package/src/reporters/sarif.ts +29 -16
  332. package/src/reporters/template.ts +4 -20
  333. package/src/reporters/text.ts +3 -3
  334. package/src/resolve.ts +284 -1115
  335. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +26 -29
  336. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
  337. package/src/roots/manifest.ts +303 -0
  338. package/src/roots/published-reach.ts +486 -0
  339. package/src/{roots.ts → roots/root-set.ts} +286 -469
  340. package/src/roots/unseen-loads.ts +345 -0
  341. package/src/run.ts +75 -91
  342. package/src/schema.ts +391 -388
  343. package/src/scope.ts +46 -138
  344. package/src/session.ts +87 -55
  345. package/src/source-files.ts +6 -11
  346. package/src/stores.ts +15 -3
  347. package/src/suppress-file.ts +24 -33
  348. package/src/suppress-inline.ts +55 -91
  349. package/src/suppress.ts +78 -79
  350. package/src/symbol-keys.ts +104 -107
  351. package/src/tests/file-class.ts +135 -0
  352. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  353. package/src/{test-support.ts → tests/support.ts} +15 -21
  354. package/src/text/compare.ts +27 -0
  355. package/src/text/glob.ts +210 -0
  356. package/src/text/named-files.ts +388 -0
  357. package/src/text/yaml.ts +747 -0
  358. package/src/type-errors.ts +18 -288
  359. package/src/type-parameter-reads.ts +187 -158
  360. package/src/unimplemented-callees.ts +297 -280
  361. package/src/unwrap.ts +34 -0
  362. package/src/usage.ts +10 -0
  363. package/src/vendor/unbash/LICENSE +15 -0
  364. package/src/vendor/unbash/VENDORED.md +16 -0
  365. package/src/vendor/unbash/ansi-c.ts +132 -0
  366. package/src/vendor/unbash/arithmetic-parts.ts +53 -0
  367. package/src/vendor/unbash/arithmetic.ts +641 -0
  368. package/src/vendor/unbash/assignment.ts +163 -0
  369. package/src/vendor/unbash/chars.ts +48 -0
  370. package/src/vendor/unbash/command.ts +47 -0
  371. package/src/vendor/unbash/expansion.ts +144 -0
  372. package/src/vendor/unbash/glob.ts +284 -0
  373. package/src/vendor/unbash/heredoc.ts +34 -0
  374. package/src/vendor/unbash/internal-types.ts +94 -0
  375. package/src/vendor/unbash/lexer.ts +4352 -0
  376. package/src/vendor/unbash/limits.ts +3 -0
  377. package/src/vendor/unbash/parser.ts +1612 -0
  378. package/src/vendor/unbash/parts.ts +96 -0
  379. package/src/vendor/unbash/substitution-context.ts +20 -0
  380. package/src/vendor/unbash/traversal.ts +182 -0
  381. package/src/vendor/unbash/types.ts +660 -0
  382. package/src/vendor/unbash/word-value.ts +64 -0
  383. package/src/vendor/unbash/word.ts +50 -0
  384. package/src/verbs/analyze.ts +255 -164
  385. package/src/verbs/describe.ts +19 -17
  386. package/src/verbs/explain.ts +93 -169
  387. package/src/verbs/print-config.ts +2 -1
  388. package/src/verbs/print-projects.ts +6 -4
  389. package/src/verbs/print-retained.ts +36 -6
  390. package/src/verbs/print-roots.ts +4 -2
  391. package/src/verbs/verb.ts +2 -8
  392. package/src/verbs/version.ts +15 -3
  393. package/dist/src/base-url.js +0 -18
  394. package/dist/src/calls.js +0 -155
  395. package/dist/src/conventions.js +0 -937
  396. package/dist/src/discover.js +0 -468
  397. package/dist/src/entry-points.js +0 -529
  398. package/dist/src/exempt-classes.js +0 -75
  399. package/dist/src/exempt.js +0 -209
  400. package/dist/src/generated-file.js +0 -95
  401. package/dist/src/glob.js +0 -65
  402. package/dist/src/manifest.js +0 -165
  403. package/dist/src/matrix.js +0 -246
  404. package/dist/src/pnpm-workspace.js +0 -120
  405. package/dist/src/roots.js +0 -672
  406. package/dist/src/serialization-contract.js +0 -611
  407. package/dist/src/setup-failure.js +0 -23
  408. package/dist/src/sweep.js +0 -224
  409. package/dist/src/test-joins.js +0 -101
  410. package/dist/src/value-flow.js +0 -74
  411. package/dist/src/version.js +0 -7
  412. package/dist/src/workflow-steps.js +0 -185
  413. package/src/base-url.ts +0 -24
  414. package/src/calls.ts +0 -225
  415. package/src/decorator.ts +0 -78
  416. package/src/discover.ts +0 -653
  417. package/src/entry-points.ts +0 -687
  418. package/src/exempt-classes.ts +0 -123
  419. package/src/exempt.ts +0 -323
  420. package/src/generated-file.ts +0 -111
  421. package/src/glob.ts +0 -67
  422. package/src/manifest.ts +0 -234
  423. package/src/matrix.ts +0 -423
  424. package/src/pnpm-workspace.ts +0 -135
  425. package/src/serialization-contract.ts +0 -849
  426. package/src/setup-failure.ts +0 -39
  427. package/src/sweep.ts +0 -347
  428. package/src/test-joins.ts +0 -120
  429. package/src/value-flow.ts +0 -104
  430. package/src/version.ts +0 -7
  431. package/src/workflow-steps.ts +0 -216
@@ -0,0 +1,492 @@
1
+ /**
2
+ * Which types of the target each of its declarations hands to code outside the package:
3
+ * the types each declaration a reference from outside reaches names, as written or as the
4
+ * checker reads it, as the precondition of `DS1501` in the Contract's kinds reads that
5
+ * reach.
6
+ */
7
+
8
+ import {
9
+ SignatureKind,
10
+ SymbolFlags,
11
+ type NodeHandle,
12
+ type Symbol as TSSymbol,
13
+ type Type,
14
+ } from "@typescript/native/sync";
15
+ import {
16
+ isArrowFunction,
17
+ isAsExpression,
18
+ isBindingElement,
19
+ isCallSignatureDeclaration,
20
+ isClassExpression,
21
+ isConstructorTypeNode,
22
+ isConstructSignatureDeclaration,
23
+ isDecorator,
24
+ isEnumMember,
25
+ isFunctionExpression,
26
+ isFunctionTypeNode,
27
+ isGetAccessorDeclaration,
28
+ isIdentifier,
29
+ isMethodDeclaration,
30
+ isMethodSignatureDeclaration,
31
+ isObjectLiteralExpression,
32
+ isParenthesizedExpression,
33
+ isPropertyAssignment,
34
+ isPropertyDeclaration,
35
+ isPropertySignatureDeclaration,
36
+ isSatisfiesExpression,
37
+ isSetAccessorDeclaration,
38
+ isSpreadAssignment,
39
+ isTypeAssertion,
40
+ isTypeReferenceNode,
41
+ type Node,
42
+ type SourceFile,
43
+ } from "@typescript/native/ast";
44
+ import { aliasChains } from "./alias-chain.ts";
45
+ import { OUTSIDE, type Graph } from "./liveness/graph.ts";
46
+ import { nodeKey, type Inventory, type InventorySymbol, type SymbolKind } from "./inventory.ts";
47
+ import { isAnswered, type Answer } from "./query.ts";
48
+ import { typeNamesOf } from "./roots/published-reach.ts";
49
+ import type { Handle, ProjectView } from "./session.ts";
50
+
51
+ /** The declarations whose values a reference holds without naming them. */
52
+ const TYPES: ReadonlySet<SymbolKind> = new Set<SymbolKind>(["class", "interface", "type", "enum"]);
53
+
54
+ /** The symbol flags of a type the source spells as a literal, whose members are its own. */
55
+ const LITERAL = SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral;
56
+
57
+ /** The members a type's definition names other types through, where exported. */
58
+ const MEMBERS: ReadonlySet<SymbolKind> = new Set<SymbolKind>([
59
+ "method",
60
+ "class-member",
61
+ "interface-method",
62
+ "type-member",
63
+ ]);
64
+
65
+ /** The declarations of a module or a namespace whose signature or type hands values on. */
66
+ const CARRYING: ReadonlySet<SymbolKind> = new Set<SymbolKind>(["function", "variable", ...TYPES]);
67
+
68
+ /** The containers whose own declarations a reference from outside can reach. */
69
+ const SCOPES: ReadonlySet<SymbolKind> = new Set<SymbolKind>(["file", "namespace"]);
70
+
71
+ /** What one project's declarations carry. */
72
+ export interface Carriers {
73
+ /** Per declaration, the declarations of the target it carries, each once. */
74
+ readonly named: ReadonlyMap<string, readonly string[]>;
75
+ /** The declarations whose surface the checker left unread, which may carry any type. */
76
+ readonly unread: ReadonlySet<string>;
77
+ }
78
+
79
+ /** What a project whose carriers no rule reads carries: nothing. */
80
+ export const NO_CARRIERS: Carriers = { named: new Map(), unread: new Set() };
81
+
82
+ /** Whether a member is named from outside its type: neither `private` nor a private name. */
83
+ function exportedMember(symbol: InventorySymbol): boolean {
84
+ return symbol.visibility === "public" || symbol.visibility === "protected";
85
+ }
86
+
87
+ /**
88
+ * The declarations of one project that carry values out: a function, a variable or a type
89
+ * a module or a namespace declares, and an exported member of a class, an interface or a
90
+ * type. Neither is filtered by its export: only a declaration the reach meets passes it
91
+ * on, and an unexported type an exported function returns passes it to what it names.
92
+ */
93
+ function carrying(held: Inventory): readonly InventorySymbol[] {
94
+ const byId = new Map(held.symbols.map((symbol) => [symbol.id, symbol]));
95
+ return held.symbols.filter((symbol) => {
96
+ const parent = byId.get(symbol.parent);
97
+ if (MEMBERS.has(symbol.kind)) {
98
+ return parent !== undefined && TYPES.has(parent.kind) && exportedMember(symbol);
99
+ }
100
+ return CARRYING.has(symbol.kind) && parent !== undefined && SCOPES.has(parent.kind);
101
+ });
102
+ }
103
+
104
+ /** The node a declaration's symbol is resolved at: its name, or itself where it has none. */
105
+ function nameNode(node: Node): Node {
106
+ return (node as { readonly name?: Node }).name ?? node;
107
+ }
108
+
109
+ /** Whether a value expression is one whose type the declaration output prints as written. */
110
+ function printedAsWritten(node: Node): boolean {
111
+ return (
112
+ isParenthesizedExpression(node) ||
113
+ isAsExpression(node) ||
114
+ isTypeAssertion(node) ||
115
+ isSatisfiesExpression(node) ||
116
+ isObjectLiteralExpression(node) ||
117
+ isArrowFunction(node) ||
118
+ isFunctionExpression(node) ||
119
+ isClassExpression(node)
120
+ );
121
+ }
122
+
123
+ /** Whether a type node is the `const` of a const assertion, which names no type. */
124
+ function isConstName(node: Node): boolean {
125
+ return isTypeReferenceNode(node) && isIdentifier(node.typeName) && node.typeName.text === "const";
126
+ }
127
+
128
+ /**
129
+ * Whether the declaration output prints a type or a member it meets by this declaration's
130
+ * written types: a function type's, a signature's, a member's, or an expression's that
131
+ * {@link printedAsWritten} holds. A type literal or a mapped type it prints from the
132
+ * checker's members, so only each member's own declaration is read.
133
+ */
134
+ function reused(node: Node): boolean {
135
+ return (
136
+ isFunctionTypeNode(node) ||
137
+ isConstructorTypeNode(node) ||
138
+ isPropertySignatureDeclaration(node) ||
139
+ isMethodSignatureDeclaration(node) ||
140
+ isCallSignatureDeclaration(node) ||
141
+ isConstructSignatureDeclaration(node) ||
142
+ isPropertyAssignment(node) ||
143
+ isPropertyDeclaration(node) ||
144
+ isMethodDeclaration(node) ||
145
+ isGetAccessorDeclaration(node) ||
146
+ isSetAccessorDeclaration(node) ||
147
+ printedAsWritten(node)
148
+ );
149
+ }
150
+
151
+ /**
152
+ * Whether the declaration output leaves out the types one node of a declaration writes.
153
+ * It prints an initializer only where its declaration has no annotation, and then as the
154
+ * checker types it, except through what {@link printedAsWritten} holds: an assertion's
155
+ * type in place of its operand, a function's or a class's signatures, an object literal's
156
+ * properties, and the operand of a `satisfies`. A decorator and an enum member's or a
157
+ * binding element's initializer are not printed.
158
+ */
159
+ function unprinted(node: Node): boolean {
160
+ const parent = node.parent as Node | undefined;
161
+ if (parent === undefined) {
162
+ return false;
163
+ }
164
+ if (isDecorator(node)) {
165
+ return true;
166
+ }
167
+ const held = parent as { readonly initializer?: Node; readonly type?: Node };
168
+ if (held.initializer === node) {
169
+ return (
170
+ isEnumMember(parent) ||
171
+ isBindingElement(parent) ||
172
+ held.type !== undefined ||
173
+ !printedAsWritten(node)
174
+ );
175
+ }
176
+ if (isAsExpression(parent) || isTypeAssertion(parent)) {
177
+ return isConstName(parent.type)
178
+ ? node === parent.type || !printedAsWritten(node)
179
+ : node === parent.expression;
180
+ }
181
+ if (isSatisfiesExpression(parent)) {
182
+ return node === parent.type || !printedAsWritten(node);
183
+ }
184
+ if (isParenthesizedExpression(parent) || isSpreadAssignment(parent)) {
185
+ return !printedAsWritten(node);
186
+ }
187
+ return false;
188
+ }
189
+
190
+ /**
191
+ * The declarations of the target each declaration of one project carries: those it names
192
+ * as written, and those its type names as the checker reads it, so an inferred result names
193
+ * its type as an annotation does. The walk reads a type's constituents, type arguments,
194
+ * alias arguments, `partsOf`, literal members and index signatures, and each signature's
195
+ * parameters, result and `signaturePartsOf`. A type of the target ends the walk, since its
196
+ * own definition is read as its own.
197
+ */
198
+ export function carriersOf<Brand>(project: ProjectView<Brand>, held: Inventory): Carriers {
199
+ const { queries } = project;
200
+ const chains = aliasChains(project, held);
201
+ const kinds = new Map(held.symbols.map((symbol) => [symbol.id, symbol.kind]));
202
+ const parents = new Map(held.symbols.map((symbol) => [symbol.id, symbol.parent]));
203
+ const wanted = new Set(carrying(held).map((symbol) => symbol.id));
204
+ const declared: {
205
+ readonly id: string;
206
+ readonly handle: Handle<Brand>;
207
+ readonly written: readonly Handle<Brand>[];
208
+ }[] = [];
209
+ // A nested carrier and any other member of a type are read on that member, not on the
210
+ // declaration that holds it; a type parameter is part of its declaration.
211
+ const readAloneIn =
212
+ (file: SourceFile) =>
213
+ (nested: Node): boolean => {
214
+ const id = held.declarations.get(nodeKey(file, nested));
215
+ const kind = id === undefined ? undefined : kinds.get(id);
216
+ return (
217
+ unprinted(nested) ||
218
+ (id !== undefined &&
219
+ kind !== "type-parameter" &&
220
+ (wanted.has(id) || TYPES.has(kinds.get(parents.get(id) ?? "") ?? "file")))
221
+ );
222
+ };
223
+ for (const file of project.ownSourceFiles()) {
224
+ const readAlone = readAloneIn(file);
225
+ const visit = (node: Node): void => {
226
+ const id = held.declarations.get(nodeKey(file, node));
227
+ if (id !== undefined && wanted.has(id)) {
228
+ declared.push({
229
+ id,
230
+ handle: project.handle(nameNode(node)),
231
+ written: typeNamesOf(node, readAlone).map((name) => project.handle(name)),
232
+ });
233
+ }
234
+ node.forEachChild(visit);
235
+ };
236
+ file.forEachChild(visit);
237
+ }
238
+
239
+ const unread = new Set<string>();
240
+ let reading = "";
241
+ const answer = <T>(found: Answer<T>, otherwise: T): T => {
242
+ if (isAnswered(found)) {
243
+ return found;
244
+ }
245
+ unread.add(reading);
246
+ return otherwise;
247
+ };
248
+ const typesOf = (symbol: TSSymbol): readonly string[] =>
249
+ chains.declarationsOf(symbol).filter((id) => TYPES.has(kinds.get(id) ?? "file"));
250
+ // The declaration output prints an anonymous type or a literal's member by its own
251
+ // declaration's written types where it has them, which name an alias the checker erases,
252
+ // so the walk of one declaration keeps the target's own declarations of those it meets.
253
+ const own = project.ownPaths();
254
+ let meeting = new Map<string, NodeHandle>();
255
+ const meet = (symbol: TSSymbol): void => {
256
+ for (const handle of symbol.declarations) {
257
+ if (own.has(handle.path)) {
258
+ meeting.set(`${handle.path}#${String(handle.index)}`, handle);
259
+ }
260
+ }
261
+ };
262
+
263
+ const signatures = (type: Type, into: Set<string>, seen: Set<number>): void => {
264
+ for (const kind of [SignatureKind.Call, SignatureKind.Construct]) {
265
+ for (const signature of answer(queries.signaturesOf(type, kind), [])) {
266
+ signature.parameters.forEach((_parameter, index) => {
267
+ walk(answer(queries.parameterType(signature, index), undefined), into, seen);
268
+ });
269
+ walk(answer(queries.returnTypeOf(signature), undefined), into, seen);
270
+ for (const part of answer(queries.signaturePartsOf(signature), [])) {
271
+ walk(part, into, seen);
272
+ }
273
+ }
274
+ }
275
+ };
276
+ // The parts of a type that spell other types, not counting the type itself.
277
+ const structure = (type: Type, into: Set<string>, seen: Set<number>): void => {
278
+ for (const part of answer(queries.constituents(type), [])) {
279
+ if (part.id !== type.id) {
280
+ walk(part, into, seen);
281
+ }
282
+ }
283
+ for (const argument of answer(queries.typeArguments(type), [])) {
284
+ walk(argument, into, seen);
285
+ }
286
+ for (const part of answer(queries.partsOf(type), [])) {
287
+ walk(part, into, seen);
288
+ }
289
+ const symbol = answer(queries.symbolOfType(type), undefined);
290
+ if (symbol !== undefined && (symbol.flags & LITERAL) !== 0) {
291
+ for (const property of answer(queries.propertiesOf(type), [])) {
292
+ meet(property);
293
+ walk(answer(queries.typeOfSymbol(property), undefined), into, seen);
294
+ }
295
+ for (const info of answer(queries.indexInfosOf(type), [])) {
296
+ walk(info.valueType, into, seen);
297
+ }
298
+ }
299
+ signatures(type, into, seen);
300
+ };
301
+ const walk = (type: Type | undefined, into: Set<string>, seen: Set<number>): void => {
302
+ if (type === undefined || seen.has(type.id)) {
303
+ return;
304
+ }
305
+ seen.add(type.id);
306
+ const alias = answer(queries.aliasSymbolOf(type), undefined);
307
+ if (alias !== undefined) {
308
+ for (const id of typesOf(alias)) {
309
+ into.add(id);
310
+ }
311
+ for (const argument of answer(queries.aliasArgumentsOf(type), [])) {
312
+ walk(argument, into, seen);
313
+ }
314
+ if (typesOf(alias).length > 0) {
315
+ return;
316
+ }
317
+ }
318
+ const symbol = answer(queries.symbolOfType(type), undefined);
319
+ const named = symbol === undefined ? [] : typesOf(symbol);
320
+ if (named.length > 0) {
321
+ for (const id of named) {
322
+ into.add(id);
323
+ }
324
+ for (const argument of answer(queries.typeArguments(type), [])) {
325
+ walk(argument, into, seen);
326
+ }
327
+ return;
328
+ }
329
+ if (symbol !== undefined) {
330
+ meet(symbol);
331
+ }
332
+ structure(type, into, seen);
333
+ };
334
+
335
+ // What one declaration's checker type names, by its kind.
336
+ const definition = (symbol: TSSymbol, kind: SymbolKind | undefined, into: Set<string>): void => {
337
+ const seen = new Set<number>();
338
+ // A class's or an interface's own definition: its properties are members, which carry
339
+ // on their own, so only its bases, signatures and index signatures are read here.
340
+ const own = (type: Type): void => {
341
+ for (const info of answer(queries.indexInfosOf(type), [])) {
342
+ walk(info.valueType, into, seen);
343
+ }
344
+ signatures(type, into, seen);
345
+ };
346
+ if (kind === "class" || kind === "interface") {
347
+ const instance = answer(queries.declaredTypeOf(symbol), undefined);
348
+ const statics =
349
+ kind === "class" ? answer(queries.typeOfSymbol(symbol), undefined) : undefined;
350
+ const sides = [instance, statics].filter((side) => side !== undefined);
351
+ for (const side of sides) {
352
+ seen.add(side.id);
353
+ }
354
+ for (const base of instance === undefined ? [] : answer(queries.baseTypes(instance), [])) {
355
+ walk(base, into, seen);
356
+ }
357
+ sides.forEach(own);
358
+ } else if (kind === "type") {
359
+ const aliased = answer(queries.declaredTypeOf(symbol), undefined);
360
+ if (aliased !== undefined) {
361
+ seen.add(aliased.id);
362
+ structure(aliased, into, seen);
363
+ }
364
+ } else if (kind !== "enum") {
365
+ walk(answer(queries.typeOfSymbol(symbol), undefined), into, seen);
366
+ }
367
+ };
368
+
369
+ const symbols = project.symbolsAt(declared.map((one) => one.handle));
370
+ const spelled = project.symbolsAt(declared.flatMap((one) => one.written));
371
+ const reached: { readonly id: string; readonly into: Set<string>; readonly met: NodeHandle[] }[] =
372
+ [];
373
+ const add = (answered: Answer<TSSymbol | undefined>, into: Set<string>): void => {
374
+ const name = answer(answered, undefined);
375
+ for (const target of name === undefined ? [] : chains.chainOf(name)) {
376
+ if (TYPES.has(kinds.get(target.id) ?? "file")) {
377
+ into.add(target.id);
378
+ }
379
+ }
380
+ };
381
+ let from = 0;
382
+ declared.forEach(({ id, written }, index) => {
383
+ reading = id;
384
+ const into = new Set<string>();
385
+ for (const answered of spelled.slice(from, from + written.length)) {
386
+ add(answered, into);
387
+ }
388
+ from += written.length;
389
+ meeting = new Map();
390
+ const symbol = answer(symbols[index], undefined);
391
+ if (symbol !== undefined) {
392
+ definition(symbol, kinds.get(id), into);
393
+ }
394
+ reached.push({ id, into, met: [...meeting.values()] });
395
+ });
396
+
397
+ const namesAt = new Map<string, readonly Handle<Brand>[]>();
398
+ const writtenAt = (handle: NodeHandle): readonly Handle<Brand>[] => {
399
+ const key = `${handle.path}#${String(handle.index)}`;
400
+ let names = namesAt.get(key);
401
+ if (names === undefined) {
402
+ const node = project.declarationAt(handle)?.node;
403
+ names =
404
+ node === undefined || !reused(node)
405
+ ? []
406
+ : typeNamesOf(node, readAloneIn(node.getSourceFile())).map((name) =>
407
+ project.handle(name),
408
+ );
409
+ namesAt.set(key, names);
410
+ }
411
+ return names;
412
+ };
413
+ const metNames = reached.map((one) => one.met.flatMap(writtenAt));
414
+ const metSpelled = project.symbolsAt(metNames.flat());
415
+ const named = new Map<string, readonly string[]>();
416
+ from = 0;
417
+ reached.forEach(({ id, into }, index) => {
418
+ reading = id;
419
+ const count = metNames[index]?.length ?? 0;
420
+ for (const answered of metSpelled.slice(from, from + count)) {
421
+ add(answered, into);
422
+ }
423
+ from += count;
424
+ into.delete(id);
425
+ named.set(id, [...into]);
426
+ });
427
+ return { named, unread };
428
+ }
429
+
430
+ /**
431
+ * The types whose values a reference from outside the package reaches through the
432
+ * package's own declarations, or every type where such a reference reaches a declaration
433
+ * whose surface the checker left unread. `outside` flags each declaration of the graph a
434
+ * reference from outside names; each passes the reach on to what it carries, a type to
435
+ * each member it exports, a namespace to each declaration it exports and a member to its
436
+ * type, until no declaration joins.
437
+ */
438
+ export function exposedTypes(
439
+ graph: Graph,
440
+ outside: readonly boolean[],
441
+ carriers: Carriers | undefined,
442
+ ): ReadonlySet<string> | "every" {
443
+ const { symbols, parent } = graph;
444
+ const members: number[][] = symbols.map(() => []);
445
+ symbols.forEach((symbol, at) => {
446
+ const container = parent[at] ?? OUTSIDE;
447
+ const holder = symbols[container];
448
+ if (
449
+ holder !== undefined &&
450
+ ((TYPES.has(holder.kind) && MEMBERS.has(symbol.kind) && exportedMember(symbol)) ||
451
+ (holder.kind === "namespace" && symbol.exported))
452
+ ) {
453
+ members[container]?.push(at);
454
+ }
455
+ });
456
+ const reached = symbols.map((_symbol, at) => outside[at] === true);
457
+ const queue = reached.flatMap((one, at) => (one ? [at] : []));
458
+ const join = (at: number): void => {
459
+ if (at !== OUTSIDE && reached[at] !== true) {
460
+ reached[at] = true;
461
+ queue.push(at);
462
+ }
463
+ };
464
+ for (let at = queue.pop(); at !== undefined; at = queue.pop()) {
465
+ const symbol = symbols[at];
466
+ if (symbol === undefined) {
467
+ continue;
468
+ }
469
+ if (carriers?.unread.has(symbol.id) === true) {
470
+ return "every";
471
+ }
472
+ for (const id of carriers?.named.get(symbol.id) ?? []) {
473
+ join(graph.at(id));
474
+ }
475
+ for (const member of members[at] ?? []) {
476
+ join(member);
477
+ }
478
+ if (MEMBERS.has(symbol.kind)) {
479
+ join(parent[at] ?? OUTSIDE);
480
+ }
481
+ }
482
+ return new Set(
483
+ symbols.flatMap((symbol, at) =>
484
+ reached[at] === true && TYPES.has(symbol.kind) ? [symbol.id] : [],
485
+ ),
486
+ );
487
+ }
488
+
489
+ /** Whether code outside the package holds values of a type through the package's declarations. */
490
+ export function exposes(exposed: ReadonlySet<string> | "every", symbol: InventorySymbol): boolean {
491
+ return TYPES.has(symbol.kind) && (exposed === "every" || exposed.has(symbol.id));
492
+ }
@@ -0,0 +1,45 @@
1
+ /** The extension lists the analysis reads files by, each written once. */
2
+
3
+ /**
4
+ * The extensions tried, in order, after a path written without one: a relative specifier
5
+ * of a configuration file (`roots.5`) and a path a command runs or loads (`roots.13`).
6
+ */
7
+ export const APPENDED_EXTENSIONS = [
8
+ ".ts",
9
+ ".tsx",
10
+ ".mts",
11
+ ".cts",
12
+ ".js",
13
+ ".jsx",
14
+ ".mjs",
15
+ ".cjs",
16
+ ] as const;
17
+
18
+ /** The extensions of a module a tool runs or loads as its configuration (`roots.2`). */
19
+ export const MODULE_EXTENSIONS = [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"] as const;
20
+
21
+ /** The extensions of a file a build writes from a source file. */
22
+ export const OUTPUT_EXTENSIONS = [
23
+ ".js",
24
+ ".mjs",
25
+ ".cjs",
26
+ ".jsx",
27
+ ".d.ts",
28
+ ".d.mts",
29
+ ".d.cts",
30
+ ] as const;
31
+
32
+ /** One list as a glob's brace list, its dots dropped: `{js,mjs}`. */
33
+ export function braced(extensions: readonly string[]): string {
34
+ return `{${extensions.map((one) => one.slice(1)).join(",")}}`;
35
+ }
36
+
37
+ /** The extension of one list a name ends with, the longest where several do. */
38
+ export function extensionOf(name: string, extensions: readonly string[]): string | undefined {
39
+ return extensions
40
+ .filter((one) => name.endsWith(one))
41
+ .reduce<string | undefined>(
42
+ (longest, one) => (one.length > (longest?.length ?? 0) ? one : longest),
43
+ undefined,
44
+ );
45
+ }
package/src/facts.ts ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The facts document `--facts` writes, `bindings.1` and `bindings.2`: the run's generated
3
+ * files under the one decision the generated-file class reads, and the binding identities
4
+ * they publish. No binding state is computed, so it states `evaluated: false` (`bindings.10`).
5
+ */
6
+
7
+ import { FACTS_VERSION } from "./contract/contract.generated.ts";
8
+ import type { BindingRecord } from "./bindings.ts";
9
+ import type { GeneratedFact } from "./exemptions/generated-file.ts";
10
+ import { LANGUAGE, PRODUCT } from "./product.ts";
11
+ import { bytewise } from "./text/compare.ts";
12
+
13
+ /** The facts document of one run, as the text written to the path `--facts` names. */
14
+ export function factsDocument(
15
+ version: string,
16
+ generated: ReadonlyMap<string, GeneratedFact>,
17
+ bindings: readonly BindingRecord[],
18
+ ): string {
19
+ const document = {
20
+ facts_version: FACTS_VERSION,
21
+ analyzer: { name: PRODUCT, version },
22
+ language: LANGUAGE,
23
+ evaluated: false,
24
+ generated: [...generated]
25
+ .sort(([a], [b]) => bytewise(a, b))
26
+ .map(([path, fact]) => ({
27
+ path,
28
+ line: fact.line,
29
+ evidence: fact.evidence,
30
+ detail: fact.detail,
31
+ ...(fact.generator === undefined
32
+ ? {}
33
+ : {
34
+ generator: {
35
+ row: fact.generator.row,
36
+ ...(fact.generator.version === undefined
37
+ ? {}
38
+ : { version: fact.generator.version }),
39
+ },
40
+ schema_files: fact.generator.schemaFiles,
41
+ }),
42
+ })),
43
+ bindings,
44
+ };
45
+ return `${JSON.stringify(document, null, 2)}\n`;
46
+ }
package/src/failure.ts ADDED
@@ -0,0 +1,63 @@
1
+ import { FAILURE_CLASSES, FAILURE_PREFIXES } from "./contract/contract.generated.ts";
2
+ import type { LocatedDiagnostic } from "./load/diagnostics.ts";
3
+ import { PRODUCT } from "./product.ts";
4
+
5
+ /** A class of failure the Contract's exit-code table names, of either group. */
6
+ type FailureClass = keyof typeof FAILURE_CLASSES;
7
+
8
+ /** One cause the run ends with the failure code for. */
9
+ export interface Failure {
10
+ readonly failureClass: FailureClass;
11
+ /** What fails and the fix, on one line. */
12
+ readonly detail: string;
13
+ }
14
+
15
+ /** The failure as a class line of the error stream, opened by its group's prefix. */
16
+ export function failureLine(failure: Failure): string {
17
+ return `${FAILURE_PREFIXES[FAILURE_CLASSES[failure.failureClass]]}${failure.failureClass}: ${failure.detail}`;
18
+ }
19
+
20
+ /**
21
+ * The lines of the error stream that name the failures: the first one's class line, the run's
22
+ * only one, then each further failure as its class and detail with no group prefix.
23
+ */
24
+ export function failureLines([first, ...further]: readonly [Failure, ...Failure[]]): string[] {
25
+ return [failureLine(first), ...further.map((one) => `${one.failureClass}: ${one.detail}`)];
26
+ }
27
+
28
+ /**
29
+ * A run the analysis cannot answer. It ends the run with the failure code and no finding
30
+ * list, printing the compiler's located errors and then the failures' lines.
31
+ */
32
+ export class FailureExit extends Error {
33
+ readonly failures: readonly [Failure, ...Failure[]];
34
+ /** The compiler's errors behind the failures, in the order it reported them. */
35
+ readonly diagnostics: readonly LocatedDiagnostic[];
36
+
37
+ constructor(
38
+ failures: readonly [Failure, ...Failure[]],
39
+ diagnostics: readonly LocatedDiagnostic[] = [],
40
+ ) {
41
+ super(failureLines(failures).join("\n"));
42
+ this.name = "FailureExit";
43
+ this.failures = failures;
44
+ this.diagnostics = diagnostics;
45
+ }
46
+ }
47
+
48
+ /** A failure exit of one failure. */
49
+ export function failureExit(
50
+ failureClass: FailureClass,
51
+ detail: string,
52
+ diagnostics: readonly LocatedDiagnostic[] = [],
53
+ ): FailureExit {
54
+ return new FailureExit([{ failureClass, detail }], diagnostics);
55
+ }
56
+
57
+ /** A fault of this analyzer itself, `fault` saying what it cannot do. */
58
+ export function productFault(fault: string): FailureExit {
59
+ return failureExit(
60
+ "product-fault",
61
+ `${PRODUCT} ${fault}: reinstall ${PRODUCT}, and report the fault to its maintainers if a reinstalled ${PRODUCT} fails the same way`,
62
+ );
63
+ }