@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
@@ -1,20 +1,29 @@
1
+ import {
2
+ CONTRACT_VERSION,
3
+ EXIT_CLEAN,
4
+ EXIT_USAGE,
5
+ FACTS_VERSION,
6
+ SCHEMA_VERSIONS,
7
+ } from "../contract/contract.generated.ts";
1
8
  import { CONFORMANCE, type Conformance } from "../conformance.ts";
2
- import { ANALYZER_NAME, LANGUAGE, SCHEMA_VERSIONS_ACCEPTED } from "../report.ts";
3
- import { CONTRACT_VERSION } from "../version.ts";
4
- import { EXIT_CLEAN, EXIT_FAILURE, EXIT_USAGE, type Verb } from "./verb.ts";
9
+ import { type Verb } from "./verb.ts";
10
+ import { diagnose, LANGUAGE, PRODUCT } from "../product.ts";
11
+ import { ownVersion } from "./version.ts";
5
12
 
6
13
  /**
7
14
  * The document `describe` writes: the analyzer, the Contract version it implements, the
8
- * report schema versions it reads, the languages it claims, and its recorded result over
9
- * the conformance corpus, a member the document omits where no run is recorded.
15
+ * report schema versions it reads, the languages it claims, the facts version it writes,
16
+ * and its recorded result over the conformance corpus, a member the document omits where
17
+ * no run is recorded.
10
18
  */
11
19
  export function describeDocument(version: string, recorded: Conformance | undefined): string {
12
20
  const document = {
13
- name: ANALYZER_NAME,
21
+ name: PRODUCT,
14
22
  version,
15
23
  contract_version: CONTRACT_VERSION,
16
- schema_versions_accepted: SCHEMA_VERSIONS_ACCEPTED,
24
+ schema_versions_accepted: SCHEMA_VERSIONS,
17
25
  languages: [LANGUAGE],
26
+ facts_version_written: FACTS_VERSION,
18
27
  ...(recorded === undefined
19
28
  ? {}
20
29
  : {
@@ -28,19 +37,12 @@ export function describeDocument(version: string, recorded: Conformance | undefi
28
37
  return `${JSON.stringify(document, null, 2)}\n`;
29
38
  }
30
39
 
31
- /** Writes this analyzer's description to the output stream, and nothing to the error stream. */
40
+ /** Writes this analyzer's description to the output stream. */
32
41
  export const describeVerb: Verb = ({ out, err, host, args }) => {
33
42
  if (args.length > 0) {
34
- err.write(`deadset-ts: describe takes no argument, got ${JSON.stringify(args[0])}\n`);
43
+ diagnose(err, `describe takes no argument, got ${JSON.stringify(args[0])}`);
35
44
  return EXIT_USAGE;
36
45
  }
37
- let version: string;
38
- try {
39
- version = host.analyzerVersion();
40
- } catch (error: unknown) {
41
- err.write(`deadset-ts: describe: ${error instanceof Error ? error.message : String(error)}\n`);
42
- return EXIT_FAILURE;
43
- }
44
- out.write(describeDocument(version, CONFORMANCE));
46
+ out.write(describeDocument(ownVersion(host), CONFORMANCE));
45
47
  return EXIT_CLEAN;
46
48
  };
@@ -1,18 +1,21 @@
1
- import { runAnalysis, type RunAnalysis } from "../analysis.ts";
2
- import { listing } from "../components.ts";
1
+ import { EXIT_CLEAN, EXIT_USAGE } from "../contract/contract.generated.ts";
2
+ import { productionMode, runAnalysis, type RunAnalysis } from "../analysis.ts";
3
+ import { listing } from "../liveness/components.ts";
3
4
  import type { Cascade } from "../config.ts";
4
- import { ConfigError } from "../config.ts";
5
5
  import type { CompletedFinding } from "../finding.ts";
6
- import { OUTSIDE, swept as judged } from "../graph.ts";
6
+ import { swept as judged, type Edge, type Graph } from "../liveness/graph.ts";
7
+ import type { Origin } from "../liveness/sweep.ts";
7
8
  import type { InventorySymbol } from "../inventory.ts";
8
- import { referenceKey, type Configured } from "../matrix.ts";
9
9
  import { partialNotes } from "../partial.ts";
10
10
  import { resolvePath } from "../paths.ts";
11
11
  import { positionKey } from "../position.ts";
12
12
  import type { Reference } from "../references.ts";
13
+ import { madeByTestCode } from "../tests/file-class.ts";
13
14
  import { resolve } from "../resolve.ts";
14
- import type { Root } from "../roots.ts";
15
- import { EXIT_CLEAN, EXIT_USAGE, type Verb, type VerbOptions } from "./verb.ts";
15
+ import { type Verb, type VerbOptions } from "./verb.ts";
16
+ import { UsageError } from "../usage.ts";
17
+ import { bytewise } from "../text/compare.ts";
18
+ import { diagnose } from "../product.ts";
16
19
 
17
20
  /**
18
21
  * The three spellings of an explanation request, each naming the symbol to explain. They are
@@ -44,16 +47,12 @@ function namedSymbol(option: (name: string) => string | undefined): string {
44
47
  });
45
48
  const [only, ...more] = named;
46
49
  if (only === undefined) {
47
- throw new ConfigError(
48
- "malformed",
49
- "",
50
+ throw new UsageError(
50
51
  "explain explains the symbol --why, --why-live or --why-not names, and none was named",
51
52
  );
52
53
  }
53
54
  if (more.length > 0) {
54
- throw new ConfigError(
55
- "malformed",
56
- "",
55
+ throw new UsageError(
57
56
  `explain explains one symbol, and ${named.map((one) => `--${one.name}`).join(", ")} each name one`,
58
57
  );
59
58
  }
@@ -101,141 +100,32 @@ function subjectOf(
101
100
  symbol.ref.toLowerCase().includes(folded) || symbol.name.toLowerCase().includes(folded),
102
101
  )
103
102
  .map(described)
104
- .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
103
+ .sort(bytewise);
105
104
  return { candidates: partial.slice(0, MAX_PARTIAL_MATCHES) };
106
105
  }
107
106
 
108
- /** Every reference of the run once, a reference several configurations make counted once. */
109
- function referencesOf(configured: readonly Configured[]): readonly Reference[] {
110
- const seen = new Set<string>();
111
- const held: Reference[] = [];
112
- for (const reference of configured.flatMap((one) => one.references)) {
113
- const key = referenceKey(reference);
114
- if (!seen.has(key)) {
115
- seen.add(key);
116
- held.push(reference);
117
- }
118
- }
119
- return held;
120
- }
121
-
122
- /** Every root of the run once per reason, in the order the projects name them. */
123
- function rootsOf(configured: readonly Configured[]): readonly Root[] {
124
- const seen = new Set<string>();
125
- return configured
126
- .flatMap((one) => one.roots)
127
- .filter((root) => {
128
- const key = [root.id, root.kind, root.source].join("\u0000");
129
- if (seen.has(key)) {
130
- return false;
131
- }
132
- seen.add(key);
133
- return true;
134
- });
135
- }
136
-
137
- /**
138
- * One step of a path: a reference, or a reference that reads a module and so reaches a
139
- * declaration the module exports.
140
- */
141
- type Hop =
142
- | { readonly k: "reference"; readonly reference: Reference }
143
- | { readonly k: "export"; readonly reference: Reference; readonly to: string };
144
-
145
- /** Where a path starts: a root of the run, or a reference a loaded consumer makes. */
146
- type Origin =
147
- | { readonly k: "root"; readonly root: Root }
148
- | { readonly k: "consumer"; readonly consumer: string };
149
-
150
- /**
151
- * The shortest path from a root or a loaded consumer to one declaration, walked breadth first
152
- * from every root at once in the order the run names them, a consumer's reference being the
153
- * first hop of a path of its own, and following the references the sweep follows: a
154
- * reference that reads a module reaches what the module exports, and an evaluation or a root
155
- * reaches the module alone. Under `production` no reference a test file made is followed,
156
- * which is the set the report's sweep counts.
157
- */
158
- function shortestPath(
159
- analysis: RunAnalysis,
160
- to: string,
161
- production: boolean,
162
- ): { readonly origin: Origin; readonly path: readonly Hop[] } | undefined {
163
- const graph = analysis.swept.matrix.union;
164
- const out = new Map<string, Reference[]>();
165
- const consumed: (Reference & { readonly consumer: string })[] = [];
166
- for (const reference of referencesOf(analysis.configured)) {
167
- if (production && reference.test) {
168
- continue;
169
- }
170
- const { consumer } = reference;
171
- if (consumer !== undefined) {
172
- consumed.push({ ...reference, consumer });
173
- continue;
174
- }
175
- const held = out.get(reference.from);
176
- if (held === undefined) {
177
- out.set(reference.from, [reference]);
178
- } else {
179
- held.push(reference);
180
- }
181
- }
182
- interface Step {
183
- readonly at: string;
184
- readonly hop: Hop | undefined;
185
- readonly previous: number;
186
- readonly origin: Origin;
187
- }
188
- const steps: Step[] = [];
189
- const seen = new Set<string>();
190
- const expanded = new Set<string>();
191
- const enter = (step: Step): void => {
192
- if (!seen.has(step.at)) {
193
- seen.add(step.at);
194
- steps.push(step);
195
- }
196
- };
197
- const follow = (reference: Reference, previous: number, origin: Origin): void => {
198
- enter({ at: reference.to, hop: { k: "reference", reference }, previous, origin });
199
- const target = graph.at(reference.to);
200
- if (reference.use === "evaluation" || target === OUTSIDE || expanded.has(reference.to)) {
201
- return;
202
- }
203
- expanded.add(reference.to);
204
- for (const exported of graph.exportsOf[target] ?? []) {
205
- const id = graph.symbols[exported]?.id;
206
- if (id !== undefined) {
207
- enter({ at: id, hop: { k: "export", reference, to: id }, previous, origin });
208
- }
209
- }
210
- };
211
- for (const root of rootsOf(analysis.configured)) {
212
- enter({ at: root.id, hop: undefined, previous: -1, origin: { k: "root", root } });
213
- }
214
- // A consumer's reference is one hop long, so it joins the walk where the roots' first
215
- // hops do.
216
- const firstHops = steps.length;
217
- for (let head = 0; ; head += 1) {
218
- if (head === firstHops) {
219
- for (const reference of consumed) {
220
- follow(reference, -1, { k: "consumer", consumer: reference.consumer });
221
- }
222
- }
223
- const step = steps[head];
224
- if (step === undefined) {
225
- break;
226
- }
227
- if (step.at === to) {
228
- const path: Hop[] = [];
229
- for (let at: Step | undefined = step; at?.hop !== undefined; at = steps[at.previous]) {
230
- path.unshift(at.hop);
107
+ /** Where a path starts, as a line names it. */
108
+ function originText(origin: Origin, graph: Graph): string {
109
+ const id = (at: number): string => graph.symbols[at]?.id ?? "";
110
+ switch (origin.k) {
111
+ case "root":
112
+ return `root ${origin.rooted.kind} ${id(origin.rooted.at)}`;
113
+ case "consumed": {
114
+ const reference = graph.references[origin.edge.reference];
115
+ if (reference?.consumer !== undefined) {
116
+ return `consumer ${reference.consumer}`;
231
117
  }
232
- return { origin: step.origin, path };
233
- }
234
- for (const reference of out.get(step.at) ?? []) {
235
- follow(reference, head, step.origin);
118
+ return reference?.unheld === true
119
+ ? `test file no project holds ${reference.from.replace(/#$/u, "")}`
120
+ : `declaration no configuration judges ${reference?.from ?? ""}`;
236
121
  }
122
+ case "exemption":
123
+ return `exemption ${origin.record.class} ${positionKey(origin.record.site)}`;
124
+ case "mark":
125
+ return `suppression of ${id(origin.at)}`;
126
+ case "unanswered":
127
+ return `unanswered question about ${id(origin.at)}`;
237
128
  }
238
- return undefined;
239
129
  }
240
130
 
241
131
  /** What made a reference: a declaration of the target, or a loaded consumer. */
@@ -243,39 +133,74 @@ function madeBy(reference: Reference): string {
243
133
  return reference.consumer === undefined ? reference.from : `consumer ${reference.consumer}`;
244
134
  }
245
135
 
246
- function referenceLine(reference: Reference, tail: string): string {
247
- return ` reference: ${positionKey(reference.position)}\t${reference.use}\t${tail}${reference.test ? "\tfrom a test file" : ""}\n`;
136
+ /**
137
+ * One reference of an answer, marked where test code made it, a test-support file's included,
138
+ * and naming the configurations that make it where they are not every one of the run.
139
+ */
140
+ function referenceLine(
141
+ reference: Reference,
142
+ tail: string,
143
+ support: ReadonlySet<string>,
144
+ configurations: { readonly making: readonly string[]; readonly run: readonly string[] },
145
+ ): string {
146
+ const partial = configurations.making.length < configurations.run.length;
147
+ return ` reference: ${positionKey(reference.position)}\t${reference.use}\t${tail}${madeByTestCode(reference, support) ? "\tfrom a test file" : ""}${partial ? `\tmade in ${configurations.making.join(" ")}` : ""}\n`;
248
148
  }
249
149
 
250
150
  /** Why a declaration no finding names and no exemption held back is live, or how it fell. */
251
151
  function liveness(analysis: RunAnalysis, subject: InventorySymbol, cascade: Cascade): string {
252
- const { sweep } = analysis.swept;
152
+ const { matrix, sweep } = analysis.swept;
153
+ const graph = matrix.union;
253
154
  const candidate = sweep.candidates.find((one) => one.id === subject.id);
254
155
  if (candidate === undefined && !judged(subject.kind)) {
255
156
  return `answer: unjudged\n unjudged: neither liveness relation judges a ${subject.kind}\n`;
256
157
  }
257
158
  let text = `answer: ${candidate === undefined ? "live" : "dead"}\n`;
258
159
  text += ` live under: ${listed(sweep.liveUnder.get(subject.id) ?? [])}\n`;
259
- for (const root of rootsOf(analysis.configured).filter((one) => one.id === subject.id)) {
260
- text += ` root: ${root.kind}${root.source === "" ? "" : `\tnamed by ${root.source}`}\n`;
160
+ const at = graph.at(subject.id);
161
+ const seen = new Set<string>();
162
+ for (const root of graph.rooted.filter((one) => one.at === at)) {
163
+ const key = `${root.kind}\u0000${root.source}`;
164
+ if (!seen.has(key)) {
165
+ seen.add(key);
166
+ text += ` root: ${root.kind}${root.source === "" ? "" : `\tnamed by ${root.source}`}\n`;
167
+ }
261
168
  }
262
- const found =
263
- shortestPath(analysis, subject.id, true) ?? shortestPath(analysis, subject.id, false);
264
- if (found !== undefined && found.path.length > 0) {
265
- const { origin } = found;
266
- text += ` reached from: ${origin.k === "root" ? `root ${origin.root.kind} ${origin.root.id}` : `consumer ${origin.consumer}`}\n`;
267
- for (const hop of found.path) {
268
- text += referenceLine(hop.reference, `${madeBy(hop.reference)} -> ${hop.reference.to}`);
169
+ const support = new Set(analysis.configured.flatMap((one) => one.supportFiles ?? []));
170
+ const line = (edge: Edge, tail: (reference: Reference) => string): string => {
171
+ const reference = graph.references[edge.reference];
172
+ return reference === undefined
173
+ ? ""
174
+ : referenceLine(reference, tail(reference), support, {
175
+ making: graph.configurations[edge.reference] ?? [],
176
+ run: matrix.configurations,
177
+ });
178
+ };
179
+ const found = sweep.path(subject.id);
180
+ if (found !== undefined && found.hops.length > 0) {
181
+ text += ` reached from: ${originText(found.origin, graph)}\n`;
182
+ for (const hop of found.hops) {
183
+ text += line(hop.edge, (reference) => `${madeBy(reference)} -> ${reference.to}`);
269
184
  if (hop.k === "export") {
270
- text += ` export: ${hop.reference.to} -> ${hop.to}\n`;
185
+ const reference = graph.references[hop.edge.reference];
186
+ text += ` export: ${reference?.to ?? ""} -> ${graph.symbols[hop.to]?.id ?? ""}\n`;
271
187
  }
272
188
  }
273
189
  } else if (found === undefined) {
274
- const references = referencesOf(analysis.configured).filter((one) => one.to === subject.id);
275
- text += " unreachable: no path of references reaches it from a root or a loaded consumer\n";
190
+ const references = graph.references.flatMap((one, place) =>
191
+ one.to === subject.id ? [place] : [],
192
+ );
193
+ text +=
194
+ " unreachable: no path of references reaches it from a root, a loaded consumer or a test file no project holds\n";
276
195
  text += ` references: ${String(references.length)}\n`;
277
- for (const reference of references) {
278
- text += referenceLine(reference, `from ${madeBy(reference)}`);
196
+ for (const place of references) {
197
+ const reference = graph.references[place];
198
+ if (reference !== undefined) {
199
+ text += referenceLine(reference, `from ${madeBy(reference)}`, support, {
200
+ making: graph.configurations[place] ?? [],
201
+ run: matrix.configurations,
202
+ });
203
+ }
279
204
  }
280
205
  }
281
206
  if (candidate !== undefined) {
@@ -341,7 +266,7 @@ function explanation(analysis: RunAnalysis, subject: InventorySymbol, cascade: C
341
266
  text += `position: ${subject.id}\n`;
342
267
  text += `configurations: ${listed(analysis.swept.matrix.heldIn[at] ?? [])}\n`;
343
268
  const found = analysis.result.findings.find((one) => positionKey(one.position) === subject.id);
344
- const retained = analysis.swept.retained.filter((one) => one.id === subject.id);
269
+ const retained = analysis.swept.sweep.retained.filter((one) => one.id === subject.id);
345
270
  if (found !== undefined) {
346
271
  text += reported(found);
347
272
  } else if (retained.length > 0) {
@@ -349,7 +274,7 @@ function explanation(analysis: RunAnalysis, subject: InventorySymbol, cascade: C
349
274
  for (const one of retained) {
350
275
  text += ` class: ${one.class}\t${positionKey(one.site)}\t${one.detail}\n`;
351
276
  }
352
- } else if (analysis.swept.heldByUnanswered.includes(subject.id)) {
277
+ } else if (analysis.swept.sweep.held.includes(subject.id)) {
353
278
  text +=
354
279
  "answer: held\n held by: a question the checker did not answer, which could have kept it live, so no finding names it\n";
355
280
  } else {
@@ -361,18 +286,17 @@ function explanation(analysis: RunAnalysis, subject: InventorySymbol, cascade: C
361
286
  /**
362
287
  * Explains one symbol from the analysis the report is built from: why a reported symbol is
363
288
  * reported, which exemption classes held a retained one back, that an unanswered question held
364
- * a held one, and for any other declaration the relations that hold it live and the shortest
365
- * path from a root or a loaded consumer, or the references it has where no path reaches it. A
366
- * request naming no one declaration exits with the usage code and names what partially
289
+ * a held one, and for any other declaration the relations that hold it live and the path the
290
+ * sweep's strongest tier reaching it follows, or the references it has where no path reaches
291
+ * it. A request naming no one declaration exits with the usage code and names what partially
367
292
  * matches it. Where the analysis was partial, the error stream says so.
368
293
  */
369
294
  export const explainVerb: Verb = ({ out, err, host, inputs, scope, openClient, option }) => {
370
295
  const named = namedSymbol(option);
371
296
  const { config, provenance } = resolve(inputs());
372
297
  const scoped = scope();
373
- const analysis = runAnalysis(openClient(config), host, scoped, config, provenance, {
374
- production: true,
375
- });
298
+ const mode = productionMode(config);
299
+ const analysis = runAnalysis(openClient(config), host, scoped, config, provenance, mode);
376
300
  const { subject, candidates } = subjectOf(analysis.swept.matrix.union.symbols, named);
377
301
  const notes = partialNotes({
378
302
  notBuilt: analysis.run.notBuilt,
@@ -380,7 +304,7 @@ export const explainVerb: Verb = ({ out, err, host, inputs, scope, openClient, o
380
304
  targetRoot: resolvePath(host.workingDirectory(), scoped.target.path),
381
305
  });
382
306
  if (subject === undefined) {
383
- err.write(`deadset-ts: ${JSON.stringify(named)} names no one symbol of the target\n`);
307
+ diagnose(err, `${JSON.stringify(named)} names no one symbol of the target`);
384
308
  for (const candidate of candidates) {
385
309
  err.write(` ${candidate}\n`);
386
310
  }
@@ -391,7 +315,7 @@ export const explainVerb: Verb = ({ out, err, host, inputs, scope, openClient, o
391
315
  out.write(explanation(analysis, subject, config.reporters.cascade));
392
316
  }
393
317
  for (const note of notes) {
394
- err.write(`deadset-ts: ${note}\n`);
318
+ diagnose(err, note);
395
319
  }
396
320
  return subject === undefined ? EXIT_USAGE : EXIT_CLEAN;
397
321
  };
@@ -1,6 +1,7 @@
1
+ import { EXIT_CLEAN } from "../contract/contract.generated.ts";
1
2
  import { printConfig } from "../print.ts";
2
3
  import { resolve } from "../resolve.ts";
3
- import { EXIT_CLEAN, type Verb } from "./verb.ts";
4
+ import { type Verb } from "./verb.ts";
4
5
 
5
6
  /** Writes the resolved configuration with the source of every setting. */
6
7
  export const printConfigVerb: Verb = ({ out, inputs }) => {
@@ -1,8 +1,10 @@
1
+ import { EXIT_CLEAN } from "../contract/contract.generated.ts";
1
2
  import { runProjects } from "../analysis.ts";
2
3
  import { partialNotes } from "../partial.ts";
3
4
  import { resolvePath } from "../paths.ts";
4
- import { resolveUnkinded } from "../resolve.ts";
5
- import { EXIT_CLEAN, type Verb } from "./verb.ts";
5
+ import { resolvePartial } from "../resolve.ts";
6
+ import { type Verb } from "./verb.ts";
7
+ import { diagnose } from "../product.ts";
6
8
 
7
9
  /**
8
10
  * Writes the name of every project one run analyzes, one per line: the identifier the
@@ -12,7 +14,7 @@ import { EXIT_CLEAN, type Verb } from "./verb.ts";
12
14
  * instead, and one that fails the analysis fails this command the same way.
13
15
  */
14
16
  export const printProjectsVerb: Verb = ({ out, err, host, inputs, scope, openClient }) => {
15
- const config = resolveUnkinded(inputs());
17
+ const config = resolvePartial(inputs());
16
18
  const scoped = scope();
17
19
  const answer = runProjects(openClient(config), host, scoped, config);
18
20
  for (const id of answer.configurations) {
@@ -23,7 +25,7 @@ export const printProjectsVerb: Verb = ({ out, err, host, inputs, scope, openCli
23
25
  unanswered: answer.unanswered,
24
26
  targetRoot: resolvePath(host.workingDirectory(), scoped.target.path),
25
27
  })) {
26
- err.write(`deadset-ts: ${note}\n`);
28
+ diagnose(err, note);
27
29
  }
28
30
  return EXIT_CLEAN;
29
31
  };
@@ -1,9 +1,39 @@
1
- import { runSweep } from "../analysis.ts";
2
- import { retainedLines } from "../exempt.ts";
1
+ import { EXIT_CLEAN } from "../contract/contract.generated.ts";
2
+ import { productionMode, runSweep } from "../analysis.ts";
3
+ import type { Exemption } from "../exemptions/lifecycle.ts";
4
+ import type { InventorySymbol } from "../inventory.ts";
3
5
  import { partialNotes } from "../partial.ts";
6
+ import { positionKey } from "../position.ts";
4
7
  import { resolvePath } from "../paths.ts";
5
8
  import { resolve } from "../resolve.ts";
6
- import { EXIT_CLEAN, type Verb } from "./verb.ts";
9
+ import { type Verb } from "./verb.ts";
10
+ import { diagnose } from "../product.ts";
11
+
12
+ /**
13
+ * One line per held-back declaration, in site order: its reference and position, then
14
+ * each record's class, site and detail, all separated by tabs.
15
+ */
16
+ function retainedLines(
17
+ symbols: readonly InventorySymbol[],
18
+ retained: readonly Exemption[],
19
+ ): readonly string[] {
20
+ const held = new Map<string, Exemption[]>();
21
+ for (const record of retained) {
22
+ held.set(record.id, [...(held.get(record.id) ?? []), record]);
23
+ }
24
+ return symbols.flatMap((symbol) => {
25
+ const records = held.get(symbol.id);
26
+ if (records === undefined) {
27
+ return [];
28
+ }
29
+ const fields = records.flatMap((record) => [
30
+ record.class,
31
+ positionKey(record.site),
32
+ record.detail,
33
+ ]);
34
+ return [[symbol.ref, positionKey(symbol.position), ...fields].join("\t")];
35
+ });
36
+ }
7
37
 
8
38
  /**
9
39
  * Writes every declaration an exemption held back in the production sweep a report is
@@ -17,9 +47,9 @@ export const printRetainedVerb: Verb = ({ out, err, host, inputs, scope, openCli
17
47
  const scoped = scope();
18
48
  const swept = runSweep(openClient(config), host, scoped, config, {
19
49
  marked: [],
20
- mode: { production: true },
50
+ mode: productionMode(config),
21
51
  });
22
- for (const line of retainedLines(swept.matrix.union.symbols, swept.retained)) {
52
+ for (const line of retainedLines(swept.matrix.union.symbols, swept.sweep.retained)) {
23
53
  out.write(`${line}\n`);
24
54
  }
25
55
  for (const note of partialNotes({
@@ -27,7 +57,7 @@ export const printRetainedVerb: Verb = ({ out, err, host, inputs, scope, openCli
27
57
  unanswered: swept.unanswered,
28
58
  targetRoot: resolvePath(host.workingDirectory(), scoped.target.path),
29
59
  })) {
30
- err.write(`deadset-ts: ${note}\n`);
60
+ diagnose(err, note);
31
61
  }
32
62
  return EXIT_CLEAN;
33
63
  };
@@ -1,8 +1,10 @@
1
+ import { EXIT_CLEAN, EXIT_FINDINGS } from "../contract/contract.generated.ts";
1
2
  import { runRoots, type RunRoot } from "../analysis.ts";
2
3
  import { partialNotes } from "../partial.ts";
3
4
  import { resolvePath } from "../paths.ts";
4
5
  import { resolve } from "../resolve.ts";
5
- import { EXIT_CLEAN, EXIT_FINDINGS, type Verb } from "./verb.ts";
6
+ import { type Verb } from "./verb.ts";
7
+ import { diagnose } from "../product.ts";
6
8
 
7
9
  /**
8
10
  * One root as a line: the declaration's reference, why it is a root, and the string
@@ -41,7 +43,7 @@ export const printRootsVerb: Verb = ({ out, err, host, inputs, scope, openClient
41
43
  unanswered: answer.unanswered,
42
44
  targetRoot: resolvePath(host.workingDirectory(), scoped.target.path),
43
45
  })) {
44
- err.write(`deadset-ts: ${note}\n`);
46
+ diagnose(err, note);
45
47
  }
46
48
  return answer.findings.length > 0 ? EXIT_FINDINGS : EXIT_CLEAN;
47
49
  };
package/src/verbs/verb.ts CHANGED
@@ -1,15 +1,9 @@
1
- import type { Config, Inputs } from "../config.ts";
1
+ import type { Inputs, PartialConfig } from "../config.ts";
2
2
  import type { Host } from "../host.ts";
3
3
  import type { Writer } from "../run.ts";
4
4
  import type { Scope } from "../scope.ts";
5
5
  import type { Engine } from "../session.ts";
6
6
 
7
- /** The exit codes the Contract's exit-code table names. */
8
- export const EXIT_CLEAN = 0;
9
- export const EXIT_FINDINGS = 1;
10
- export const EXIT_USAGE = 2;
11
- export const EXIT_FAILURE = 3;
12
-
13
7
  /**
14
8
  * What one verb is handed: the streams it writes, the platform it reads, and the
15
9
  * options that follow its name, read only when the verb asks for what they name, so
@@ -27,7 +21,7 @@ interface Invocation {
27
21
  * Opens the compiler client for a run under `config`. A client the verb opened is
28
22
  * closed if the verb throws.
29
23
  */
30
- readonly openClient: (config: Config) => Engine;
24
+ readonly openClient: (config: PartialConfig) => Engine;
31
25
  /** The arguments after the verb's name, as written. */
32
26
  readonly args: readonly string[];
33
27
  /** The last value one of the verb's own options was given, undefined where none was. */
@@ -1,8 +1,20 @@
1
- import { CONTRACT_VERSION } from "../version.ts";
2
- import { EXIT_CLEAN, type Verb } from "./verb.ts";
1
+ import { CONTRACT_VERSION, EXIT_CLEAN } from "../contract/contract.generated.ts";
2
+ import { productFault } from "../failure.ts";
3
+ import type { Host } from "../host.ts";
4
+ import { type Verb } from "./verb.ts";
5
+ import { message, PRODUCT } from "../product.ts";
6
+
7
+ /** The version the host reports for this analyzer; one it cannot read is a fault of the analyzer. */
8
+ export function ownVersion(host: Host): string {
9
+ try {
10
+ return host.analyzerVersion();
11
+ } catch (error: unknown) {
12
+ throw productFault(`cannot read its own version: ${message(error)}`);
13
+ }
14
+ }
3
15
 
4
16
  /** Writes the version the host reports and the Contract version this analyzer implements. */
5
17
  export const versionVerb: Verb = ({ out, host }) => {
6
- out.write(`deadset-ts ${host.analyzerVersion()}\ncontract ${CONTRACT_VERSION}\n`);
18
+ out.write(`${PRODUCT} ${ownVersion(host)}\ncontract ${CONTRACT_VERSION}\n`);
7
19
  return EXIT_CLEAN;
8
20
  };
@@ -1,18 +0,0 @@
1
- import { resolvePath } from "./paths.js";
2
- /**
3
- * The `paths` one configuration's resolved options map under the compilers before version
4
- * 7, each target absolute: a target is read against the effective `baseUrl`, and a specifier
5
- * no other pattern maps is looked up below it. Undefined where no `baseUrl` is set, so the
6
- * options' own `paths` stand. Version 7 reads no `baseUrl`:
7
- * https://github.com/microsoft/TypeScript/issues/62207
8
- */
9
- export function baseUrlPaths(options) {
10
- const baseUrl = Reflect.get(options, "baseUrl");
11
- if (typeof baseUrl !== "string") {
12
- return undefined;
13
- }
14
- return Object.fromEntries(Object.entries({ "*": ["*"], ...options.paths }).map(([key, targets]) => [
15
- key,
16
- targets.map((target) => resolvePath(baseUrl, target)),
17
- ]));
18
- }