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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/README.md +3 -1
  2. package/THIRD_PARTY_NOTICES.md +27 -0
  3. package/dist/bin/mapper-connection.js +2 -1
  4. package/dist/bin/node-host.js +24 -5
  5. package/dist/src/alias-chain.js +2 -7
  6. package/dist/src/amd.js +81 -0
  7. package/dist/src/analysis.js +269 -432
  8. package/dist/src/augmentations.js +64 -3
  9. package/dist/src/automatic-types.js +10 -29
  10. package/dist/src/bindings.js +382 -0
  11. package/dist/src/calls.js +279 -43
  12. package/dist/src/commands/held.js +499 -0
  13. package/dist/src/commands/read.js +161 -0
  14. package/dist/src/commands/shell.js +169 -0
  15. package/dist/src/commands/tools.js +1847 -0
  16. package/dist/src/component-files.js +3 -2
  17. package/dist/src/component-layer.js +4 -2
  18. package/dist/src/config.js +6 -82
  19. package/dist/src/conformance-record.js +1 -1
  20. package/dist/src/consumers.js +10 -38
  21. package/dist/src/contextual-uses.js +57 -26
  22. package/dist/src/contract/config.generated.js +561 -0
  23. package/dist/src/contract/contract.generated.js +1369 -0
  24. package/dist/src/contract/report.generated.js +866 -0
  25. package/dist/src/dependencies.js +164 -121
  26. package/dist/src/destructuring.js +1 -19
  27. package/dist/src/edges.js +38 -122
  28. package/dist/src/element-access.js +181 -168
  29. package/dist/src/entries/build-scripts.js +222 -0
  30. package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
  31. package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
  32. package/dist/src/entries/conventions.js +740 -0
  33. package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
  34. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
  35. package/dist/src/entries/run-directories.js +77 -0
  36. package/dist/src/entries/sources.js +144 -0
  37. package/dist/src/entries/static-module.js +670 -0
  38. package/dist/src/entries/test-runners.js +650 -0
  39. package/dist/src/entries/workflow-steps.js +345 -0
  40. package/dist/src/enum-group.js +3 -10
  41. package/dist/src/erased-stores.js +4 -6
  42. package/dist/src/exempt-classes.js +1 -63
  43. package/dist/src/exempt.js +21 -66
  44. package/dist/src/exposure.js +400 -0
  45. package/dist/src/extensions.js +37 -0
  46. package/dist/src/facts.js +38 -0
  47. package/dist/src/failure.js +36 -0
  48. package/dist/src/file-facts.js +3 -26
  49. package/dist/src/findings/completion.js +109 -56
  50. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  51. package/dist/src/findings/emitters.js +27 -41
  52. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  53. package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
  54. package/dist/src/findings/interfaces.js +4 -5
  55. package/dist/src/findings/intra-function.js +16 -13
  56. package/dist/src/findings/non-code-artifacts.js +17 -12
  57. package/dist/src/findings/reads-and-writes.js +86 -27
  58. package/dist/src/findings/self-check.js +44 -30
  59. package/dist/src/findings/unused-declarations.js +29 -45
  60. package/dist/src/findings/visibility-narrowing.js +23 -31
  61. package/dist/src/findings-pass.js +13 -21
  62. package/dist/src/framework-lifecycle.js +46 -19
  63. package/dist/src/fs/document.js +52 -0
  64. package/dist/src/fs/manifest.js +67 -0
  65. package/dist/src/fs/tree.js +88 -0
  66. package/dist/src/generated-file.js +174 -28
  67. package/dist/src/git-ignore.js +39 -26
  68. package/dist/src/import-bindings.js +73 -28
  69. package/dist/src/index/sites.js +557 -0
  70. package/dist/src/index.js +2 -2
  71. package/dist/src/indexed-access.js +523 -478
  72. package/dist/src/injection-container.js +2 -2
  73. package/dist/src/interface-satisfaction.js +1 -1
  74. package/dist/src/intra-function-parts.js +63 -43
  75. package/dist/src/inventory/commonjs.js +507 -0
  76. package/dist/src/inventory/enumerate.js +167 -0
  77. package/dist/src/inventory/syntax.js +236 -0
  78. package/dist/src/inventory.js +323 -724
  79. package/dist/src/javascript-file.js +48 -0
  80. package/dist/src/json-document.js +198 -67
  81. package/dist/src/keyof-comparisons.js +126 -107
  82. package/dist/src/kinds.js +3 -366
  83. package/dist/src/{components.js → liveness/components.js} +2 -3
  84. package/dist/src/{graph.js → liveness/graph.js} +52 -28
  85. package/dist/src/liveness/matrix.js +99 -0
  86. package/dist/src/liveness/sweep.js +558 -0
  87. package/dist/src/load/classify.js +289 -0
  88. package/dist/src/load/diagnostics.js +87 -0
  89. package/dist/src/load/discover.js +285 -0
  90. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  91. package/dist/src/load/expected-module.js +136 -0
  92. package/dist/src/load/load.js +27 -0
  93. package/dist/src/load/module-lookup.js +37 -0
  94. package/dist/src/load/package-scope.js +56 -0
  95. package/dist/src/load/plan.js +313 -0
  96. package/dist/src/load/specifiers.js +113 -0
  97. package/dist/src/load/synthesize.js +152 -0
  98. package/dist/src/load/test-globals.js +207 -0
  99. package/dist/src/load/test-joins.js +82 -0
  100. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  101. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  102. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
  103. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  104. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  105. package/dist/src/module-declarations.js +70 -85
  106. package/dist/src/overrides.js +134 -112
  107. package/dist/src/partial.js +2 -1
  108. package/dist/src/paths.js +82 -16
  109. package/dist/src/platform-calls.js +78 -0
  110. package/dist/src/platform-symbols.js +134 -0
  111. package/dist/src/position.js +43 -1
  112. package/dist/src/print.js +11 -79
  113. package/dist/src/product.js +13 -0
  114. package/dist/src/query.js +47 -0
  115. package/dist/src/ref.js +12 -20
  116. package/dist/src/references/read-rule.js +1 -0
  117. package/dist/src/references/read-rules.js +48 -0
  118. package/dist/src/references/sink.js +237 -0
  119. package/dist/src/references/sources.js +450 -0
  120. package/dist/src/references.js +117 -1074
  121. package/dist/src/report-schema.js +51 -0
  122. package/dist/src/report.js +57 -41
  123. package/dist/src/reporters/annotations.js +15 -8
  124. package/dist/src/reporters/sarif.js +16 -10
  125. package/dist/src/reporters/template.js +4 -19
  126. package/dist/src/resolve.js +246 -730
  127. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
  128. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
  129. package/dist/src/roots/manifest.js +216 -0
  130. package/dist/src/roots/published-reach.js +412 -0
  131. package/dist/src/roots/root-set.js +487 -0
  132. package/dist/src/roots/unseen-loads.js +236 -0
  133. package/dist/src/run.js +66 -77
  134. package/dist/src/schema.js +320 -343
  135. package/dist/src/scope.js +38 -115
  136. package/dist/src/serialization-contract.js +601 -22
  137. package/dist/src/session.js +37 -29
  138. package/dist/src/source-files.js +6 -10
  139. package/dist/src/stores.js +4 -2
  140. package/dist/src/suppress-file.js +25 -28
  141. package/dist/src/suppress-inline.js +36 -83
  142. package/dist/src/suppress.js +50 -71
  143. package/dist/src/symbol-keys.js +92 -88
  144. package/dist/src/template-field.js +9 -19
  145. package/dist/src/tests/file-class.js +76 -0
  146. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  147. package/dist/src/{test-support.js → tests/support.js} +5 -12
  148. package/dist/src/text/compare.js +26 -0
  149. package/dist/src/text/glob.js +194 -0
  150. package/dist/src/text/named-files.js +298 -0
  151. package/dist/src/text/yaml.js +684 -0
  152. package/dist/src/type-errors.js +11 -232
  153. package/dist/src/type-parameter-reads.js +178 -139
  154. package/dist/src/unimplemented-callees.js +262 -242
  155. package/dist/src/unwrap.js +23 -0
  156. package/dist/src/usage.js +10 -0
  157. package/dist/src/vendor/unbash/ansi-c.js +132 -0
  158. package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
  159. package/dist/src/vendor/unbash/arithmetic.js +591 -0
  160. package/dist/src/vendor/unbash/assignment.js +131 -0
  161. package/dist/src/vendor/unbash/chars.js +48 -0
  162. package/dist/src/vendor/unbash/command.js +41 -0
  163. package/dist/src/vendor/unbash/expansion.js +80 -0
  164. package/dist/src/vendor/unbash/glob.js +268 -0
  165. package/dist/src/vendor/unbash/heredoc.js +27 -0
  166. package/dist/src/vendor/unbash/internal-types.js +1 -0
  167. package/dist/src/vendor/unbash/lexer.js +4274 -0
  168. package/dist/src/vendor/unbash/limits.js +3 -0
  169. package/dist/src/vendor/unbash/parser.js +1366 -0
  170. package/dist/src/vendor/unbash/parts.js +57 -0
  171. package/dist/src/vendor/unbash/substitution-context.js +8 -0
  172. package/dist/src/vendor/unbash/traversal.js +212 -0
  173. package/dist/src/vendor/unbash/types.js +1 -0
  174. package/dist/src/vendor/unbash/word-value.js +61 -0
  175. package/dist/src/vendor/unbash/word.js +40 -0
  176. package/dist/src/verbs/analyze.js +194 -127
  177. package/dist/src/verbs/describe.js +13 -18
  178. package/dist/src/verbs/explain.js +85 -139
  179. package/dist/src/verbs/print-config.js +2 -1
  180. package/dist/src/verbs/print-projects.js +6 -4
  181. package/dist/src/verbs/print-retained.js +7 -5
  182. package/dist/src/verbs/print-roots.js +4 -2
  183. package/dist/src/verbs/verb.js +1 -5
  184. package/dist/src/verbs/version.js +14 -3
  185. package/jsr.json +2 -1
  186. package/package.json +14 -8
  187. package/src/alias-chain.ts +2 -9
  188. package/src/amd.ts +130 -0
  189. package/src/analysis.ts +424 -650
  190. package/src/augmentations.ts +93 -4
  191. package/src/automatic-types.ts +12 -30
  192. package/src/bindings.ts +460 -0
  193. package/src/calls.ts +338 -46
  194. package/src/commands/held.ts +632 -0
  195. package/src/commands/read.ts +242 -0
  196. package/src/commands/shell.ts +228 -0
  197. package/src/commands/tools.ts +2382 -0
  198. package/src/component-files.ts +4 -2
  199. package/src/component-layer.ts +4 -2
  200. package/src/config.ts +31 -302
  201. package/src/conformance-record.ts +1 -1
  202. package/src/consumers.ts +16 -66
  203. package/src/contextual-uses.ts +66 -34
  204. package/src/contract/config.generated.ts +821 -0
  205. package/src/contract/contract.generated.ts +1452 -0
  206. package/src/contract/report.generated.ts +1241 -0
  207. package/src/dependencies.ts +222 -127
  208. package/src/destructuring.ts +1 -31
  209. package/src/edges.ts +41 -140
  210. package/src/element-access.ts +190 -187
  211. package/src/entries/build-scripts.ts +292 -0
  212. package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
  213. package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
  214. package/src/{conventions.ts → entries/conventions.ts} +367 -583
  215. package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
  216. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
  217. package/src/entries/run-directories.ts +108 -0
  218. package/src/entries/sources.ts +266 -0
  219. package/src/entries/static-module.ts +858 -0
  220. package/src/entries/test-runners.ts +835 -0
  221. package/src/entries/workflow-steps.ts +432 -0
  222. package/src/enum-group.ts +2 -11
  223. package/src/erased-stores.ts +3 -7
  224. package/src/exempt-classes.ts +1 -75
  225. package/src/exempt.ts +70 -98
  226. package/src/exposure.ts +492 -0
  227. package/src/extensions.ts +45 -0
  228. package/src/facts.ts +46 -0
  229. package/src/failure.ts +63 -0
  230. package/src/file-facts.ts +15 -25
  231. package/src/finding.ts +10 -10
  232. package/src/findings/boundary.ts +11 -0
  233. package/src/findings/completion.ts +133 -64
  234. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  235. package/src/findings/emitter.ts +9 -10
  236. package/src/findings/emitters.ts +38 -52
  237. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  238. package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
  239. package/src/findings/interfaces.ts +7 -9
  240. package/src/findings/intra-function.ts +16 -14
  241. package/src/findings/non-code-artifacts.ts +24 -15
  242. package/src/findings/reads-and-writes.ts +118 -41
  243. package/src/findings/self-check.ts +51 -38
  244. package/src/findings/unused-declarations.ts +31 -49
  245. package/src/findings/visibility-narrowing.ts +36 -40
  246. package/src/findings-pass.ts +15 -31
  247. package/src/framework-lifecycle.ts +47 -19
  248. package/src/fs/document.ts +70 -0
  249. package/src/fs/manifest.ts +96 -0
  250. package/src/fs/tree.ts +110 -0
  251. package/src/generated-file.ts +242 -35
  252. package/src/git-ignore.ts +50 -26
  253. package/src/host.ts +12 -5
  254. package/src/import-bindings.ts +98 -29
  255. package/src/index/sites.ts +781 -0
  256. package/src/index.ts +2 -2
  257. package/src/indexed-access.ts +570 -527
  258. package/src/injection-container.ts +2 -2
  259. package/src/interface-satisfaction.ts +2 -2
  260. package/src/intra-function-parts.ts +73 -44
  261. package/src/inventory/commonjs.ts +696 -0
  262. package/src/inventory/enumerate.ts +203 -0
  263. package/src/inventory/syntax.ts +311 -0
  264. package/src/inventory.ts +442 -895
  265. package/src/javascript-file.ts +54 -0
  266. package/src/json-document.ts +241 -76
  267. package/src/keyof-comparisons.ts +133 -122
  268. package/src/kinds.ts +5 -413
  269. package/src/{components.ts → liveness/components.ts} +4 -6
  270. package/src/{graph.ts → liveness/graph.ts} +100 -35
  271. package/src/liveness/matrix.ts +162 -0
  272. package/src/liveness/sweep.ts +855 -0
  273. package/src/load/classify.ts +433 -0
  274. package/src/load/diagnostics.ts +154 -0
  275. package/src/load/discover.ts +471 -0
  276. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  277. package/src/load/expected-module.ts +194 -0
  278. package/src/load/load.ts +73 -0
  279. package/src/load/module-lookup.ts +50 -0
  280. package/src/load/package-scope.ts +74 -0
  281. package/src/load/plan.ts +513 -0
  282. package/src/load/specifiers.ts +171 -0
  283. package/src/load/synthesize.ts +230 -0
  284. package/src/load/test-globals.ts +251 -0
  285. package/src/load/test-joins.ts +98 -0
  286. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  287. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  288. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
  289. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  290. package/src/{workspace.ts → load/workspace.ts} +90 -134
  291. package/src/module-declarations.ts +74 -98
  292. package/src/overrides.ts +162 -134
  293. package/src/partial.ts +3 -2
  294. package/src/paths.ts +92 -16
  295. package/src/platform-calls.ts +119 -0
  296. package/src/platform-symbols.ts +189 -0
  297. package/src/position.ts +44 -1
  298. package/src/print.ts +12 -92
  299. package/src/product.ts +18 -0
  300. package/src/query.ts +92 -0
  301. package/src/ref.ts +12 -20
  302. package/src/references/read-rule.ts +60 -0
  303. package/src/references/read-rules.ts +55 -0
  304. package/src/references/sink.ts +314 -0
  305. package/src/references/sources.ts +632 -0
  306. package/src/references.ts +187 -1450
  307. package/src/report-schema.ts +68 -0
  308. package/src/report.ts +103 -226
  309. package/src/reporters/annotations.ts +22 -11
  310. package/src/reporters/json.ts +1 -1
  311. package/src/reporters/reporter.ts +2 -4
  312. package/src/reporters/reporters.ts +1 -1
  313. package/src/reporters/sarif.ts +29 -16
  314. package/src/reporters/template.ts +4 -20
  315. package/src/reporters/text.ts +3 -3
  316. package/src/resolve.ts +284 -1115
  317. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +27 -29
  318. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
  319. package/src/roots/manifest.ts +303 -0
  320. package/src/roots/published-reach.ts +486 -0
  321. package/src/{roots.ts → roots/root-set.ts} +286 -469
  322. package/src/roots/unseen-loads.ts +345 -0
  323. package/src/run.ts +75 -91
  324. package/src/schema.ts +391 -388
  325. package/src/scope.ts +46 -138
  326. package/src/serialization-contract.ts +769 -23
  327. package/src/session.ts +87 -55
  328. package/src/source-files.ts +6 -11
  329. package/src/stores.ts +15 -3
  330. package/src/suppress-file.ts +24 -33
  331. package/src/suppress-inline.ts +55 -91
  332. package/src/suppress.ts +78 -79
  333. package/src/symbol-keys.ts +104 -107
  334. package/src/template-field.ts +15 -25
  335. package/src/tests/file-class.ts +135 -0
  336. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  337. package/src/{test-support.ts → tests/support.ts} +15 -21
  338. package/src/text/compare.ts +27 -0
  339. package/src/text/glob.ts +210 -0
  340. package/src/text/named-files.ts +388 -0
  341. package/src/text/yaml.ts +747 -0
  342. package/src/type-errors.ts +18 -288
  343. package/src/type-parameter-reads.ts +187 -158
  344. package/src/unimplemented-callees.ts +297 -280
  345. package/src/unwrap.ts +34 -0
  346. package/src/usage.ts +10 -0
  347. package/src/vendor/unbash/LICENSE +15 -0
  348. package/src/vendor/unbash/VENDORED.md +16 -0
  349. package/src/vendor/unbash/ansi-c.ts +132 -0
  350. package/src/vendor/unbash/arithmetic-parts.ts +53 -0
  351. package/src/vendor/unbash/arithmetic.ts +641 -0
  352. package/src/vendor/unbash/assignment.ts +163 -0
  353. package/src/vendor/unbash/chars.ts +48 -0
  354. package/src/vendor/unbash/command.ts +47 -0
  355. package/src/vendor/unbash/expansion.ts +144 -0
  356. package/src/vendor/unbash/glob.ts +284 -0
  357. package/src/vendor/unbash/heredoc.ts +34 -0
  358. package/src/vendor/unbash/internal-types.ts +94 -0
  359. package/src/vendor/unbash/lexer.ts +4352 -0
  360. package/src/vendor/unbash/limits.ts +3 -0
  361. package/src/vendor/unbash/parser.ts +1612 -0
  362. package/src/vendor/unbash/parts.ts +96 -0
  363. package/src/vendor/unbash/substitution-context.ts +20 -0
  364. package/src/vendor/unbash/traversal.ts +182 -0
  365. package/src/vendor/unbash/types.ts +660 -0
  366. package/src/vendor/unbash/word-value.ts +64 -0
  367. package/src/vendor/unbash/word.ts +50 -0
  368. package/src/verbs/analyze.ts +255 -164
  369. package/src/verbs/describe.ts +19 -17
  370. package/src/verbs/explain.ts +93 -169
  371. package/src/verbs/print-config.ts +2 -1
  372. package/src/verbs/print-projects.ts +6 -4
  373. package/src/verbs/print-retained.ts +7 -5
  374. package/src/verbs/print-roots.ts +4 -2
  375. package/src/verbs/verb.ts +2 -8
  376. package/src/verbs/version.ts +15 -3
  377. package/dist/src/base-url.js +0 -18
  378. package/dist/src/conventions.js +0 -937
  379. package/dist/src/discover.js +0 -468
  380. package/dist/src/entry-points.js +0 -529
  381. package/dist/src/glob.js +0 -65
  382. package/dist/src/manifest.js +0 -165
  383. package/dist/src/matrix.js +0 -246
  384. package/dist/src/pnpm-workspace.js +0 -120
  385. package/dist/src/roots.js +0 -672
  386. package/dist/src/setup-failure.js +0 -23
  387. package/dist/src/sweep.js +0 -224
  388. package/dist/src/test-joins.js +0 -101
  389. package/dist/src/version.js +0 -7
  390. package/dist/src/workflow-steps.js +0 -185
  391. package/src/base-url.ts +0 -24
  392. package/src/discover.ts +0 -653
  393. package/src/entry-points.ts +0 -687
  394. package/src/glob.ts +0 -67
  395. package/src/manifest.ts +0 -234
  396. package/src/matrix.ts +0 -423
  397. package/src/pnpm-workspace.ts +0 -135
  398. package/src/setup-failure.ts +0 -39
  399. package/src/sweep.ts +0 -347
  400. package/src/test-joins.ts +0 -120
  401. package/src/version.ts +0 -7
  402. package/src/workflow-steps.ts +0 -216
@@ -8,50 +8,57 @@
8
8
  import { isStringLiteralLikeNode } from "@typescript/native/ast";
9
9
  import { lineOf, readComponent } from "./component-files.js";
10
10
  import { kindOf } from "./config.js";
11
- import { consumerLoads, consumerReferences, moduleIdentity, } from "./consumers.js";
12
- import { configuredDeclarations, configuredRef, declarationsNamed, } from "./configured-declarations.js";
11
+ import { consumerReferences } from "./consumers.js";
12
+ import { configuredDeclarations, configuredRef, declarationsNamed, } from "./roots/configured-declarations.js";
13
13
  import { decorator } from "./decorator.js";
14
14
  import { configurationNeeds, dependenciesOf, projectNeeds } from "./dependencies.js";
15
+ import { carriersOf, NO_CARRIERS } from "./exposure.js";
15
16
  import { deprecatedDeclarations } from "./deprecation.js";
16
- import { discoverProjects, DiscoveryError, isGuess, MISSING_GLOBAL_TYPE, projectErrors, renderDiagnostic, targetRelative, withBaseUrlPaths, } from "./discover.js";
17
- import { conventionFailuresFor, generatedFiles, readConventions, } from "./conventions.js";
17
+ import { moduleIdentity } from "./load/discover.js";
18
+ import { loadRun } from "./load/load.js";
19
+ import { readSources } from "./entries/sources.js";
20
+ import { readWorkflows } from "./entries/workflow-steps.js";
18
21
  import { readEdgeSides } from "./edges.js";
19
22
  import { enumGroup } from "./enum-group.js";
23
+ import { bindingsOf, distinctBindings } from "./bindings.js";
20
24
  import { generatedFile, generatedFilesOf } from "./generated-file.js";
21
- import { inOperandNames } from "./in-operands.js";
25
+ import { inOperandNames } from "./findings/in-operands.js";
22
26
  import { sourceFilesOf } from "./source-files.js";
23
- import { evidenceRecords, heldRecords, disabledClasses, exemptionsOf, holdingWhile, isUnansweredRecord, retainedIn, } from "./exempt.js";
27
+ import { evidenceRecords, heldRecords, disabledClasses, exemptionsOf, isUnansweredRecord, writtenRecords, } from "./exempt.js";
24
28
  import { heldByInclusion, sourcePaths, sourceTree } from "./file-facts.js";
25
- import { globExpression } from "./glob.js";
26
29
  import { findingsPass, recordedFindings, rowKey } from "./findings-pass.js";
27
30
  import { unmatchedRootFindings } from "./findings/self-check.js";
28
31
  import { frameworkLifecycle } from "./framework-lifecycle.js";
29
- import { implementations, mergeImplementations } from "./implementations.js";
32
+ import { implementations, mergeImplementations } from "./findings/implementations.js";
30
33
  import { injectionContainer } from "./injection-container.js";
31
34
  import { interfaceSatisfaction, settledSatisfaction } from "./interface-satisfaction.js";
32
35
  import { intraFunctionFacts, projectParts } from "./intra-function-parts.js";
33
- import { inventory } from "./inventory.js";
34
- import { packageEntries, readManifest } from "./manifest.js";
35
- import { liveFilesAt, matrixOf, referenceKey, sweepMatrix, } from "./matrix.js";
36
- import { dirnamePath, extensionOf, joinPath, normalizePath, relativePath, resolvePath, } from "./paths.js";
36
+ import {} from "./inventory.js";
37
+ import { inventory } from "./inventory/enumerate.js";
38
+ import { readManifest } from "./roots/manifest.js";
39
+ import { matrixOf, referenceKey } from "./liveness/matrix.js";
40
+ import { ancestors, dirnamePath, extensionOf, joinPath, relativePath, resolvePath, } from "./paths.js";
37
41
  import { byPosition, isComponentFile } from "./position.js";
38
- import { LANGUAGE } from "./report.js";
39
- import { SetupError, setupLine } from "./setup-failure.js";
40
- import { pathsOf, readErrors, skippedRoots, skippedUnits, } from "./type-errors.js";
42
+ import { skippedUnits } from "./type-errors.js";
41
43
  import { reflectiveLookup } from "./reflective-lookup.js";
42
- import { references, testFileRulesOf } from "./references.js";
43
- import { roots, unmatchedEverywhere, } from "./roots.js";
44
- import { serializationContract } from "./serialization-contract.js";
45
- import { outsideTestReferences, testFilesAt } from "./outside-tests.js";
46
- import { joinedTestFiles, withJoinedTests } from "./test-joins.js";
47
- import { supportReferences, testSupportFiles } from "./test-support.js";
48
- import { diagnosticsOf, ownedAs, runSession, } from "./session.js";
44
+ import { references } from "./references.js";
45
+ import { rootSet, unmatchedEverywhere, } from "./roots/root-set.js";
46
+ import { decodedMembers, serializationContract } from "./serialization-contract.js";
47
+ import { outsideTestReferences, testFilesAt } from "./tests/outside.js";
48
+ import { formedForNode } from "./load/synthesize.js";
49
+ import { GLOBALS_RUNNER, namesTestGlobals } from "./load/test-globals.js";
50
+ import { targetTestFile, testFilePaths, testFileRulesOf, withheldBy, } from "./tests/file-class.js";
51
+ import { testSupportFiles } from "./tests/support.js";
49
52
  import { accessorsOf, storesOf } from "./stores.js";
50
53
  import { isPartKind } from "./suppress.js";
51
54
  import { bindRows, readBaseline, readIgnoreFile } from "./suppress-file.js";
52
55
  import { inlineDirectives, inlineSuppressions } from "./suppress-inline.js";
56
+ import { sweep } from "./liveness/sweep.js";
53
57
  import { readTemplates, templateField } from "./template-field.js";
54
- import { ownErrors, workspaceRun } from "./workspace-run.js";
58
+ import { bytewise } from "./text/compare.js";
59
+ import { holdsManifest, manifestAt } from "./fs/manifest.js";
60
+ import { runDirectories } from "./entries/run-directories.js";
61
+ import { globExpression } from "./text/glob.js";
55
62
  /** The setting whose source decides where a finding about a configured root sits. */
56
63
  const ROOTS_SETTING = "roots.patterns";
57
64
  /**
@@ -68,288 +75,91 @@ function documentOf(host, provenance, setting, targetRoot) {
68
75
  const document = resolvePath(host.workingDirectory(), origin.label);
69
76
  return relativePath(resolvePath(host.workingDirectory(), targetRoot), document) ?? "";
70
77
  }
71
- /** Two strings ordered bytewise. */
72
- function compare(a, b) {
73
- if (a === b) {
74
- return 0;
75
- }
76
- return a < b ? -1 : 1;
77
- }
78
78
  /**
79
- * The manifests the analysis reads, each once: the target's own, then every workspace
80
- * member's and every nested package's below the target root.
81
- */
82
- function conventionManifests(host, targetRoot, memberDirs, nestedDirs) {
83
- const found = new Map();
84
- if (host.kindOf(joinPath(targetRoot, "package.json")) === "file") {
85
- found.set(targetRoot, { dir: targetRoot, path: "package.json" });
86
- }
87
- for (const [dirs, nested] of [
88
- [memberDirs, false],
89
- [nestedDirs, true],
90
- ]) {
91
- for (const dir of dirs) {
92
- const below = relativePath(targetRoot, dir);
93
- if (below !== undefined && !found.has(dir)) {
94
- found.set(dir, { dir, path: `${below}/package.json`, nested });
95
- }
96
- }
97
- }
98
- return [...found.values()];
99
- }
100
- /**
101
- * The nested packages of a run: each directory below the target root, in no `node_modules`
102
- * directory and none of `known`, that holds a `package.json` and lies at or above one of
103
- * `files`, the program's source files and the compiler configuration files, in path order.
104
- */
105
- function nestedPackageDirs(host, targetRoot, files, known) {
106
- const seen = new Set();
107
- const found = [];
108
- for (const file of files) {
109
- for (let dir = dirnamePath(file); dir !== targetRoot && !seen.has(dir) && relativePath(targetRoot, dir) !== undefined; dir = dirnamePath(dir)) {
110
- seen.add(dir);
111
- const below = relativePath(targetRoot, dir) ?? "";
112
- if (!below.split("/").includes("node_modules") &&
113
- !known.has(dir) &&
114
- host.kindOf(joinPath(dir, "package.json")) === "file") {
115
- found.push(dir);
116
- }
117
- }
118
- }
119
- return found.sort(compare);
120
- }
121
- /**
122
- * Reads every project the scope discovers, and each declared consumer's, in one snapshot,
123
- * each checked for errors first. `stage` is handed a target project and enumerates and roots
124
- * it if it reads it; a consumer project is read for its references to the target. A type error
125
- * in an own file skips the unit holding it. A guess that does not load or meets a setup failure
126
- * is dropped into `notBuilt` (see {@link isGuess}); any other such project fails the run, as
127
- * does a run whose every guess was dropped.
79
+ * Reads every project the load phase analyzes through `stage`, which enumerates and roots one
80
+ * if it reads it, and each declared consumer's project for its references to the target,
81
+ * in the same snapshot. A type error in an own file skips the unit holding it.
128
82
  */
129
83
  function readProjects(engine, host, scope, config, stage) {
130
84
  const targetRoot = scope.target.path;
131
- const discovered = discoverProjects(engine, host, scope, config.analysis.configurations);
132
- if (discovered.configFiles.length === 0 && discovered.notBuilt.length === 0) {
133
- throw new DiscoveryError(`${targetRoot} holds no compiler configuration, so the run holds no program`, []);
134
- }
135
- const ids = new Map(discovered.projects.map((project) => [project.configFile, project.id]));
136
- const loads = consumerLoads(engine, host, scope, discovered.configFiles);
137
- const consumerOf = new Map(loads.flatMap((load) => load.configFiles.map((configFile) => [configFile, load.consumer])));
138
85
  const absoluteRoot = resolvePath(host.workingDirectory(), targetRoot);
139
- const workspace = workspaceRun(engine, host, absoluteRoot, discovered.configFiles, readManifest(host, targetRoot));
86
+ const testPatterns = config.ts.test_files.map(globExpression);
140
87
  const parse = (fileName, text) => engine.parseSourceFile(fileName, text);
141
- const memberDirs = workspace?.memberDirs ?? [];
142
- // The nested packages are known only once every program is open, and every visit reads
143
- // the conventions and options they decide, so both are set in the session's first step.
144
- let nestedDirs = [];
145
- let conventions = readConventions(host, parse, [], config.ts.disabledConventions);
146
- let options;
147
- const readManifests = (opened) => {
148
- nestedDirs = nestedPackageDirs(host, normalizePath(absoluteRoot), opened
149
- .filter((one) => !consumerOf.has(one.configFile))
150
- .flatMap((one) => [one.configFile, ...one.fileNames()]), new Set(memberDirs));
151
- conventions = readConventions(host, parse, conventionManifests(host, absoluteRoot, memberDirs, nestedDirs), config.ts.disabledConventions);
152
- options = {
88
+ return loadRun(engine, host, scope, config, ({ plan, classified, runFiles }) => {
89
+ const { packages, conventions } = plan;
90
+ const workflows = readWorkflows(host, targetRoot);
91
+ const options = {
153
92
  host,
154
- manifest: workspace?.manifest ?? readManifest(host, targetRoot),
155
- otherPackages: [
156
- ...(workspace?.entries ?? []),
157
- ...packageEntries(host, normalizePath(absoluteRoot), nestedDirs),
158
- ],
159
- patterns: config.rootPatterns,
160
- entryFiles: config.ts.entryFiles,
161
- conventions,
162
- testFiles: config.ts.testFiles,
93
+ manifest: packages.manifest,
94
+ otherPackages: packages.entries,
95
+ patterns: config.roots.patterns,
96
+ entryFiles: config.ts.entry_files,
163
97
  parse,
164
- publishedAPI: config.targetKind !== "" && kindOf(config.targetKind, LANGUAGE) === "library",
165
- publishedMembers: new Set((workspace?.entries ?? []).filter((entry) => entry.published).map((entry) => entry.dir)),
166
- runFiles: new Set(opened.flatMap((one) => one.fileNames().map((name) => resolvePath(host.workingDirectory(), name)))),
98
+ publishedAPI: config.target.kind !== undefined && kindOf(config.target.kind) === "library",
99
+ publishedMembers: packages.published,
100
+ runFiles,
167
101
  };
168
- };
169
- const notBuilt = [...discovered.notBuilt];
170
- const dropped = (configFile, error) => {
171
- notBuilt.push({
172
- id: ids.get(configFile) ?? configFile,
173
- configFile,
174
- error: targetRelative(error, absoluteRoot),
175
- });
176
- };
177
- const failures = [];
178
- const unbuildable = [];
179
- const setupDropped = [];
180
- const librariesUnfound = [];
181
- const consumed = new Map();
182
- const heldFiles = new Set();
183
- let outsideTests = [];
184
- const setupMet = (configFile, met) => {
185
- const [first] = met;
186
- if (first !== undefined && isGuess(discovered, configFile)) {
187
- dropped(configFile, setupLine(first));
188
- setupDropped.push(...met);
189
- }
190
- else {
191
- unbuildable.push(...met);
192
- }
193
- };
194
- const testPatterns = config.ts.testFiles.map(globExpression);
195
- const joins = discovered.derived
196
- ? joinedTestFiles(engine, host, absoluteRoot, discovered.configFiles, testPatterns)
197
- : new Map();
198
- const programs = withBaseUrlPaths(engine, host, [...discovered.configFiles, ...consumerOf.keys()], workspace?.programs ?? new Map());
199
- const session = runSession(engine, [...discovered.configFiles, ...consumerOf.keys()], (opened) => {
200
- const consumer = consumerOf.get(opened.configFile);
201
- const setup = consumer === undefined ? workspace?.unbuildable(opened.configFile) : undefined;
202
- if (setup !== undefined) {
203
- setupMet(opened.configFile, [
204
- { setupClass: "workspace-member-without-source", detail: setup },
205
- ]);
206
- return undefined;
207
- }
208
- const referenceOnly = workspace === undefined || consumer !== undefined
209
- ? () => false
210
- : workspace.referenceOnly(opened.configFile, opened.rootFiles);
211
- const project = workspace === undefined || consumer !== undefined
212
- ? opened
213
- : ownedAs(opened, (file, fromExternalLibrary) => workspace.ownFile(file, fromExternalLibrary));
214
- const raw = projectErrors(diagnosticsOf(project));
215
- const errors = { load: raw.load, check: ownErrors(raw.check, referenceOnly) };
216
- const [unloaded] = errors.load;
217
- if (unloaded !== undefined &&
218
- consumer === undefined &&
219
- isGuess(discovered, project.configFile)) {
220
- dropped(project.configFile, renderDiagnostic(unloaded, (path) => relativePath(absoluteRoot, path) ?? path));
221
- return undefined;
222
- }
223
- if (errors.load.length > 0) {
224
- failures.push(...errors.load);
225
- return undefined;
226
- }
227
- const reading = readErrors(project, errors.check, {
228
- host,
229
- targetRoot: consumer === undefined
230
- ? absoluteRoot
231
- : resolvePath(host.workingDirectory(), consumer.path),
232
- paths: pathsOf(engine, project.configFile),
102
+ const heldFiles = new Set();
103
+ const answers = classified.analyzed.map(({ plan: planned, project, skips, referenceOnly }) => {
104
+ const read = () => {
105
+ const held = inventory(project, host, targetRoot);
106
+ const own = sourceFilesOf(project, targetRoot);
107
+ const sources = readSources({
108
+ host,
109
+ targetRoot,
110
+ files: own,
111
+ parse,
112
+ testFiles: config.ts.test_files,
113
+ conventions,
114
+ workflows,
115
+ });
116
+ const rooted = rootSet(project, held, targetRoot, { ...options, sources, skips });
117
+ const generated = generatedFilesOf(own, sources.generated);
118
+ return {
119
+ configuration: planned.id,
120
+ configFile: project.configFile,
121
+ held,
122
+ rooted,
123
+ typeErrorSkips: skips.map((one) => one.record),
124
+ skipped: skippedUnits(skips, absoluteRoot),
125
+ referenceOnly: project
126
+ .ownSourceFiles()
127
+ .filter((file) => referenceOnly(file.fileName))
128
+ .flatMap((file) => relativePath(absoluteRoot, file.fileName) ?? []),
129
+ generated,
130
+ bindings: bindingsOf(own.byPath, generated, new Map(held.symbols
131
+ .filter((one) => one.kind === "file")
132
+ .map((one) => [one.position.path, one.ref]))),
133
+ sources,
134
+ formedForNode: formedForNode(planned),
135
+ };
136
+ };
137
+ for (const file of project.ownSourceFiles()) {
138
+ heldFiles.add(relativePath(absoluteRoot, file.fileName) ?? file.fileName);
139
+ }
140
+ return stage(project, { configuration: planned.id, read });
233
141
  });
234
- if (consumer !== undefined && reading.missing.length > 0) {
235
- unbuildable.push(...reading.missing.map((one) => ({
236
- setupClass: "missing-consumer",
237
- detail: `the consumer ${consumer.path} does not build, its dependencies not installed: ${one.detail}`,
238
- })));
239
- return undefined;
240
- }
241
- if (reading.missing.length > 0) {
242
- setupMet(project.configFile, reading.missing);
243
- return undefined;
244
- }
245
- const unconventional = consumer === undefined
246
- ? conventionFailuresFor(conventions, project.configFile, project.ownSourceFiles().map((file) => file.fileName))
247
- : [];
248
- if (unconventional.length > 0) {
249
- setupMet(project.configFile, unconventional);
250
- return undefined;
251
- }
252
- if (consumer !== undefined) {
253
- for (const reference of consumerReferences(project, host, targetRoot, {
254
- id: consumer.id,
255
- root: consumer.path,
256
- }, config)) {
142
+ const consumed = new Map();
143
+ const consumerHeld = new Set();
144
+ for (const { project, consumer } of classified.consumed) {
145
+ const side = { id: consumer.id, root: consumer.path };
146
+ const read = consumerReferences(project, host, targetRoot, side, config, parse);
147
+ for (const reference of read.references) {
257
148
  consumed.set(referenceKey(reference), reference);
258
149
  }
259
- return undefined;
260
- }
261
- librariesUnfound.push(...raw.unfound.map((one) => ({
262
- configFile: project.configFile,
263
- error: renderDiagnostic(one, (path) => relativePath(absoluteRoot, path) ?? path),
264
- })));
265
- const missingGlobal = raw.unfound.find(({ diagnostic }) => diagnostic.code === MISSING_GLOBAL_TYPE);
266
- const skips = missingGlobal === undefined
267
- ? reading.skips
268
- : [
269
- ...reading.skips,
270
- ...project.ownSourceFiles().map((file) => ({
271
- record: {
272
- path: relativePath(absoluteRoot, file.fileName) ?? file.fileName,
273
- line: 1,
274
- message: missingGlobal.diagnostic.text,
275
- },
276
- file,
277
- unit: file,
278
- })),
279
- ];
280
- const configuration = ids.get(project.configFile) ?? project.configFile;
281
- const read = () => {
282
- const held = inventory(project, host, targetRoot);
283
- const found = roots(project, held, targetRoot, options);
284
- const kept = skippedRoots(project, held, skips);
285
- const rooted = kept.length === 0
286
- ? found
287
- : {
288
- ...found,
289
- liveUnderReachability: [
290
- ...found.liveUnderReachability,
291
- ...kept.map((id) => ({ id, kind: "type-error", source: "" })),
292
- ],
293
- };
294
- const own = sourceFilesOf(project, targetRoot);
295
- return {
296
- configuration,
297
- configFile: project.configFile,
298
- held,
299
- rooted,
300
- typeErrorSkips: skips.map((one) => one.record),
301
- skipped: skippedUnits(skips, absoluteRoot),
302
- referenceOnly: project
303
- .ownSourceFiles()
304
- .filter((file) => referenceOnly(file.fileName))
305
- .flatMap((file) => relativePath(absoluteRoot, file.fileName) ?? []),
306
- generated: generatedFilesOf(own, generatedFiles(conventions, own)),
307
- testFileNames: conventions.testFiles,
308
- };
309
- };
310
- for (const file of project.ownSourceFiles()) {
311
- heldFiles.add(relativePath(absoluteRoot, file.fileName) ?? file.fileName);
312
- }
313
- return stage(project, { configuration, read });
314
- }, discovered.derived ? "record" : "refuse", joins.size === 0 ? programs : withJoinedTests(engine, host, programs, joins), () => {
315
- outsideTests = testFilesAt(host, targetRoot, sourcePaths(host, targetRoot).filter((path) => !heldFiles.has(path) && testPatterns.some((pattern) => pattern.test(path))), parse);
316
- }, readManifests);
317
- for (const configFile of session.unopened) {
318
- if (consumerOf.has(configFile) || !isGuess(discovered, configFile)) {
319
- throw new DiscoveryError(`${configFile} opened no project`, []);
150
+ for (const id of read.held) {
151
+ consumerHeld.add(id);
152
+ }
320
153
  }
321
- dropped(configFile, "the compiler opened no project for the configuration");
322
- }
323
- if (unbuildable.length > 0) {
324
- throw new SetupError(unbuildable);
325
- }
326
- if (failures.length > 0) {
327
- throw new DiscoveryError(`${String(failures.length)} error(s), so no answer was produced`, failures);
328
- }
329
- const answers = session.projects.filter((answer) => answer !== undefined);
330
- const [first] = notBuilt;
331
- if (answers.length === 0 && setupDropped.length > 0) {
332
- throw new SetupError(setupDropped);
333
- }
334
- if (answers.length === 0 && first !== undefined) {
335
- throw new DiscoveryError(`no configuration discovery derived could be built; ${first.id}: ${first.error}`, []);
336
- }
337
- return {
338
- answers,
339
- consumers: {
340
- loaded: loads.map((load) => load.consumer),
154
+ const outsideTests = testFilesAt(host, targetRoot, sourcePaths(host, targetRoot).filter((path) => !heldFiles.has(path) && testPatterns.some((pattern) => pattern.test(path))), parse);
155
+ return {
156
+ answers,
341
157
  references: [...consumed.values()],
342
- },
343
- notBuilt,
344
- unanswered: session.unanswered,
345
- componentsUnread: workspace?.componentsUnread ?? [],
346
- librariesUnfound,
347
- conventionsApplied: conventions.applied,
348
- conventionUses: conventions.uses,
349
- memberDirs,
350
- nestedDirs,
351
- outsideTests,
352
- };
158
+ consumerHeld: [...consumerHeld],
159
+ outsideTests,
160
+ workflows,
161
+ };
162
+ });
353
163
  }
354
164
  /**
355
165
  * The projects the run the scope and the configuration describe analyzes, each read
@@ -358,7 +168,11 @@ function readProjects(engine, host, scope, config, stage) {
358
168
  */
359
169
  export function runProjects(engine, host, scope, config) {
360
170
  const read = readProjects(engine, host, scope, config, (_project, opened) => opened.configuration);
361
- return { configurations: read.answers, notBuilt: read.notBuilt, unanswered: read.unanswered };
171
+ return {
172
+ configurations: read.result.answers,
173
+ notBuilt: read.classified.notBuilt,
174
+ unanswered: read.unanswered,
175
+ };
362
176
  }
363
177
  /**
364
178
  * The root set of the run the scope and the configuration describe.
@@ -369,7 +183,7 @@ export function runProjects(engine, host, scope, config) {
369
183
  export function runRoots(engine, host, scope, config, provenance) {
370
184
  const targetRoot = scope.target.path;
371
185
  const read = readProjects(engine, host, scope, config, (_project, opened) => opened.read());
372
- const projects = read.answers;
186
+ const projects = read.result.answers;
373
187
  const configurations = [];
374
188
  const merged = new Map();
375
189
  for (const answer of projects) {
@@ -397,16 +211,25 @@ export function runRoots(engine, host, scope, config, provenance) {
397
211
  }
398
212
  }
399
213
  }
400
- const ordered = [...merged.values()].sort((a, b) => byPosition(a.position, b.position) || compare(a.kind, b.kind) || compare(a.source, b.source));
401
- const unmatched = unmatchedEverywhere(config.rootPatterns, projects.map((answer) => answer.rooted));
214
+ const ordered = [...merged.values()].sort((a, b) => byPosition(a.position, b.position) ||
215
+ bytewise(a.kind, b.kind) ||
216
+ bytewise(a.source, b.source));
217
+ const unmatched = unmatchedEverywhere(config.roots.patterns, projects.map((answer) => answer.rooted));
402
218
  return {
403
219
  configurations,
404
220
  roots: ordered,
405
221
  findings: unmatchedRootFindings(unmatched, documentOf(host, provenance, ROOTS_SETTING, targetRoot)),
406
- notBuilt: read.notBuilt,
222
+ notBuilt: read.classified.notBuilt,
407
223
  unanswered: read.unanswered,
408
224
  };
409
225
  }
226
+ /** The production mode a configuration sets: a consumer's test reference is classed as `analysis.consumer_tests` says. */
227
+ export function productionMode(config) {
228
+ return {
229
+ production: true,
230
+ consumerTestsProduction: config.analysis.consumer_tests === "production",
231
+ };
232
+ }
410
233
  /** The exemption classes this analyzer detects, each by its detector; any other retains nothing. */
411
234
  export const DETECTORS = new Map([
412
235
  ["interface-satisfaction", interfaceSatisfaction],
@@ -435,18 +258,9 @@ function testEvidence(host, targetRoot, projects) {
435
258
  }
436
259
  }
437
260
  const manifests = new Map();
438
- const manifestAt = (dir) => {
261
+ const manifestIn = (dir) => {
439
262
  if (!manifests.has(dir)) {
440
- let value;
441
- try {
442
- value = JSON.parse(host.readFile(joinPath(dir, "package.json")));
443
- }
444
- catch {
445
- value = undefined;
446
- }
447
- manifests.set(dir, typeof value === "object" && value !== null && !Array.isArray(value)
448
- ? value
449
- : undefined);
263
+ manifests.set(dir, manifestAt(host, dir));
450
264
  }
451
265
  return manifests.get(dir);
452
266
  };
@@ -455,16 +269,14 @@ function testEvidence(host, targetRoot, projects) {
455
269
  return {
456
270
  imports,
457
271
  devDependency: (path, name) => {
458
- for (let dir = dirnamePath(joinPath(root, path));; dir = dirnamePath(dir)) {
459
- const manifest = manifestAt(dir);
272
+ for (const dir of ancestors(dirnamePath(joinPath(root, path)), root)) {
273
+ const manifest = manifestIn(dir);
460
274
  const other = OTHER_SECTIONS.some((one) => declares(manifest?.[one], name));
461
275
  if (declares(manifest?.[DEV_SECTION], name) || other) {
462
276
  return !other;
463
277
  }
464
- if (normalizePath(dir) === normalizePath(root) || dirnamePath(dir) === dir) {
465
- return false;
466
- }
467
278
  }
279
+ return false;
468
280
  },
469
281
  };
470
282
  }
@@ -478,15 +290,19 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
478
290
  const targetRoot = scope.target.path;
479
291
  const disabled = disabledClasses(config);
480
292
  const templates = disabled.has("template-field")
481
- ? { delimiters: config.analysis.templateDelimiters, files: [] }
293
+ ? { delimiters: config.analysis.template_delimiters, files: [] }
482
294
  : readTemplates(host, targetRoot, config.analysis);
483
295
  const consumers = scope.consumers.map((consumer) => consumer.path);
296
+ const directories = runDirectories(host, targetRoot, (fileName, text) => engine.parseSourceFile(fileName, text));
484
297
  const read = readProjects(engine, host, scope, config, (project, opened) => {
485
298
  const projectRead = opened.read();
299
+ const testFile = targetTestFile(projectRead.sources.testFiles);
486
300
  const resolved = references(project, projectRead.held, targetRoot, {
487
- testFiles: config.ts.testFiles,
488
- testFileNames: projectRead.testFileNames,
301
+ testFile,
302
+ directories,
303
+ formedForNode: projectRead.formedForNode,
489
304
  });
305
+ const testFiles = testFilePaths(project, targetRoot, testFile);
490
306
  const evidence = evidenceRecords({
491
307
  project,
492
308
  held: projectRead.held,
@@ -494,57 +310,91 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
494
310
  templates,
495
311
  ts: config.ts,
496
312
  consumers,
497
- ...(config.analysis.generatedFiles === "include"
313
+ ...(config.analysis.generated_files === "include"
498
314
  ? {}
499
315
  : { generated: projectRead.generated }),
500
316
  }, detectors, disabled);
501
317
  const components = project.ownSourceFiles().filter(isComponentFile);
318
+ const injected = project.program
319
+ .getSourceFileNames()
320
+ .some((name) => name.endsWith(`/node_modules/${GLOBALS_RUNNER}/globals.d.ts`));
502
321
  const pathOf = (file) => relativePath(targetRoot, file.fileName) ?? file.fileName;
503
322
  return {
504
323
  projectRead,
505
324
  references: resolved.references,
506
- testFiles: resolved.testFilePaths,
325
+ held: resolved.held,
326
+ possiblyLoaded: resolved.possiblyLoaded,
327
+ testFiles,
507
328
  evidence,
508
329
  componentFiles: components.map(pathOf),
509
330
  imports: new Map(project.ownSourceFiles().flatMap((file) => {
510
331
  const path = relativePath(targetRoot, file.fileName);
511
- return path === undefined
512
- ? []
513
- : [[path, file.imports.filter(isStringLiteralLikeNode).map((one) => one.text)]];
332
+ if (path === undefined) {
333
+ return [];
334
+ }
335
+ const specifiers = file.imports.filter(isStringLiteralLikeNode).map((one) => one.text);
336
+ // A file calling the globals a program declares is written for their runner.
337
+ return [
338
+ [
339
+ path,
340
+ injected && namesTestGlobals(project, file)
341
+ ? [...specifiers, GLOBALS_RUNNER]
342
+ : specifiers,
343
+ ],
344
+ ];
514
345
  })),
515
346
  componentWarnings: components.flatMap((file) => readComponent(file.originalText, extensionOf(file.fileName)).warnings.map((warning) => ({
516
347
  path: pathOf(file),
517
348
  line: lineOf(file.originalText, warning.offset),
518
349
  reason: warning.reason,
519
350
  }))),
520
- extra: extra(project, projectRead, resolved.references, resolved.testFilePaths),
351
+ decoded: decodedMembers(project, projectRead.held, productionFiles(project, targetRoot, testFiles), consumers),
352
+ extra: extra(project, projectRead, resolved.references, testFiles, resolved.unseenLoads.map((position) => ({
353
+ configuration: projectRead.configuration,
354
+ position,
355
+ }))),
521
356
  };
522
357
  });
523
- const outsidePaths = read.outsideTests.map((one) => one.path);
524
- const withOutside = read.answers.map((one) => ({
358
+ const outsidePaths = read.result.outsideTests.map((one) => one.path);
359
+ const withOutside = read.result.answers.map((one) => ({
525
360
  ...one,
526
361
  references: [
527
362
  ...one.references,
528
- ...outsideTestReferences(read.outsideTests, one.projectRead.held, targetRoot),
363
+ ...outsideTestReferences(read.result.outsideTests, one.projectRead.held, targetRoot),
529
364
  ],
530
365
  testFiles: [...one.testFiles, ...outsidePaths],
531
366
  }));
532
367
  // Test-support code is code only test code imports in any configuration of the run: a
533
368
  // configuration that holds no test file says nothing about what the tests import.
534
- const { support, testUsed } = testSupportFiles(withOutside.flatMap((one) => one.projectRead.held.symbols), withOutside.flatMap((one) => one.references), withOutside.flatMap((one) => one.projectRead.rooted.liveUnderReachability), withOutside.flatMap((one) => one.testFiles), testEvidence(host, targetRoot, withOutside));
535
- const settled = settledSatisfaction(withOutside.map((one) => ({ evidence: one.evidence, held: one.projectRead.held })), [...withOutside.flatMap((one) => one.references), ...read.consumers.references]);
369
+ const { support, testUsed } = testSupportFiles(withOutside.flatMap((one) => one.projectRead.held.symbols), withOutside.flatMap((one) => one.references),
370
+ // An outside declaration naming a global augmentation calls nothing of its file.
371
+ withOutside.flatMap((one) => one.projectRead.rooted.liveUnderReachability.filter((root) => root.kind !== "global-augmentation")), withOutside.flatMap((one) => one.testFiles), testEvidence(host, targetRoot, withOutside));
372
+ // A member a decode fills or a copy carries is written: a value decoded and sent again carries it on.
373
+ const written = new Set([
374
+ ...countedWrites([...withOutside.flatMap((one) => one.references), ...read.result.references], support, mode),
375
+ ...withOutside.flatMap((one) => [
376
+ ...one.decoded.filled,
377
+ ...one.decoded.parsed,
378
+ ...one.decoded.copied,
379
+ ]),
380
+ ]);
381
+ const evidence = withOutside.map((one) => writtenRecords(one.evidence, written));
382
+ const settled = settledSatisfaction(withOutside.map((one, index) => ({
383
+ evidence: evidence[index] ?? [],
384
+ held: one.projectRead.held,
385
+ })), [...withOutside.flatMap((one) => one.references), ...read.result.references]);
536
386
  const answers = withOutside.map((one, index) => {
537
387
  const { projectRead } = one;
538
388
  const satisfied = settled[index];
539
- const detected = heldRecords(satisfied?.evidence ?? one.evidence, {
389
+ const detected = heldRecords(satisfied?.evidence ?? evidence[index] ?? [], {
540
390
  mode,
541
391
  testFiles: new Set([...one.testFiles, ...support]),
542
392
  });
543
393
  const exempt = detected.records;
544
- const made = supportReferences([...one.references, ...(satisfied?.references ?? [])], support);
394
+ const made = [...one.references, ...(satisfied?.references ?? [])];
545
395
  const held = new Set(projectRead.held.symbols.map((symbol) => symbol.position.path));
546
- const supportFiles = [...support].filter((path) => held.has(path)).sort();
547
- const testUsedFiles = [...testUsed].filter((path) => held.has(path)).sort();
396
+ const supportFiles = [...support].filter((path) => held.has(path)).sort(bytewise);
397
+ const testUsedFiles = [...testUsed].filter((path) => held.has(path)).sort(bytewise);
548
398
  const configured = {
549
399
  configuration: projectRead.configuration,
550
400
  symbols: projectRead.held.symbols,
@@ -568,20 +418,23 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
568
418
  unanswered: [
569
419
  ...projectRead.held.unanswered,
570
420
  ...projectRead.rooted.unanswered,
571
- ...made
572
- .filter((reference) => reference.resolution === "by-name")
573
- .map((reference) => reference.to),
421
+ ...made.filter((reference) => reference.guessed === true).map((reference) => reference.to),
422
+ ...one.held,
574
423
  ...exempt.filter(isUnansweredRecord).map((record) => record.id),
424
+ ...one.decoded.unanswered,
575
425
  ],
426
+ filledOutside: one.decoded.filled,
427
+ possiblyLoaded: one.possiblyLoaded,
576
428
  typeErrorSkips: projectRead.typeErrorSkips,
577
429
  unmappedEntries: projectRead.rooted.unmappedEntries,
430
+ heldScripts: projectRead.rooted.heldScripts,
578
431
  skipped: projectRead.skipped,
579
432
  componentFiles: one.componentFiles,
580
433
  componentWarnings: one.componentWarnings,
581
434
  extra: one.extra,
582
435
  };
583
436
  });
584
- const consumed = read.consumers.references;
437
+ const consumed = read.result.references;
585
438
  const projects = answers.map((one) => consumed.length === 0
586
439
  ? one
587
440
  : {
@@ -597,44 +450,26 @@ function readRun(engine, host, scope, config, mode, detectors, extra) {
597
450
  unansweredHeld: [
598
451
  ...new Set([
599
452
  ...answers.flatMap((one) => one.unanswered),
600
- ...consumed.filter((one) => one.resolution === "by-name").map((one) => one.to),
453
+ ...consumed.filter((one) => one.guessed === true).map((one) => one.to),
454
+ ...read.result.consumerHeld,
601
455
  ]),
602
456
  ],
603
457
  projects,
604
- consumers: read.consumers.loaded,
605
- notBuilt: read.notBuilt,
458
+ consumers: read.plan.discovery.consumers,
459
+ declaresConsumers: scope.consumers.length > 0,
460
+ notBuilt: read.classified.notBuilt,
606
461
  unanswered: read.unanswered,
607
- componentsUnread: read.componentsUnread,
608
- librariesUnfound: read.librariesUnfound,
609
- conventionsApplied: read.conventionsApplied,
610
- conventionUses: read.conventionUses,
611
- memberDirs: read.memberDirs,
612
- nestedDirs: read.nestedDirs,
462
+ componentsUnread: read.plan.workspace?.componentsUnread ?? [],
463
+ librariesUnfound: read.classified.librariesUnfound,
464
+ unresolvedSpecifiers: read.classified.unresolvedSpecifiers,
465
+ unread: read.plan.unread,
466
+ conventionsApplied: read.plan.conventions.applied,
467
+ conventionUses: read.plan.conventions.uses,
468
+ memberDirs: read.plan.packages.members,
469
+ nestedDirs: read.plan.packages.nested,
470
+ workflows: read.result.workflows,
613
471
  };
614
472
  }
615
- /**
616
- * The run swept under one set of marks with the records that hold. A record a component
617
- * file's markup holds counts only while the file is live, and what it holds may be what
618
- * keeps the file live, so each file's markup joins only once a sweep without it finds the
619
- * file live, until a sweep finds no further file live.
620
- */
621
- function holdingSweep(read, input) {
622
- const paths = new Set(read.exempt.flatMap((record) => record.whileLive ?? []));
623
- let live = new Set();
624
- for (;;) {
625
- const swept = {
626
- ...input,
627
- exempt: holdingWhile(read.exempt, live),
628
- unanswered: read.unansweredHeld,
629
- };
630
- const result = sweepMatrix(read.matrix, swept);
631
- const next = new Set(liveFilesAt(read.matrix, result, paths).map((one) => one.position.path));
632
- if (next.size === live.size) {
633
- return { swept, result };
634
- }
635
- live = next;
636
- }
637
- }
638
473
  /**
639
474
  * The test references exemption evidence written in a test file makes: each is a read of
640
475
  * the declaration it would retain, made by the test file at the evidence's site.
@@ -662,6 +497,13 @@ function evidenceReferences(symbols, inTestFiles) {
662
497
  ];
663
498
  });
664
499
  }
500
+ /**
501
+ * The declarations a write the mode counts stores into, a write a test-support file
502
+ * makes being a test's.
503
+ */
504
+ function countedWrites(references, support, mode) {
505
+ return new Set(references.flatMap((reference) => reference.use === "write" && !withheldBy(mode, reference, support) ? [reference.to] : []));
506
+ }
665
507
  /**
666
508
  * The declarations every reference the mode counts stores into, a loaded consumer's
667
509
  * reference counting as a read: what the write-only kind would report but for a record.
@@ -670,8 +512,9 @@ function writtenOnly(read, mode) {
670
512
  const written = new Set();
671
513
  const readSome = new Set();
672
514
  for (const { configured } of read.projects) {
515
+ const support = new Set(configured.supportFiles ?? []);
673
516
  for (const reference of configured.references) {
674
- if (mode.production && reference.test) {
517
+ if (withheldBy(mode, reference, support)) {
675
518
  continue;
676
519
  }
677
520
  if (reference.use === "write" && reference.consumer === undefined) {
@@ -684,55 +527,22 @@ function writtenOnly(read, mode) {
684
527
  }
685
528
  return new Set([...written].filter((id) => !readSome.has(id)));
686
529
  }
687
- /**
688
- * The sweep of a run read once, under one set of marks. Where a question went unanswered,
689
- * the run is swept once more without what that question could have kept live and without
690
- * the references that stood in for its answer, and every declaration that sweep judges
691
- * dead and this one judges live, or dead by another rule, is held by the gap too, as is
692
- * every declaration that makes such a reference.
693
- */
530
+ /** The sweep of a run read once, under one set of marks. */
694
531
  function sweptOf(read, input) {
695
- const { swept, result } = holdingSweep(read, input);
696
- const exempt = swept.exempt ?? [];
697
- const held = new Set(read.unansweredHeld);
698
- if (held.size > 0) {
699
- // What a declaration reads where the checker did not answer is unknown, so a rule
700
- // over what it reads, the test of dead code among them, cannot judge it.
701
- for (const { configured } of read.projects) {
702
- for (const reference of configured.references) {
703
- if (reference.resolution === "by-name") {
704
- held.add(reference.from);
705
- }
706
- }
707
- }
708
- const dead = new Map(result.candidates.map((candidate) => [candidate.id, candidate]));
709
- const answered = matrixOf(read.projects.map(({ configured }) => ({
710
- ...configured,
711
- references: configured.references.filter((one) => one.resolution !== "by-name"),
712
- })));
713
- const bare = {
714
- ...swept,
715
- exempt: exempt.filter((record) => !isUnansweredRecord(record)),
716
- unanswered: [],
717
- };
718
- for (const candidate of sweepMatrix(answered, bare).candidates) {
719
- const kept = dead.get(candidate.id);
720
- if (kept?.testOfDeadCode !== candidate.testOfDeadCode ||
721
- kept.relation !== candidate.relation) {
722
- held.add(candidate.id);
723
- }
724
- }
725
- }
532
+ const componentFiles = [...new Set(read.projects.flatMap((one) => one.componentFiles))].sort(bytewise);
726
533
  return {
727
534
  matrix: read.matrix,
728
- sweep: result,
729
- exempt,
730
- retained: retainedIn(read.matrix, swept, writtenOnly(read, input.mode)),
535
+ sweep: sweep(read.matrix, {
536
+ ...input,
537
+ exempt: read.exempt,
538
+ unanswered: read.unansweredHeld,
539
+ componentFiles,
540
+ unseenCallers: !read.declaresConsumers,
541
+ writeOnly: writtenOnly(read, input.mode),
542
+ }),
731
543
  notBuilt: read.notBuilt,
732
544
  unanswered: read.unanswered,
733
- heldByUnanswered: [...held],
734
545
  skipped: read.projects.flatMap((one) => one.skipped),
735
- componentFiles: [...new Set(read.projects.flatMap((one) => one.componentFiles))].sort(compare),
736
546
  };
737
547
  }
738
548
  /**
@@ -746,23 +556,32 @@ function sweptOf(read, input) {
746
556
  export function runSweep(engine, host, scope, config, input, detectors = DETECTORS) {
747
557
  return sweptOf(readRun(engine, host, scope, config, input.mode, detectors, () => undefined), input);
748
558
  }
559
+ /** The project's own files below the target root that are no test file. */
560
+ function productionFiles(project, targetRoot, testFiles) {
561
+ const tests = new Set(testFiles);
562
+ return [...sourceFilesOf(project, targetRoot).byPath].flatMap(([path, file]) => tests.has(path) ? [] : [file]);
563
+ }
749
564
  /** Reads a run's projects with every per-project fact an emitter reads. */
750
565
  export function readEmitterRun(engine, host, scope, config, mode, detectors) {
751
566
  const targetRoot = scope.target.path;
752
- const run = readRun(engine, host, scope, config, mode, detectors, (project, read, references, testFiles) => ({
567
+ const run = readRun(engine, host, scope, config, mode, detectors, (project, read, references, testFiles, unseenLoads) => ({
753
568
  deprecation: deprecatedDeclarations(project, read.held),
754
569
  accessors: accessorsOf(project, read.held),
755
- needs: projectNeeds(project, read.held, host, targetRoot, (fileName, text) => engine.parseSourceFile(fileName, text)),
570
+ needs: projectNeeds(project, read.held, host, targetRoot, (fileName, text) => engine.parseSourceFile(fileName, text), read.sources.configuration, read.sources.workflows),
756
571
  implementations: implementations(project, read.held),
757
572
  heldByInclusion: heldByInclusion(project, targetRoot),
758
- generated: [...read.generated.keys()],
573
+ generated: read.generated,
574
+ bindings: read.bindings,
759
575
  inOperands: inOperandNames(project, targetRoot, testFiles),
760
576
  rooted: read.rooted,
761
577
  directives: inlineDirectives(project, read.held, targetRoot).filter((directive) => !read.referenceOnly.includes(directive.site.path)),
762
578
  declarationsNamed: declarationsNamed(project, read.held, configuredDeclarations(config)),
763
579
  parts: projectParts(project, read.held, references, targetRoot),
580
+ unseenLoads,
581
+ // Only a closed world reports an unnecessary export, which is all the carriers decide.
582
+ carriers: config.consumers.complete ? carriersOf(project, read.held) : NO_CARRIERS,
764
583
  }));
765
- // Whether a declaration carries the marker decides its code, so one whose marker went
584
+ // Whether a declaration carries the marker decides its code, so one whose answer went
766
585
  // unread is reported by nothing.
767
586
  const unread = run.projects.flatMap((one) => one.extra.deprecation.unanswered);
768
587
  return unread.length === 0
@@ -805,16 +624,11 @@ function judgedMembers(host, targetRoot, read) {
805
624
  }
806
625
  /** The directory of the nearest `package.json` at or above a file, inside `root`, else `root`. */
807
626
  function nearestManifestDir(host, root, file) {
808
- for (let dir = dirnamePath(file); relativePath(root, dir) !== undefined; dir = dirnamePath(dir)) {
809
- if (host.kindOf(joinPath(dir, "package.json")) === "file") {
810
- return dir;
811
- }
812
- }
813
- return root;
627
+ return ancestors(dirnamePath(file), root).find((dir) => holdsManifest(host, dir)) ?? root;
814
628
  }
815
629
  /**
816
630
  * The input every emitter reads over one sweep of a read run: the facts beside the sweep
817
- * each kind family reads, every per-project one read in the same session as the sweep.
631
+ * each emitter reads, every per-project one read in the same session as the sweep.
818
632
  */
819
633
  export function emitterInputOver(host, scope, config, read, input, selfCheck) {
820
634
  const targetRoot = scope.target.path;
@@ -827,15 +641,20 @@ export function emitterInputOver(host, scope, config, read, input, selfCheck) {
827
641
  deprecated: new Set(projects.flatMap((one) => one.extra.deprecation.deprecated)),
828
642
  stores: storesOf(projects.map((one) => ({
829
643
  references: one.configured.references,
644
+ support: new Set(one.configured.supportFiles ?? []),
830
645
  accessors: one.extra.accessors,
831
- })), swept.exempt, input.mode),
832
- dependencies: dependenciesOf(host, targetRoot, [...projects.map((one) => one.extra.needs), configurationNeeds(read.conventionUses)], swept.sweep.candidates.map((candidate) => candidate.id), members.read, members.unbuilt, read.nestedDirs),
646
+ })), swept.sweep.exempt, input.mode),
647
+ dependencies: dependenciesOf(host, targetRoot, read.workflows, [...projects.map((one) => one.extra.needs), configurationNeeds(read.conventionUses)], swept.sweep.candidates.map((candidate) => candidate.id), members.read, members.unbuilt, read.nestedDirs),
833
648
  implementations: mergeImplementations(projects.map((one) => one.extra.implementations)),
834
649
  files: {
835
650
  tree: sourceTree(host, targetRoot),
836
651
  heldByInclusion: new Set(projects.flatMap((one) => one.extra.heldByInclusion)),
837
- generated: new Set(projects.flatMap((one) => one.extra.generated)),
652
+ generated: new Set(projects.flatMap((one) => [...one.extra.generated.keys()])),
838
653
  inOperands: new Set(projects.flatMap((one) => one.extra.inOperands)),
654
+ unseenLoads: projects.flatMap((one) => one.extra.unseenLoads),
655
+ unwrittenRuns: new Set(projects.flatMap((one) => one.heldScripts
656
+ .filter((held) => held.unwritten)
657
+ .map((held) => relativePath(resolvePath(host.workingDirectory(), targetRoot), held.dir) ?? "."))),
839
658
  },
840
659
  boundary: {
841
660
  consumers: {
@@ -844,9 +663,17 @@ export function emitterInputOver(host, scope, config, read, input, selfCheck) {
844
663
  },
845
664
  encapsulated: readManifest(host, targetRoot).declaresExports,
846
665
  edges: readEdgeSides(host, targetRoot),
666
+ filledOutside: new Set(projects.flatMap((one) => one.filledOutside)),
667
+ possiblyLoaded: new Set(projects.flatMap((one) => one.possiblyLoaded)),
668
+ carriers: {
669
+ named: new Map([
670
+ ...Map.groupBy(projects.flatMap((one) => [...one.extra.carriers.named]), ([id]) => id),
671
+ ].map(([id, entries]) => [id, [...new Set(entries.flatMap(([, named]) => named))]])),
672
+ unread: new Set(projects.flatMap((one) => [...one.extra.carriers.unread])),
673
+ },
847
674
  },
848
675
  selfCheck,
849
- intraFunction: intraFunctionFacts(projects.map((one) => one.extra.parts), projects.flatMap((one) => one.configured.references), new Set([...swept.exempt.map((one) => one.id), ...swept.heldByUnanswered])),
676
+ intraFunction: intraFunctionFacts(projects.map((one) => one.extra.parts), projects.flatMap((one) => one.configured.references), new Set([...swept.sweep.exempt.map((one) => one.id), ...swept.sweep.held])),
850
677
  };
851
678
  }
852
679
  /**
@@ -854,7 +681,7 @@ export function emitterInputOver(host, scope, config, read, input, selfCheck) {
854
681
  * directives, the ignore file's entries and the baseline's rows are bound before any
855
682
  * sweep, and the run is swept once under every bound record's mark and once under none,
856
683
  * so a record is decided against the finding its code would have produced. The
857
- * self-check family reports the refused suppressions and the roots that named nothing.
684
+ * configuration family reports the refused suppressions and the roots that named nothing.
858
685
  * Beside the inputs it answers the projects and test-file rules a report names.
859
686
  */
860
687
  function readAnalysis(engine, host, scope, config, provenance, mode, detectors) {
@@ -872,7 +699,7 @@ function readAnalysis(engine, host, scope, config, provenance, mode, detectors)
872
699
  id: one.configured.configuration,
873
700
  configFile: one.configFile,
874
701
  })),
875
- testFileRules: testFileRulesOf(config.ts.testFiles, read.projects.flatMap((one) => one.configured.testFiles), read.projects.flatMap((one) => one.configured.supportFiles ?? [])),
702
+ testFileRules: testFileRulesOf(config.ts.test_files, read.projects.flatMap((one) => one.configured.testFiles), read.projects.flatMap((one) => one.configured.supportFiles ?? [])),
876
703
  typeErrorSkips: read.projects.flatMap((one) => one.typeErrorSkips),
877
704
  componentWarnings: [
878
705
  ...new Map(read.projects
@@ -884,8 +711,14 @@ function readAnalysis(engine, host, scope, config, provenance, mode, detectors)
884
711
  unanswered: read.unanswered,
885
712
  componentsUnread: read.componentsUnread,
886
713
  librariesUnfound: read.librariesUnfound,
714
+ unresolvedSpecifiers: read.unresolvedSpecifiers,
715
+ unread: read.unread,
887
716
  conventionsApplied: read.conventionsApplied,
888
717
  unmappedEntries: unmappedEverywhere(read.projects),
718
+ heldScripts: read.projects.flatMap((one) => one.heldScripts.map((held) => ({ ...held, configFile: one.configFile }))),
719
+ unseenLoads: read.projects.flatMap((one) => one.extra.unseenLoads),
720
+ generated: new Map(read.projects.flatMap((one) => [...one.extra.generated])),
721
+ bindings: distinctBindings(read.projects.flatMap((one) => one.extra.bindings)),
889
722
  },
890
723
  configured: read.projects.map((one) => one.configured),
891
724
  symbols,
@@ -901,7 +734,7 @@ function inputsOver(host, scope, config, provenance, mode, read, documents) {
901
734
  };
902
735
  const facts = {
903
736
  refusals: suppressions.refusals,
904
- unmatchedRoots: unmatchedEverywhere(config.rootPatterns, read.projects.map((one) => one.extra.rooted)),
737
+ unmatchedRoots: unmatchedEverywhere(config.roots.patterns, read.projects.map((one) => one.extra.rooted)),
905
738
  rootsDocument: documentOf(host, provenance, ROOTS_SETTING, targetRoot),
906
739
  unmatchedDeclarations: configuredDeclarations(config)
907
740
  .filter((_, at) => !read.projects.some((one) => one.extra.declarationsNamed[at] === true))
@@ -937,7 +770,7 @@ function unmappedEverywhere(projects) {
937
770
  }
938
771
  /**
939
772
  * The analysis of the run the scope and the configuration describe: the run read with its
940
- * suppressions bound, every family's findings with the suppressions applied and the
773
+ * suppressions bound, every emitter's findings with the suppressions applied and the
941
774
  * declared edges evaluated, the projects and test-file rules the report names, and the sweep
942
775
  * an explanation reads.
943
776
  */
@@ -948,12 +781,16 @@ export function runAnalysis(engine, host, scope, config, provenance, mode, detec
948
781
  }
949
782
  /**
950
783
  * One count per configuration of the run in which the checker left a question unanswered:
951
- * the questions asked in its project, and the declarations of its own the run holds for them.
784
+ * the questions asked in its project, a formed program's manifest that does not parse or cannot
785
+ * be read and a package whose command strings name files the project holds each counted as one, and the
786
+ * declarations of its own the run holds for them.
952
787
  */
953
788
  export function unansweredCounts(analysis) {
954
- const held = new Set(analysis.swept.heldByUnanswered);
789
+ const held = new Set(analysis.swept.sweep.held);
955
790
  return analysis.run.projects.flatMap((project) => {
956
- const questions = analysis.run.unanswered.filter((one) => one.configFile === project.configFile).length;
791
+ const questions = analysis.run.unanswered.filter((one) => one.configFile === project.configFile).length +
792
+ analysis.run.unread.filter((one) => one.kind === "manifest" && one.configFile === project.configFile).length +
793
+ analysis.run.heldScripts.filter((one) => one.configFile === project.configFile && one.files.length > 0).length;
957
794
  if (questions === 0) {
958
795
  return [];
959
796
  }