@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
package/dist/src/sweep.js DELETED
@@ -1,224 +0,0 @@
1
- /**
2
- * Which declarations of one graph are dead, and under which liveness relation.
3
- * Reference counting holds a declaration live when any declaration references it,
4
- * whatever that one's own liveness, or when it is a root of a kind that names a caller;
5
- * reachability holds it live when a path of references reaches it from a root. So a
6
- * declaration only unreachable ones reference is live under the first, dead under the second.
7
- */
8
- import { namesACaller, OUTSIDE } from "./graph.js";
9
- /**
10
- * Answers which declarations of one graph are dead under the input's mode.
11
- *
12
- * The order is the order the answers depend on: the callers and the marks are live
13
- * before either relation runs, the candidate set is every judged declaration at least
14
- * one relation does not hold live and no exemption holds back, and the tests of dead
15
- * code join it.
16
- */
17
- export function sweep(graph, input) {
18
- const marked = flagged(graph, input.marked);
19
- const exempt = flagged(graph, [
20
- ...(input.exempt ?? []).map((record) => record.id),
21
- ...(input.unanswered ?? []),
22
- ]);
23
- const held = marked.map((mark, at) => mark || exempt[at] === true);
24
- // Every root, every mark and every exemption seeds reachability. A root of a kind that
25
- // names a caller, and a mark, are live under reference counting as well; a root that
26
- // only supposes a caller is not, and neither is an exemption.
27
- const called = graph.symbols.map(() => false);
28
- for (const root of graph.rooted) {
29
- if (namesACaller(root.kind)) {
30
- called[root.at] = true;
31
- }
32
- }
33
- const counted = (at) => {
34
- const made = graph.made[at];
35
- if (made === undefined) {
36
- return 0;
37
- }
38
- return input.mode.production ? made.production : made.production + made.test;
39
- };
40
- const reached = reachable(graph, held, input.mode);
41
- const liveUnder = graph.symbols.map((_symbol, at) => {
42
- const relations = [];
43
- if (marked[at] === true || called[at] === true || counted(at) > 0) {
44
- relations.push("reference-counting");
45
- }
46
- if (reached[at] === true) {
47
- relations.push("reachability");
48
- }
49
- return relations;
50
- });
51
- const dead = graph.symbols.map((_symbol, at) => graph.subject[at] === true && exempt[at] !== true && (liveUnder[at]?.length ?? 0) < 2);
52
- const testOfDeadCode = admitTestsOfDeadCode(graph, dead, held);
53
- const candidates = [];
54
- const live = new Map();
55
- graph.symbols.forEach((symbol, at) => {
56
- const relations = liveUnder[at] ?? [];
57
- if (relations.length > 0) {
58
- live.set(symbol.id, relations);
59
- }
60
- if (dead[at] !== true) {
61
- return;
62
- }
63
- candidates.push({
64
- id: symbol.id,
65
- productionRefs: graph.made[at]?.production ?? 0,
66
- testRefs: graph.made[at]?.test ?? 0,
67
- relation: counted(at) === 0 ? "reference-counting" : "reachability",
68
- testOfDeadCode: testOfDeadCode[at] === true,
69
- });
70
- });
71
- return { liveUnder: live, candidates };
72
- }
73
- /**
74
- * The directory a test runner reads a manual mock from, whose exports it puts in place of
75
- * the module's: https://jestjs.io/docs/manual-mocks
76
- */
77
- const MANUAL_MOCKS = "__mocks__";
78
- /** Whether a test runner calls or reads one export of a test file: a function, or any export of a manual mock. */
79
- export function runnerCalls(symbol) {
80
- return symbol.kind === "function" || symbol.position.path.split("/").includes(MANUAL_MOCKS);
81
- }
82
- /**
83
- * Per declaration of the graph, whether the run that counts test references reaches it.
84
- * That run's roots are the graph's own and, of each test file, its top level and every
85
- * function it exports, which a test runner may call, and every export of a manual mock,
86
- * which the runner reads; any other export of a test file, and test-support code, which
87
- * runs where a test imports it, are judged as any file's are.
88
- * `held` seeds it as a mark or an exemption seeds a sweep.
89
- */
90
- export function reachedWithTheTests(graph, held) {
91
- const tests = graph.symbols.flatMap((symbol, at) => {
92
- const exported = symbol.exported && graph.symbols[graph.parent[at] ?? OUTSIDE]?.kind === "file";
93
- const called = exported && runnerCalls(symbol);
94
- return graph.test[at] === true &&
95
- graph.support[at] !== true &&
96
- (symbol.kind === "file" || called)
97
- ? [{ at, kind: "test-runner" }]
98
- : [];
99
- });
100
- return reachable({ ...graph, rooted: [...graph.rooted, ...tests] }, flagged(graph, held), {
101
- production: false,
102
- });
103
- }
104
- /**
105
- * The references a loaded consumer makes that the mode counts. A production mode counts
106
- * none a consumer's test file made, as it counts none of the target's.
107
- */
108
- function callsOf(graph, mode) {
109
- return graph.consumed.filter((edge) => !mode.production || !edge.test);
110
- }
111
- /** Per declaration of the graph, whether one of the identifiers names it. */
112
- function flagged(graph, ids) {
113
- const flags = graph.symbols.map(() => false);
114
- for (const id of ids) {
115
- const at = graph.at(id);
116
- if (at !== OUTSIDE) {
117
- flags[at] = true;
118
- }
119
- }
120
- return flags;
121
- }
122
- /**
123
- * Per declaration, whether a seed reaches it. The two seeds reach through different
124
- * reference sets: a held declaration, marked or exempt, is live by a mechanism the
125
- * analysis cannot see, so no mode withholds a reference it makes, a test declaration's
126
- * included, while a root reaches through the references the mode counts. The held seed
127
- * runs first, so what it reaches is expanded under the wider rule.
128
- */
129
- function reachable(graph, held, mode) {
130
- const reached = graph.symbols.map(() => false);
131
- const expanded = graph.symbols.map(() => false);
132
- const queue = [];
133
- // Reaching a file reaches its top level: the references written outside every
134
- // declaration it holds. A reference that reads a file reads the module's namespace,
135
- // which reaches what the module exports as well. An evaluation runs the top level
136
- // and reads no export, and a root does not expand either: a file a runtime runs
137
- // without reading its exports is a root by itself.
138
- const enter = (at, expands) => {
139
- if (!reached[at]) {
140
- reached[at] = true;
141
- queue.push(at);
142
- }
143
- if (!expands || expanded[at] === true) {
144
- return;
145
- }
146
- expanded[at] = true;
147
- for (const exported of graph.exportsOf[at] ?? []) {
148
- enter(exported, false);
149
- }
150
- };
151
- const walk = (holding) => {
152
- for (let at = queue.pop(); at !== undefined; at = queue.pop()) {
153
- for (const edge of graph.out[at] ?? []) {
154
- if (!holding && mode.production && edge.test) {
155
- continue;
156
- }
157
- enter(edge.to, !edge.evaluation);
158
- }
159
- }
160
- };
161
- held.forEach((hold, at) => {
162
- if (hold) {
163
- enter(at, false);
164
- }
165
- });
166
- walk(true);
167
- for (const root of graph.rooted) {
168
- enter(root.at, false);
169
- }
170
- // A consumer's reference reaches what it names as one of the target's own does.
171
- for (const edge of callsOf(graph, mode)) {
172
- enter(edge.to, !edge.evaluation);
173
- }
174
- walk(false);
175
- return reached;
176
- }
177
- /**
178
- * Admits every test declaration whose set of referenced production declarations is
179
- * non-empty and wholly dead, and returns which it admitted. An ambient declaration describes
180
- * code the target does not implement, so it is no production declaration here. The set is
181
- * read from every reference the test makes, which a production sweep does not count. A
182
- * test-support declaration a test referencing a live target also references is a live
183
- * target of every test referencing it. A marked or exempt test is never admitted.
184
- */
185
- function admitTestsOfDeadCode(graph, dead, held) {
186
- const testCode = (at) => graph.test[at] === true || graph.support[at] === true;
187
- const judged = graph.symbols.map((_symbol, at) => {
188
- let targets = 0;
189
- let live = 0;
190
- if (testCode(at) && graph.subject[at] === true && held[at] !== true) {
191
- for (const edge of graph.out[at] ?? []) {
192
- if (testCode(edge.to) ||
193
- graph.subject[edge.to] !== true ||
194
- graph.ambient[edge.to] === true) {
195
- continue;
196
- }
197
- targets += 1;
198
- if (dead[edge.to] !== true) {
199
- live += 1;
200
- }
201
- }
202
- }
203
- return { targets, live };
204
- });
205
- const shared = new Set();
206
- judged.forEach(({ live }, at) => {
207
- if (live > 0) {
208
- for (const edge of graph.out[at] ?? []) {
209
- if (graph.support[edge.to] === true) {
210
- shared.add(edge.to);
211
- }
212
- }
213
- }
214
- });
215
- const admitted = graph.symbols.map(() => false);
216
- judged.forEach(({ targets, live }, at) => {
217
- const sharing = (graph.out[at] ?? []).some((edge) => shared.has(edge.to) && edge.to !== at);
218
- if (targets > 0 && live === 0 && !sharing) {
219
- dead[at] = true;
220
- admitted[at] = true;
221
- }
222
- });
223
- return admitted;
224
- }
@@ -1,101 +0,0 @@
1
- /**
2
- * The test files a derived matrix holds although no configuration's file list names them.
3
- * The test runner compiles such a file with the options of the nearest compiler
4
- * configuration at or above it, so the file joins that configuration's program as a file
5
- * its list names, unless a `package.json` below that configuration's directory makes the
6
- * file another package's, which its own test runner compiles.
7
- */
8
- import { sourcePaths } from "./file-facts.js";
9
- import { dirnamePath, joinPath, relativePath } from "./paths.js";
10
- import { writtenPath } from "./workspace-programs.js";
11
- const PREFERRED = "/tsconfig.json";
12
- /** The configurations of one directory in the order a file joins them: `tsconfig.json` first. */
13
- function byPreference(a, b) {
14
- const first = a.endsWith(PREFERRED) ? 0 : 1;
15
- const second = b.endsWith(PREFERRED) ? 0 : 1;
16
- return first - second || (a < b ? -1 : a > b ? 1 : 0);
17
- }
18
- /**
19
- * Per configuration of `configFiles`, the absolute paths of the test files that join it:
20
- * each file below `root` a pattern of `patterns` names, that no configuration's file list
21
- * holds, joins the configuration nearest at or above its directory when no `package.json`
22
- * sits between them. A configuration the compiler cannot read lists nothing and is joined
23
- * by nothing.
24
- */
25
- export function joinedTestFiles(engine, host, root, configFiles, patterns) {
26
- const listed = new Set();
27
- const byDir = new Map();
28
- for (const configFile of configFiles) {
29
- let fileNames;
30
- try {
31
- fileNames = engine.parseConfigFile(configFile).fileNames;
32
- }
33
- catch {
34
- continue;
35
- }
36
- fileNames.forEach((name) => listed.add(name));
37
- const dir = dirnamePath(configFile);
38
- byDir.set(dir, [...(byDir.get(dir) ?? []), configFile].sort(byPreference));
39
- }
40
- const joins = new Map();
41
- for (const path of sourcePaths(host, root)) {
42
- const file = joinPath(root, path);
43
- if (listed.has(file) || !patterns.some((pattern) => pattern.test(path))) {
44
- continue;
45
- }
46
- for (let dir = dirnamePath(file);; dir = dirnamePath(dir)) {
47
- const [nearest] = byDir.get(dir) ?? [];
48
- if (nearest !== undefined) {
49
- joins.set(nearest, [...(joins.get(nearest) ?? []), file]);
50
- break;
51
- }
52
- if (host.kindOf(joinPath(dir, "package.json")) === "file" ||
53
- dir === root ||
54
- relativePath(root, dir) === undefined) {
55
- break;
56
- }
57
- }
58
- }
59
- return joins;
60
- }
61
- /**
62
- * How the snapshot reads each configuration a test file joins: the program `programs`
63
- * describes with the files added to its root files, or a configuration only the snapshot
64
- * holds that extends the one `programs` writes, or the configuration itself, and lists
65
- * every file the configuration lists and the joined ones.
66
- */
67
- export function withJoinedTests(engine, host, programs, joins) {
68
- const found = new Map(programs);
69
- for (const [configFile, files] of joins) {
70
- const program = programs.get(configFile);
71
- if (program?.kind === "program") {
72
- found.set(configFile, {
73
- kind: "program",
74
- params: {
75
- ...program.params,
76
- rootFiles: [...(program.params.rootFiles ?? []), ...files],
77
- },
78
- });
79
- continue;
80
- }
81
- let listed;
82
- try {
83
- listed =
84
- program?.kind === "configuration"
85
- ? engine.parseConfigJson(JSON.parse(program.text), program.file).fileNames
86
- : engine.parseConfigFile(configFile).fileNames;
87
- }
88
- catch {
89
- continue;
90
- }
91
- const value = program?.kind === "configuration"
92
- ? { ...JSON.parse(program.text), files: [...listed, ...files] }
93
- : { extends: configFile, files: [...listed, ...files] };
94
- found.set(configFile, {
95
- kind: "configuration",
96
- file: program?.kind === "configuration" ? program.file : writtenPath(host, configFile),
97
- text: `${JSON.stringify({ ...value, include: [] }, null, 2)}\n`,
98
- });
99
- }
100
- return found;
101
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * The Contract version this analyzer implements. It is the resolved value of
3
- * `contract_version` when no configuration source supplies one, and it moves
4
- * independently of the analyzer's own version, which is the one the host answers
5
- * from the package the analyzer was installed from.
6
- */
7
- export const CONTRACT_VERSION = "8.0.0";
@@ -1,185 +0,0 @@
1
- /**
2
- * The source files a CI workflow's `run:` steps and the repository's git hooks name by their
3
- * path from the target root. A workflow or hook file is read as text, line by line, with no
4
- * YAML parsed.
5
- */
6
- import { scriptTokens } from "./manifest.js";
7
- import { joinPath, relativePath, resolvePath } from "./paths.js";
8
- const WORKFLOWS = ".github/workflows";
9
- /** A line holding a run command: indentation and one sequence marker before `run:`. */
10
- const RUN_LINE = /^(\s*(?:- )?)run:(.*)$/u;
11
- /** The directories whose every file is a git hook script, run as the shell runs it. */
12
- const HOOK_DIRS = [".husky", ".githooks"];
13
- /** The hook manager files whose commands are written under a key, with that key. */
14
- const HOOK_MANAGERS = [
15
- [".pre-commit-config.yaml", /^(\s*(?:- )?)entry:(.*)$/u],
16
- ["lefthook.yml", RUN_LINE],
17
- ["lefthook.yaml", RUN_LINE],
18
- [".lefthook.yml", RUN_LINE],
19
- ];
20
- /** The names GNU make reads a makefile under, in the order it tries them. */
21
- const MAKEFILES = ["GNUmakefile", "makefile", "Makefile"];
22
- /** The operators that end one shell command of a recipe line. */
23
- const COMMAND_SEPARATORS = /&&|\|\||;|\|/u;
24
- const BLOCK_SCALAR = /^[|>][+-]?$/u;
25
- const QUOTED = /^(["'])(.*)\1$/su;
26
- /** A token holding one of these is computed or a pattern, so it names no file. */
27
- const COMPUTED = /[${*?[]/u;
28
- const INDENT = /^\s*/u;
29
- /** The files directly in one directory whose name `accepts`, in name order. */
30
- function filesIn(host, dir, accepts) {
31
- let entries;
32
- try {
33
- entries = host.readDirectory(dir);
34
- }
35
- catch {
36
- return [];
37
- }
38
- return entries
39
- .filter((entry) => !entry.directory && accepts(entry.name))
40
- .map((entry) => joinPath(dir, entry.name))
41
- .sort();
42
- }
43
- function readText(host, path) {
44
- try {
45
- return host.readFile(path);
46
- }
47
- catch {
48
- return undefined;
49
- }
50
- }
51
- /** Every command line one workflow file's `run:` steps, or the steps under `key`, hold. */
52
- export function runCommands(text, key = RUN_LINE) {
53
- const lines = text.split(/\r?\n/u);
54
- const found = [];
55
- for (let at = 0; at < lines.length; at += 1) {
56
- const match = key.exec(lines[at] ?? "");
57
- if (match === null) {
58
- continue;
59
- }
60
- const column = (match[1] ?? "").length;
61
- const value = (match[2] ?? "").trim().replace(QUOTED, "$2");
62
- if (!BLOCK_SCALAR.test(value)) {
63
- found.push(value);
64
- continue;
65
- }
66
- for (let next = at + 1; next < lines.length; next += 1) {
67
- const line = lines[next] ?? "";
68
- if (line.trim() !== "" && (INDENT.exec(line)?.[0].length ?? 0) <= column) {
69
- break;
70
- }
71
- found.push(line);
72
- }
73
- }
74
- return found;
75
- }
76
- /**
77
- * Every token the recipe lines of the target root's makefile hold, each with the directory
78
- * below the root it is read against: a recipe line is one that starts with a tab, joined
79
- * with the lines a trailing `\` continues it onto, and make runs each in a shell of its
80
- * own, so a `cd` moves the directory of the later commands of its line alone.
81
- */
82
- function recipeTokens(host, root) {
83
- const path = MAKEFILES.map((name) => joinPath(root, name)).find((candidate) => host.kindOf(candidate) === "file");
84
- const text = path === undefined ? undefined : readText(host, path);
85
- if (text === undefined) {
86
- return [];
87
- }
88
- const found = [];
89
- for (const line of text.replace(/\\\r?\n/gu, " ").split(/\r?\n/u)) {
90
- if (!line.startsWith("\t")) {
91
- continue;
92
- }
93
- let dir = root;
94
- for (const command of withoutComment(line.slice(1).replace(/^[@+-]+/u, "")).split(COMMAND_SEPARATORS)) {
95
- const tokens = scriptTokens(command);
96
- const [first, target, ...rest] = tokens;
97
- if (first === "cd" && target !== undefined && rest.length === 0 && !COMPUTED.test(target)) {
98
- dir = resolvePath(dir, target);
99
- continue;
100
- }
101
- for (const token of tokens) {
102
- found.push({ token, dir: relativePath(root, dir) ?? "" });
103
- }
104
- }
105
- }
106
- return found;
107
- }
108
- /** One shell line up to its comment: a `#` that starts a word outside quotes. */
109
- function withoutComment(line) {
110
- let quote = "";
111
- for (let at = 0; at < line.length; at += 1) {
112
- const char = line[at];
113
- if (quote !== "") {
114
- if (char === quote) {
115
- quote = "";
116
- }
117
- else if (char === "\\" && quote === '"') {
118
- at += 1;
119
- }
120
- }
121
- else if (char === "'" || char === '"') {
122
- quote = char;
123
- }
124
- else if (char === "\\") {
125
- at += 1;
126
- }
127
- else if (char === "#" && (at === 0 || /\s/u.test(line[at - 1] ?? ""))) {
128
- return line.slice(0, at);
129
- }
130
- }
131
- return line;
132
- }
133
- /**
134
- * Every token the target root's workflow steps, git hooks and makefile hold: the `run:`
135
- * steps of the workflow files in `.github/workflows`, every line of each file in `.husky`
136
- * and `.githooks`, the `entry:` commands of `.pre-commit-config.yaml`, the `run:` commands
137
- * of a lefthook file and the makefile's recipe lines.
138
- */
139
- export function workflowTokens(host, targetRoot) {
140
- const root = resolvePath(host.workingDirectory(), targetRoot);
141
- const commands = [];
142
- for (const path of filesIn(host, joinPath(root, WORKFLOWS), (name) => /\.ya?ml$/u.test(name))) {
143
- commands.push(...runCommands(readText(host, path) ?? ""));
144
- }
145
- for (const dir of HOOK_DIRS) {
146
- for (const path of filesIn(host, joinPath(root, dir), () => true)) {
147
- commands.push(...(readText(host, path) ?? "").split(/\r?\n/u).map(withoutComment));
148
- }
149
- }
150
- for (const [name, key] of HOOK_MANAGERS) {
151
- commands.push(...runCommands(readText(host, joinPath(root, name)) ?? "", key));
152
- }
153
- return [
154
- ...commands.flatMap((command) => scriptTokens(command)),
155
- ...recipeTokens(host, root).map(({ token }) => token),
156
- ];
157
- }
158
- /**
159
- * The own files the target root's workflow steps and git hooks name, as
160
- * {@link workflowTokens} reads them: a token equal to a file's path below the target root,
161
- * with or without a leading `./`, whatever directory the step runs in.
162
- */
163
- export function workflowEntries(host, targetRoot, files) {
164
- const found = [];
165
- for (const token of workflowTokens(host, targetRoot)) {
166
- if (COMPUTED.test(token)) {
167
- continue;
168
- }
169
- const file = files.byPath.get(token.startsWith("./") ? token.slice(2) : token);
170
- if (file !== undefined) {
171
- found.push({ file, source: token });
172
- }
173
- }
174
- const root = resolvePath(host.workingDirectory(), targetRoot);
175
- for (const { token, dir } of recipeTokens(host, root)) {
176
- const below = COMPUTED.test(token) || dir === ""
177
- ? undefined
178
- : relativePath(root, resolvePath(joinPath(root, dir), token));
179
- const file = below === undefined ? undefined : files.byPath.get(below);
180
- if (file !== undefined) {
181
- found.push({ file, source: token });
182
- }
183
- }
184
- return found;
185
- }
package/src/base-url.ts DELETED
@@ -1,24 +0,0 @@
1
- import { resolvePath } from "./paths.ts";
2
- import type { Engine } from "./session.ts";
3
-
4
- type CompilerOptions = ReturnType<Engine["parseConfigFile"]>["options"];
5
-
6
- /**
7
- * The `paths` one configuration's resolved options map under the compilers before version
8
- * 7, each target absolute: a target is read against the effective `baseUrl`, and a specifier
9
- * no other pattern maps is looked up below it. Undefined where no `baseUrl` is set, so the
10
- * options' own `paths` stand. Version 7 reads no `baseUrl`:
11
- * https://github.com/microsoft/TypeScript/issues/62207
12
- */
13
- export function baseUrlPaths(options: CompilerOptions): Record<string, string[]> | undefined {
14
- const baseUrl: unknown = Reflect.get(options, "baseUrl");
15
- if (typeof baseUrl !== "string") {
16
- return undefined;
17
- }
18
- return Object.fromEntries(
19
- Object.entries({ "*": ["*"], ...options.paths }).map(([key, targets]) => [
20
- key,
21
- targets.map((target) => resolvePath(baseUrl, target)),
22
- ]),
23
- );
24
- }