@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
@@ -1,47 +1,34 @@
1
1
  /**
2
2
  * The workspace a target sits in: the packages `pnpm-workspace.yaml` or a manifest's
3
- * `workspaces` declares in the nearest directory at or above the target root, up to
4
- * its repository root, where its patterns name the package the target is in, each
5
- * with the compiler configurations in its directory. A
6
- * member is the workspace root or a directory the patterns name that holds a named
7
- * manifest, never one below `node_modules`.
3
+ * `workspaces` declares in the nearest directory at or above the target root, up to its
4
+ * repository root, where its patterns name the package the target is in, each with the
5
+ * compiler configurations in its directory.
8
6
  */
9
- import { DiscoveryError } from "./discover.js";
7
+ import { configFilesIn } from "./discover.js";
8
+ import { failureExit } from "../failure.js";
10
9
  import { commonDirectory } from "./emit-map.js";
11
- import { dirnamePath, joinPath, relativePath } from "./paths.js";
12
- import { pnpmPackages } from "./pnpm-workspace.js";
13
- const MANIFEST = "package.json";
10
+ import { ancestors, dirnamePath, joinPath, relativePath } from "../paths.js";
11
+ import { bytewise } from "../text/compare.js";
12
+ import { isRecord } from "../json-document.js";
13
+ import { directoriesIn, repositoryOf } from "../fs/tree.js";
14
+ import { holdsManifest, inInstalledPackages, INSTALLED_PACKAGES, MANIFEST, manifestAt, } from "../fs/manifest.js";
15
+ import { braceExpanded, pathMatches, segmentMatches } from "../text/glob.js";
16
+ import { yamlKey } from "../text/yaml.js";
14
17
  const PNPM_WORKSPACE = "pnpm-workspace.yaml";
15
- const CONFIG_FILE = /^tsconfig.*\.json$/u;
16
- function isRecord(value) {
17
- return typeof value === "object" && value !== null && !Array.isArray(value);
18
- }
19
- /** One manifest, decoded, or `undefined` where there is none to read. */
20
- function manifestAt(host, dir) {
21
- let text;
22
- try {
23
- text = host.readFile(joinPath(dir, MANIFEST));
24
- }
25
- catch {
26
- return undefined;
27
- }
28
- try {
29
- const value = JSON.parse(text);
30
- return isRecord(value) ? value : undefined;
31
- }
32
- catch {
33
- return undefined;
34
- }
35
- }
36
18
  /** The patterns one directory declares a workspace with, or `undefined` where it declares none. */
37
19
  function declarationAt(host, dir) {
38
20
  const pnpm = joinPath(dir, PNPM_WORKSPACE);
39
21
  if (host.kindOf(pnpm) === "file") {
40
- const read = pnpmPackages(host.readFile(pnpm));
41
- if (read.kind === "refused") {
42
- throw new DiscoveryError(`${pnpm}: ${read.reason}; the workspace's packages are read from a sequence of strings`, []);
22
+ const read = yamlKey(host.readFile(pnpm), "packages");
23
+ if (read.kind === "absent") {
24
+ return { file: pnpm, patterns: [] };
43
25
  }
44
- return { file: pnpm, patterns: read.kind === "listed" ? read.patterns : [] };
26
+ const listed = read.kind === "value" ? read.value : undefined;
27
+ if (!Array.isArray(listed) || !listed.every((entry) => typeof entry === "string")) {
28
+ const reason = read.kind === "refused" ? read.reason : "packages is not a sequence of strings";
29
+ throw failureExit("no-program", `${pnpm}: ${reason}; the workspace's packages are read from a sequence of strings: correct the declaration`);
30
+ }
31
+ return { file: pnpm, patterns: listed };
45
32
  }
46
33
  const manifest = manifestAt(host, dir);
47
34
  if (manifest === undefined || !Object.hasOwn(manifest, "workspaces")) {
@@ -50,7 +37,7 @@ function declarationAt(host, dir) {
50
37
  const declared = manifest["workspaces"];
51
38
  const list = isRecord(declared) ? declared["packages"] : declared;
52
39
  if (!Array.isArray(list) || !list.every((entry) => typeof entry === "string")) {
53
- throw new DiscoveryError(`${joinPath(dir, MANIFEST)}: workspaces is neither an array of strings nor an object whose packages is one`, []);
40
+ throw failureExit("no-program", `${joinPath(dir, MANIFEST)}: workspaces is neither an array of strings nor an object whose packages is one: correct the declaration`);
54
41
  }
55
42
  return { file: joinPath(dir, MANIFEST), patterns: list };
56
43
  }
@@ -62,20 +49,6 @@ function declaresWorkspace(host, dir) {
62
49
  const manifest = manifestAt(host, dir);
63
50
  return manifest !== undefined && Object.hasOwn(manifest, "workspaces");
64
51
  }
65
- /** A pattern with every brace list expanded into its alternatives. */
66
- function braceExpanded(pattern) {
67
- const open = pattern.indexOf("{");
68
- const close = open < 0 ? -1 : pattern.indexOf("}", open);
69
- if (close < 0) {
70
- return [pattern];
71
- }
72
- const before = pattern.slice(0, open);
73
- const after = pattern.slice(close + 1);
74
- return pattern
75
- .slice(open + 1, close)
76
- .split(",")
77
- .flatMap((member) => braceExpanded(before + member + after));
78
- }
79
52
  /**
80
53
  * The segments of one pattern below the workspace root, `.` and empty segments
81
54
  * dropped and `..` taken back, or `undefined` where it leaves the root.
@@ -96,52 +69,6 @@ function segmentsOf(pattern) {
96
69
  }
97
70
  return segments;
98
71
  }
99
- /**
100
- * Whether one directory name matches one pattern segment: `*` stands for any run of
101
- * characters and `?` for one, and neither matches a leading dot.
102
- */
103
- function segmentMatches(segment, name) {
104
- if (name.startsWith(".") && !segment.startsWith(".")) {
105
- return false;
106
- }
107
- const source = Array.from(segment)
108
- .map((character) => {
109
- if (character === "*") {
110
- return ".*";
111
- }
112
- if (character === "?") {
113
- return ".";
114
- }
115
- return character.replaceAll(/[.+^${}()|[\]\\/]/gu, (c) => `\\${c}`);
116
- })
117
- .join("");
118
- return new RegExp(`^${source}$`, "u").test(name);
119
- }
120
- /** Whether one path's segments match one pattern's, `**` standing for any run of segments. */
121
- function pathMatches(pattern, path) {
122
- const [head, ...rest] = pattern;
123
- if (head === undefined) {
124
- return path.length === 0;
125
- }
126
- if (head === "**") {
127
- return (pathMatches(rest, path) ||
128
- (path.length > 0 && !(path[0] ?? "").startsWith(".") && pathMatches(pattern, path.slice(1))));
129
- }
130
- const [name, ...below] = path;
131
- return name !== undefined && segmentMatches(head, name) && pathMatches(rest, below);
132
- }
133
- function subdirectories(host, dir) {
134
- try {
135
- return host
136
- .readDirectory(dir)
137
- .filter((entry) => entry.directory && entry.name !== "node_modules" && entry.name !== ".git")
138
- .map((entry) => entry.name)
139
- .sort();
140
- }
141
- catch {
142
- return [];
143
- }
144
- }
145
72
  /**
146
73
  * Every directory below `dir` one pattern names. `**` does not descend into a
147
74
  * directory that declares a workspace of its own, whose packages are that
@@ -155,7 +82,7 @@ function expand(host, dir, pattern, into) {
155
82
  }
156
83
  if (head === "**") {
157
84
  expand(host, dir, rest, into);
158
- for (const name of subdirectories(host, dir)) {
85
+ for (const name of directoriesIn(host, dir)) {
159
86
  if (name.startsWith(".")) {
160
87
  continue;
161
88
  }
@@ -166,12 +93,12 @@ function expand(host, dir, pattern, into) {
166
93
  }
167
94
  if (!head.includes("*") && !head.includes("?")) {
168
95
  const child = joinPath(dir, head);
169
- if (head !== "node_modules" && host.kindOf(child) === "directory") {
96
+ if (head !== INSTALLED_PACKAGES && host.kindOf(child) === "directory") {
170
97
  expand(host, child, rest, into);
171
98
  }
172
99
  return;
173
100
  }
174
- for (const name of subdirectories(host, dir)) {
101
+ for (const name of directoriesIn(host, dir)) {
175
102
  if (segmentMatches(head, name)) {
176
103
  expand(host, joinPath(dir, name), rest, into);
177
104
  }
@@ -208,10 +135,10 @@ function namesDirectory(root, patterns, dir) {
208
135
  if (below === undefined) {
209
136
  return false;
210
137
  }
211
- const path = below.split("/");
212
- if (path.includes("node_modules")) {
138
+ if (inInstalledPackages(below)) {
213
139
  return false;
214
140
  }
141
+ const path = below.split("/");
215
142
  let named = false;
216
143
  for (const written of patterns) {
217
144
  const negated = written.startsWith("!");
@@ -238,18 +165,7 @@ function layoutOf(configFile, parsed) {
238
165
  return { outDir: parsed.outDir, declarationDir: parsed.declarationDir, sourceDirs };
239
166
  }
240
167
  function configurationsOf(host, dir, parse) {
241
- let names;
242
- try {
243
- names = host
244
- .readDirectory(dir)
245
- .filter((entry) => !entry.directory && CONFIG_FILE.test(entry.name))
246
- .map((entry) => entry.name)
247
- .sort();
248
- }
249
- catch {
250
- return [];
251
- }
252
- return names.flatMap((name) => {
168
+ return configFilesIn(host, dir).flatMap((name) => {
253
169
  const configFile = joinPath(dir, name);
254
170
  const parsed = parse(configFile);
255
171
  return parsed === undefined
@@ -267,31 +183,27 @@ function configurationsOf(host, dir, parse) {
267
183
  * highest directory below it, at or above the target root, that holds a manifest.
268
184
  */
269
185
  function nearestDeclaration(host, targetRoot) {
270
- let dir = targetRoot;
271
186
  let highestPackage;
272
- for (;;) {
187
+ for (const dir of ancestors(targetRoot, repositoryOf(host, targetRoot)?.root)) {
273
188
  const declared = declarationAt(host, dir);
274
189
  if (declared !== undefined) {
275
190
  return { root: dir, ...declared, highestPackage };
276
191
  }
277
- if (host.kindOf(joinPath(dir, MANIFEST)) === "file") {
192
+ if (holdsManifest(host, dir)) {
278
193
  highestPackage = dir;
279
194
  }
280
- const up = dirnamePath(dir);
281
- if (up === dir || host.kindOf(joinPath(dir, ".git")) !== "absent") {
282
- return undefined;
283
- }
284
- dir = up;
285
195
  }
196
+ return undefined;
286
197
  }
287
198
  /**
288
199
  * The workspace the target sits in, or `undefined` where none holds it: no directory
289
200
  * from the target root up to its repository root declares one with a member beside
290
201
  * its root, or the nearest one does not name the highest package below it, at or
291
202
  * above the target root, among its members. `parse` reads one compiler configuration,
292
- * or answers `undefined` where it does not read.
203
+ * or answers `undefined` where it does not read. `known`, a workspace already read, is the
204
+ * answer where the nearest declaration is its own, so its members are not listed again.
293
205
  */
294
- export function findWorkspace(host, targetRoot, parse) {
206
+ export function findWorkspace(host, targetRoot, parse, known) {
295
207
  const declared = nearestDeclaration(host, targetRoot);
296
208
  if (declared === undefined) {
297
209
  return undefined;
@@ -300,6 +212,9 @@ export function findWorkspace(host, targetRoot, parse) {
300
212
  !namesDirectory(declared.root, declared.patterns, declared.highestPackage)) {
301
213
  return undefined;
302
214
  }
215
+ if (known?.root === declared.root) {
216
+ return known;
217
+ }
303
218
  const members = [];
304
219
  for (const dir of memberDirectories(host, declared.root, declared.patterns)) {
305
220
  const manifest = manifestAt(host, dir);
@@ -320,7 +235,10 @@ export function findWorkspace(host, targetRoot, parse) {
320
235
  if (members.length < 2) {
321
236
  return undefined;
322
237
  }
323
- members.sort((a, b) => a.dir === declared.root ? -1 : b.dir === declared.root ? 1 : a.dir < b.dir ? -1 : 1);
238
+ members.sort((a, b) => a.dir === declared.root ? -1 : b.dir === declared.root ? 1 : bytewise(a.dir, b.dir));
239
+ return assembled(host, declared.root, members);
240
+ }
241
+ function assembled(host, root, members) {
324
242
  const named = new Map();
325
243
  for (const member of members) {
326
244
  named.set(member.name, [...(named.get(member.name) ?? []), member]);
@@ -332,11 +250,12 @@ export function findWorkspace(host, targetRoot, parse) {
332
250
  return scopes.get(dir);
333
251
  }
334
252
  const up = dirnamePath(dir);
335
- const found = host.kindOf(joinPath(dir, MANIFEST)) === "file" ? dir : up === dir ? undefined : scopeOf(up);
253
+ const found = holdsManifest(host, dir) ? dir : up === dir ? undefined : scopeOf(up);
336
254
  scopes.set(dir, found);
337
255
  return found;
338
256
  };
339
257
  return {
258
+ root,
340
259
  members,
341
260
  named,
342
261
  memberOf: (path) => {
@@ -345,6 +264,25 @@ export function findWorkspace(host, targetRoot, parse) {
345
264
  },
346
265
  };
347
266
  }
267
+ /**
268
+ * The workspace with the programs the run forms put first among each member's configurations,
269
+ * by the member's directory: a formed program has no file on disk to list, so its file list
270
+ * is what makes a member's JavaScript its source.
271
+ */
272
+ export function withFormed(host, workspace, formed) {
273
+ return assembled(host, workspace.root, workspace.members.map((member) => {
274
+ const own = formed.get(member.dir) ?? [];
275
+ return own.length === 0
276
+ ? member
277
+ : {
278
+ ...member,
279
+ configurations: [
280
+ ...own.map((layout) => ({ fileNames: new Set(layout.fileNames) })),
281
+ ...member.configurations,
282
+ ],
283
+ };
284
+ }));
285
+ }
348
286
  /**
349
287
  * Whether one configuration holds one file only for the references it makes: the file
350
288
  * belongs to a workspace package, the root included, and the configuration does not
@@ -5,11 +5,12 @@
5
5
  * to the same module. One that names it by name or pattern also reads the members it
6
6
  * imports, whatever file the specifier resolves to, as a compiler reading no such file does.
7
7
  */
8
- import { isCallExpression, isExportDeclaration, isExternalModuleReference, isImportDeclaration, isImportEqualsDeclaration, isImportTypeNode, isLiteralTypeNode, isModuleDeclaration, isNamespaceExport, isNamespaceImport, isNoSubstitutionTemplateLiteral, isStringLiteral, SyntaxKind, } from "@typescript/native/ast";
8
+ import { isCallExpression, isExportDeclaration, isExternalModuleReference, isImportDeclaration, isImportEqualsDeclaration, isImportTypeNode, isLiteralTypeNode, isModuleDeclaration, isNoSubstitutionTemplateLiteral, isStringLiteral, SyntaxKind, } from "@typescript/native/ast";
9
+ import { namesImported } from "./import-bindings.js";
9
10
  import { nodeKey } from "./inventory.js";
10
- import { renderPosition } from "./position.js";
11
11
  import { UNANSWERED } from "./query.js";
12
12
  import { aliasFragment, nameComponent } from "./ref.js";
13
+ import { isPathSpecifier } from "./paths.js";
13
14
  /** Whether a node is a specifier's text: a string literal or a template with no substitution. */
14
15
  function literalText(node) {
15
16
  return node !== undefined && (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node));
@@ -36,32 +37,12 @@ function specifierOf(node) {
36
37
  }
37
38
  return undefined;
38
39
  }
39
- /**
40
- * The export names an import or a re-export reads from the module it names: none for a
41
- * namespace, a star or a bare form.
42
- */
43
- export function namesImported(node) {
44
- if (isImportDeclaration(node)) {
45
- const clause = node.importClause;
46
- const bindings = clause?.namedBindings;
47
- return [
48
- ...(clause?.name === undefined ? [] : ["default"]),
49
- ...(bindings === undefined || isNamespaceImport(bindings)
50
- ? []
51
- : bindings.elements.map((one) => (one.propertyName ?? one.name).text)),
52
- ];
53
- }
54
- const clause = isExportDeclaration(node) ? node.exportClause : undefined;
55
- return clause === undefined || isNamespaceExport(clause)
56
- ? []
57
- : clause.elements.map((one) => (one.propertyName ?? one.name).text);
58
- }
59
40
  /**
60
41
  * Whether a specifier matches a declaration's name, the name's one `*` standing for any run.
61
42
  * A relative name is resolved against its own file, so no specifier names it by its text.
62
43
  */
63
44
  function namesModule(specifier, name) {
64
- if (/^(?:\.{1,2}(?:\/|$)|\/)/u.test(name)) {
45
+ if (isPathSpecifier(name)) {
65
46
  return false;
66
47
  }
67
48
  const star = name.indexOf("*");
@@ -107,67 +88,71 @@ function namedBy(held) {
107
88
  });
108
89
  }
109
90
  /**
110
- * The references the imports of one project's own files make to the module declarations
111
- * they name, each at the import's specifier.
91
+ * The reads the imports of a side's files make of the module declarations of the target they
92
+ * name, each at the import's specifier. A specifier the checker leaves unanswered still names
93
+ * a declaration by its name or pattern.
112
94
  */
113
- export function moduleDeclarationReferences(project, held, root, testFiles) {
114
- const imports = [];
115
- const declared = [];
116
- for (const file of project.ownSourceFiles()) {
117
- const fileId = held.declarations.get(nodeKey(file, file));
118
- if (fileId === undefined) {
119
- continue;
120
- }
121
- const visit = (node, from) => {
122
- const own = held.declarations.get(nodeKey(file, node));
123
- if (isModuleDeclaration(node) && literalText(node.name) && own !== undefined) {
124
- declared.push({ id: own, name: node.name });
125
- }
126
- const specifier = specifierOf(node);
127
- if (specifier !== undefined) {
128
- imports.push({ file, from, specifier, names: namesImported(node) });
129
- }
130
- node.forEachChild((child) => {
131
- visit(child, own ?? from);
132
- });
133
- };
134
- file.forEachChild((child) => {
135
- visit(child, fileId);
136
- });
137
- }
138
- if (declared.length === 0 || imports.length === 0) {
139
- return [];
140
- }
141
- const asked = [...declared.map((one) => one.name), ...imports.map((one) => one.specifier)];
142
- const answers = project.symbolsAt(asked.map((node) => project.handle(node)));
143
- const moduleOf = (at) => {
144
- const symbol = answers[at];
145
- return symbol === undefined || symbol === UNANSWERED ? undefined : symbol.id;
146
- };
147
- const named = namedBy(held);
148
- const found = [];
149
- imports.forEach((one, index) => {
150
- const resolved = moduleOf(declared.length + index);
151
- const position = renderPosition(one.file, root, one.specifier.getStart());
152
- const read = (to, resolution, test) => {
153
- found.push({ from: one.from, to, position, use: "read", resolution, test });
154
- };
155
- const test = testFiles.has(position.path);
156
- const same = new Set(declared
157
- .filter((_, at) => resolved !== undefined && resolved === moduleOf(at))
158
- .map((declaration) => declaration.id));
159
- for (const id of same) {
160
- read(id, "batch", test);
161
- }
162
- for (const declaration of named(one.specifier.text, one.names)) {
163
- // A wildcard declaration is how the compiler types the file a matching specifier
164
- // names, so the import uses it whoever writes it, a test included.
165
- if (declaration.wildcard || !same.has(declaration.id)) {
166
- for (const to of [declaration.id, ...declaration.members]) {
167
- read(to, "syntax", test && !declaration.wildcard);
95
+ export const moduleDeclarations = {
96
+ start() {
97
+ const imports = [];
98
+ return {
99
+ visit(node, { file, from }) {
100
+ const specifier = specifierOf(node);
101
+ if (specifier !== undefined) {
102
+ imports.push({ file, from, specifier, names: namesImported(node) });
168
103
  }
169
- }
170
- }
171
- });
172
- return found;
173
- }
104
+ },
105
+ reads({ project, held }) {
106
+ const found = [];
107
+ // A module declaration whose name is a string is written at a file's top level.
108
+ const declared = project.ownSourceFiles().flatMap((file) => file.statements.flatMap((statement) => {
109
+ const id = held.declarations.get(nodeKey(file, statement));
110
+ return isModuleDeclaration(statement) && literalText(statement.name) && id !== undefined
111
+ ? [{ id, name: statement.name }]
112
+ : [];
113
+ }));
114
+ if (declared.length === 0 || imports.length === 0) {
115
+ return found;
116
+ }
117
+ const asked = [...declared.map((one) => one.name), ...imports.map((one) => one.specifier)];
118
+ const answers = project.symbolsAt(asked.map((node) => project.handle(node)));
119
+ const moduleOf = (at) => {
120
+ const symbol = answers[at];
121
+ return symbol === undefined || symbol === UNANSWERED ? undefined : symbol.id;
122
+ };
123
+ const named = namedBy(held);
124
+ imports.forEach((one, index) => {
125
+ const resolved = moduleOf(declared.length + index);
126
+ const read = (to, via, production) => {
127
+ found.push({
128
+ kind: "named",
129
+ from: one.from,
130
+ to,
131
+ file: one.file,
132
+ at: one.specifier,
133
+ use: "read",
134
+ via,
135
+ ...(production ? { production: true } : {}),
136
+ });
137
+ };
138
+ const same = new Set(declared
139
+ .filter((_, at) => resolved !== undefined && resolved === moduleOf(at))
140
+ .map((declaration) => declaration.id));
141
+ for (const id of same) {
142
+ read(id, "batch", false);
143
+ }
144
+ for (const declaration of named(one.specifier.text, one.names)) {
145
+ // A wildcard declaration is how the compiler types the file a matching specifier
146
+ // names, so the import uses it whoever writes it, a test included.
147
+ if (declaration.wildcard || !same.has(declaration.id)) {
148
+ for (const to of [declaration.id, ...declaration.members]) {
149
+ read(to, "syntax", declaration.wildcard);
150
+ }
151
+ }
152
+ }
153
+ });
154
+ return found;
155
+ },
156
+ };
157
+ },
158
+ };