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

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 (402) 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 +2 -7
  6. package/dist/src/amd.js +81 -0
  7. package/dist/src/analysis.js +269 -432
  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/calls.js +279 -43
  12. package/dist/src/commands/held.js +499 -0
  13. package/dist/src/commands/read.js +161 -0
  14. package/dist/src/commands/shell.js +169 -0
  15. package/dist/src/commands/tools.js +1847 -0
  16. package/dist/src/component-files.js +3 -2
  17. package/dist/src/component-layer.js +4 -2
  18. package/dist/src/config.js +6 -82
  19. package/dist/src/conformance-record.js +1 -1
  20. package/dist/src/consumers.js +10 -38
  21. package/dist/src/contextual-uses.js +57 -26
  22. package/dist/src/contract/config.generated.js +561 -0
  23. package/dist/src/contract/contract.generated.js +1369 -0
  24. package/dist/src/contract/report.generated.js +866 -0
  25. package/dist/src/dependencies.js +164 -121
  26. package/dist/src/destructuring.js +1 -19
  27. package/dist/src/edges.js +38 -122
  28. package/dist/src/element-access.js +181 -168
  29. package/dist/src/entries/build-scripts.js +222 -0
  30. package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
  31. package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
  32. package/dist/src/entries/conventions.js +740 -0
  33. package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
  34. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
  35. package/dist/src/entries/run-directories.js +77 -0
  36. package/dist/src/entries/sources.js +144 -0
  37. package/dist/src/entries/static-module.js +670 -0
  38. package/dist/src/entries/test-runners.js +650 -0
  39. package/dist/src/entries/workflow-steps.js +345 -0
  40. package/dist/src/enum-group.js +3 -10
  41. package/dist/src/erased-stores.js +4 -6
  42. package/dist/src/exempt-classes.js +1 -63
  43. package/dist/src/exempt.js +21 -66
  44. package/dist/src/exposure.js +400 -0
  45. package/dist/src/extensions.js +37 -0
  46. package/dist/src/facts.js +38 -0
  47. package/dist/src/failure.js +36 -0
  48. package/dist/src/file-facts.js +3 -26
  49. package/dist/src/findings/completion.js +109 -56
  50. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  51. package/dist/src/findings/emitters.js +27 -41
  52. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  53. package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
  54. package/dist/src/findings/interfaces.js +4 -5
  55. package/dist/src/findings/intra-function.js +16 -13
  56. package/dist/src/findings/non-code-artifacts.js +17 -12
  57. package/dist/src/findings/reads-and-writes.js +86 -27
  58. package/dist/src/findings/self-check.js +44 -30
  59. package/dist/src/findings/unused-declarations.js +29 -45
  60. package/dist/src/findings/visibility-narrowing.js +23 -31
  61. package/dist/src/findings-pass.js +13 -21
  62. package/dist/src/framework-lifecycle.js +46 -19
  63. package/dist/src/fs/document.js +52 -0
  64. package/dist/src/fs/manifest.js +67 -0
  65. package/dist/src/fs/tree.js +88 -0
  66. package/dist/src/generated-file.js +174 -28
  67. package/dist/src/git-ignore.js +39 -26
  68. package/dist/src/import-bindings.js +73 -28
  69. package/dist/src/index/sites.js +557 -0
  70. package/dist/src/index.js +2 -2
  71. package/dist/src/indexed-access.js +523 -478
  72. package/dist/src/injection-container.js +2 -2
  73. package/dist/src/interface-satisfaction.js +1 -1
  74. package/dist/src/intra-function-parts.js +63 -43
  75. package/dist/src/inventory/commonjs.js +507 -0
  76. package/dist/src/inventory/enumerate.js +167 -0
  77. package/dist/src/inventory/syntax.js +236 -0
  78. package/dist/src/inventory.js +323 -724
  79. package/dist/src/javascript-file.js +48 -0
  80. package/dist/src/json-document.js +198 -67
  81. package/dist/src/keyof-comparisons.js +126 -107
  82. package/dist/src/kinds.js +3 -366
  83. package/dist/src/{components.js → liveness/components.js} +2 -3
  84. package/dist/src/{graph.js → liveness/graph.js} +52 -28
  85. package/dist/src/liveness/matrix.js +99 -0
  86. package/dist/src/liveness/sweep.js +558 -0
  87. package/dist/src/load/classify.js +289 -0
  88. package/dist/src/load/diagnostics.js +87 -0
  89. package/dist/src/load/discover.js +285 -0
  90. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  91. package/dist/src/load/expected-module.js +136 -0
  92. package/dist/src/load/load.js +27 -0
  93. package/dist/src/load/module-lookup.js +37 -0
  94. package/dist/src/load/package-scope.js +56 -0
  95. package/dist/src/load/plan.js +313 -0
  96. package/dist/src/load/specifiers.js +113 -0
  97. package/dist/src/load/synthesize.js +152 -0
  98. package/dist/src/load/test-globals.js +207 -0
  99. package/dist/src/load/test-joins.js +82 -0
  100. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  101. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  102. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
  103. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  104. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  105. package/dist/src/module-declarations.js +70 -85
  106. package/dist/src/overrides.js +134 -112
  107. package/dist/src/partial.js +2 -1
  108. package/dist/src/paths.js +82 -16
  109. package/dist/src/platform-calls.js +78 -0
  110. package/dist/src/platform-symbols.js +134 -0
  111. package/dist/src/position.js +43 -1
  112. package/dist/src/print.js +11 -79
  113. package/dist/src/product.js +13 -0
  114. package/dist/src/query.js +47 -0
  115. package/dist/src/ref.js +12 -20
  116. package/dist/src/references/read-rule.js +1 -0
  117. package/dist/src/references/read-rules.js +48 -0
  118. package/dist/src/references/sink.js +237 -0
  119. package/dist/src/references/sources.js +450 -0
  120. package/dist/src/references.js +117 -1074
  121. package/dist/src/report-schema.js +51 -0
  122. package/dist/src/report.js +57 -41
  123. package/dist/src/reporters/annotations.js +15 -8
  124. package/dist/src/reporters/sarif.js +16 -10
  125. package/dist/src/reporters/template.js +4 -19
  126. package/dist/src/resolve.js +246 -730
  127. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
  128. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
  129. package/dist/src/roots/manifest.js +216 -0
  130. package/dist/src/roots/published-reach.js +412 -0
  131. package/dist/src/roots/root-set.js +487 -0
  132. package/dist/src/roots/unseen-loads.js +236 -0
  133. package/dist/src/run.js +66 -77
  134. package/dist/src/schema.js +320 -343
  135. package/dist/src/scope.js +38 -115
  136. package/dist/src/serialization-contract.js +601 -22
  137. package/dist/src/session.js +37 -29
  138. package/dist/src/source-files.js +6 -10
  139. package/dist/src/stores.js +4 -2
  140. package/dist/src/suppress-file.js +25 -28
  141. package/dist/src/suppress-inline.js +36 -83
  142. package/dist/src/suppress.js +50 -71
  143. package/dist/src/symbol-keys.js +92 -88
  144. package/dist/src/template-field.js +9 -19
  145. package/dist/src/tests/file-class.js +76 -0
  146. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  147. package/dist/src/{test-support.js → tests/support.js} +5 -12
  148. package/dist/src/text/compare.js +26 -0
  149. package/dist/src/text/glob.js +194 -0
  150. package/dist/src/text/named-files.js +298 -0
  151. package/dist/src/text/yaml.js +684 -0
  152. package/dist/src/type-errors.js +11 -232
  153. package/dist/src/type-parameter-reads.js +178 -139
  154. package/dist/src/unimplemented-callees.js +262 -242
  155. package/dist/src/unwrap.js +23 -0
  156. package/dist/src/usage.js +10 -0
  157. package/dist/src/vendor/unbash/ansi-c.js +132 -0
  158. package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
  159. package/dist/src/vendor/unbash/arithmetic.js +591 -0
  160. package/dist/src/vendor/unbash/assignment.js +131 -0
  161. package/dist/src/vendor/unbash/chars.js +48 -0
  162. package/dist/src/vendor/unbash/command.js +41 -0
  163. package/dist/src/vendor/unbash/expansion.js +80 -0
  164. package/dist/src/vendor/unbash/glob.js +268 -0
  165. package/dist/src/vendor/unbash/heredoc.js +27 -0
  166. package/dist/src/vendor/unbash/internal-types.js +1 -0
  167. package/dist/src/vendor/unbash/lexer.js +4274 -0
  168. package/dist/src/vendor/unbash/limits.js +3 -0
  169. package/dist/src/vendor/unbash/parser.js +1366 -0
  170. package/dist/src/vendor/unbash/parts.js +57 -0
  171. package/dist/src/vendor/unbash/substitution-context.js +8 -0
  172. package/dist/src/vendor/unbash/traversal.js +212 -0
  173. package/dist/src/vendor/unbash/types.js +1 -0
  174. package/dist/src/vendor/unbash/word-value.js +61 -0
  175. package/dist/src/vendor/unbash/word.js +40 -0
  176. package/dist/src/verbs/analyze.js +194 -127
  177. package/dist/src/verbs/describe.js +13 -18
  178. package/dist/src/verbs/explain.js +85 -139
  179. package/dist/src/verbs/print-config.js +2 -1
  180. package/dist/src/verbs/print-projects.js +6 -4
  181. package/dist/src/verbs/print-retained.js +7 -5
  182. package/dist/src/verbs/print-roots.js +4 -2
  183. package/dist/src/verbs/verb.js +1 -5
  184. package/dist/src/verbs/version.js +14 -3
  185. package/jsr.json +2 -1
  186. package/package.json +14 -8
  187. package/src/alias-chain.ts +2 -9
  188. package/src/amd.ts +130 -0
  189. package/src/analysis.ts +424 -650
  190. package/src/augmentations.ts +93 -4
  191. package/src/automatic-types.ts +12 -30
  192. package/src/bindings.ts +460 -0
  193. package/src/calls.ts +338 -46
  194. package/src/commands/held.ts +632 -0
  195. package/src/commands/read.ts +242 -0
  196. package/src/commands/shell.ts +228 -0
  197. package/src/commands/tools.ts +2382 -0
  198. package/src/component-files.ts +4 -2
  199. package/src/component-layer.ts +4 -2
  200. package/src/config.ts +31 -302
  201. package/src/conformance-record.ts +1 -1
  202. package/src/consumers.ts +16 -66
  203. package/src/contextual-uses.ts +66 -34
  204. package/src/contract/config.generated.ts +821 -0
  205. package/src/contract/contract.generated.ts +1452 -0
  206. package/src/contract/report.generated.ts +1241 -0
  207. package/src/dependencies.ts +222 -127
  208. package/src/destructuring.ts +1 -31
  209. package/src/edges.ts +41 -140
  210. package/src/element-access.ts +190 -187
  211. package/src/entries/build-scripts.ts +292 -0
  212. package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
  213. package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
  214. package/src/{conventions.ts → entries/conventions.ts} +367 -583
  215. package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
  216. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
  217. package/src/entries/run-directories.ts +108 -0
  218. package/src/entries/sources.ts +266 -0
  219. package/src/entries/static-module.ts +858 -0
  220. package/src/entries/test-runners.ts +835 -0
  221. package/src/entries/workflow-steps.ts +432 -0
  222. package/src/enum-group.ts +2 -11
  223. package/src/erased-stores.ts +3 -7
  224. package/src/exempt-classes.ts +1 -75
  225. package/src/exempt.ts +70 -98
  226. package/src/exposure.ts +492 -0
  227. package/src/extensions.ts +45 -0
  228. package/src/facts.ts +46 -0
  229. package/src/failure.ts +63 -0
  230. package/src/file-facts.ts +15 -25
  231. package/src/finding.ts +10 -10
  232. package/src/findings/boundary.ts +11 -0
  233. package/src/findings/completion.ts +133 -64
  234. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  235. package/src/findings/emitter.ts +9 -10
  236. package/src/findings/emitters.ts +38 -52
  237. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  238. package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
  239. package/src/findings/interfaces.ts +7 -9
  240. package/src/findings/intra-function.ts +16 -14
  241. package/src/findings/non-code-artifacts.ts +24 -15
  242. package/src/findings/reads-and-writes.ts +118 -41
  243. package/src/findings/self-check.ts +51 -38
  244. package/src/findings/unused-declarations.ts +31 -49
  245. package/src/findings/visibility-narrowing.ts +36 -40
  246. package/src/findings-pass.ts +15 -31
  247. package/src/framework-lifecycle.ts +47 -19
  248. package/src/fs/document.ts +70 -0
  249. package/src/fs/manifest.ts +96 -0
  250. package/src/fs/tree.ts +110 -0
  251. package/src/generated-file.ts +242 -35
  252. package/src/git-ignore.ts +50 -26
  253. package/src/host.ts +12 -5
  254. package/src/import-bindings.ts +98 -29
  255. package/src/index/sites.ts +781 -0
  256. package/src/index.ts +2 -2
  257. package/src/indexed-access.ts +570 -527
  258. package/src/injection-container.ts +2 -2
  259. package/src/interface-satisfaction.ts +2 -2
  260. package/src/intra-function-parts.ts +73 -44
  261. package/src/inventory/commonjs.ts +696 -0
  262. package/src/inventory/enumerate.ts +203 -0
  263. package/src/inventory/syntax.ts +311 -0
  264. package/src/inventory.ts +442 -895
  265. package/src/javascript-file.ts +54 -0
  266. package/src/json-document.ts +241 -76
  267. package/src/keyof-comparisons.ts +133 -122
  268. package/src/kinds.ts +5 -413
  269. package/src/{components.ts → liveness/components.ts} +4 -6
  270. package/src/{graph.ts → liveness/graph.ts} +100 -35
  271. package/src/liveness/matrix.ts +162 -0
  272. package/src/liveness/sweep.ts +855 -0
  273. package/src/load/classify.ts +433 -0
  274. package/src/load/diagnostics.ts +154 -0
  275. package/src/load/discover.ts +471 -0
  276. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  277. package/src/load/expected-module.ts +194 -0
  278. package/src/load/load.ts +73 -0
  279. package/src/load/module-lookup.ts +50 -0
  280. package/src/load/package-scope.ts +74 -0
  281. package/src/load/plan.ts +513 -0
  282. package/src/load/specifiers.ts +171 -0
  283. package/src/load/synthesize.ts +230 -0
  284. package/src/load/test-globals.ts +251 -0
  285. package/src/load/test-joins.ts +98 -0
  286. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  287. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  288. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
  289. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  290. package/src/{workspace.ts → load/workspace.ts} +90 -134
  291. package/src/module-declarations.ts +74 -98
  292. package/src/overrides.ts +162 -134
  293. package/src/partial.ts +3 -2
  294. package/src/paths.ts +92 -16
  295. package/src/platform-calls.ts +119 -0
  296. package/src/platform-symbols.ts +189 -0
  297. package/src/position.ts +44 -1
  298. package/src/print.ts +12 -92
  299. package/src/product.ts +18 -0
  300. package/src/query.ts +92 -0
  301. package/src/ref.ts +12 -20
  302. package/src/references/read-rule.ts +60 -0
  303. package/src/references/read-rules.ts +55 -0
  304. package/src/references/sink.ts +314 -0
  305. package/src/references/sources.ts +632 -0
  306. package/src/references.ts +187 -1450
  307. package/src/report-schema.ts +68 -0
  308. package/src/report.ts +103 -226
  309. package/src/reporters/annotations.ts +22 -11
  310. package/src/reporters/json.ts +1 -1
  311. package/src/reporters/reporter.ts +2 -4
  312. package/src/reporters/reporters.ts +1 -1
  313. package/src/reporters/sarif.ts +29 -16
  314. package/src/reporters/template.ts +4 -20
  315. package/src/reporters/text.ts +3 -3
  316. package/src/resolve.ts +284 -1115
  317. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +27 -29
  318. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
  319. package/src/roots/manifest.ts +303 -0
  320. package/src/roots/published-reach.ts +486 -0
  321. package/src/{roots.ts → roots/root-set.ts} +286 -469
  322. package/src/roots/unseen-loads.ts +345 -0
  323. package/src/run.ts +75 -91
  324. package/src/schema.ts +391 -388
  325. package/src/scope.ts +46 -138
  326. package/src/serialization-contract.ts +769 -23
  327. package/src/session.ts +87 -55
  328. package/src/source-files.ts +6 -11
  329. package/src/stores.ts +15 -3
  330. package/src/suppress-file.ts +24 -33
  331. package/src/suppress-inline.ts +55 -91
  332. package/src/suppress.ts +78 -79
  333. package/src/symbol-keys.ts +104 -107
  334. package/src/template-field.ts +15 -25
  335. package/src/tests/file-class.ts +135 -0
  336. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  337. package/src/{test-support.ts → tests/support.ts} +15 -21
  338. package/src/text/compare.ts +27 -0
  339. package/src/text/glob.ts +210 -0
  340. package/src/text/named-files.ts +388 -0
  341. package/src/text/yaml.ts +747 -0
  342. package/src/type-errors.ts +18 -288
  343. package/src/type-parameter-reads.ts +187 -158
  344. package/src/unimplemented-callees.ts +297 -280
  345. package/src/unwrap.ts +34 -0
  346. package/src/usage.ts +10 -0
  347. package/src/vendor/unbash/LICENSE +15 -0
  348. package/src/vendor/unbash/VENDORED.md +16 -0
  349. package/src/vendor/unbash/ansi-c.ts +132 -0
  350. package/src/vendor/unbash/arithmetic-parts.ts +53 -0
  351. package/src/vendor/unbash/arithmetic.ts +641 -0
  352. package/src/vendor/unbash/assignment.ts +163 -0
  353. package/src/vendor/unbash/chars.ts +48 -0
  354. package/src/vendor/unbash/command.ts +47 -0
  355. package/src/vendor/unbash/expansion.ts +144 -0
  356. package/src/vendor/unbash/glob.ts +284 -0
  357. package/src/vendor/unbash/heredoc.ts +34 -0
  358. package/src/vendor/unbash/internal-types.ts +94 -0
  359. package/src/vendor/unbash/lexer.ts +4352 -0
  360. package/src/vendor/unbash/limits.ts +3 -0
  361. package/src/vendor/unbash/parser.ts +1612 -0
  362. package/src/vendor/unbash/parts.ts +96 -0
  363. package/src/vendor/unbash/substitution-context.ts +20 -0
  364. package/src/vendor/unbash/traversal.ts +182 -0
  365. package/src/vendor/unbash/types.ts +660 -0
  366. package/src/vendor/unbash/word-value.ts +64 -0
  367. package/src/vendor/unbash/word.ts +50 -0
  368. package/src/verbs/analyze.ts +255 -164
  369. package/src/verbs/describe.ts +19 -17
  370. package/src/verbs/explain.ts +93 -169
  371. package/src/verbs/print-config.ts +2 -1
  372. package/src/verbs/print-projects.ts +6 -4
  373. package/src/verbs/print-retained.ts +7 -5
  374. package/src/verbs/print-roots.ts +4 -2
  375. package/src/verbs/verb.ts +2 -8
  376. package/src/verbs/version.ts +15 -3
  377. package/dist/src/base-url.js +0 -18
  378. package/dist/src/conventions.js +0 -937
  379. package/dist/src/discover.js +0 -468
  380. package/dist/src/entry-points.js +0 -529
  381. package/dist/src/glob.js +0 -65
  382. package/dist/src/manifest.js +0 -165
  383. package/dist/src/matrix.js +0 -246
  384. package/dist/src/pnpm-workspace.js +0 -120
  385. package/dist/src/roots.js +0 -672
  386. package/dist/src/setup-failure.js +0 -23
  387. package/dist/src/sweep.js +0 -224
  388. package/dist/src/test-joins.js +0 -101
  389. package/dist/src/version.js +0 -7
  390. package/dist/src/workflow-steps.js +0 -185
  391. package/src/base-url.ts +0 -24
  392. package/src/discover.ts +0 -653
  393. package/src/entry-points.ts +0 -687
  394. package/src/glob.ts +0 -67
  395. package/src/manifest.ts +0 -234
  396. package/src/matrix.ts +0 -423
  397. package/src/pnpm-workspace.ts +0 -135
  398. package/src/setup-failure.ts +0 -39
  399. package/src/sweep.ts +0 -347
  400. package/src/test-joins.ts +0 -120
  401. package/src/version.ts +0 -7
  402. package/src/workflow-steps.ts +0 -216
@@ -1,36 +1,36 @@
1
- import { runAnalysis, runBaselineWrite, unansweredCounts, } from "../analysis.js";
2
- import { ConfigError, kindOf } from "../config.js";
1
+ import { CONTRACT_VERSION, EXIT_CLEAN } from "../contract/contract.generated.js";
2
+ import { productionMode, runAnalysis, runBaselineWrite, unansweredCounts, } from "../analysis.js";
3
+ import { kindOf } from "../config.js";
3
4
  import { CONFORMANCE, DECLARED_GAPS } from "../conformance.js";
4
- import { moduleIdentity } from "../consumers.js";
5
5
  import { analyzerProvenance, verdictOf } from "../findings-pass.js";
6
- import { joinPath, normalizePath, relativePath, resolvePath } from "../paths.js";
6
+ import { factsDocument } from "../facts.js";
7
+ import { dirnamePath, joinPath, normalizePath, relativePath, resolvePath } from "../paths.js";
8
+ import { moduleIdentity } from "../load/discover.js";
7
9
  import { partialNotes } from "../partial.js";
8
- import { buildReport, LANGUAGE, capFindings, sortFindings, } from "../report.js";
10
+ import { buildReport, capFindings, sortFindings, } from "../report.js";
11
+ import { reportRefusals } from "../report-schema.js";
9
12
  import { json } from "../reporters/json.js";
10
13
  import { RENDERINGS } from "../reporters/reporters.js";
11
14
  import { parseTemplate, TemplateError } from "../reporters/template.js";
12
15
  import { resolve } from "../resolve.js";
13
16
  import { otherSchemeRows, rowReason, writeBaseline } from "../suppress-file.js";
14
- import { CONTRACT_VERSION } from "../version.js";
15
- import { EXIT_CLEAN, EXIT_FAILURE } from "./verb.js";
17
+ import {} from "./verb.js";
18
+ import { UsageError } from "../usage.js";
19
+ import { bytewise } from "../text/compare.js";
20
+ import { productFault, failureExit } from "../failure.js";
21
+ import { diagnose, message } from "../product.js";
22
+ import { ownVersion } from "./version.js";
16
23
  /** The options `analyze` takes beside the ones every verb takes. */
17
24
  export const ANALYZE_OPTIONS = {
18
- plain: ["report", "baseline-write", "exit-code", "template"],
25
+ plain: ["report", "facts", "baseline-write", "exit-code", "template"],
19
26
  repeatable: ["format"],
20
27
  };
21
28
  /** The two values `--exit-code` takes; on, the default, puts the run's verdict in the exit code. */
22
29
  const EXIT_CODE_ON = "on";
23
30
  const EXIT_CODE_OFF = "off";
24
- /** A path of the run no report can name, which ends the run with the failure code. */
25
- class ReportPathError extends Error {
26
- constructor(message) {
27
- super(message);
28
- this.name = "ReportPathError";
29
- }
30
- }
31
31
  /** The formats this analyzer renders, for a message that names them. */
32
32
  function formatNames() {
33
- return [...RENDERINGS.keys()].sort().join(", ");
33
+ return [...RENDERINGS.keys()].sort(bytewise).join(", ");
34
34
  }
35
35
  /** The renderings one invocation writes: the ones it named, else the configuration's. */
36
36
  function formatsOf(named, configured) {
@@ -38,10 +38,10 @@ function formatsOf(named, configured) {
38
38
  const seen = new Set();
39
39
  for (const format of formats) {
40
40
  if (!RENDERINGS.has(format)) {
41
- throw new ConfigError("malformed", "", `${JSON.stringify(format)} is not a format this analyzer renders: the formats are ${formatNames()}`);
41
+ throw new UsageError(`${JSON.stringify(format)} is not a format this analyzer renders: the formats are ${formatNames()}`);
42
42
  }
43
43
  if (seen.has(format)) {
44
- throw new ConfigError("malformed", "", `the format ${JSON.stringify(format)} is named twice`);
44
+ throw new UsageError(`the format ${JSON.stringify(format)} is named twice`);
45
45
  }
46
46
  seen.add(format);
47
47
  }
@@ -58,7 +58,7 @@ function runRelative(invoked, path) {
58
58
  }
59
59
  const below = relativePath(invoked, path);
60
60
  if (below === undefined) {
61
- throw new ReportPathError(`a report names its target relative to the directory the run was invoked from, and ${invoked} does not contain ${path}: run from a directory that does`);
61
+ throw failureExit("unreportable-path", `a report names its target relative to the directory the run was invoked from, and ${invoked} does not contain ${path}: run from a directory that does`);
62
62
  }
63
63
  return below;
64
64
  }
@@ -77,12 +77,76 @@ function unmappedNotes(entries, targetRoot) {
77
77
  };
78
78
  });
79
79
  }
80
+ /**
81
+ * One note per load of a production file the run cannot resolve, each site once: a file
82
+ * it loads is a root the run does not see, so `ts.roots_complete` lifts no cap there.
83
+ */
84
+ function unseenLoadNotes(loads) {
85
+ return [
86
+ ...new Map(loads.map((load) => {
87
+ const { path, line, column } = load.position;
88
+ const site = `${path}:${String(line)}:${String(column)}`;
89
+ const note = {
90
+ kind: "computed-load",
91
+ path: dirnamePath(path),
92
+ message: `${site} loads a module by a computed path the analysis cannot resolve, so the configurations compiling it report what no root reaches at probable at most, whatever ts.roots_complete says`,
93
+ };
94
+ return [site, note];
95
+ })).values(),
96
+ ];
97
+ }
98
+ /** One note per package whose command strings name files a configuration holds, naming every such file. */
99
+ function heldScriptNotes(held, targetRoot) {
100
+ const files = new Map();
101
+ const unwritten = new Set();
102
+ for (const one of held) {
103
+ files.set(one.dir, new Set([...(files.get(one.dir) ?? []), ...one.files]));
104
+ if (one.unwritten) {
105
+ unwritten.add(one.dir);
106
+ }
107
+ }
108
+ return [...files].map(([dir, paths]) => ({
109
+ kind: "unread-command",
110
+ path: relativePath(targetRoot, dir) ?? ".",
111
+ message: [
112
+ ...(paths.size === 0
113
+ ? []
114
+ : [
115
+ `commands the analysis does not read name ${[...paths].sort(bytewise).join(", ")}, so no finding is reported about ${paths.size === 1 ? "that file itself or the names it exports" : "those files themselves or the names they export"}`,
116
+ ]),
117
+ ...(unwritten.has(dir)
118
+ ? [
119
+ "a command runs a file whose path no word of it writes, so a finding that a file of the package is never built or never imported is possible at most",
120
+ ]
121
+ : []),
122
+ ].join("; "),
123
+ }));
124
+ }
125
+ function unresolvedNotes(specifiers) {
126
+ return specifiers.map(({ specifier, position }) => ({
127
+ kind: "unresolved-specifier",
128
+ path: dirnamePath(position.path),
129
+ message: `${position.path}:${String(position.line)}:${String(position.column)} loads ${JSON.stringify(specifier)}, which resolves to no file, so it references nothing`,
130
+ }));
131
+ }
132
+ function unreadLine(input, targetRoot) {
133
+ switch (input.kind) {
134
+ case "manifest": {
135
+ const path = relativePath(targetRoot, input.manifest) ?? input.manifest;
136
+ return input.reason === undefined
137
+ ? `${path} does not parse, so the manifest facts of the program formed for its package are unanswered: correct the manifest`
138
+ : `${path} cannot be read, so the manifest facts of the program formed for its package are unanswered: give the run read access to it: ${input.reason}`;
139
+ }
140
+ case "ignore-file":
141
+ return `${relativePath(targetRoot, input.path) ?? input.path} cannot be read, so the JavaScript files it would ignore are analyzed: ${input.reason}`;
142
+ }
143
+ }
80
144
  /** Each project the run dropped as a report names it, by its configuration file below the target. */
81
145
  function notBuiltOf(dropped, targetRoot) {
82
146
  return dropped.map((one) => {
83
147
  const project = relativePath(targetRoot, one.configFile);
84
148
  if (project === undefined) {
85
- throw new ReportPathError(`the project ${one.id} would be opened from ${one.configFile}, which is not below the target ${targetRoot}, so no report can name it`);
149
+ throw failureExit("unreportable-path", `the project ${one.id} would be opened from ${one.configFile}, which is not below the target ${targetRoot}, so no report can name it: analyze a target that holds it`);
86
150
  }
87
151
  return { id: one.id, project, error: one.error };
88
152
  });
@@ -92,11 +156,24 @@ function configurationsOf(projects, targetRoot) {
92
156
  return projects.map((one) => {
93
157
  const project = relativePath(targetRoot, one.configFile);
94
158
  if (project === undefined) {
95
- throw new ReportPathError(`the project ${one.id} is opened from ${one.configFile}, which is not below the target ${targetRoot}, so no report can name it`);
159
+ throw failureExit("unreportable-path", `the project ${one.id} is opened from ${one.configFile}, which is not below the target ${targetRoot}, so no report can name it: analyze a target that holds it`);
96
160
  }
97
161
  return { id: one.id, project };
98
162
  });
99
163
  }
164
+ /**
165
+ * Writes one document the run was asked for. A document that cannot be produced or written
166
+ * ends the run with the run failure that names it and `fix`, the documents written before it
167
+ * kept.
168
+ */
169
+ function writeDocument(host, path, fix, produce) {
170
+ try {
171
+ host.writeDocument(path, produce());
172
+ }
173
+ catch (error) {
174
+ throw failureExit("unwritten-output", `${path}: ${message(error)}: ${fix}`);
175
+ }
176
+ }
100
177
  /** A count with its noun, so a message reads for one record as well as for several. */
101
178
  function counted(n, noun) {
102
179
  return `${String(n)} ${noun}${n === 1 ? "" : "s"}`;
@@ -109,7 +186,7 @@ function counted(n, noun) {
109
186
  function templateOf(host, invoked, named, formats) {
110
187
  if (named === undefined || named === "") {
111
188
  if (formats.includes("template")) {
112
- throw new ConfigError("malformed", "", "the template format renders the template --template names, and none was named");
189
+ throw new UsageError("the template format renders the template --template names, and none was named");
113
190
  }
114
191
  return undefined;
115
192
  }
@@ -118,7 +195,7 @@ function templateOf(host, invoked, named, formats) {
118
195
  source = host.readFile(resolvePath(invoked, named));
119
196
  }
120
197
  catch (error) {
121
- throw new ConfigError("malformed", "", `--template=${named}: ${error instanceof Error ? error.message : String(error)}`);
198
+ throw new UsageError(`--template=${named}: ${message(error)}`);
122
199
  }
123
200
  try {
124
201
  return parseTemplate(source);
@@ -127,7 +204,7 @@ function templateOf(host, invoked, named, formats) {
127
204
  if (!(error instanceof TemplateError)) {
128
205
  throw error;
129
206
  }
130
- throw new ConfigError("malformed", "", `--template=${named}: ${error.message}`);
207
+ throw new UsageError(`--template=${named}: ${error.message}`);
131
208
  }
132
209
  }
133
210
  /**
@@ -141,144 +218,134 @@ function templateOf(host, invoked, named, formats) {
141
218
  export const analyzeVerb = ({ err, host, inputs, scope, openClient, option, repeated }) => {
142
219
  const reportPath = option("report");
143
220
  if (reportPath === undefined || reportPath === "") {
144
- throw new ConfigError("malformed", "", "analyze writes its report to the path --report names, and no path was named");
221
+ throw new UsageError("analyze writes its report to the path --report names, and no path was named");
145
222
  }
146
223
  const exitCode = option("exit-code") ?? EXIT_CODE_ON;
147
224
  if (exitCode !== EXIT_CODE_ON && exitCode !== EXIT_CODE_OFF) {
148
- throw new ConfigError("malformed", "", `--exit-code=${JSON.stringify(exitCode)}: the values are ${EXIT_CODE_ON} and ${EXIT_CODE_OFF}`);
225
+ throw new UsageError(`--exit-code=${JSON.stringify(exitCode)}: the values are ${EXIT_CODE_ON} and ${EXIT_CODE_OFF}`);
149
226
  }
150
227
  const { config, provenance } = resolve(inputs());
151
- const kind = config.targetKind;
152
- if (kind === "") {
153
- throw new ConfigError("missing-target-kind", "target.kind", "target.kind is not set");
154
- }
155
228
  const invoked = host.workingDirectory();
156
229
  const baseline = option("baseline-write");
230
+ const facts = option("facts");
231
+ if (facts === "") {
232
+ throw new UsageError("--facts names the path the facts document is written to, and named none");
233
+ }
157
234
  const documents = {
158
235
  report: resolvePath(invoked, reportPath),
236
+ facts: facts === undefined ? undefined : resolvePath(invoked, facts),
159
237
  formats: formatsOf(repeated("format"), config.reporters.formats),
160
238
  baseline: baseline === undefined ? undefined : resolvePath(invoked, baseline),
161
239
  };
162
240
  const template = templateOf(host, invoked, option("template"), documents.formats);
163
241
  const scoped = scope();
164
242
  const targetRoot = scoped.target.path;
165
- let version;
166
- try {
167
- version = host.analyzerVersion();
243
+ const version = ownVersion(host);
244
+ let recorded;
245
+ const root = runRelative(invoked, targetRoot);
246
+ const mode = productionMode(config);
247
+ let analysis;
248
+ if (documents.baseline === undefined) {
249
+ analysis = runAnalysis(openClient(config), host, scoped, config, provenance, mode);
250
+ recorded = [];
168
251
  }
169
- catch (error) {
170
- err.write(`deadset-ts: ${error instanceof Error ? error.message : String(error)}\n`);
171
- return EXIT_FAILURE;
252
+ else {
253
+ const reason = rowReason(analyzerProvenance(version));
254
+ const write = runBaselineWrite(openClient(config), host, scoped, config, provenance, mode, reason);
255
+ analysis = write.first;
256
+ recorded = write.rows;
172
257
  }
173
- let report;
174
- let recorded;
175
- let verdict;
176
- let partial;
177
- let warnings;
178
- let unread;
179
- let unfound;
180
- try {
181
- const root = runRelative(invoked, targetRoot);
182
- const mode = { production: true };
183
- let analysis;
184
- if (documents.baseline === undefined) {
185
- analysis = runAnalysis(openClient(config), host, scoped, config, provenance, mode);
186
- recorded = [];
187
- }
188
- else {
189
- const reason = rowReason(analyzerProvenance(version));
190
- const write = runBaselineWrite(openClient(config), host, scoped, config, provenance, mode, reason);
191
- analysis = write.first;
192
- recorded = write.rows;
193
- }
194
- const { result, run } = analysis;
195
- warnings = run.componentWarnings;
196
- unread = run.componentsUnread.map(({ configFile, reason }) => `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: its component files are not read: ${reason}`);
197
- unfound = run.librariesUnfound.map(({ configFile, error }) => `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: ${error}: the configuration is analyzed without that library`);
198
- partial = partialNotes({
199
- notBuilt: run.notBuilt,
200
- unanswered: run.unanswered,
201
- targetRoot: resolvePath(invoked, targetRoot),
202
- });
203
- const built = buildReport({
204
- contractVersion: CONTRACT_VERSION,
205
- version,
206
- conformance: CONFORMANCE,
207
- declaredGaps: DECLARED_GAPS,
208
- target: {
209
- kind: kindOf(kind, LANGUAGE),
210
- root,
211
- identity: moduleIdentity(host, scoped.target),
212
- },
213
- configurations: configurationsOf(run.projects, targetRoot),
214
- notBuilt: notBuiltOf(run.notBuilt, targetRoot),
215
- loaded: run.consumers.map((consumer) => ({
216
- id: consumer.id,
217
- path: runRelative(invoked, consumer.path),
218
- })),
219
- unavailable: [],
220
- result,
221
- testFileRules: run.testFileRules,
222
- typeErrorSkips: run.typeErrorSkips,
223
- unanswered: unansweredCounts(analysis),
224
- conventionsApplied: run.conventionsApplied,
225
- notes: unmappedNotes(run.unmappedEntries, resolvePath(invoked, targetRoot)),
226
- });
227
- report = capFindings(sortFindings(built, config.reporters.sort), config.reporters.maxFindings);
228
- verdict = verdictOf(result, config);
258
+ const { result, run } = analysis;
259
+ const warnings = run.componentWarnings;
260
+ const unread = run.componentsUnread.map(({ configFile, reason }) => `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: its component files are not read: ${reason}`);
261
+ const unfound = run.librariesUnfound.map(({ configFile, error }) => `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: ${error}: the configuration is analyzed without that library`);
262
+ const unreadInputs = run.unread.map((one) => unreadLine(one, resolvePath(invoked, targetRoot)));
263
+ const partial = partialNotes({
264
+ notBuilt: run.notBuilt,
265
+ unanswered: run.unanswered,
266
+ targetRoot: resolvePath(invoked, targetRoot),
267
+ });
268
+ const built = buildReport({
269
+ contractVersion: CONTRACT_VERSION,
270
+ version,
271
+ conformance: CONFORMANCE,
272
+ declaredGaps: DECLARED_GAPS,
273
+ target: {
274
+ kind: kindOf(config.target.kind),
275
+ root,
276
+ identity: moduleIdentity(host, scoped.target),
277
+ },
278
+ configurations: configurationsOf(run.projects, targetRoot),
279
+ notBuilt: notBuiltOf(run.notBuilt, targetRoot),
280
+ loaded: run.consumers.map((consumer) => ({
281
+ id: consumer.id,
282
+ path: runRelative(invoked, consumer.path),
283
+ })),
284
+ unavailable: [],
285
+ result,
286
+ testFileRules: run.testFileRules,
287
+ typeErrorSkips: run.typeErrorSkips,
288
+ unanswered: unansweredCounts(analysis),
289
+ conventionsApplied: run.conventionsApplied,
290
+ listsComponents: config.reporters.cascade === "full",
291
+ notes: [
292
+ ...unmappedNotes(run.unmappedEntries, resolvePath(invoked, targetRoot)),
293
+ ...unseenLoadNotes(run.unseenLoads),
294
+ ...unresolvedNotes(run.unresolvedSpecifiers),
295
+ ...heldScriptNotes(run.heldScripts, resolvePath(invoked, targetRoot)),
296
+ ],
297
+ });
298
+ const report = capFindings(sortFindings(built, config.reporters.sort), config.reporters.max_findings);
299
+ const verdict = verdictOf(result, config);
300
+ const [refused] = reportRefusals(report);
301
+ if (refused !== undefined) {
302
+ throw productFault(`built a report that breaks the report schema at ${refused.pointer || "the document"}: ${refused.keyword}: ${refused.reason}`);
229
303
  }
230
- catch (error) {
231
- if (!(error instanceof ReportPathError)) {
232
- throw error;
233
- }
234
- err.write(`deadset-ts: ${error.message}\n`);
235
- return EXIT_FAILURE;
304
+ writeDocument(host, documents.report, "name a path the run can write", () => json(report));
305
+ const factsPath = documents.facts;
306
+ if (factsPath !== undefined) {
307
+ writeDocument(host, factsPath, "name a path the run can write", () => [
308
+ factsDocument(version, run.generated, run.bindings),
309
+ ]);
236
310
  }
237
- try {
238
- host.writeDocument(documents.report, json(report));
239
- const options = {
240
- failOn: config.reporters.failOn,
241
- readSource: (path) => host.readFile(joinPath(targetRoot, path)),
242
- template,
243
- };
244
- for (const format of documents.formats) {
245
- const rendering = RENDERINGS.get(format);
246
- if (rendering !== undefined) {
247
- host.writeDocument(documents.report + rendering.suffix, rendering.render(report, options));
248
- }
249
- }
250
- if (documents.baseline !== undefined) {
251
- const kept = host.kindOf(documents.baseline) === "file"
252
- ? otherSchemeRows(host.readFile(documents.baseline))
253
- : [];
254
- host.writeDocument(documents.baseline, writeBaseline(recorded, analyzerProvenance(version), kept));
311
+ const options = {
312
+ readSource: (path) => host.readFile(joinPath(targetRoot, path)),
313
+ template,
314
+ };
315
+ for (const format of documents.formats) {
316
+ const rendering = RENDERINGS.get(format);
317
+ if (rendering !== undefined) {
318
+ writeDocument(host, documents.report + rendering.suffix, "name a path the run can write, or correct the template that renders it", () => rendering.render(report, options));
255
319
  }
256
320
  }
257
- catch (error) {
258
- err.write(`deadset-ts: ${error instanceof Error ? error.message : String(error)}\n`);
259
- return EXIT_FAILURE;
321
+ const baselinePath = documents.baseline;
322
+ if (baselinePath !== undefined) {
323
+ writeDocument(host, baselinePath, "name a path the run can write, or repair the rows of the baseline the run would keep", () => {
324
+ const kept = host.kindOf(baselinePath) === "file" ? otherSchemeRows(host.readFile(baselinePath)) : [];
325
+ return writeBaseline(recorded, analyzerProvenance(version), kept);
326
+ });
260
327
  }
261
328
  for (const note of partial) {
262
- err.write(`deadset-ts: ${note}\n`);
329
+ diagnose(err, note);
263
330
  }
264
- for (const line of [...unread, ...unfound]) {
265
- err.write(`deadset-ts: ${line}\n`);
331
+ for (const line of [...unread, ...unfound, ...unreadInputs]) {
332
+ diagnose(err, line);
266
333
  }
267
334
  for (const warning of warnings) {
268
- err.write(`deadset-ts: ${warning.path}:${String(warning.line)}: a <script> start tag that begins a line is not read as a block: ${warning.reason}\n`);
335
+ diagnose(err, `${warning.path}:${String(warning.line)}: a <script> start tag that begins a line is not read as a block: ${warning.reason}`);
269
336
  }
270
337
  for (const skip of report.type_error_skips) {
271
- err.write(`deadset-ts: ${skip.path}:${String(skip.line)}: ${skip.message}: the function or statement holding this type error is not evaluated\n`);
338
+ diagnose(err, `${skip.path}:${String(skip.line)}: ${skip.message}: the function or statement holding this type error is not evaluated`);
272
339
  }
273
340
  if (report.totals.pending > 0) {
274
- err.write(`deadset-ts: ${counted(report.totals.pending, "pending finding")}: the report names a declared cross-language edge, and no merge has resolved it\n`);
341
+ diagnose(err, `${counted(report.totals.pending, "pending finding")}: the report names a declared cross-language edge, and no merge has resolved it`);
275
342
  }
276
343
  if (report.totals.stale_suppressions > 0) {
277
- err.write(`deadset-ts: ${counted(report.totals.stale_suppressions, "stale suppression")}\n`);
344
+ diagnose(err, counted(report.totals.stale_suppressions, "stale suppression"));
278
345
  }
279
346
  if (exitCode === EXIT_CODE_OFF) {
280
347
  if (verdict !== EXIT_CLEAN) {
281
- err.write(`deadset-ts: the exit code is configured off: the verdict of this run is ${String(verdict)}\n`);
348
+ diagnose(err, `the exit code is configured off: the verdict of this run is ${String(verdict)}`);
282
349
  }
283
350
  return EXIT_CLEAN;
284
351
  }
@@ -1,19 +1,22 @@
1
+ import { CONTRACT_VERSION, EXIT_CLEAN, EXIT_USAGE, FACTS_VERSION, SCHEMA_VERSIONS, } from "../contract/contract.generated.js";
1
2
  import { CONFORMANCE } from "../conformance.js";
2
- import { ANALYZER_NAME, LANGUAGE, SCHEMA_VERSIONS_ACCEPTED } from "../report.js";
3
- import { CONTRACT_VERSION } from "../version.js";
4
- import { EXIT_CLEAN, EXIT_FAILURE, EXIT_USAGE } from "./verb.js";
3
+ import {} from "./verb.js";
4
+ import { diagnose, LANGUAGE, PRODUCT } from "../product.js";
5
+ import { ownVersion } from "./version.js";
5
6
  /**
6
7
  * The document `describe` writes: the analyzer, the Contract version it implements, the
7
- * report schema versions it reads, the languages it claims, and its recorded result over
8
- * the conformance corpus, a member the document omits where no run is recorded.
8
+ * report schema versions it reads, the languages it claims, the facts version it writes,
9
+ * and its recorded result over the conformance corpus, a member the document omits where
10
+ * no run is recorded.
9
11
  */
10
12
  export function describeDocument(version, recorded) {
11
13
  const document = {
12
- name: ANALYZER_NAME,
14
+ name: PRODUCT,
13
15
  version,
14
16
  contract_version: CONTRACT_VERSION,
15
- schema_versions_accepted: SCHEMA_VERSIONS_ACCEPTED,
17
+ schema_versions_accepted: SCHEMA_VERSIONS,
16
18
  languages: [LANGUAGE],
19
+ facts_version_written: FACTS_VERSION,
17
20
  ...(recorded === undefined
18
21
  ? {}
19
22
  : {
@@ -26,20 +29,12 @@ export function describeDocument(version, recorded) {
26
29
  };
27
30
  return `${JSON.stringify(document, null, 2)}\n`;
28
31
  }
29
- /** Writes this analyzer's description to the output stream, and nothing to the error stream. */
32
+ /** Writes this analyzer's description to the output stream. */
30
33
  export const describeVerb = ({ out, err, host, args }) => {
31
34
  if (args.length > 0) {
32
- err.write(`deadset-ts: describe takes no argument, got ${JSON.stringify(args[0])}\n`);
35
+ diagnose(err, `describe takes no argument, got ${JSON.stringify(args[0])}`);
33
36
  return EXIT_USAGE;
34
37
  }
35
- let version;
36
- try {
37
- version = host.analyzerVersion();
38
- }
39
- catch (error) {
40
- err.write(`deadset-ts: describe: ${error instanceof Error ? error.message : String(error)}\n`);
41
- return EXIT_FAILURE;
42
- }
43
- out.write(describeDocument(version, CONFORMANCE));
38
+ out.write(describeDocument(ownVersion(host), CONFORMANCE));
44
39
  return EXIT_CLEAN;
45
40
  };