@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
@@ -0,0 +1,50 @@
1
+ // Code generated by scripts/vendor-unbash.ts from unbash 6.0.0 (968c14992a43dc06ce29c9f51858abd4a87851ea). DO NOT EDIT.
2
+ // @ts-nocheck
3
+ import type { Word, WordPart } from "./internal-types.ts";
4
+ import { unescapeBareValue, wordPartsValue } from "./word-value.ts";
5
+
6
+ export type PartsResolver = (source: string, word: Word, depth: number) => WordPart[] | undefined;
7
+
8
+ export class WordImpl implements Word {
9
+ type = "Word" as const;
10
+ text: string;
11
+ pos: number;
12
+ end: number;
13
+ #source: string | undefined;
14
+ #resolver: PartsResolver | undefined;
15
+ #depth: number;
16
+ #parts: WordPart[] | undefined | null;
17
+ #value: string | null = null;
18
+
19
+ constructor(text: string, pos: number, end: number, source?: string, resolver?: PartsResolver, depth = 0) {
20
+ this.text = text;
21
+ this.pos = pos;
22
+ this.end = end;
23
+ this.#source = source;
24
+ this.#resolver = resolver;
25
+ this.#depth = depth;
26
+ this.#parts = resolver === undefined ? undefined : null;
27
+ }
28
+
29
+ get value(): string {
30
+ if (this.#value === null) {
31
+ const parts = this.#source === undefined && this.#parts === null ? undefined : this.parts;
32
+ this.#value = parts ? wordPartsValue(parts) : unescapeBareValue(this.text);
33
+ }
34
+ return this.#value;
35
+ }
36
+
37
+ get parts(): WordPart[] | undefined {
38
+ if (this.#parts === null) {
39
+ this.#parts = this.#resolver?.(this.#source ?? "", this, this.#depth) ?? undefined;
40
+ }
41
+ return this.#parts;
42
+ }
43
+ set parts(v: WordPart[] | undefined) {
44
+ this.#parts = v ?? undefined;
45
+ }
46
+
47
+ toJSON() {
48
+ return { type: this.type, text: this.text, pos: this.pos, end: this.end, parts: this.parts, value: this.value };
49
+ }
50
+ }
@@ -1,41 +1,50 @@
1
+ import { CONTRACT_VERSION, EXIT_CLEAN, type Format } from "../contract/contract.generated.ts";
1
2
  import {
3
+ productionMode,
2
4
  runAnalysis,
3
5
  runBaselineWrite,
4
6
  unansweredCounts,
5
- type ComponentWarning,
6
7
  type RunAnalysis,
7
8
  type RunProject,
8
9
  } from "../analysis.ts";
9
- import { ConfigError, kindOf, type Format } from "../config.ts";
10
+ import { kindOf } from "../config.ts";
10
11
  import { CONFORMANCE, DECLARED_GAPS } from "../conformance.ts";
11
- import { moduleIdentity } from "../consumers.ts";
12
12
  import { analyzerProvenance, verdictOf } from "../findings-pass.ts";
13
- import { joinPath, normalizePath, relativePath, resolvePath } from "../paths.ts";
13
+ import { factsDocument } from "../facts.ts";
14
+ import { dirnamePath, joinPath, normalizePath, relativePath, resolvePath } from "../paths.ts";
14
15
  import type { Host } from "../host.ts";
15
- import type { ManifestEntry } from "../manifest.ts";
16
- import type { NotBuilt } from "../discover.ts";
16
+ import type { ManifestEntry } from "../roots/manifest.ts";
17
+ import type { HeldScripts } from "../roots/root-set.ts";
18
+ import { moduleIdentity, type NotBuilt } from "../load/discover.ts";
17
19
  import { partialNotes } from "../partial.ts";
18
20
  import {
19
21
  buildReport,
20
- LANGUAGE,
21
22
  capFindings,
22
23
  sortFindings,
23
- type Report,
24
24
  type ReportConfiguration,
25
25
  type ReportNotBuilt,
26
26
  type ReportNote,
27
27
  } from "../report.ts";
28
+ import { reportRefusals } from "../report-schema.ts";
28
29
  import { json } from "../reporters/json.ts";
29
30
  import { RENDERINGS } from "../reporters/reporters.ts";
30
31
  import { parseTemplate, TemplateError, type Template } from "../reporters/template.ts";
31
32
  import { resolve } from "../resolve.ts";
32
33
  import { otherSchemeRows, rowReason, writeBaseline, type Recorded } from "../suppress-file.ts";
33
- import { CONTRACT_VERSION } from "../version.ts";
34
- import { EXIT_CLEAN, EXIT_FAILURE, type Verb, type VerbOptions } from "./verb.ts";
34
+ import type { UnseenLoad } from "../roots/unseen-loads.ts";
35
+ import type { UnreadInput } from "../load/plan.ts";
36
+ import type { UnresolvedSpecifier } from "../load/specifiers.ts";
37
+
38
+ import { type Verb, type VerbOptions } from "./verb.ts";
39
+ import { UsageError } from "../usage.ts";
40
+ import { bytewise } from "../text/compare.ts";
41
+ import { productFault, failureExit } from "../failure.ts";
42
+ import { diagnose, message } from "../product.ts";
43
+ import { ownVersion } from "./version.ts";
35
44
 
36
45
  /** The options `analyze` takes beside the ones every verb takes. */
37
46
  export const ANALYZE_OPTIONS: VerbOptions = {
38
- plain: ["report", "baseline-write", "exit-code", "template"],
47
+ plain: ["report", "facts", "baseline-write", "exit-code", "template"],
39
48
  repeatable: ["format"],
40
49
  };
41
50
 
@@ -43,17 +52,9 @@ export const ANALYZE_OPTIONS: VerbOptions = {
43
52
  const EXIT_CODE_ON = "on";
44
53
  const EXIT_CODE_OFF = "off";
45
54
 
46
- /** A path of the run no report can name, which ends the run with the failure code. */
47
- class ReportPathError extends Error {
48
- constructor(message: string) {
49
- super(message);
50
- this.name = "ReportPathError";
51
- }
52
- }
53
-
54
55
  /** The formats this analyzer renders, for a message that names them. */
55
56
  function formatNames(): string {
56
- return [...RENDERINGS.keys()].sort().join(", ");
57
+ return [...RENDERINGS.keys()].sort(bytewise).join(", ");
57
58
  }
58
59
 
59
60
  /** The renderings one invocation writes: the ones it named, else the configuration's. */
@@ -62,14 +63,12 @@ function formatsOf(named: readonly string[], configured: readonly Format[]): rea
62
63
  const seen = new Set<string>();
63
64
  for (const format of formats) {
64
65
  if (!RENDERINGS.has(format as Format)) {
65
- throw new ConfigError(
66
- "malformed",
67
- "",
66
+ throw new UsageError(
68
67
  `${JSON.stringify(format)} is not a format this analyzer renders: the formats are ${formatNames()}`,
69
68
  );
70
69
  }
71
70
  if (seen.has(format)) {
72
- throw new ConfigError("malformed", "", `the format ${JSON.stringify(format)} is named twice`);
71
+ throw new UsageError(`the format ${JSON.stringify(format)} is named twice`);
73
72
  }
74
73
  seen.add(format);
75
74
  }
@@ -87,7 +86,8 @@ function runRelative(invoked: string, path: string): string {
87
86
  }
88
87
  const below = relativePath(invoked, path);
89
88
  if (below === undefined) {
90
- throw new ReportPathError(
89
+ throw failureExit(
90
+ "unreportable-path",
91
91
  `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`,
92
92
  );
93
93
  }
@@ -113,13 +113,84 @@ function unmappedNotes(
113
113
  });
114
114
  }
115
115
 
116
+ /**
117
+ * One note per load of a production file the run cannot resolve, each site once: a file
118
+ * it loads is a root the run does not see, so `ts.roots_complete` lifts no cap there.
119
+ */
120
+ function unseenLoadNotes(loads: readonly UnseenLoad[]): readonly ReportNote[] {
121
+ return [
122
+ ...new Map(
123
+ loads.map((load) => {
124
+ const { path, line, column } = load.position;
125
+ const site = `${path}:${String(line)}:${String(column)}`;
126
+ const note: ReportNote = {
127
+ kind: "computed-load",
128
+ path: dirnamePath(path),
129
+ 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`,
130
+ };
131
+ return [site, note] as const;
132
+ }),
133
+ ).values(),
134
+ ];
135
+ }
136
+
137
+ /** One note per package whose command strings name files a configuration holds, naming every such file. */
138
+ function heldScriptNotes(held: readonly HeldScripts[], targetRoot: string): readonly ReportNote[] {
139
+ const files = new Map<string, Set<string>>();
140
+ const unwritten = new Set<string>();
141
+ for (const one of held) {
142
+ files.set(one.dir, new Set([...(files.get(one.dir) ?? []), ...one.files]));
143
+ if (one.unwritten) {
144
+ unwritten.add(one.dir);
145
+ }
146
+ }
147
+ return [...files].map(([dir, paths]) => ({
148
+ kind: "unread-command",
149
+ path: relativePath(targetRoot, dir) ?? ".",
150
+ message: [
151
+ ...(paths.size === 0
152
+ ? []
153
+ : [
154
+ `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"}`,
155
+ ]),
156
+ ...(unwritten.has(dir)
157
+ ? [
158
+ "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",
159
+ ]
160
+ : []),
161
+ ].join("; "),
162
+ }));
163
+ }
164
+
165
+ function unresolvedNotes(specifiers: readonly UnresolvedSpecifier[]): readonly ReportNote[] {
166
+ return specifiers.map(({ specifier, position }) => ({
167
+ kind: "unresolved-specifier",
168
+ path: dirnamePath(position.path),
169
+ message: `${position.path}:${String(position.line)}:${String(position.column)} loads ${JSON.stringify(specifier)}, which resolves to no file, so it references nothing`,
170
+ }));
171
+ }
172
+
173
+ function unreadLine(input: UnreadInput, targetRoot: string): string {
174
+ switch (input.kind) {
175
+ case "manifest": {
176
+ const path = relativePath(targetRoot, input.manifest) ?? input.manifest;
177
+ return input.reason === undefined
178
+ ? `${path} does not parse, so the manifest facts of the program formed for its package are unanswered: correct the manifest`
179
+ : `${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}`;
180
+ }
181
+ case "ignore-file":
182
+ return `${relativePath(targetRoot, input.path) ?? input.path} cannot be read, so the JavaScript files it would ignore are analyzed: ${input.reason}`;
183
+ }
184
+ }
185
+
116
186
  /** Each project the run dropped as a report names it, by its configuration file below the target. */
117
187
  function notBuiltOf(dropped: readonly NotBuilt[], targetRoot: string): readonly ReportNotBuilt[] {
118
188
  return dropped.map((one) => {
119
189
  const project = relativePath(targetRoot, one.configFile);
120
190
  if (project === undefined) {
121
- throw new ReportPathError(
122
- `the project ${one.id} would be opened from ${one.configFile}, which is not below the target ${targetRoot}, so no report can name it`,
191
+ throw failureExit(
192
+ "unreportable-path",
193
+ `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`,
123
194
  );
124
195
  }
125
196
  return { id: one.id, project, error: one.error };
@@ -134,14 +205,33 @@ function configurationsOf(
134
205
  return projects.map((one) => {
135
206
  const project = relativePath(targetRoot, one.configFile);
136
207
  if (project === undefined) {
137
- throw new ReportPathError(
138
- `the project ${one.id} is opened from ${one.configFile}, which is not below the target ${targetRoot}, so no report can name it`,
208
+ throw failureExit(
209
+ "unreportable-path",
210
+ `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`,
139
211
  );
140
212
  }
141
213
  return { id: one.id, project };
142
214
  });
143
215
  }
144
216
 
217
+ /**
218
+ * Writes one document the run was asked for. A document that cannot be produced or written
219
+ * ends the run with the run failure that names it and `fix`, the documents written before it
220
+ * kept.
221
+ */
222
+ function writeDocument(
223
+ host: Host,
224
+ path: string,
225
+ fix: string,
226
+ produce: () => Iterable<string>,
227
+ ): void {
228
+ try {
229
+ host.writeDocument(path, produce());
230
+ } catch (error: unknown) {
231
+ throw failureExit("unwritten-output", `${path}: ${message(error)}: ${fix}`);
232
+ }
233
+ }
234
+
145
235
  /** A count with its noun, so a message reads for one record as well as for several. */
146
236
  function counted(n: number, noun: string): string {
147
237
  return `${String(n)} ${noun}${n === 1 ? "" : "s"}`;
@@ -160,9 +250,7 @@ function templateOf(
160
250
  ): Template | undefined {
161
251
  if (named === undefined || named === "") {
162
252
  if (formats.includes("template")) {
163
- throw new ConfigError(
164
- "malformed",
165
- "",
253
+ throw new UsageError(
166
254
  "the template format renders the template --template names, and none was named",
167
255
  );
168
256
  }
@@ -172,11 +260,7 @@ function templateOf(
172
260
  try {
173
261
  source = host.readFile(resolvePath(invoked, named));
174
262
  } catch (error: unknown) {
175
- throw new ConfigError(
176
- "malformed",
177
- "",
178
- `--template=${named}: ${error instanceof Error ? error.message : String(error)}`,
179
- );
263
+ throw new UsageError(`--template=${named}: ${message(error)}`);
180
264
  }
181
265
  try {
182
266
  return parseTemplate(source);
@@ -184,13 +268,14 @@ function templateOf(
184
268
  if (!(error instanceof TemplateError)) {
185
269
  throw error;
186
270
  }
187
- throw new ConfigError("malformed", "", `--template=${named}: ${error.message}`);
271
+ throw new UsageError(`--template=${named}: ${error.message}`);
188
272
  }
189
273
  }
190
274
 
191
275
  /** Every document one invocation asked for: the report, each rendering beside it, a baseline. */
192
276
  interface Documents {
193
277
  readonly report: string;
278
+ readonly facts: string | undefined;
194
279
  readonly formats: readonly Format[];
195
280
  readonly baseline: string | undefined;
196
281
  }
@@ -206,29 +291,26 @@ interface Documents {
206
291
  export const analyzeVerb: Verb = ({ err, host, inputs, scope, openClient, option, repeated }) => {
207
292
  const reportPath = option("report");
208
293
  if (reportPath === undefined || reportPath === "") {
209
- throw new ConfigError(
210
- "malformed",
211
- "",
294
+ throw new UsageError(
212
295
  "analyze writes its report to the path --report names, and no path was named",
213
296
  );
214
297
  }
215
298
  const exitCode = option("exit-code") ?? EXIT_CODE_ON;
216
299
  if (exitCode !== EXIT_CODE_ON && exitCode !== EXIT_CODE_OFF) {
217
- throw new ConfigError(
218
- "malformed",
219
- "",
300
+ throw new UsageError(
220
301
  `--exit-code=${JSON.stringify(exitCode)}: the values are ${EXIT_CODE_ON} and ${EXIT_CODE_OFF}`,
221
302
  );
222
303
  }
223
304
  const { config, provenance } = resolve(inputs());
224
- const kind = config.targetKind;
225
- if (kind === "") {
226
- throw new ConfigError("missing-target-kind", "target.kind", "target.kind is not set");
227
- }
228
305
  const invoked = host.workingDirectory();
229
306
  const baseline = option("baseline-write");
307
+ const facts = option("facts");
308
+ if (facts === "") {
309
+ throw new UsageError("--facts names the path the facts document is written to, and named none");
310
+ }
230
311
  const documents: Documents = {
231
312
  report: resolvePath(invoked, reportPath),
313
+ facts: facts === undefined ? undefined : resolvePath(invoked, facts),
232
314
  formats: formatsOf(repeated("format"), config.reporters.formats),
233
315
  baseline: baseline === undefined ? undefined : resolvePath(invoked, baseline),
234
316
  };
@@ -236,147 +318,156 @@ export const analyzeVerb: Verb = ({ err, host, inputs, scope, openClient, option
236
318
  const scoped = scope();
237
319
  const targetRoot = scoped.target.path;
238
320
 
239
- let version: string;
240
- try {
241
- version = host.analyzerVersion();
242
- } catch (error: unknown) {
243
- err.write(`deadset-ts: ${error instanceof Error ? error.message : String(error)}\n`);
244
- return EXIT_FAILURE;
245
- }
321
+ const version = ownVersion(host);
246
322
 
247
- let report: Report;
248
323
  let recorded: readonly Recorded[];
249
- let verdict: number;
250
- let partial: readonly string[];
251
- let warnings: readonly ComponentWarning[];
252
- let unread: readonly string[];
253
- let unfound: readonly string[];
254
- try {
255
- const root = runRelative(invoked, targetRoot);
256
- const mode = { production: true };
257
- let analysis: RunAnalysis;
258
- if (documents.baseline === undefined) {
259
- analysis = runAnalysis(openClient(config), host, scoped, config, provenance, mode);
260
- recorded = [];
261
- } else {
262
- const reason = rowReason(analyzerProvenance(version));
263
- const write = runBaselineWrite(
264
- openClient(config),
265
- host,
266
- scoped,
267
- config,
268
- provenance,
269
- mode,
270
- reason,
271
- );
272
- analysis = write.first;
273
- recorded = write.rows;
274
- }
275
- const { result, run } = analysis;
276
- warnings = run.componentWarnings;
277
- unread = run.componentsUnread.map(
278
- ({ configFile, reason }) =>
279
- `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: its component files are not read: ${reason}`,
280
- );
281
- unfound = run.librariesUnfound.map(
282
- ({ configFile, error }) =>
283
- `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: ${error}: the configuration is analyzed without that library`,
324
+ const root = runRelative(invoked, targetRoot);
325
+ const mode = productionMode(config);
326
+ let analysis: RunAnalysis;
327
+ if (documents.baseline === undefined) {
328
+ analysis = runAnalysis(openClient(config), host, scoped, config, provenance, mode);
329
+ recorded = [];
330
+ } else {
331
+ const reason = rowReason(analyzerProvenance(version));
332
+ const write = runBaselineWrite(
333
+ openClient(config),
334
+ host,
335
+ scoped,
336
+ config,
337
+ provenance,
338
+ mode,
339
+ reason,
284
340
  );
285
- partial = partialNotes({
286
- notBuilt: run.notBuilt,
287
- unanswered: run.unanswered,
288
- targetRoot: resolvePath(invoked, targetRoot),
289
- });
290
- const built = buildReport({
291
- contractVersion: CONTRACT_VERSION,
292
- version,
293
- conformance: CONFORMANCE,
294
- declaredGaps: DECLARED_GAPS,
295
- target: {
296
- kind: kindOf(kind, LANGUAGE),
297
- root,
298
- identity: moduleIdentity(host, scoped.target),
299
- },
300
- configurations: configurationsOf(run.projects, targetRoot),
301
- notBuilt: notBuiltOf(run.notBuilt, targetRoot),
302
- loaded: run.consumers.map((consumer) => ({
303
- id: consumer.id,
304
- path: runRelative(invoked, consumer.path),
305
- })),
306
- unavailable: [],
307
- result,
308
- testFileRules: run.testFileRules,
309
- typeErrorSkips: run.typeErrorSkips,
310
- unanswered: unansweredCounts(analysis),
311
- conventionsApplied: run.conventionsApplied,
312
- notes: unmappedNotes(run.unmappedEntries, resolvePath(invoked, targetRoot)),
313
- });
314
- report = capFindings(sortFindings(built, config.reporters.sort), config.reporters.maxFindings);
315
- verdict = verdictOf(result, config);
316
- } catch (error: unknown) {
317
- if (!(error instanceof ReportPathError)) {
318
- throw error;
319
- }
320
- err.write(`deadset-ts: ${error.message}\n`);
321
- return EXIT_FAILURE;
341
+ analysis = write.first;
342
+ recorded = write.rows;
322
343
  }
344
+ const { result, run } = analysis;
345
+ const warnings = run.componentWarnings;
346
+ const unread = run.componentsUnread.map(
347
+ ({ configFile, reason }) =>
348
+ `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: its component files are not read: ${reason}`,
349
+ );
350
+ const unfound = run.librariesUnfound.map(
351
+ ({ configFile, error }) =>
352
+ `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: ${error}: the configuration is analyzed without that library`,
353
+ );
354
+ const unreadInputs = run.unread.map((one) => unreadLine(one, resolvePath(invoked, targetRoot)));
323
355
 
324
- try {
325
- host.writeDocument(documents.report, json(report));
326
- const options = {
327
- failOn: config.reporters.failOn,
328
- readSource: (path: string) => host.readFile(joinPath(targetRoot, path)),
329
- template,
330
- };
331
- for (const format of documents.formats) {
332
- const rendering = RENDERINGS.get(format);
333
- if (rendering !== undefined) {
334
- host.writeDocument(documents.report + rendering.suffix, rendering.render(report, options));
335
- }
336
- }
337
- if (documents.baseline !== undefined) {
338
- const kept =
339
- host.kindOf(documents.baseline) === "file"
340
- ? otherSchemeRows(host.readFile(documents.baseline))
341
- : [];
342
- host.writeDocument(
343
- documents.baseline,
344
- writeBaseline(recorded, analyzerProvenance(version), kept),
356
+ const partial = partialNotes({
357
+ notBuilt: run.notBuilt,
358
+ unanswered: run.unanswered,
359
+ targetRoot: resolvePath(invoked, targetRoot),
360
+ });
361
+ const built = buildReport({
362
+ contractVersion: CONTRACT_VERSION,
363
+ version,
364
+ conformance: CONFORMANCE,
365
+ declaredGaps: DECLARED_GAPS,
366
+ target: {
367
+ kind: kindOf(config.target.kind),
368
+ root,
369
+ identity: moduleIdentity(host, scoped.target),
370
+ },
371
+ configurations: configurationsOf(run.projects, targetRoot),
372
+ notBuilt: notBuiltOf(run.notBuilt, targetRoot),
373
+ loaded: run.consumers.map((consumer) => ({
374
+ id: consumer.id,
375
+ path: runRelative(invoked, consumer.path),
376
+ })),
377
+ unavailable: [],
378
+ result,
379
+ testFileRules: run.testFileRules,
380
+ typeErrorSkips: run.typeErrorSkips,
381
+ unanswered: unansweredCounts(analysis),
382
+ conventionsApplied: run.conventionsApplied,
383
+ listsComponents: config.reporters.cascade === "full",
384
+ notes: [
385
+ ...unmappedNotes(run.unmappedEntries, resolvePath(invoked, targetRoot)),
386
+ ...unseenLoadNotes(run.unseenLoads),
387
+ ...unresolvedNotes(run.unresolvedSpecifiers),
388
+ ...heldScriptNotes(run.heldScripts, resolvePath(invoked, targetRoot)),
389
+ ],
390
+ });
391
+ const report = capFindings(
392
+ sortFindings(built, config.reporters.sort),
393
+ config.reporters.max_findings,
394
+ );
395
+ const verdict = verdictOf(result, config);
396
+
397
+ const [refused] = reportRefusals(report);
398
+ if (refused !== undefined) {
399
+ throw productFault(
400
+ `built a report that breaks the report schema at ${refused.pointer || "the document"}: ${refused.keyword}: ${refused.reason}`,
401
+ );
402
+ }
403
+ writeDocument(host, documents.report, "name a path the run can write", () => json(report));
404
+ const factsPath = documents.facts;
405
+ if (factsPath !== undefined) {
406
+ writeDocument(host, factsPath, "name a path the run can write", () => [
407
+ factsDocument(version, run.generated, run.bindings),
408
+ ]);
409
+ }
410
+ const options = {
411
+ readSource: (path: string) => host.readFile(joinPath(targetRoot, path)),
412
+ template,
413
+ };
414
+ for (const format of documents.formats) {
415
+ const rendering = RENDERINGS.get(format);
416
+ if (rendering !== undefined) {
417
+ writeDocument(
418
+ host,
419
+ documents.report + rendering.suffix,
420
+ "name a path the run can write, or correct the template that renders it",
421
+ () => rendering.render(report, options),
345
422
  );
346
423
  }
347
- } catch (error: unknown) {
348
- err.write(`deadset-ts: ${error instanceof Error ? error.message : String(error)}\n`);
349
- return EXIT_FAILURE;
424
+ }
425
+ const baselinePath = documents.baseline;
426
+ if (baselinePath !== undefined) {
427
+ writeDocument(
428
+ host,
429
+ baselinePath,
430
+ "name a path the run can write, or repair the rows of the baseline the run would keep",
431
+ () => {
432
+ const kept =
433
+ host.kindOf(baselinePath) === "file" ? otherSchemeRows(host.readFile(baselinePath)) : [];
434
+ return writeBaseline(recorded, analyzerProvenance(version), kept);
435
+ },
436
+ );
350
437
  }
351
438
 
352
439
  for (const note of partial) {
353
- err.write(`deadset-ts: ${note}\n`);
440
+ diagnose(err, note);
354
441
  }
355
- for (const line of [...unread, ...unfound]) {
356
- err.write(`deadset-ts: ${line}\n`);
442
+ for (const line of [...unread, ...unfound, ...unreadInputs]) {
443
+ diagnose(err, line);
357
444
  }
358
445
  for (const warning of warnings) {
359
- err.write(
360
- `deadset-ts: ${warning.path}:${String(warning.line)}: a <script> start tag that begins a line is not read as a block: ${warning.reason}\n`,
446
+ diagnose(
447
+ err,
448
+ `${warning.path}:${String(warning.line)}: a <script> start tag that begins a line is not read as a block: ${warning.reason}`,
361
449
  );
362
450
  }
363
451
  for (const skip of report.type_error_skips) {
364
- err.write(
365
- `deadset-ts: ${skip.path}:${String(skip.line)}: ${skip.message}: the function or statement holding this type error is not evaluated\n`,
452
+ diagnose(
453
+ err,
454
+ `${skip.path}:${String(skip.line)}: ${skip.message}: the function or statement holding this type error is not evaluated`,
366
455
  );
367
456
  }
368
457
  if (report.totals.pending > 0) {
369
- err.write(
370
- `deadset-ts: ${counted(report.totals.pending, "pending finding")}: the report names a declared cross-language edge, and no merge has resolved it\n`,
458
+ diagnose(
459
+ err,
460
+ `${counted(report.totals.pending, "pending finding")}: the report names a declared cross-language edge, and no merge has resolved it`,
371
461
  );
372
462
  }
373
463
  if (report.totals.stale_suppressions > 0) {
374
- err.write(`deadset-ts: ${counted(report.totals.stale_suppressions, "stale suppression")}\n`);
464
+ diagnose(err, counted(report.totals.stale_suppressions, "stale suppression"));
375
465
  }
376
466
  if (exitCode === EXIT_CODE_OFF) {
377
467
  if (verdict !== EXIT_CLEAN) {
378
- err.write(
379
- `deadset-ts: the exit code is configured off: the verdict of this run is ${String(verdict)}\n`,
468
+ diagnose(
469
+ err,
470
+ `the exit code is configured off: the verdict of this run is ${String(verdict)}`,
380
471
  );
381
472
  }
382
473
  return EXIT_CLEAN;