@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
package/src/manifest.ts DELETED
@@ -1,234 +0,0 @@
1
- /**
2
- * The entry points a package manifest names, which are roots because something
3
- * outside the analyzed program reaches them: a consumer importing the package, or a
4
- * shell running its command or one of its scripts. {@link readManifest} reads one
5
- * directory's manifest, {@link packageEntries} those of the packages below the target root.
6
- */
7
-
8
- import type { Host } from "./host.ts";
9
- import { isAbsolutePath, joinPath, relativePath, resolvePath } from "./paths.ts";
10
-
11
- /** The manifest's own name. */
12
- const MANIFEST = "package.json";
13
-
14
- /** The three members that name an entry point beside `exports` and `bin`. */
15
- const LEGACY_MEMBERS = ["main", "module", "types"] as const;
16
-
17
- /** What reaches one entry point the manifest names. */
18
- type EntryRole =
19
- /** A consumer importing the package, which is a caller the analysis cannot see. */
20
- | "import"
21
- /** A shell running the package's command, which is a caller that exists. */
22
- | "run"
23
- /** A token of one of the package's scripts, which the package manager runs. */
24
- | "script";
25
-
26
- /** One entry point the manifest names. */
27
- export interface ManifestEntry {
28
- /**
29
- * The member that named it, spelled as a reader of the manifest reads one:
30
- * `main`, `bin["deadset-ts"]`, `exports["."]["import"]`. It is what a maintainer
31
- * edits, so it is what a root reports as the string that named it.
32
- */
33
- readonly member: string;
34
- /** The target the member carries, resolved against the manifest's directory. */
35
- readonly path: string;
36
- readonly role: EntryRole;
37
- /**
38
- * Whether the member declares what a consumer may import, which is `exports` and
39
- * the three members that preceded it. A command is published too, and is not this:
40
- * `exports` is the surface a library's published API is read from.
41
- */
42
- readonly published: boolean;
43
- /** The directory of the manifest that names it, which `path` was resolved against. */
44
- readonly dir: string;
45
- }
46
-
47
- function isRecord(value: unknown): value is Record<string, unknown> {
48
- return typeof value === "object" && value !== null && !Array.isArray(value);
49
- }
50
-
51
- /**
52
- * Whether one member's value names a file of this package rather than another
53
- * package or a URL. A target written with no leading dot is a path too, which is
54
- * how the members that preceded `exports` are written.
55
- */
56
- function isTarget(value: string, requireDot: boolean): boolean {
57
- if (value === "" || isAbsolutePath(value) || value.includes("://")) {
58
- return false;
59
- }
60
- return !requireDot || value.startsWith("./");
61
- }
62
-
63
- /** Where a script's command line splits into tokens: white space and the shell's operators. */
64
- const SCRIPT_SEPARATORS = /\s+|&&|\|\||;|\|/u;
65
-
66
- /** A token written inside one pair of quotes. */
67
- const QUOTED = /^(["'])(.*)\1$/su;
68
-
69
- /**
70
- * Every token one script's command line holds, each with one pair of enclosing quotes
71
- * removed. A token holding a wildcard is a pattern rather than a path, and names no
72
- * entry point.
73
- */
74
- export function scriptTokens(command: string): readonly string[] {
75
- return command
76
- .split(SCRIPT_SEPARATORS)
77
- .map((token) => token.replace(QUOTED, "$2"))
78
- .filter((token) => token !== "" && !token.includes("*"));
79
- }
80
-
81
- /** One member's spelling below another: `exports` then `exports["."]`. */
82
- function below(member: string, key: string): string {
83
- return `${member}[${JSON.stringify(key)}]`;
84
- }
85
-
86
- /**
87
- * Every target one `exports` value carries, at the member each is written under.
88
- *
89
- * The value nests strings, subpath or condition objects and alternative arrays to
90
- * any depth; a `null` blocks a subpath. Every level is walked, because each
91
- * condition names its own entry file, and a key's meaning is never read.
92
- */
93
- function exportTargets(value: unknown, member: string, found: Omit<ManifestEntry, "dir">[]): void {
94
- if (typeof value === "string") {
95
- if (isTarget(value, true)) {
96
- found.push({ member, path: value, role: "import", published: true });
97
- }
98
- return;
99
- }
100
- if (Array.isArray(value)) {
101
- value.forEach((alternative, index) => {
102
- exportTargets(alternative, below(member, String(index)), found);
103
- });
104
- return;
105
- }
106
- if (!isRecord(value)) {
107
- return;
108
- }
109
- for (const [key, held] of Object.entries(value)) {
110
- exportTargets(held, below(member, key), found);
111
- }
112
- }
113
-
114
- /** The manifest at the target root, decoded, or undefined where there is none to read. */
115
- function manifestOf(host: Host, targetRoot: string): Record<string, unknown> | undefined {
116
- let text: string;
117
- try {
118
- text = host.readFile(joinPath(targetRoot, MANIFEST));
119
- } catch {
120
- return undefined;
121
- }
122
- let value: unknown;
123
- try {
124
- value = JSON.parse(text);
125
- } catch {
126
- // A manifest this program cannot read names no entry point, which is the same
127
- // answer as an absent one. What a manifest's contents say is not refused here:
128
- // the package manager owns that refusal, and an analysis of a tree it rejects
129
- // is not the run's subject.
130
- return undefined;
131
- }
132
- return isRecord(value) ? value : undefined;
133
- }
134
-
135
- /** What one manifest declares about where its package is entered. */
136
- export interface Manifest {
137
- /**
138
- * Every entry point the manifest names, in the order the members are read: `main`,
139
- * `module`, `types`, then each `bin` command, then every target of `exports`, then
140
- * every token of each script, which names a file only where one is at its path. Each
141
- * path is absolute.
142
- */
143
- readonly entries: readonly ManifestEntry[];
144
- /**
145
- * Whether an `exports` member is written at all. A package that declares one has
146
- * said exactly what a consumer may import, so its published API is what `exports`
147
- * reaches; a package that declares none publishes whatever the members that
148
- * preceded it name.
149
- */
150
- readonly declaresExports: boolean;
151
- }
152
-
153
- /**
154
- * What the manifest in `targetRoot` declares about where its package is entered.
155
- *
156
- * A target is taken as written. It is not resolved to a source file here, because
157
- * which file a target names is a fact about the compiler configuration that emits
158
- * it and there is one such configuration per project, while there is one manifest.
159
- */
160
- export function readManifest(host: Host, targetRoot: string): Manifest {
161
- const manifest = manifestOf(host, targetRoot);
162
- if (manifest === undefined) {
163
- return { entries: [], declaresExports: false };
164
- }
165
-
166
- const found: Omit<ManifestEntry, "dir">[] = [];
167
- for (const member of LEGACY_MEMBERS) {
168
- const value = manifest[member];
169
- if (typeof value === "string" && isTarget(value, false)) {
170
- found.push({ member, path: value, role: "import", published: true });
171
- }
172
- }
173
-
174
- const bin = manifest["bin"];
175
- if (typeof bin === "string" && isTarget(bin, false)) {
176
- found.push({ member: "bin", path: bin, role: "run", published: false });
177
- } else if (isRecord(bin)) {
178
- for (const [command, value] of Object.entries(bin)) {
179
- if (typeof value === "string" && isTarget(value, false)) {
180
- found.push({ member: below("bin", command), path: value, role: "run", published: false });
181
- }
182
- }
183
- }
184
-
185
- exportTargets(manifest["exports"], "exports", found);
186
-
187
- const scripts = manifest["scripts"];
188
- if (isRecord(scripts)) {
189
- for (const [name, command] of Object.entries(scripts)) {
190
- if (typeof command !== "string") {
191
- continue;
192
- }
193
- for (const token of new Set(scriptTokens(command))) {
194
- found.push({
195
- member: below("scripts", name),
196
- path: token,
197
- role: "script",
198
- published: false,
199
- });
200
- }
201
- }
202
- }
203
-
204
- return {
205
- entries: found.map((entry) => ({
206
- ...entry,
207
- path: resolvePath(targetRoot, entry.path),
208
- dir: targetRoot,
209
- })),
210
- declaresExports: manifest["exports"] !== undefined,
211
- };
212
- }
213
-
214
- /**
215
- * The entry points the manifests of the nested packages in `dirs` name. Each entry is
216
- * spelled under its manifest's path below the target root, and is published by its own
217
- * manifest's rule, as the target's own entries are.
218
- */
219
- export function packageEntries(
220
- host: Host,
221
- targetRoot: string,
222
- dirs: readonly string[],
223
- ): readonly ManifestEntry[] {
224
- return dirs.flatMap((dir) => {
225
- const manifest = readManifest(host, dir);
226
- const where = `${relativePath(targetRoot, dir) ?? dir}/${MANIFEST}`;
227
- return manifest.entries.map((entry) => ({
228
- ...entry,
229
- member: `${where} ${entry.member}`,
230
- published:
231
- entry.published && (!manifest.declaresExports || entry.member.startsWith("exports")),
232
- }));
233
- });
234
- }
package/src/matrix.ts DELETED
@@ -1,423 +0,0 @@
1
- /**
2
- * One run's projects as one matrix: every declaration any project holds, keyed by its
3
- * position and carrying the configurations that hold it, swept once per configuration
4
- * and intersected, with the dead components computed once over every configuration.
5
- */
6
-
7
- import { componentsOf, type Component, type Positional } from "./components.ts";
8
- import { graphOf, OUTSIDE, type Graph } from "./graph.ts";
9
- import type { InventorySymbol } from "./inventory.ts";
10
- import { byPosition } from "./position.ts";
11
- import type { Reference } from "./references.ts";
12
- import type { Root } from "./roots.ts";
13
- import {
14
- reachedWithTheTests,
15
- sweep,
16
- type Candidate,
17
- type Liveness,
18
- type Relation,
19
- type SweepInput,
20
- } from "./sweep.ts";
21
-
22
- /** What the passes answered for one configuration of the run. */
23
- export interface Configured {
24
- /** The name discovery gives the configuration's project. */
25
- readonly configuration: string;
26
- readonly symbols: readonly InventorySymbol[];
27
- readonly references: readonly Reference[];
28
- readonly roots: readonly Root[];
29
- /** The paths the reference pass classified as test files. */
30
- readonly testFiles: readonly string[];
31
- /** The paths of the test-support files, which only test code imports. */
32
- readonly supportFiles?: readonly string[] | undefined;
33
- /** The paths of the files only tests reach that are no test-support file. */
34
- readonly testUsedFiles?: readonly string[] | undefined;
35
- /** The ids of the ambient declarations, which describe code the target does not implement. */
36
- readonly ambient?: ReadonlySet<string> | undefined;
37
- /**
38
- * The paths of the workspace-package files the configuration holds but does not
39
- * compile itself. Their declarations count in its graph and its verdict on them is no
40
- * finding.
41
- */
42
- readonly referenceOnly?: readonly string[] | undefined;
43
- /** Each declaration's dependents, by id, as the configuration's inventory states them. */
44
- readonly dependents?: ReadonlyMap<string, readonly string[]> | undefined;
45
- }
46
-
47
- /** The run's configurations, indexed for the sweep. */
48
- export interface Matrix {
49
- /** The configurations, in the run's order. */
50
- readonly configurations: readonly string[];
51
- /** Per configuration, in the same order, the graph of what that configuration holds. */
52
- readonly graphs: readonly Graph[];
53
- /**
54
- * The graph over every configuration at once: every declaration a configuration
55
- * holds in a file it does not hold only for its references, once per position and in
56
- * site order, and every reference any configuration makes, a reference several
57
- * configurations make at one position counted once.
58
- */
59
- readonly union: Graph;
60
- /**
61
- * Per declaration of {@link Matrix.union}, at its position there, the configurations
62
- * whose project holds it, in the run's order.
63
- */
64
- readonly heldIn: readonly (readonly string[])[];
65
- /**
66
- * Per declaration of {@link Matrix.union}, whether a file only tests reach that is no
67
- * test-support file holds it in some configuration: production code only tests use.
68
- */
69
- readonly testUsed: readonly boolean[];
70
- /** Each declaration's dependents, by id, as the first configuration holding it states them. */
71
- readonly dependents: ReadonlyMap<string, readonly string[]>;
72
- }
73
-
74
- /** One declaration dead in every configuration that holds it. */
75
- export interface MatrixCandidate extends Candidate {
76
- /** The configurations the declaration is dead in, which are every one that holds it. */
77
- readonly configurations: readonly string[];
78
- /**
79
- * The declaration of test-support code that test code references, outside the
80
- * test-of-dead-code rule, that is or contains this one, the outermost where two do.
81
- * Such a declaration is not dead while test code references it, so neither it nor a
82
- * declaration it contains is a member of a dead component.
83
- */
84
- readonly heldByTests: string | undefined;
85
- /**
86
- * Whether a test file declares it, no test of dead code, and the run that counts test
87
- * references does not reach it: it is reported as a production declaration of its
88
- * shape nothing references would be.
89
- */
90
- readonly unreferencedTest: boolean;
91
- /**
92
- * Whether it is dead only because code only tests use is: production code only tests
93
- * use holds it and the run that counts test references reaches it, or such a
94
- * declaration reaches it through dead declarations.
95
- */
96
- readonly testUsed: boolean;
97
- /**
98
- * Whether test code the run that counts test references reaches, and that is no test of
99
- * dead code, references it: a test that stays keeps it.
100
- */
101
- readonly keptByTests: boolean;
102
- }
103
-
104
- /** One run's sweep. */
105
- export interface SweepResult {
106
- /**
107
- * Per declaration, the relations that hold it live in at least one configuration,
108
- * reference counting first. A declaration no relation holds live anywhere has no entry.
109
- */
110
- readonly liveUnder: ReadonlyMap<string, readonly Relation[]>;
111
- /** The declarations dead in every configuration that holds them, in site order. */
112
- readonly candidates: readonly MatrixCandidate[];
113
- /** The dead components, each before every component it reaches, each identifier once per run. */
114
- readonly components: readonly Component[];
115
- }
116
-
117
- /**
118
- * What makes one reference one reference, whichever configuration made it. A consumer's
119
- * position is rendered against its own root, so the consumer is part of what it names.
120
- */
121
- export function referenceKey(reference: Reference): string {
122
- const { path, line, column } = reference.position;
123
- return [
124
- reference.consumer ?? "",
125
- reference.from,
126
- reference.to,
127
- path,
128
- String(line),
129
- String(column),
130
- reference.use,
131
- ].join("\u0000");
132
- }
133
-
134
- /**
135
- * Indexes what the passes answered for each configuration of one run, in the run's order.
136
- * A declaration is keyed by its rendered position, with the fields of the first
137
- * configuration that judges it; one in a file every holder holds only for its references
138
- * is judged by none and is not in the union. One reference at one position of a file
139
- * several configurations compile is one reference; two one configuration makes are two.
140
- */
141
- export function matrixOf(per: readonly Configured[]): Matrix {
142
- const symbols: InventorySymbol[] = [];
143
- const holders = new Map<string, string[]>();
144
- const references: Reference[] = [];
145
- const firstSeen = new Map<string, number>();
146
- const judged = new Set<string>();
147
- const dependents = new Map<string, readonly string[]>();
148
- per.forEach((one, index) => {
149
- for (const [id, after] of one.dependents ?? []) {
150
- if (!dependents.has(id)) {
151
- dependents.set(id, after);
152
- }
153
- }
154
- const referenceOnly = new Set(one.referenceOnly);
155
- for (const symbol of one.symbols) {
156
- const held = holders.get(symbol.id);
157
- if (held === undefined) {
158
- holders.set(symbol.id, [one.configuration]);
159
- } else if (!held.includes(one.configuration)) {
160
- held.push(one.configuration);
161
- }
162
- if (!referenceOnly.has(symbol.position.path) && !judged.has(symbol.id)) {
163
- judged.add(symbol.id);
164
- symbols.push(symbol);
165
- }
166
- }
167
- for (const reference of one.references) {
168
- const key = referenceKey(reference);
169
- const seen = firstSeen.get(key);
170
- if (seen === undefined) {
171
- firstSeen.set(key, index);
172
- } else if (seen !== index) {
173
- continue;
174
- }
175
- references.push(reference);
176
- }
177
- });
178
- symbols.sort((a, b) => byPosition(a.position, b.position));
179
- const testUsed = new Set(per.flatMap((one) => one.testUsedFiles ?? []));
180
-
181
- return {
182
- configurations: per.map((one) => one.configuration),
183
- graphs: per.map((one) =>
184
- graphOf(one.symbols, one.references, one.roots, one.testFiles, one.supportFiles, one.ambient),
185
- ),
186
- union: graphOf(
187
- symbols,
188
- references,
189
- per.flatMap((one) => one.roots),
190
- [...new Set(per.flatMap((one) => one.testFiles))],
191
- [...new Set(per.flatMap((one) => one.supportFiles ?? []))],
192
- new Set(per.flatMap((one) => [...(one.ambient ?? [])])),
193
- ),
194
- heldIn: symbols.map((symbol) => holders.get(symbol.id) ?? []),
195
- testUsed: symbols.map((symbol) => testUsed.has(symbol.position.path)),
196
- dependents,
197
- };
198
- }
199
-
200
- /**
201
- * Answers which declarations of the run are dead in every configuration that holds them.
202
- *
203
- * Liveness is a question about one configuration, because a file another configuration
204
- * does not compile makes no reference there and a root it does not hold seeds nothing
205
- * there, so each configuration is swept on its own graph under the run's input. A
206
- * declaration is a candidate when every configuration holding it judged it one: a
207
- * reference under one configuration is a reference, so what one project uses is never
208
- * reported, and a configuration that does not hold a declaration says nothing about it.
209
- * The candidate's relation is reference counting where every configuration found it so,
210
- * and reachability otherwise; its counts are the union's, one per reference.
211
- *
212
- * The components are computed once, over the union and the intersected dead set, so one
213
- * dead component is one entry of the run with one identifier.
214
- */
215
- export function sweepMatrix(matrix: Matrix, input: SweepInput): SweepResult {
216
- const per = matrix.graphs.map((graph) => sweep(graph, input));
217
- const byConfiguration = new Map<string, ReadonlyMap<string, Candidate>>(
218
- matrix.configurations.map((configuration, index) => [
219
- configuration,
220
- new Map((per[index]?.candidates ?? []).map((candidate) => [candidate.id, candidate])),
221
- ]),
222
- );
223
-
224
- const union = matrix.union;
225
- const heldBy: (string | undefined)[] = union.symbols.map(() => undefined);
226
- const testReached = reachedWithTheTests(union, [
227
- ...input.marked,
228
- ...(input.exempt ?? []).map((record) => record.id),
229
- ...(input.unanswered ?? []),
230
- ]);
231
- const judged = union.symbols.map((symbol, at): readonly Candidate[] | undefined => {
232
- const held = matrix.heldIn[at] ?? [];
233
- const found = held.map((configuration) => byConfiguration.get(configuration)?.get(symbol.id));
234
- return held.length === 0 || found.some((candidate) => candidate === undefined)
235
- ? undefined
236
- : found.filter((candidate): candidate is Candidate => candidate !== undefined);
237
- });
238
- // A configuration that does not hold a test's subject's caller finds the subject dead,
239
- // so a test is of dead code only where every production subject it names is dead in
240
- // every configuration that holds it.
241
- const subjectsDead = (at: number): boolean =>
242
- (union.out[at] ?? []).every(
243
- (edge) =>
244
- union.test[edge.to] === true ||
245
- union.support[edge.to] === true ||
246
- union.ambient[edge.to] === true ||
247
- union.subject[edge.to] !== true ||
248
- judged[edge.to] !== undefined,
249
- );
250
- const admittedAt = (at: number): boolean =>
251
- judged[at]?.every((candidate) => candidate.testOfDeadCode) === true && subjectsDead(at);
252
- const kept = keptByTests(union, testReached, admittedAt);
253
- const testUsed = testUsedReach(
254
- union,
255
- union.symbols.map((_symbol, at) => matrix.testUsed[at] === true && testReached[at] === true),
256
- judged.map((one) => one !== undefined),
257
- );
258
- const candidates: MatrixCandidate[] = [];
259
- union.symbols.forEach((symbol, at) => {
260
- const all = judged[at];
261
- if (all === undefined) {
262
- return;
263
- }
264
- const held = matrix.heldIn[at] ?? [];
265
- const admitted = admittedAt(at);
266
- const testRefs = union.made[at]?.test ?? 0;
267
- const heldByTests =
268
- heldBy[union.parent[at] ?? OUTSIDE] ??
269
- (union.support[at] === true && testRefs > 0 && !admitted ? symbol.id : undefined);
270
- const unreferenced = union.test[at] === true && !admitted && testReached[at] !== true;
271
- heldBy[at] = heldByTests;
272
- const productionRefs = union.made[at]?.production ?? 0;
273
- const counted = all.every((candidate) => candidate.relation === "reference-counting");
274
- candidates.push({
275
- id: symbol.id,
276
- productionRefs,
277
- testRefs,
278
- // The run that judges a test-file declaration counts its test references.
279
- relation: (unreferenced ? productionRefs + testRefs === 0 : counted)
280
- ? "reference-counting"
281
- : "reachability",
282
- testOfDeadCode: admitted,
283
- configurations: held,
284
- heldByTests,
285
- unreferencedTest: unreferenced,
286
- testUsed: testUsed[at] === true,
287
- keptByTests: kept[at] === true,
288
- });
289
- });
290
-
291
- const liveUnder = liveAnywhere(union.symbols, per);
292
- return {
293
- liveUnder,
294
- candidates,
295
- components: deadComponents(matrix, { liveUnder, candidates }, new Set()),
296
- };
297
- }
298
-
299
- /** Per declaration of the union, whether one of `seeds` is it or reaches it through `dead` declarations. */
300
- function testUsedReach(
301
- union: Graph,
302
- seeds: readonly boolean[],
303
- dead: readonly boolean[],
304
- ): readonly boolean[] {
305
- // A file is no candidate, and its top level is what reaches what it alone calls.
306
- const reached = seeds.map((seed, at) => seed && dead[at] === true);
307
- const queue = seeds.flatMap((one, at) => (one ? [at] : []));
308
- for (let at = queue.pop(); at !== undefined; at = queue.pop()) {
309
- for (const edge of union.out[at] ?? []) {
310
- if (dead[edge.to] === true && reached[edge.to] !== true) {
311
- reached[edge.to] = true;
312
- queue.push(edge.to);
313
- }
314
- }
315
- }
316
- return reached;
317
- }
318
-
319
- /** Per declaration of the union, whether test code `reached` holds and `admitted` rejects references it. */
320
- function keptByTests(
321
- union: Graph,
322
- reached: readonly boolean[],
323
- admitted: (at: number) => boolean,
324
- ): readonly boolean[] {
325
- const kept = union.symbols.map(() => false);
326
- union.out.forEach((edges, from) => {
327
- const testCode = union.test[from] === true || union.support[from] === true;
328
- if (!testCode || reached[from] !== true || admitted(from)) {
329
- return;
330
- }
331
- for (const edge of edges) {
332
- if (edge.test) {
333
- kept[edge.to] = true;
334
- }
335
- }
336
- });
337
- return kept;
338
- }
339
-
340
- /**
341
- * The dead components of one sweep over the union, with the file declarations at `files`
342
- * dead as well: a file that is deleted whole takes the declarations it holds and every
343
- * dead declaration only its top level references with it.
344
- */
345
- export function deadComponents(
346
- matrix: Matrix,
347
- result: Pick<SweepResult, "liveUnder" | "candidates">,
348
- files: ReadonlySet<number>,
349
- ): readonly Component[] {
350
- const union = matrix.union;
351
- const byId = new Map(result.candidates.map((candidate) => [candidate.id, candidate]));
352
- const candidateAt = (at: number): MatrixCandidate | undefined =>
353
- byId.get(union.symbols[at]?.id ?? "");
354
- return componentsOf(
355
- union,
356
- union.symbols.map((_symbol, at) => {
357
- const candidate = candidateAt(at);
358
- return files.has(at) || (candidate !== undefined && candidate.heldByTests === undefined);
359
- }),
360
- union.symbols.map((_symbol, at) => candidateAt(at)?.testOfDeadCode === true),
361
- union.symbols.map((_symbol, at) => candidateAt(at)?.unreferencedTest === true),
362
- positionsOf(union, matrix.dependents, result.liveUnder),
363
- );
364
- }
365
-
366
- /**
367
- * The file declarations at `paths`, below the target root, that one sweep holds live
368
- * under both relations, the rule a judged declaration is live by.
369
- */
370
- export function liveFilesAt(
371
- matrix: Matrix,
372
- result: SweepResult,
373
- paths: ReadonlySet<string>,
374
- ): readonly InventorySymbol[] {
375
- return matrix.union.symbols.filter(
376
- (symbol) =>
377
- symbol.kind === "file" &&
378
- paths.has(symbol.position.path) &&
379
- (result.liveUnder.get(symbol.id)?.length ?? 0) === RELATIONS.length,
380
- );
381
- }
382
-
383
- /**
384
- * Each declaration's dependents by its place in the union, and per place whether the
385
- * declaration is live under reachability in some configuration.
386
- */
387
- function positionsOf(
388
- union: Graph,
389
- dependents: ReadonlyMap<string, readonly string[]>,
390
- liveUnder: ReadonlyMap<string, readonly Relation[]>,
391
- ): Positional {
392
- return {
393
- dependents: union.symbols.map((symbol) =>
394
- (dependents.get(symbol.id) ?? []).map((id) => union.at(id)).filter((at) => at !== OUTSIDE),
395
- ),
396
- live: union.symbols.map(
397
- (symbol) => liveUnder.get(symbol.id)?.includes("reachability") === true,
398
- ),
399
- };
400
- }
401
-
402
- /** The relations in the order a declaration's entry lists them. */
403
- const RELATIONS: readonly Relation[] = ["reference-counting", "reachability"];
404
-
405
- /**
406
- * Per declaration, in site order, every relation that holds it live in at least one
407
- * configuration.
408
- */
409
- function liveAnywhere(
410
- symbols: readonly InventorySymbol[],
411
- per: readonly Liveness[],
412
- ): ReadonlyMap<string, readonly Relation[]> {
413
- const live = new Map<string, readonly Relation[]>();
414
- for (const symbol of symbols) {
415
- const relations = RELATIONS.filter((relation) =>
416
- per.some((liveness) => (liveness.liveUnder.get(symbol.id) ?? []).includes(relation)),
417
- );
418
- if (relations.length > 0) {
419
- live.set(symbol.id, relations);
420
- }
421
- }
422
- return live;
423
- }