@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/analysis.ts CHANGED
@@ -6,131 +6,90 @@
6
6
  * another project's checker, which holds only for views the session hands out.
7
7
  */
8
8
 
9
- import { isStringLiteralLikeNode } from "@typescript/native/ast";
9
+ import { isStringLiteralLikeNode, type SourceFile } from "@typescript/native/ast";
10
10
  import { lineOf, readComponent } from "./component-files.ts";
11
- import { kindOf, type Config, type Provenance } from "./config.ts";
12
- import {
13
- consumerLoads,
14
- consumerReferences,
15
- moduleIdentity,
16
- type LoadedConsumer,
17
- } from "./consumers.ts";
11
+ import { kindOf, type PartialConfig, type Provenance, type ResolvedConfig } from "./config.ts";
12
+ import { consumerReferences } from "./consumers.ts";
18
13
  import {
19
14
  configuredDeclarations,
20
15
  configuredRef,
21
16
  declarationsNamed,
22
- } from "./configured-declarations.ts";
23
- import { decorator } from "./decorator.ts";
17
+ } from "./roots/configured-declarations.ts";
24
18
  import { configurationNeeds, dependenciesOf, projectNeeds } from "./dependencies.ts";
19
+ import { carriersOf, NO_CARRIERS, type Carriers } from "./exposure.ts";
25
20
  import { deprecatedDeclarations, type Deprecation } from "./deprecation.ts";
26
- import {
27
- discoverProjects,
28
- DiscoveryError,
29
- isGuess,
30
- MISSING_GLOBAL_TYPE,
31
- projectErrors,
32
- renderDiagnostic,
33
- targetRelative,
34
- withBaseUrlPaths,
35
- type LocatedDiagnostic,
36
- type NotBuilt,
37
- } from "./discover.ts";
38
- import {
39
- conventionFailuresFor,
40
- generatedFiles,
41
- readConventions,
42
- type AppliedConvention,
43
- type ConventionManifest,
44
- type Conventions,
45
- } from "./conventions.ts";
21
+ import { moduleIdentity, type LoadedConsumer, type NotBuilt } from "./load/discover.ts";
22
+ import type { LibraryUnfound } from "./load/classify.ts";
23
+ import { loadRun, type LoadedRun } from "./load/load.ts";
24
+ import type { AppliedConvention } from "./entries/conventions.ts";
25
+ import { readSources, type SourceFacts } from "./entries/sources.ts";
26
+ import { readWorkflows, type Workflows } from "./entries/workflow-steps.ts";
46
27
  import { readEdgeSides } from "./edges.ts";
47
- import { enumGroup } from "./enum-group.ts";
48
- import { generatedFile, generatedFilesOf } from "./generated-file.ts";
49
- import { inOperandNames } from "./in-operands.ts";
28
+ import { bindingsOf, distinctBindings, type BindingRecord } from "./bindings.ts";
29
+ import { generatedFilesOf, type GeneratedFact } from "./exemptions/generated-file.ts";
30
+ import { inOperandNames } from "./findings/in-operands.ts";
50
31
  import { sourceFilesOf } from "./source-files.ts";
51
- import {
52
- evidenceRecords,
53
- heldRecords,
54
- disabledClasses,
55
- exemptionsOf,
56
- holdingWhile,
57
- isUnansweredRecord,
58
- retainedIn,
59
- type Detector,
60
- type Detectors,
61
- } from "./exempt.ts";
62
- import type { TSExemptionClass } from "./exempt-classes.ts";
32
+ import { DETECTORS, detection } from "./exemptions/detectors.ts";
33
+ import { exemptionsOf, settle, type Detectors, type Exemption } from "./exemptions/lifecycle.ts";
63
34
  import { heldByInclusion, sourcePaths, sourceTree } from "./file-facts.ts";
64
- import { globExpression } from "./glob.ts";
65
35
  import type { Finding } from "./finding.ts";
66
36
  import { findingsPass, recordedFindings, rowKey, type PassResult } from "./findings-pass.ts";
67
37
  import type { EmitterInput } from "./findings/emitter.ts";
68
38
  import { unmatchedRootFindings, type SelfCheckFacts } from "./findings/self-check.ts";
69
- import { frameworkLifecycle } from "./framework-lifecycle.ts";
70
39
  import type { Host } from "./host.ts";
71
- import { implementations, mergeImplementations } from "./implementations.ts";
72
- import { injectionContainer } from "./injection-container.ts";
73
- import { interfaceSatisfaction, settledSatisfaction } from "./interface-satisfaction.ts";
40
+ import { implementations, mergeImplementations } from "./findings/implementations.ts";
74
41
  import { intraFunctionFacts, projectParts, type ProjectParts } from "./intra-function-parts.ts";
75
- import { inventory, type Inventory, type InventorySymbol } from "./inventory.ts";
76
- import { packageEntries, readManifest, type ManifestEntry } from "./manifest.ts";
77
- import {
78
- liveFilesAt,
79
- matrixOf,
80
- referenceKey,
81
- sweepMatrix,
82
- type Configured,
83
- type Matrix,
84
- type SweepResult,
85
- } from "./matrix.ts";
42
+ import { type Inventory, type InventorySymbol } from "./inventory.ts";
43
+ import { inventory } from "./inventory/enumerate.ts";
44
+ import { readManifest, type ManifestEntry } from "./roots/manifest.ts";
45
+ import { matrixOf, referenceKey, type Configured, type Matrix } from "./liveness/matrix.ts";
86
46
  import {
47
+ ancestors,
87
48
  dirnamePath,
88
49
  extensionOf,
89
50
  joinPath,
90
- normalizePath,
91
51
  relativePath,
92
52
  resolvePath,
93
53
  } from "./paths.ts";
94
54
  import type { UnansweredQuestion } from "./query.ts";
95
55
  import { byPosition, isComponentFile, type Position } from "./position.ts";
96
- import { LANGUAGE, type TypeErrorSkip, type UnansweredCount } from "./report.ts";
97
- import { SetupError, setupLine, type SetupFailure } from "./setup-failure.ts";
98
- import {
99
- pathsOf,
100
- readErrors,
101
- skippedRoots,
102
- skippedUnits,
103
- type SkippedUnit,
104
- } from "./type-errors.ts";
105
- import { reflectiveLookup } from "./reflective-lookup.ts";
106
- import { references, testFileRulesOf, type Reference, type TestFileRule } from "./references.ts";
56
+ import type { TypeErrorSkip, UnansweredCount } from "./report.ts";
57
+ import { skippedUnits, type SkippedUnit } from "./type-errors.ts";
58
+ import { references, type Reference } from "./references.ts";
107
59
  import {
108
- roots,
60
+ rootSet,
109
61
  unmatchedEverywhere,
110
62
  type RootKind,
111
- type RootOptions,
112
63
  type Roots,
113
- } from "./roots.ts";
64
+ type HeldScripts,
65
+ } from "./roots/root-set.ts";
114
66
  import type { Scope } from "./scope.ts";
115
- import { serializationContract } from "./serialization-contract.ts";
116
- import { outsideTestReferences, testFilesAt, type OutsideTest } from "./outside-tests.ts";
117
- import { joinedTestFiles, withJoinedTests } from "./test-joins.ts";
118
- import { supportReferences, testSupportFiles, type TestEvidence } from "./test-support.ts";
67
+ import { decodedMembers, type Decoded } from "./exemptions/serialization-contract.ts";
68
+ import { outsideTestReferences, testFilesAt, type OutsideTest } from "./tests/outside.ts";
69
+ import type { UnseenLoad } from "./roots/unseen-loads.ts";
70
+ import type { UnresolvedSpecifier } from "./load/specifiers.ts";
71
+ import { formedForNode } from "./load/synthesize.ts";
72
+ import type { UnreadInput } from "./load/plan.ts";
73
+ import { GLOBALS_RUNNER, namesTestGlobals } from "./load/test-globals.ts";
119
74
  import {
120
- diagnosticsOf,
121
- ownedAs,
122
- runSession,
123
- type Engine,
124
- type OpenedFiles,
125
- type ProjectView,
126
- } from "./session.ts";
75
+ targetTestFile,
76
+ testFilePaths,
77
+ testFileRulesOf,
78
+ withheldBy,
79
+ type TestFileRule,
80
+ } from "./tests/file-class.ts";
81
+ import { testSupportFiles, type TestEvidence } from "./tests/support.ts";
82
+ import type { Engine, ProjectView } from "./session.ts";
127
83
  import { accessorsOf, storesOf } from "./stores.ts";
128
84
  import { isPartKind, type SuppressionRecord, type Suppressions, type Verdict } from "./suppress.ts";
129
85
  import { bindRows, readBaseline, readIgnoreFile, type Recorded } from "./suppress-file.ts";
130
86
  import { inlineDirectives, inlineSuppressions, type InlineDirective } from "./suppress-inline.ts";
131
- import type { Exemption, Mode, SweepInput } from "./sweep.ts";
132
- import { readTemplates, templateField } from "./template-field.ts";
133
- import { ownErrors, workspaceRun } from "./workspace-run.ts";
87
+ import { sweep, type Sweep, type SweepPolicy } from "./liveness/sweep.ts";
88
+ import type { Mode } from "./tests/file-class.ts";
89
+ import { bytewise } from "./text/compare.ts";
90
+ import { holdsManifest, manifestAt } from "./fs/manifest.ts";
91
+ import { runDirectories } from "./entries/run-directories.ts";
92
+ import { globExpression } from "./text/glob.ts";
134
93
 
135
94
  /** The setting whose source decides where a finding about a configured root sits. */
136
95
  const ROOTS_SETTING = "roots.patterns";
@@ -187,14 +146,6 @@ function documentOf(
187
146
  return relativePath(resolvePath(host.workingDirectory(), targetRoot), document) ?? "";
188
147
  }
189
148
 
190
- /** Two strings ordered bytewise. */
191
- function compare(a: string, b: string): number {
192
- if (a === b) {
193
- return 0;
194
- }
195
- return a < b ? -1 : 1;
196
- }
197
-
198
149
  /** What every stage after the root set reads of one project. */
199
150
  interface ProjectRead {
200
151
  readonly configuration: string;
@@ -211,10 +162,14 @@ interface ProjectRead {
211
162
  readonly typeErrorSkips: readonly TypeErrorSkip[];
212
163
  /** The lines each of those skips withholds every finding on. */
213
164
  readonly skipped: readonly SkippedUnit[];
214
- /** The project's generated files, by path below the target root, each with the detail its retentions name. */
215
- readonly generated: ReadonlyMap<string, string>;
216
- /** The files, absolute, an applied convention row names as test files. */
217
- readonly testFileNames: ReadonlySet<string>;
165
+ /** The project's generated files, by path below the target root, each with what decided it. */
166
+ readonly generated: ReadonlyMap<string, GeneratedFact>;
167
+ /** The binding identities its generated files publish (`bindings.6`, `bindings.7`). */
168
+ readonly bindings: readonly BindingRecord[];
169
+ /** What the project's entry sources enter and name, read once. */
170
+ readonly sources: SourceFacts;
171
+ /** Whether the run formed the program to resolve its modules as Node does (program.36). */
172
+ readonly formedForNode: boolean;
218
173
  }
219
174
 
220
175
  /** One target project the run analyzes, as its stage is handed it. */
@@ -224,346 +179,67 @@ interface OpenedProject {
224
179
  readonly read: () => ProjectRead;
225
180
  }
226
181
 
227
- /** What a run read of the consumers its scope declares. */
228
- interface ConsumerReads {
229
- /** Every declared consumer, each loaded, in the scope's order. */
230
- readonly loaded: readonly LoadedConsumer[];
182
+ /** What reading a loaded run's projects answered. */
183
+ interface ProjectsRead<Answer> {
184
+ readonly answers: readonly Answer[];
231
185
  /** Every reference a consumer makes to a declaration of the target, each once. */
232
186
  readonly references: readonly Reference[];
233
- }
234
-
235
- /** What a run read of its projects: each target project's answer, and its consumers. */
236
- interface ReadProjects<Answer> {
237
- readonly answers: readonly Answer[];
238
- readonly consumers: ConsumerReads;
239
- /** The derived configurations the run dropped, in the order it met them. */
240
- readonly notBuilt: readonly NotBuilt[];
241
- /** Every question the checker could not answer, each once. */
242
- readonly unanswered: readonly UnansweredQuestion[];
243
- /** Per configuration whose component files the run cannot read, the reason. */
244
- readonly componentsUnread: readonly ComponentsUnread[];
245
- /** Per analyzed configuration, each library it names that the compiler cannot find. */
246
- readonly librariesUnfound: readonly LibraryUnfound[];
247
- /** The convention rows the run applied. */
248
- readonly conventionsApplied: readonly AppliedConvention[];
249
- /** The dependencies the applied rows' short names use. */
250
- readonly conventionUses: readonly string[];
251
- /** The directory of every workspace member, absolute. */
252
- readonly memberDirs: readonly string[];
253
- /** The directory of every nested package, absolute. */
254
- readonly nestedDirs: readonly string[];
187
+ /** The declarations a consumer's read rules held, each once. */
188
+ readonly consumerHeld: readonly string[];
255
189
  /** The test files below the target root no project the run reads holds, parsed. */
256
190
  readonly outsideTests: readonly OutsideTest[];
191
+ /** The target root's workflow steps, git hooks and makefile, read once for every project. */
192
+ readonly workflows: Workflows;
257
193
  }
258
194
 
259
195
  /**
260
- * The manifests the analysis reads, each once: the target's own, then every workspace
261
- * member's and every nested package's below the target root.
262
- */
263
- function conventionManifests(
264
- host: Host,
265
- targetRoot: string,
266
- memberDirs: readonly string[],
267
- nestedDirs: readonly string[],
268
- ): readonly ConventionManifest[] {
269
- const found = new Map<string, ConventionManifest>();
270
- if (host.kindOf(joinPath(targetRoot, "package.json")) === "file") {
271
- found.set(targetRoot, { dir: targetRoot, path: "package.json" });
272
- }
273
- for (const [dirs, nested] of [
274
- [memberDirs, false],
275
- [nestedDirs, true],
276
- ] as const) {
277
- for (const dir of dirs) {
278
- const below = relativePath(targetRoot, dir);
279
- if (below !== undefined && !found.has(dir)) {
280
- found.set(dir, { dir, path: `${below}/package.json`, nested });
281
- }
282
- }
283
- }
284
- return [...found.values()];
285
- }
286
-
287
- /**
288
- * The nested packages of a run: each directory below the target root, in no `node_modules`
289
- * directory and none of `known`, that holds a `package.json` and lies at or above one of
290
- * `files`, the program's source files and the compiler configuration files, in path order.
291
- */
292
- function nestedPackageDirs(
293
- host: Host,
294
- targetRoot: string,
295
- files: Iterable<string>,
296
- known: ReadonlySet<string>,
297
- ): readonly string[] {
298
- const seen = new Set<string>();
299
- const found: string[] = [];
300
- for (const file of files) {
301
- for (
302
- let dir = dirnamePath(file);
303
- dir !== targetRoot && !seen.has(dir) && relativePath(targetRoot, dir) !== undefined;
304
- dir = dirnamePath(dir)
305
- ) {
306
- seen.add(dir);
307
- const below = relativePath(targetRoot, dir) ?? "";
308
- if (
309
- !below.split("/").includes("node_modules") &&
310
- !known.has(dir) &&
311
- host.kindOf(joinPath(dir, "package.json")) === "file"
312
- ) {
313
- found.push(dir);
314
- }
315
- }
316
- }
317
- return found.sort(compare);
318
- }
319
-
320
- /**
321
- * Reads every project the scope discovers, and each declared consumer's, in one snapshot,
322
- * each checked for errors first. `stage` is handed a target project and enumerates and roots
323
- * it if it reads it; a consumer project is read for its references to the target. A type error
324
- * in an own file skips the unit holding it. A guess that does not load or meets a setup failure
325
- * is dropped into `notBuilt` (see {@link isGuess}); any other such project fails the run, as
326
- * does a run whose every guess was dropped.
196
+ * Reads every project the load phase analyzes through `stage`, which enumerates and roots one
197
+ * if it reads it, and each declared consumer's project for its references to the target,
198
+ * in the same snapshot. A type error in an own file skips the unit holding it.
327
199
  */
328
200
  function readProjects<Answer>(
329
201
  engine: Engine,
330
202
  host: Host,
331
203
  scope: Scope,
332
- config: Config,
204
+ config: PartialConfig,
333
205
  stage: <Brand>(project: ProjectView<Brand>, opened: OpenedProject) => Answer,
334
- ): ReadProjects<Answer> {
206
+ ): LoadedRun<ProjectsRead<Answer>> {
335
207
  const targetRoot = scope.target.path;
336
- const discovered = discoverProjects(engine, host, scope, config.analysis.configurations);
337
- if (discovered.configFiles.length === 0 && discovered.notBuilt.length === 0) {
338
- throw new DiscoveryError(
339
- `${targetRoot} holds no compiler configuration, so the run holds no program`,
340
- [],
341
- );
342
- }
343
- const ids = new Map(discovered.projects.map((project) => [project.configFile, project.id]));
344
- const loads = consumerLoads(engine, host, scope, discovered.configFiles);
345
- const consumerOf = new Map(
346
- loads.flatMap((load) =>
347
- load.configFiles.map((configFile) => [configFile, load.consumer] as const),
348
- ),
349
- );
350
208
  const absoluteRoot = resolvePath(host.workingDirectory(), targetRoot);
351
- const workspace = workspaceRun(
352
- engine,
353
- host,
354
- absoluteRoot,
355
- discovered.configFiles,
356
- readManifest(host, targetRoot),
357
- );
209
+ const testPatterns = config.ts.test_files.map(globExpression);
358
210
  const parse = (fileName: string, text: string) => engine.parseSourceFile(fileName, text);
359
- const memberDirs = workspace?.memberDirs ?? [];
360
- // The nested packages are known only once every program is open, and every visit reads
361
- // the conventions and options they decide, so both are set in the session's first step.
362
- let nestedDirs: readonly string[] = [];
363
- let conventions = readConventions(host, parse, [], config.ts.disabledConventions);
364
- let options: RootOptions & { readonly parse: typeof parse; readonly conventions: Conventions };
365
- const readManifests = (opened: readonly OpenedFiles[]): void => {
366
- nestedDirs = nestedPackageDirs(
367
- host,
368
- normalizePath(absoluteRoot),
369
- opened
370
- .filter((one) => !consumerOf.has(one.configFile))
371
- .flatMap((one) => [one.configFile, ...one.fileNames()]),
372
- new Set(memberDirs),
373
- );
374
- conventions = readConventions(
211
+ return loadRun(engine, host, scope, config, ({ plan, classified, runFiles }) => {
212
+ const { packages, conventions } = plan;
213
+ const workflows = readWorkflows(host, targetRoot);
214
+ const options = {
375
215
  host,
216
+ manifest: packages.manifest,
217
+ otherPackages: packages.entries,
218
+ patterns: config.roots.patterns,
219
+ entryFiles: config.ts.entry_files,
376
220
  parse,
377
- conventionManifests(host, absoluteRoot, memberDirs, nestedDirs),
378
- config.ts.disabledConventions,
379
- );
380
- options = {
381
- host,
382
- manifest: workspace?.manifest ?? readManifest(host, targetRoot),
383
- otherPackages: [
384
- ...(workspace?.entries ?? []),
385
- ...packageEntries(host, normalizePath(absoluteRoot), nestedDirs),
386
- ],
387
- patterns: config.rootPatterns,
388
- entryFiles: config.ts.entryFiles,
389
- conventions,
390
- testFiles: config.ts.testFiles,
391
- parse,
392
- publishedAPI: config.targetKind !== "" && kindOf(config.targetKind, LANGUAGE) === "library",
393
- publishedMembers: new Set(
394
- (workspace?.entries ?? []).filter((entry) => entry.published).map((entry) => entry.dir),
395
- ),
396
- runFiles: new Set(
397
- opened.flatMap((one) =>
398
- one.fileNames().map((name) => resolvePath(host.workingDirectory(), name)),
399
- ),
400
- ),
221
+ publishedAPI: config.target.kind !== undefined && kindOf(config.target.kind) === "library",
222
+ publishedMembers: packages.published,
223
+ runFiles,
401
224
  };
402
- };
403
- const notBuilt: NotBuilt[] = [...discovered.notBuilt];
404
- const dropped = (configFile: string, error: string): void => {
405
- notBuilt.push({
406
- id: ids.get(configFile) ?? configFile,
407
- configFile,
408
- error: targetRelative(error, absoluteRoot),
409
- });
410
- };
411
- const failures: LocatedDiagnostic[] = [];
412
- const unbuildable: SetupFailure[] = [];
413
- const setupDropped: SetupFailure[] = [];
414
- const librariesUnfound: LibraryUnfound[] = [];
415
- const consumed = new Map<string, Reference>();
416
- const heldFiles = new Set<string>();
417
- let outsideTests: readonly OutsideTest[] = [];
418
- const setupMet = (configFile: string, met: readonly SetupFailure[]): void => {
419
- const [first] = met;
420
- if (first !== undefined && isGuess(discovered, configFile)) {
421
- dropped(configFile, setupLine(first));
422
- setupDropped.push(...met);
423
- } else {
424
- unbuildable.push(...met);
425
- }
426
- };
427
- const testPatterns = config.ts.testFiles.map(globExpression);
428
- const joins = discovered.derived
429
- ? joinedTestFiles(engine, host, absoluteRoot, discovered.configFiles, testPatterns)
430
- : new Map<string, readonly string[]>();
431
- const programs = withBaseUrlPaths(
432
- engine,
433
- host,
434
- [...discovered.configFiles, ...consumerOf.keys()],
435
- workspace?.programs ?? new Map(),
436
- );
437
- const session = runSession(
438
- engine,
439
- [...discovered.configFiles, ...consumerOf.keys()],
440
- (opened) => {
441
- const consumer = consumerOf.get(opened.configFile);
442
- const setup = consumer === undefined ? workspace?.unbuildable(opened.configFile) : undefined;
443
- if (setup !== undefined) {
444
- setupMet(opened.configFile, [
445
- { setupClass: "workspace-member-without-source", detail: setup },
446
- ]);
447
- return undefined;
448
- }
449
- const referenceOnly =
450
- workspace === undefined || consumer !== undefined
451
- ? () => false
452
- : workspace.referenceOnly(opened.configFile, opened.rootFiles);
453
- const project =
454
- workspace === undefined || consumer !== undefined
455
- ? opened
456
- : ownedAs(opened, (file, fromExternalLibrary) =>
457
- workspace.ownFile(file, fromExternalLibrary),
458
- );
459
- const raw = projectErrors(diagnosticsOf(project));
460
- const errors = { load: raw.load, check: ownErrors(raw.check, referenceOnly) };
461
- const [unloaded] = errors.load;
462
- if (
463
- unloaded !== undefined &&
464
- consumer === undefined &&
465
- isGuess(discovered, project.configFile)
466
- ) {
467
- dropped(
468
- project.configFile,
469
- renderDiagnostic(unloaded, (path) => relativePath(absoluteRoot, path) ?? path),
470
- );
471
- return undefined;
472
- }
473
- if (errors.load.length > 0) {
474
- failures.push(...errors.load);
475
- return undefined;
476
- }
477
- const reading = readErrors(project, errors.check, {
478
- host,
479
- targetRoot:
480
- consumer === undefined
481
- ? absoluteRoot
482
- : resolvePath(host.workingDirectory(), consumer.path),
483
- paths: pathsOf(engine, project.configFile),
484
- });
485
- if (consumer !== undefined && reading.missing.length > 0) {
486
- unbuildable.push(
487
- ...reading.missing.map((one) => ({
488
- setupClass: "missing-consumer" as const,
489
- detail: `the consumer ${consumer.path} does not build, its dependencies not installed: ${one.detail}`,
490
- })),
491
- );
492
- return undefined;
493
- }
494
- if (reading.missing.length > 0) {
495
- setupMet(project.configFile, reading.missing);
496
- return undefined;
497
- }
498
- const unconventional =
499
- consumer === undefined
500
- ? conventionFailuresFor(
501
- conventions,
502
- project.configFile,
503
- project.ownSourceFiles().map((file) => file.fileName),
504
- )
505
- : [];
506
- if (unconventional.length > 0) {
507
- setupMet(project.configFile, unconventional);
508
- return undefined;
509
- }
510
- if (consumer !== undefined) {
511
- for (const reference of consumerReferences(
512
- project,
513
- host,
514
- targetRoot,
515
- {
516
- id: consumer.id,
517
- root: consumer.path,
518
- },
519
- config,
520
- )) {
521
- consumed.set(referenceKey(reference), reference);
522
- }
523
- return undefined;
524
- }
525
- librariesUnfound.push(
526
- ...raw.unfound.map((one) => ({
527
- configFile: project.configFile,
528
- error: renderDiagnostic(one, (path) => relativePath(absoluteRoot, path) ?? path),
529
- })),
530
- );
531
- const missingGlobal = raw.unfound.find(
532
- ({ diagnostic }) => diagnostic.code === MISSING_GLOBAL_TYPE,
533
- );
534
- const skips =
535
- missingGlobal === undefined
536
- ? reading.skips
537
- : [
538
- ...reading.skips,
539
- ...project.ownSourceFiles().map((file) => ({
540
- record: {
541
- path: relativePath(absoluteRoot, file.fileName) ?? file.fileName,
542
- line: 1,
543
- message: missingGlobal.diagnostic.text,
544
- },
545
- file,
546
- unit: file,
547
- })),
548
- ];
549
- const configuration = ids.get(project.configFile) ?? project.configFile;
225
+ const heldFiles = new Set<string>();
226
+ const answers = classified.analyzed.map(({ plan: planned, project, skips, referenceOnly }) => {
550
227
  const read = (): ProjectRead => {
551
228
  const held = inventory(project, host, targetRoot);
552
- const found = roots(project, held, targetRoot, options);
553
- const kept = skippedRoots(project, held, skips);
554
- const rooted =
555
- kept.length === 0
556
- ? found
557
- : {
558
- ...found,
559
- liveUnderReachability: [
560
- ...found.liveUnderReachability,
561
- ...kept.map((id) => ({ id, kind: "type-error" as const, source: "" })),
562
- ],
563
- };
564
229
  const own = sourceFilesOf(project, targetRoot);
230
+ const sources = readSources({
231
+ host,
232
+ targetRoot,
233
+ files: own,
234
+ parse,
235
+ testFiles: config.ts.test_files,
236
+ conventions,
237
+ workflows,
238
+ });
239
+ const rooted = rootSet(project, held, targetRoot, { ...options, sources, skips });
240
+ const generated = generatedFilesOf(own, sources.generated);
565
241
  return {
566
- configuration,
242
+ configuration: planned.id,
567
243
  configFile: project.configFile,
568
244
  held,
569
245
  rooted,
@@ -573,71 +249,53 @@ function readProjects<Answer>(
573
249
  .ownSourceFiles()
574
250
  .filter((file) => referenceOnly(file.fileName))
575
251
  .flatMap((file) => relativePath(absoluteRoot, file.fileName) ?? []),
576
- generated: generatedFilesOf(own, generatedFiles(conventions, own)),
577
- testFileNames: conventions.testFiles,
252
+ generated,
253
+ bindings: bindingsOf(
254
+ own.byPath,
255
+ generated,
256
+ new Map(
257
+ held.symbols
258
+ .filter((one) => one.kind === "file")
259
+ .map((one) => [one.position.path, one.ref]),
260
+ ),
261
+ ),
262
+ sources,
263
+ formedForNode: formedForNode(planned),
578
264
  };
579
265
  };
580
266
  for (const file of project.ownSourceFiles()) {
581
267
  heldFiles.add(relativePath(absoluteRoot, file.fileName) ?? file.fileName);
582
268
  }
583
- return stage(project, { configuration, read });
584
- },
585
- discovered.derived ? "record" : "refuse",
586
- joins.size === 0 ? programs : withJoinedTests(engine, host, programs, joins),
587
- () => {
588
- outsideTests = testFilesAt(
589
- host,
590
- targetRoot,
591
- sourcePaths(host, targetRoot).filter(
592
- (path) => !heldFiles.has(path) && testPatterns.some((pattern) => pattern.test(path)),
593
- ),
594
- parse,
595
- );
596
- },
597
- readManifests,
598
- );
599
- for (const configFile of session.unopened) {
600
- if (consumerOf.has(configFile) || !isGuess(discovered, configFile)) {
601
- throw new DiscoveryError(`${configFile} opened no project`, []);
269
+ return stage(project, { configuration: planned.id, read });
270
+ });
271
+ const consumed = new Map<string, Reference>();
272
+ const consumerHeld = new Set<string>();
273
+ for (const { project, consumer } of classified.consumed) {
274
+ const side = { id: consumer.id, root: consumer.path };
275
+ const read = consumerReferences(project, host, targetRoot, side, config, parse);
276
+ for (const reference of read.references) {
277
+ consumed.set(referenceKey(reference), reference);
278
+ }
279
+ for (const id of read.held) {
280
+ consumerHeld.add(id);
281
+ }
602
282
  }
603
- dropped(configFile, "the compiler opened no project for the configuration");
604
- }
605
- if (unbuildable.length > 0) {
606
- throw new SetupError(unbuildable);
607
- }
608
- if (failures.length > 0) {
609
- throw new DiscoveryError(
610
- `${String(failures.length)} error(s), so no answer was produced`,
611
- failures,
612
- );
613
- }
614
- const answers = session.projects.filter((answer): answer is Answer => answer !== undefined);
615
- const [first] = notBuilt;
616
- if (answers.length === 0 && setupDropped.length > 0) {
617
- throw new SetupError(setupDropped);
618
- }
619
- if (answers.length === 0 && first !== undefined) {
620
- throw new DiscoveryError(
621
- `no configuration discovery derived could be built; ${first.id}: ${first.error}`,
622
- [],
283
+ const outsideTests = testFilesAt(
284
+ host,
285
+ targetRoot,
286
+ sourcePaths(host, targetRoot).filter(
287
+ (path) => !heldFiles.has(path) && testPatterns.some((pattern) => pattern.test(path)),
288
+ ),
289
+ parse,
623
290
  );
624
- }
625
- return {
626
- answers,
627
- consumers: {
628
- loaded: loads.map((load) => load.consumer),
291
+ return {
292
+ answers,
629
293
  references: [...consumed.values()],
630
- },
631
- notBuilt,
632
- unanswered: session.unanswered,
633
- componentsUnread: workspace?.componentsUnread ?? [],
634
- librariesUnfound,
635
- conventionsApplied: conventions.applied,
636
- conventionUses: conventions.uses,
637
- memberDirs,
638
- nestedDirs,
639
- outsideTests,
640
- };
294
+ consumerHeld: [...consumerHeld],
295
+ outsideTests,
296
+ workflows,
297
+ };
298
+ });
641
299
  }
642
300
 
643
301
  /** The projects one run analyzes, and what reading them left out. */
@@ -655,7 +313,12 @@ interface RunProjects {
655
313
  * for the errors and setup failures that decide whether it is analyzed, dropped or
656
314
  * fails the run, exactly as the analysis reads them.
657
315
  */
658
- export function runProjects(engine: Engine, host: Host, scope: Scope, config: Config): RunProjects {
316
+ export function runProjects(
317
+ engine: Engine,
318
+ host: Host,
319
+ scope: Scope,
320
+ config: PartialConfig,
321
+ ): RunProjects {
659
322
  const read = readProjects(
660
323
  engine,
661
324
  host,
@@ -663,7 +326,11 @@ export function runProjects(engine: Engine, host: Host, scope: Scope, config: Co
663
326
  config,
664
327
  (_project, opened) => opened.configuration,
665
328
  );
666
- return { configurations: read.answers, notBuilt: read.notBuilt, unanswered: read.unanswered };
329
+ return {
330
+ configurations: read.result.answers,
331
+ notBuilt: read.classified.notBuilt,
332
+ unanswered: read.unanswered,
333
+ };
667
334
  }
668
335
 
669
336
  /**
@@ -676,12 +343,12 @@ export function runRoots(
676
343
  engine: Engine,
677
344
  host: Host,
678
345
  scope: Scope,
679
- config: Config,
346
+ config: ResolvedConfig,
680
347
  provenance: Provenance,
681
348
  ): RunRoots {
682
349
  const targetRoot = scope.target.path;
683
350
  const read = readProjects(engine, host, scope, config, (_project, opened) => opened.read());
684
- const projects = read.answers;
351
+ const projects = read.result.answers;
685
352
 
686
353
  const configurations: string[] = [];
687
354
  const merged = new Map<string, Omit<RunRoot, "configurations"> & { configurations: string[] }>();
@@ -712,10 +379,12 @@ export function runRoots(
712
379
 
713
380
  const ordered = [...merged.values()].sort(
714
381
  (a, b) =>
715
- byPosition(a.position, b.position) || compare(a.kind, b.kind) || compare(a.source, b.source),
382
+ byPosition(a.position, b.position) ||
383
+ bytewise(a.kind, b.kind) ||
384
+ bytewise(a.source, b.source),
716
385
  );
717
386
  const unmatched = unmatchedEverywhere(
718
- config.rootPatterns,
387
+ config.roots.patterns,
719
388
  projects.map((answer) => answer.rooted),
720
389
  );
721
390
  return {
@@ -725,58 +394,39 @@ export function runRoots(
725
394
  unmatched,
726
395
  documentOf(host, provenance, ROOTS_SETTING, targetRoot),
727
396
  ),
728
- notBuilt: read.notBuilt,
397
+ notBuilt: read.classified.notBuilt,
729
398
  unanswered: read.unanswered,
730
399
  };
731
400
  }
732
401
 
402
+ /** The production mode a configuration sets: a consumer's test reference is classed as `analysis.consumer_tests` says. */
403
+ export function productionMode(config: PartialConfig): Mode {
404
+ return {
405
+ production: true,
406
+ consumerTestsProduction: config.analysis.consumer_tests === "production",
407
+ };
408
+ }
409
+
733
410
  /** The run's sweep, beside the matrix it judged. */
734
411
  export interface RunSweep {
735
412
  readonly matrix: Matrix;
736
- readonly sweep: SweepResult;
737
- /** The exemption records that hold under the sweep. */
738
- readonly exempt: readonly Exemption[];
739
- /**
740
- * The exemption records that held back a declaration some configuration of the run
741
- * would otherwise judge dead, in the declarations' site order.
742
- */
743
- readonly retained: readonly Exemption[];
413
+ readonly sweep: Sweep;
744
414
  /** The derived configurations the run dropped. */
745
415
  readonly notBuilt: readonly NotBuilt[];
746
416
  /** Every question the checker could not answer, each once. */
747
417
  readonly unanswered: readonly UnansweredQuestion[];
748
- /**
749
- * Every declaration an unanswered question could have kept live, and every one only
750
- * such a declaration keeps live. The run reports none of them.
751
- */
752
- readonly heldByUnanswered: readonly string[];
753
418
  /** The lines of the units type errors skipped, on which the run reports nothing. */
754
419
  readonly skipped: readonly SkippedUnit[];
755
- /** The component files the run read, by path below the target root, each once. */
756
- readonly componentFiles: readonly string[];
757
420
  }
758
421
 
759
422
  /** One `<script` start tag of a component file the run read no block for. */
760
- export interface ComponentWarning {
423
+ interface ComponentWarning {
761
424
  /** The file, below the target root. */
762
425
  readonly path: string;
763
426
  readonly line: number;
764
427
  readonly reason: string;
765
428
  }
766
429
 
767
- /** The exemption classes this analyzer detects, each by its detector; any other retains nothing. */
768
- export const DETECTORS: Detectors = new Map<TSExemptionClass, Detector>([
769
- ["interface-satisfaction", interfaceSatisfaction],
770
- ["enum-group", enumGroup],
771
- ["generated-file", generatedFile],
772
- ["template-field", templateField],
773
- ["reflective-lookup", reflectiveLookup],
774
- ["decorator", decorator],
775
- ["injection-container", injectionContainer],
776
- ["framework-lifecycle", frameworkLifecycle],
777
- ["serialization-contract", serializationContract],
778
- ]);
779
-
780
430
  /** What the sweep of one run reads of each project, beside what a caller's stage adds. */
781
431
  interface SweptProject<Extra> {
782
432
  readonly configFile: string;
@@ -784,6 +434,10 @@ interface SweptProject<Extra> {
784
434
  readonly exempt: readonly Exemption[];
785
435
  /** The declarations of the project an unanswered question could have kept live. */
786
436
  readonly unanswered: readonly string[];
437
+ /** The data members a generic declared outside the analysis fills, which it may read. */
438
+ readonly filledOutside: readonly string[];
439
+ /** What only a bundler's retry of an import Node leaves unresolved names (program.38). */
440
+ readonly possiblyLoaded: readonly string[];
787
441
  readonly typeErrorSkips: readonly TypeErrorSkip[];
788
442
  readonly skipped: readonly SkippedUnit[];
789
443
  /** The component files the project holds of its own, by path below the target root. */
@@ -791,6 +445,7 @@ interface SweptProject<Extra> {
791
445
  readonly componentWarnings: readonly ComponentWarning[];
792
446
  /** The manifest entries the project reads back to no file of its own. */
793
447
  readonly unmappedEntries: readonly ManifestEntry[];
448
+ readonly heldScripts: readonly HeldScripts[];
794
449
  readonly extra: Extra;
795
450
  }
796
451
 
@@ -798,12 +453,17 @@ interface SweptProject<Extra> {
798
453
  interface ReadProject<Extra> {
799
454
  readonly projectRead: ProjectRead;
800
455
  readonly references: readonly Reference[];
456
+ /** The declarations its read rules held where the checker did not answer. */
457
+ readonly held: readonly string[];
458
+ readonly possiblyLoaded: readonly string[];
801
459
  readonly testFiles: readonly string[];
802
460
  readonly evidence: readonly Exemption[];
803
461
  readonly componentFiles: readonly string[];
804
462
  readonly componentWarnings: readonly ComponentWarning[];
805
463
  /** Per own file below the target root, the module specifiers its imports write. */
806
464
  readonly imports: ReadonlyMap<string, readonly string[]>;
465
+ /** The data members its production code decodes into. */
466
+ readonly decoded: Decoded;
807
467
  readonly extra: Extra;
808
468
  }
809
469
 
@@ -816,6 +476,8 @@ interface ReadRun<Extra> {
816
476
  readonly projects: readonly SweptProject<Extra>[];
817
477
  /** Every declared consumer, each loaded, in the scope's order. */
818
478
  readonly consumers: readonly LoadedConsumer[];
479
+ /** Whether the scope declares a consumer, loaded or not. */
480
+ readonly declaresConsumers: boolean;
819
481
  /** The derived configurations the run dropped. */
820
482
  readonly notBuilt: readonly NotBuilt[];
821
483
  /** Every question the checker could not answer, each once. */
@@ -824,6 +486,10 @@ interface ReadRun<Extra> {
824
486
  readonly componentsUnread: readonly ComponentsUnread[];
825
487
  /** Per analyzed configuration, each library it names that the compiler cannot find. */
826
488
  readonly librariesUnfound: readonly LibraryUnfound[];
489
+ /** The relative specifiers of the run's unchecked JavaScript files that resolve to no file. */
490
+ readonly unresolvedSpecifiers: readonly UnresolvedSpecifier[];
491
+ /** The inputs the run could not read. */
492
+ readonly unread: readonly UnreadInput[];
827
493
  /** The convention rows the run applied. */
828
494
  readonly conventionsApplied: readonly AppliedConvention[];
829
495
  /** The dependencies the applied rows' short names use. */
@@ -832,6 +498,8 @@ interface ReadRun<Extra> {
832
498
  readonly memberDirs: readonly string[];
833
499
  /** The directory of every nested package, absolute. */
834
500
  readonly nestedDirs: readonly string[];
501
+ /** The target root's workflow steps, git hooks and makefile, read once. */
502
+ readonly workflows: Workflows;
835
503
  }
836
504
 
837
505
  /** The manifest section of a package test evidence counts, and the sections that keep one out of it. */
@@ -855,20 +523,9 @@ function testEvidence(
855
523
  }
856
524
  }
857
525
  const manifests = new Map<string, Readonly<Record<string, unknown>> | undefined>();
858
- const manifestAt = (dir: string): Readonly<Record<string, unknown>> | undefined => {
526
+ const manifestIn = (dir: string): Readonly<Record<string, unknown>> | undefined => {
859
527
  if (!manifests.has(dir)) {
860
- let value: unknown;
861
- try {
862
- value = JSON.parse(host.readFile(joinPath(dir, "package.json")));
863
- } catch {
864
- value = undefined;
865
- }
866
- manifests.set(
867
- dir,
868
- typeof value === "object" && value !== null && !Array.isArray(value)
869
- ? (value as Record<string, unknown>)
870
- : undefined,
871
- );
528
+ manifests.set(dir, manifestAt(host, dir));
872
529
  }
873
530
  return manifests.get(dir);
874
531
  };
@@ -878,16 +535,14 @@ function testEvidence(
878
535
  return {
879
536
  imports,
880
537
  devDependency: (path, name) => {
881
- for (let dir = dirnamePath(joinPath(root, path)); ; dir = dirnamePath(dir)) {
882
- const manifest = manifestAt(dir);
538
+ for (const dir of ancestors(dirnamePath(joinPath(root, path)), root)) {
539
+ const manifest = manifestIn(dir);
883
540
  const other = OTHER_SECTIONS.some((one) => declares(manifest?.[one], name));
884
541
  if (declares(manifest?.[DEV_SECTION], name) || other) {
885
542
  return !other;
886
543
  }
887
- if (normalizePath(dir) === normalizePath(root) || dirnamePath(dir) === dir) {
888
- return false;
889
- }
890
544
  }
545
+ return false;
891
546
  },
892
547
  };
893
548
  }
@@ -902,7 +557,7 @@ function readRun<Extra>(
902
557
  engine: Engine,
903
558
  host: Host,
904
559
  scope: Scope,
905
- config: Config,
560
+ config: ResolvedConfig,
906
561
  mode: Mode,
907
562
  detectors: Detectors,
908
563
  extra: <Brand>(
@@ -910,50 +565,55 @@ function readRun<Extra>(
910
565
  read: ProjectRead,
911
566
  references: readonly Reference[],
912
567
  testFiles: readonly string[],
568
+ unseenLoads: readonly UnseenLoad[],
913
569
  ) => Extra,
914
570
  ): ReadRun<Extra> {
915
571
  const targetRoot = scope.target.path;
916
- const disabled = disabledClasses(config);
917
- const templates = disabled.has("template-field")
918
- ? { delimiters: config.analysis.templateDelimiters, files: [] }
919
- : readTemplates(host, targetRoot, config.analysis);
920
572
  const consumers = scope.consumers.map((consumer) => consumer.path);
573
+ const detect = detection(host, targetRoot, config, consumers, detectors);
574
+ const directories = runDirectories(host, targetRoot, (fileName, text) =>
575
+ engine.parseSourceFile(fileName, text),
576
+ );
921
577
  const read = readProjects<ReadProject<Extra>>(engine, host, scope, config, (project, opened) => {
922
578
  const projectRead = opened.read();
579
+ const testFile = targetTestFile(projectRead.sources.testFiles);
923
580
  const resolved = references(project, projectRead.held, targetRoot, {
924
- testFiles: config.ts.testFiles,
925
- testFileNames: projectRead.testFileNames,
581
+ testFile,
582
+ directories,
583
+ formedForNode: projectRead.formedForNode,
926
584
  });
927
- const evidence = evidenceRecords(
928
- {
929
- project,
930
- held: projectRead.held,
931
- targetRoot,
932
- templates,
933
- ts: config.ts,
934
- consumers,
935
- ...(config.analysis.generatedFiles === "include"
936
- ? {}
937
- : { generated: projectRead.generated }),
938
- },
939
- detectors,
940
- disabled,
941
- );
585
+ const testFiles = testFilePaths(project, targetRoot, testFile);
586
+ const evidence = detect({ project, held: projectRead.held, generated: projectRead.generated });
942
587
  const components = project.ownSourceFiles().filter(isComponentFile);
588
+ const injected = project.program
589
+ .getSourceFileNames()
590
+ .some((name) => name.endsWith(`/node_modules/${GLOBALS_RUNNER}/globals.d.ts`));
943
591
  const pathOf = (file: (typeof components)[number]): string =>
944
592
  relativePath(targetRoot, file.fileName) ?? file.fileName;
945
593
  return {
946
594
  projectRead,
947
595
  references: resolved.references,
948
- testFiles: resolved.testFilePaths,
596
+ held: resolved.held,
597
+ possiblyLoaded: resolved.possiblyLoaded,
598
+ testFiles,
949
599
  evidence,
950
600
  componentFiles: components.map(pathOf),
951
601
  imports: new Map(
952
602
  project.ownSourceFiles().flatMap((file) => {
953
603
  const path = relativePath(targetRoot, file.fileName);
954
- return path === undefined
955
- ? []
956
- : [[path, file.imports.filter(isStringLiteralLikeNode).map((one) => one.text)]];
604
+ if (path === undefined) {
605
+ return [];
606
+ }
607
+ const specifiers = file.imports.filter(isStringLiteralLikeNode).map((one) => one.text);
608
+ // A file calling the globals a program declares is written for their runner.
609
+ return [
610
+ [
611
+ path,
612
+ injected && namesTestGlobals(project, file)
613
+ ? [...specifiers, GLOBALS_RUNNER]
614
+ : specifiers,
615
+ ],
616
+ ];
957
617
  }),
958
618
  ),
959
619
  componentWarnings: components.flatMap((file) =>
@@ -963,15 +623,30 @@ function readRun<Extra>(
963
623
  reason: warning.reason,
964
624
  })),
965
625
  ),
966
- extra: extra(project, projectRead, resolved.references, resolved.testFilePaths),
626
+ decoded: decodedMembers(
627
+ project,
628
+ projectRead.held,
629
+ productionFiles(project, targetRoot, testFiles),
630
+ consumers,
631
+ ),
632
+ extra: extra(
633
+ project,
634
+ projectRead,
635
+ resolved.references,
636
+ testFiles,
637
+ resolved.unseenLoads.map((position) => ({
638
+ configuration: projectRead.configuration,
639
+ position,
640
+ })),
641
+ ),
967
642
  };
968
643
  });
969
- const outsidePaths = read.outsideTests.map((one) => one.path);
970
- const withOutside = read.answers.map((one) => ({
644
+ const outsidePaths = read.result.outsideTests.map((one) => one.path);
645
+ const withOutside = read.result.answers.map((one) => ({
971
646
  ...one,
972
647
  references: [
973
648
  ...one.references,
974
- ...outsideTestReferences(read.outsideTests, one.projectRead.held, targetRoot),
649
+ ...outsideTestReferences(read.result.outsideTests, one.projectRead.held, targetRoot),
975
650
  ],
976
651
  testFiles: [...one.testFiles, ...outsidePaths],
977
652
  }));
@@ -980,30 +655,51 @@ function readRun<Extra>(
980
655
  const { support, testUsed } = testSupportFiles(
981
656
  withOutside.flatMap((one) => one.projectRead.held.symbols),
982
657
  withOutside.flatMap((one) => one.references),
983
- withOutside.flatMap((one) => one.projectRead.rooted.liveUnderReachability),
658
+ // An outside declaration naming a global augmentation calls nothing of its file.
659
+ withOutside.flatMap((one) =>
660
+ one.projectRead.rooted.liveUnderReachability.filter(
661
+ (root) => root.kind !== "global-augmentation",
662
+ ),
663
+ ),
984
664
  withOutside.flatMap((one) => one.testFiles),
985
665
  testEvidence(host, targetRoot, withOutside),
986
666
  );
987
- const settled = settledSatisfaction(
988
- withOutside.map((one) => ({ evidence: one.evidence, held: one.projectRead.held })),
989
- [...withOutside.flatMap((one) => one.references), ...read.consumers.references],
667
+ // A member a decode fills or a copy carries is written: a value decoded and sent again carries it on.
668
+ const written = new Set([
669
+ ...countedWrites(
670
+ [...withOutside.flatMap((one) => one.references), ...read.result.references],
671
+ support,
672
+ mode,
673
+ ),
674
+ ...withOutside.flatMap((one) => [
675
+ ...one.decoded.filled,
676
+ ...one.decoded.parsed,
677
+ ...one.decoded.copied,
678
+ ]),
679
+ ]);
680
+ const settled = settle(
681
+ withOutside.map((one) => ({
682
+ records: one.evidence,
683
+ held: one.projectRead.held,
684
+ testFiles: new Set([...one.testFiles, ...support]),
685
+ })),
686
+ {
687
+ references: [...withOutside.flatMap((one) => one.references), ...read.result.references],
688
+ written,
689
+ mode,
690
+ },
990
691
  );
991
692
  const answers = withOutside.map((one, index): SweptProject<Extra> => {
992
693
  const { projectRead } = one;
993
- const satisfied = settled[index];
994
- const detected = heldRecords(satisfied?.evidence ?? one.evidence, {
995
- mode,
996
- testFiles: new Set([...one.testFiles, ...support]),
997
- });
998
- const exempt = detected.records;
999
- const made = supportReferences([...one.references, ...(satisfied?.references ?? [])], support);
694
+ const exempt = settled[index]?.records ?? [];
695
+ const made = [...one.references, ...(settled[index]?.references ?? [])];
1000
696
  const held = new Set(projectRead.held.symbols.map((symbol) => symbol.position.path));
1001
- const supportFiles = [...support].filter((path) => held.has(path)).sort();
1002
- const testUsedFiles = [...testUsed].filter((path) => held.has(path)).sort();
697
+ const supportFiles = [...support].filter((path) => held.has(path)).sort(bytewise);
698
+ const testUsedFiles = [...testUsed].filter((path) => held.has(path)).sort(bytewise);
1003
699
  const configured: Configured = {
1004
700
  configuration: projectRead.configuration,
1005
701
  symbols: projectRead.held.symbols,
1006
- references: [...made, ...evidenceReferences(projectRead.held.symbols, detected.inTestFiles)],
702
+ references: made,
1007
703
  roots: projectRead.rooted.liveUnderReachability,
1008
704
  testFiles: [...one.testFiles, ...supportFiles],
1009
705
  ...(supportFiles.length === 0 ? {} : { supportFiles }),
@@ -1023,20 +719,23 @@ function readRun<Extra>(
1023
719
  unanswered: [
1024
720
  ...projectRead.held.unanswered,
1025
721
  ...projectRead.rooted.unanswered,
1026
- ...made
1027
- .filter((reference) => reference.resolution === "by-name")
1028
- .map((reference) => reference.to),
1029
- ...exempt.filter(isUnansweredRecord).map((record) => record.id),
722
+ ...made.filter((reference) => reference.guessed === true).map((reference) => reference.to),
723
+ ...one.held,
724
+ ...exempt.filter((record) => record.unanswered === true).map((record) => record.id),
725
+ ...one.decoded.unanswered,
1030
726
  ],
727
+ filledOutside: one.decoded.filled,
728
+ possiblyLoaded: one.possiblyLoaded,
1031
729
  typeErrorSkips: projectRead.typeErrorSkips,
1032
730
  unmappedEntries: projectRead.rooted.unmappedEntries,
731
+ heldScripts: projectRead.rooted.heldScripts,
1033
732
  skipped: projectRead.skipped,
1034
733
  componentFiles: one.componentFiles,
1035
734
  componentWarnings: one.componentWarnings,
1036
735
  extra: one.extra,
1037
736
  };
1038
737
  });
1039
- const consumed = read.consumers.references;
738
+ const consumed = read.result.references;
1040
739
  const projects = answers.map((one) =>
1041
740
  consumed.length === 0
1042
741
  ? one
@@ -1054,80 +753,41 @@ function readRun<Extra>(
1054
753
  unansweredHeld: [
1055
754
  ...new Set([
1056
755
  ...answers.flatMap((one) => one.unanswered),
1057
- ...consumed.filter((one) => one.resolution === "by-name").map((one) => one.to),
756
+ ...consumed.filter((one) => one.guessed === true).map((one) => one.to),
757
+ ...read.result.consumerHeld,
1058
758
  ]),
1059
759
  ],
1060
760
  projects,
1061
- consumers: read.consumers.loaded,
1062
- notBuilt: read.notBuilt,
761
+ consumers: read.plan.discovery.consumers,
762
+ declaresConsumers: scope.consumers.length > 0,
763
+ notBuilt: read.classified.notBuilt,
1063
764
  unanswered: read.unanswered,
1064
- componentsUnread: read.componentsUnread,
1065
- librariesUnfound: read.librariesUnfound,
1066
- conventionsApplied: read.conventionsApplied,
1067
- conventionUses: read.conventionUses,
1068
- memberDirs: read.memberDirs,
1069
- nestedDirs: read.nestedDirs,
765
+ componentsUnread: read.plan.workspace?.componentsUnread ?? [],
766
+ librariesUnfound: read.classified.librariesUnfound,
767
+ unresolvedSpecifiers: read.classified.unresolvedSpecifiers,
768
+ unread: read.plan.unread,
769
+ conventionsApplied: read.plan.conventions.applied,
770
+ conventionUses: read.plan.conventions.uses,
771
+ memberDirs: read.plan.packages.members,
772
+ nestedDirs: read.plan.packages.nested,
773
+ workflows: read.result.workflows,
1070
774
  };
1071
775
  }
1072
776
 
1073
777
  /**
1074
- * The run swept under one set of marks with the records that hold. A record a component
1075
- * file's markup holds counts only while the file is live, and what it holds may be what
1076
- * keeps the file live, so each file's markup joins only once a sweep without it finds the
1077
- * file live, until a sweep finds no further file live.
1078
- */
1079
- function holdingSweep<Extra>(
1080
- read: ReadRun<Extra>,
1081
- input: Pick<SweepInput, "marked" | "mode">,
1082
- ): { readonly swept: SweepInput; readonly result: SweepResult } {
1083
- const paths = new Set(read.exempt.flatMap((record) => record.whileLive ?? []));
1084
- let live = new Set<string>();
1085
- for (;;) {
1086
- const swept: SweepInput = {
1087
- ...input,
1088
- exempt: holdingWhile(read.exempt, live),
1089
- unanswered: read.unansweredHeld,
1090
- };
1091
- const result = sweepMatrix(read.matrix, swept);
1092
- const next = new Set(liveFilesAt(read.matrix, result, paths).map((one) => one.position.path));
1093
- if (next.size === live.size) {
1094
- return { swept, result };
1095
- }
1096
- live = next;
1097
- }
1098
- }
1099
-
1100
- /**
1101
- * The test references exemption evidence written in a test file makes: each is a read of
1102
- * the declaration it would retain, made by the test file at the evidence's site.
778
+ * The declarations a write the mode counts stores into, a write a test-support file
779
+ * makes being a test's.
1103
780
  */
1104
- function evidenceReferences(
1105
- symbols: readonly InventorySymbol[],
1106
- inTestFiles: readonly Exemption[],
1107
- ): readonly Reference[] {
1108
- if (inTestFiles.length === 0) {
1109
- return [];
1110
- }
1111
- const files = new Map(
1112
- symbols
1113
- .filter((symbol) => symbol.kind === "file")
1114
- .map((symbol) => [symbol.position.path, symbol.id]),
781
+ function countedWrites(
782
+ references: readonly Reference[],
783
+ support: ReadonlySet<string>,
784
+ mode: Mode,
785
+ ): ReadonlySet<string> {
786
+ return new Set(
787
+ references.flatMap((reference) =>
788
+ reference.use === "write" && !withheldBy(mode, reference, support) ? [reference.to] : [],
789
+ ),
1115
790
  );
1116
- return inTestFiles.flatMap((record) => {
1117
- const from = files.get(record.site.path);
1118
- return from === undefined
1119
- ? []
1120
- : [
1121
- {
1122
- from,
1123
- to: record.id,
1124
- position: record.site,
1125
- use: "read",
1126
- resolution: "syntax",
1127
- test: true,
1128
- },
1129
- ];
1130
- });
1131
791
  }
1132
792
 
1133
793
  /**
@@ -1138,8 +798,9 @@ function writtenOnly<Extra>(read: ReadRun<Extra>, mode: Mode): ReadonlySet<strin
1138
798
  const written = new Set<string>();
1139
799
  const readSome = new Set<string>();
1140
800
  for (const { configured } of read.projects) {
801
+ const support = new Set(configured.supportFiles ?? []);
1141
802
  for (const reference of configured.references) {
1142
- if (mode.production && reference.test) {
803
+ if (withheldBy(mode, reference, support)) {
1143
804
  continue;
1144
805
  }
1145
806
  if (reference.use === "write" && reference.consumer === undefined) {
@@ -1152,62 +813,27 @@ function writtenOnly<Extra>(read: ReadRun<Extra>, mode: Mode): ReadonlySet<strin
1152
813
  return new Set([...written].filter((id) => !readSome.has(id)));
1153
814
  }
1154
815
 
1155
- /**
1156
- * The sweep of a run read once, under one set of marks. Where a question went unanswered,
1157
- * the run is swept once more without what that question could have kept live and without
1158
- * the references that stood in for its answer, and every declaration that sweep judges
1159
- * dead and this one judges live, or dead by another rule, is held by the gap too, as is
1160
- * every declaration that makes such a reference.
1161
- */
816
+ /** The sweep of a run read once, under one set of marks. */
1162
817
  function sweptOf<Extra>(
1163
818
  read: ReadRun<Extra>,
1164
- input: Pick<SweepInput, "marked" | "mode">,
819
+ input: Pick<SweepPolicy, "marked" | "mode">,
1165
820
  ): RunSweep {
1166
- const { swept, result } = holdingSweep(read, input);
1167
- const exempt = swept.exempt ?? [];
1168
- const held = new Set(read.unansweredHeld);
1169
- if (held.size > 0) {
1170
- // What a declaration reads where the checker did not answer is unknown, so a rule
1171
- // over what it reads, the test of dead code among them, cannot judge it.
1172
- for (const { configured } of read.projects) {
1173
- for (const reference of configured.references) {
1174
- if (reference.resolution === "by-name") {
1175
- held.add(reference.from);
1176
- }
1177
- }
1178
- }
1179
- const dead = new Map(result.candidates.map((candidate) => [candidate.id, candidate]));
1180
- const answered = matrixOf(
1181
- read.projects.map(({ configured }) => ({
1182
- ...configured,
1183
- references: configured.references.filter((one) => one.resolution !== "by-name"),
1184
- })),
1185
- );
1186
- const bare: SweepInput = {
1187
- ...swept,
1188
- exempt: exempt.filter((record) => !isUnansweredRecord(record)),
1189
- unanswered: [],
1190
- };
1191
- for (const candidate of sweepMatrix(answered, bare).candidates) {
1192
- const kept = dead.get(candidate.id);
1193
- if (
1194
- kept?.testOfDeadCode !== candidate.testOfDeadCode ||
1195
- kept.relation !== candidate.relation
1196
- ) {
1197
- held.add(candidate.id);
1198
- }
1199
- }
1200
- }
821
+ const componentFiles = [...new Set(read.projects.flatMap((one) => one.componentFiles))].sort(
822
+ bytewise,
823
+ );
1201
824
  return {
1202
825
  matrix: read.matrix,
1203
- sweep: result,
1204
- exempt,
1205
- retained: retainedIn(read.matrix, swept, writtenOnly(read, input.mode)),
826
+ sweep: sweep(read.matrix, {
827
+ ...input,
828
+ exempt: read.exempt,
829
+ unanswered: read.unansweredHeld,
830
+ componentFiles,
831
+ unseenCallers: !read.declaresConsumers,
832
+ writeOnly: writtenOnly(read, input.mode),
833
+ }),
1206
834
  notBuilt: read.notBuilt,
1207
835
  unanswered: read.unanswered,
1208
- heldByUnanswered: [...held],
1209
836
  skipped: read.projects.flatMap((one) => one.skipped),
1210
- componentFiles: [...new Set(read.projects.flatMap((one) => one.componentFiles))].sort(compare),
1211
837
  };
1212
838
  }
1213
839
 
@@ -1223,8 +849,8 @@ export function runSweep(
1223
849
  engine: Engine,
1224
850
  host: Host,
1225
851
  scope: Scope,
1226
- config: Config,
1227
- input: Pick<SweepInput, "marked" | "mode">,
852
+ config: ResolvedConfig,
853
+ input: Pick<SweepPolicy, "marked" | "mode">,
1228
854
  detectors: Detectors = DETECTORS,
1229
855
  ): RunSweep {
1230
856
  return sweptOf(
@@ -1240,12 +866,27 @@ interface EmitterExtra {
1240
866
  readonly needs: ReturnType<typeof projectNeeds>;
1241
867
  readonly implementations: ReturnType<typeof implementations>;
1242
868
  readonly heldByInclusion: readonly string[];
1243
- readonly generated: readonly string[];
869
+ readonly generated: ReadonlyMap<string, GeneratedFact>;
870
+ readonly bindings: readonly BindingRecord[];
1244
871
  readonly inOperands: readonly string[];
1245
872
  readonly rooted: Roots;
1246
873
  readonly directives: readonly InlineDirective[];
1247
874
  readonly declarationsNamed: readonly boolean[];
1248
875
  readonly parts: ProjectParts;
876
+ readonly unseenLoads: readonly UnseenLoad[];
877
+ readonly carriers: Carriers;
878
+ }
879
+
880
+ /** The project's own files below the target root that are no test file. */
881
+ function productionFiles<Brand>(
882
+ project: ProjectView<Brand>,
883
+ targetRoot: string,
884
+ testFiles: readonly string[],
885
+ ): readonly SourceFile[] {
886
+ const tests = new Set(testFiles);
887
+ return [...sourceFilesOf(project, targetRoot).byPath].flatMap(([path, file]) =>
888
+ tests.has(path) ? [] : [file],
889
+ );
1249
890
  }
1250
891
 
1251
892
  /** Reads a run's projects with every per-project fact an emitter reads. */
@@ -1253,7 +894,7 @@ export function readEmitterRun(
1253
894
  engine: Engine,
1254
895
  host: Host,
1255
896
  scope: Scope,
1256
- config: Config,
897
+ config: ResolvedConfig,
1257
898
  mode: Mode,
1258
899
  detectors: Detectors,
1259
900
  ): ReadRun<EmitterExtra> {
@@ -1265,15 +906,22 @@ export function readEmitterRun(
1265
906
  config,
1266
907
  mode,
1267
908
  detectors,
1268
- (project, read, references, testFiles) => ({
909
+ (project, read, references, testFiles, unseenLoads) => ({
1269
910
  deprecation: deprecatedDeclarations(project, read.held),
1270
911
  accessors: accessorsOf(project, read.held),
1271
- needs: projectNeeds(project, read.held, host, targetRoot, (fileName, text) =>
1272
- engine.parseSourceFile(fileName, text),
912
+ needs: projectNeeds(
913
+ project,
914
+ read.held,
915
+ host,
916
+ targetRoot,
917
+ (fileName, text) => engine.parseSourceFile(fileName, text),
918
+ read.sources.configuration,
919
+ read.sources.workflows,
1273
920
  ),
1274
921
  implementations: implementations(project, read.held),
1275
922
  heldByInclusion: heldByInclusion(project, targetRoot),
1276
- generated: [...read.generated.keys()],
923
+ generated: read.generated,
924
+ bindings: read.bindings,
1277
925
  inOperands: inOperandNames(project, targetRoot, testFiles),
1278
926
  rooted: read.rooted,
1279
927
  directives: inlineDirectives(project, read.held, targetRoot).filter(
@@ -1281,9 +929,12 @@ export function readEmitterRun(
1281
929
  ),
1282
930
  declarationsNamed: declarationsNamed(project, read.held, configuredDeclarations(config)),
1283
931
  parts: projectParts(project, read.held, references, targetRoot),
932
+ unseenLoads,
933
+ // Only a closed world reports an unnecessary export, which is all the carriers decide.
934
+ carriers: config.consumers.complete ? carriersOf(project, read.held) : NO_CARRIERS,
1284
935
  }),
1285
936
  );
1286
- // Whether a declaration carries the marker decides its code, so one whose marker went
937
+ // Whether a declaration carries the marker decides its code, so one whose answer went
1287
938
  // unread is reported by nothing.
1288
939
  const unread = run.projects.flatMap((one) => one.extra.deprecation.unanswered);
1289
940
  return unread.length === 0
@@ -1335,24 +986,19 @@ function judgedMembers(
1335
986
 
1336
987
  /** The directory of the nearest `package.json` at or above a file, inside `root`, else `root`. */
1337
988
  function nearestManifestDir(host: Host, root: string, file: string): string {
1338
- for (let dir = dirnamePath(file); relativePath(root, dir) !== undefined; dir = dirnamePath(dir)) {
1339
- if (host.kindOf(joinPath(dir, "package.json")) === "file") {
1340
- return dir;
1341
- }
1342
- }
1343
- return root;
989
+ return ancestors(dirnamePath(file), root).find((dir) => holdsManifest(host, dir)) ?? root;
1344
990
  }
1345
991
 
1346
992
  /**
1347
993
  * The input every emitter reads over one sweep of a read run: the facts beside the sweep
1348
- * each kind family reads, every per-project one read in the same session as the sweep.
994
+ * each emitter reads, every per-project one read in the same session as the sweep.
1349
995
  */
1350
996
  export function emitterInputOver(
1351
997
  host: Host,
1352
998
  scope: Scope,
1353
- config: Config,
999
+ config: ResolvedConfig,
1354
1000
  read: ReadRun<EmitterExtra>,
1355
- input: Pick<SweepInput, "marked" | "mode">,
1001
+ input: Pick<SweepPolicy, "marked" | "mode">,
1356
1002
  selfCheck: SelfCheckFacts,
1357
1003
  ): EmitterInput {
1358
1004
  const targetRoot = scope.target.path;
@@ -1366,14 +1012,16 @@ export function emitterInputOver(
1366
1012
  stores: storesOf(
1367
1013
  projects.map((one) => ({
1368
1014
  references: one.configured.references,
1015
+ support: new Set(one.configured.supportFiles ?? []),
1369
1016
  accessors: one.extra.accessors,
1370
1017
  })),
1371
- swept.exempt,
1018
+ swept.sweep.exempt,
1372
1019
  input.mode,
1373
1020
  ),
1374
1021
  dependencies: dependenciesOf(
1375
1022
  host,
1376
1023
  targetRoot,
1024
+ read.workflows,
1377
1025
  [...projects.map((one) => one.extra.needs), configurationNeeds(read.conventionUses)],
1378
1026
  swept.sweep.candidates.map((candidate) => candidate.id),
1379
1027
  members.read,
@@ -1384,8 +1032,19 @@ export function emitterInputOver(
1384
1032
  files: {
1385
1033
  tree: sourceTree(host, targetRoot),
1386
1034
  heldByInclusion: new Set(projects.flatMap((one) => one.extra.heldByInclusion)),
1387
- generated: new Set(projects.flatMap((one) => one.extra.generated)),
1035
+ generated: new Set(projects.flatMap((one) => [...one.extra.generated.keys()])),
1388
1036
  inOperands: new Set(projects.flatMap((one) => one.extra.inOperands)),
1037
+ unseenLoads: projects.flatMap((one) => one.extra.unseenLoads),
1038
+ unwrittenRuns: new Set(
1039
+ projects.flatMap((one) =>
1040
+ one.heldScripts
1041
+ .filter((held) => held.unwritten)
1042
+ .map(
1043
+ (held) =>
1044
+ relativePath(resolvePath(host.workingDirectory(), targetRoot), held.dir) ?? ".",
1045
+ ),
1046
+ ),
1047
+ ),
1389
1048
  },
1390
1049
  boundary: {
1391
1050
  consumers: {
@@ -1394,12 +1053,25 @@ export function emitterInputOver(
1394
1053
  },
1395
1054
  encapsulated: readManifest(host, targetRoot).declaresExports,
1396
1055
  edges: readEdgeSides(host, targetRoot),
1056
+ filledOutside: new Set(projects.flatMap((one) => one.filledOutside)),
1057
+ possiblyLoaded: new Set(projects.flatMap((one) => one.possiblyLoaded)),
1058
+ carriers: {
1059
+ named: new Map(
1060
+ [
1061
+ ...Map.groupBy(
1062
+ projects.flatMap((one) => [...one.extra.carriers.named]),
1063
+ ([id]) => id,
1064
+ ),
1065
+ ].map(([id, entries]) => [id, [...new Set(entries.flatMap(([, named]) => named))]]),
1066
+ ),
1067
+ unread: new Set(projects.flatMap((one) => [...one.extra.carriers.unread])),
1068
+ },
1397
1069
  },
1398
1070
  selfCheck,
1399
1071
  intraFunction: intraFunctionFacts(
1400
1072
  projects.map((one) => one.extra.parts),
1401
1073
  projects.flatMap((one) => one.configured.references),
1402
- new Set([...swept.exempt.map((one) => one.id), ...swept.heldByUnanswered]),
1074
+ new Set([...swept.sweep.exempt.map((one) => one.id), ...swept.sweep.held]),
1403
1075
  ),
1404
1076
  };
1405
1077
  }
@@ -1429,14 +1101,14 @@ interface AnalysisReader {
1429
1101
  * directives, the ignore file's entries and the baseline's rows are bound before any
1430
1102
  * sweep, and the run is swept once under every bound record's mark and once under none,
1431
1103
  * so a record is decided against the finding its code would have produced. The
1432
- * self-check family reports the refused suppressions and the roots that named nothing.
1104
+ * configuration family reports the refused suppressions and the roots that named nothing.
1433
1105
  * Beside the inputs it answers the projects and test-file rules a report names.
1434
1106
  */
1435
1107
  function readAnalysis(
1436
1108
  engine: Engine,
1437
1109
  host: Host,
1438
1110
  scope: Scope,
1439
- config: Config,
1111
+ config: ResolvedConfig,
1440
1112
  provenance: Provenance,
1441
1113
  mode: Mode,
1442
1114
  detectors: Detectors,
@@ -1457,7 +1129,7 @@ function readAnalysis(
1457
1129
  configFile: one.configFile,
1458
1130
  })),
1459
1131
  testFileRules: testFileRulesOf(
1460
- config.ts.testFiles,
1132
+ config.ts.test_files,
1461
1133
  read.projects.flatMap((one) => one.configured.testFiles),
1462
1134
  read.projects.flatMap((one) => one.configured.supportFiles ?? []),
1463
1135
  ),
@@ -1474,8 +1146,16 @@ function readAnalysis(
1474
1146
  unanswered: read.unanswered,
1475
1147
  componentsUnread: read.componentsUnread,
1476
1148
  librariesUnfound: read.librariesUnfound,
1149
+ unresolvedSpecifiers: read.unresolvedSpecifiers,
1150
+ unread: read.unread,
1477
1151
  conventionsApplied: read.conventionsApplied,
1478
1152
  unmappedEntries: unmappedEverywhere(read.projects),
1153
+ heldScripts: read.projects.flatMap((one) =>
1154
+ one.heldScripts.map((held) => ({ ...held, configFile: one.configFile })),
1155
+ ),
1156
+ unseenLoads: read.projects.flatMap((one) => one.extra.unseenLoads),
1157
+ generated: new Map(read.projects.flatMap((one) => [...one.extra.generated])),
1158
+ bindings: distinctBindings(read.projects.flatMap((one) => one.extra.bindings)),
1479
1159
  },
1480
1160
  configured: read.projects.map((one) => one.configured),
1481
1161
  symbols,
@@ -1487,7 +1167,7 @@ function readAnalysis(
1487
1167
  function inputsOver(
1488
1168
  host: Host,
1489
1169
  scope: Scope,
1490
- config: Config,
1170
+ config: ResolvedConfig,
1491
1171
  provenance: Provenance,
1492
1172
  mode: Mode,
1493
1173
  read: ReadRun<EmitterExtra>,
@@ -1501,7 +1181,7 @@ function inputsOver(
1501
1181
  const facts: SelfCheckFacts = {
1502
1182
  refusals: suppressions.refusals,
1503
1183
  unmatchedRoots: unmatchedEverywhere(
1504
- config.rootPatterns,
1184
+ config.roots.patterns,
1505
1185
  read.projects.map((one) => one.extra.rooted),
1506
1186
  ),
1507
1187
  rootsDocument: documentOf(host, provenance, ROOTS_SETTING, targetRoot),
@@ -1570,10 +1250,22 @@ interface RunFacts {
1570
1250
  readonly componentsUnread: readonly ComponentsUnread[];
1571
1251
  /** Per analyzed configuration, each library it names that the compiler cannot find. */
1572
1252
  readonly librariesUnfound: readonly LibraryUnfound[];
1253
+ /** The relative specifiers of the run's unchecked JavaScript files that resolve to no file. */
1254
+ readonly unresolvedSpecifiers: readonly UnresolvedSpecifier[];
1255
+ /** The inputs the run could not read. */
1256
+ readonly unread: readonly UnreadInput[];
1573
1257
  /** The convention rows the run applied. */
1574
1258
  readonly conventionsApplied: readonly AppliedConvention[];
1575
1259
  /** The manifest entries no project of the run reads back to a file, each once. */
1576
1260
  readonly unmappedEntries: readonly ManifestEntry[];
1261
+ /** Per project, by its compiler configuration file, each package whose command strings name files it holds. */
1262
+ readonly heldScripts: readonly (HeldScripts & { readonly configFile: string })[];
1263
+ /** The loads of production files whose target the run cannot resolve, per configuration. */
1264
+ readonly unseenLoads: readonly UnseenLoad[];
1265
+ /** Every generated file of the run, by its path below the target root, each once. */
1266
+ readonly generated: ReadonlyMap<string, GeneratedFact>;
1267
+ /** Every binding record the run's generated files publish, each once. */
1268
+ readonly bindings: readonly BindingRecord[];
1577
1269
  }
1578
1270
 
1579
1271
  /** One configuration whose component files a run cannot read. */
@@ -1582,13 +1274,6 @@ interface ComponentsUnread {
1582
1274
  readonly reason: string;
1583
1275
  }
1584
1276
 
1585
- /** One library an analyzed configuration names that the compiler cannot find. */
1586
- interface LibraryUnfound {
1587
- readonly configFile: string;
1588
- /** The compiler's error, rendered as a dropped configuration's is. */
1589
- readonly error: string;
1590
- }
1591
-
1592
1277
  /** The findings of one run, beside what a report states about the run itself. */
1593
1278
  export interface RunAnalysis {
1594
1279
  readonly result: PassResult;
@@ -1601,7 +1286,7 @@ export interface RunAnalysis {
1601
1286
 
1602
1287
  /**
1603
1288
  * The analysis of the run the scope and the configuration describe: the run read with its
1604
- * suppressions bound, every family's findings with the suppressions applied and the
1289
+ * suppressions bound, every emitter's findings with the suppressions applied and the
1605
1290
  * declared edges evaluated, the projects and test-file rules the report names, and the sweep
1606
1291
  * an explanation reads.
1607
1292
  */
@@ -1609,7 +1294,7 @@ export function runAnalysis(
1609
1294
  engine: Engine,
1610
1295
  host: Host,
1611
1296
  scope: Scope,
1612
- config: Config,
1297
+ config: ResolvedConfig,
1613
1298
  provenance: Provenance,
1614
1299
  mode: Mode,
1615
1300
  detectors: Detectors = DETECTORS,
@@ -1621,14 +1306,22 @@ export function runAnalysis(
1621
1306
 
1622
1307
  /**
1623
1308
  * One count per configuration of the run in which the checker left a question unanswered:
1624
- * the questions asked in its project, and the declarations of its own the run holds for them.
1309
+ * the questions asked in its project, a formed program's manifest that does not parse or cannot
1310
+ * be read and a package whose command strings name files the project holds each counted as one, and the
1311
+ * declarations of its own the run holds for them.
1625
1312
  */
1626
1313
  export function unansweredCounts(analysis: RunAnalysis): readonly UnansweredCount[] {
1627
- const held = new Set(analysis.swept.heldByUnanswered);
1314
+ const held = new Set(analysis.swept.sweep.held);
1628
1315
  return analysis.run.projects.flatMap((project) => {
1629
- const questions = analysis.run.unanswered.filter(
1630
- (one) => one.configFile === project.configFile,
1631
- ).length;
1316
+ const questions =
1317
+ analysis.run.unanswered.filter((one) => one.configFile === project.configFile).length +
1318
+ analysis.run.unread.filter(
1319
+ (one) => one.kind === "manifest" && one.configFile === project.configFile,
1320
+ ).length +
1321
+ analysis.run.heldScripts.filter(
1322
+ (one) => one.configFile === project.configFile && one.files.length > 0,
1323
+ ).length;
1324
+
1632
1325
  if (questions === 0) {
1633
1326
  return [];
1634
1327
  }
@@ -1665,7 +1358,7 @@ export function runBaselineWrite(
1665
1358
  engine: Engine,
1666
1359
  host: Host,
1667
1360
  scope: Scope,
1668
- config: Config,
1361
+ config: ResolvedConfig,
1669
1362
  provenance: Provenance,
1670
1363
  mode: Mode,
1671
1364
  reason: string,