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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/README.md +3 -1
  2. package/THIRD_PARTY_NOTICES.md +27 -0
  3. package/dist/bin/mapper-connection.js +2 -1
  4. package/dist/bin/node-host.js +24 -5
  5. package/dist/src/alias-chain.js +35 -9
  6. package/dist/src/amd.js +81 -0
  7. package/dist/src/analysis.js +274 -496
  8. package/dist/src/augmentations.js +64 -3
  9. package/dist/src/automatic-types.js +10 -29
  10. package/dist/src/bindings.js +382 -0
  11. package/dist/src/commands/held.js +499 -0
  12. package/dist/src/commands/read.js +161 -0
  13. package/dist/src/commands/shell.js +169 -0
  14. package/dist/src/commands/tools.js +1847 -0
  15. package/dist/src/component-files.js +3 -2
  16. package/dist/src/component-layer.js +4 -2
  17. package/dist/src/config.js +6 -82
  18. package/dist/src/conformance-record.js +2 -2
  19. package/dist/src/consumers.js +10 -38
  20. package/dist/src/contextual-uses.js +57 -26
  21. package/dist/src/contract/config.generated.js +561 -0
  22. package/dist/src/contract/contract.generated.js +1370 -0
  23. package/dist/src/contract/report.generated.js +866 -0
  24. package/dist/src/dependencies.js +165 -122
  25. package/dist/src/destructuring.js +1 -19
  26. package/dist/src/edges.js +38 -122
  27. package/dist/src/element-access.js +181 -168
  28. package/dist/src/entries/build-scripts.js +222 -0
  29. package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
  30. package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
  31. package/dist/src/entries/conventions.js +740 -0
  32. package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
  33. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
  34. package/dist/src/entries/run-directories.js +77 -0
  35. package/dist/src/entries/sources.js +144 -0
  36. package/dist/src/entries/static-module.js +670 -0
  37. package/dist/src/entries/test-runners.js +650 -0
  38. package/dist/src/entries/workflow-steps.js +345 -0
  39. package/dist/src/exemptions/argument-places.js +131 -0
  40. package/dist/src/exemptions/calls.js +338 -0
  41. package/dist/src/exemptions/classes.js +13 -0
  42. package/dist/src/{decorator.js → exemptions/decorator.js} +19 -30
  43. package/dist/src/exemptions/detectors.js +48 -0
  44. package/dist/src/{enum-group.js → exemptions/enum-group.js} +9 -16
  45. package/dist/src/{erased-stores.js → exemptions/erased-stores.js} +7 -11
  46. package/dist/src/{framework-lifecycle.js → exemptions/framework-lifecycle.js} +76 -54
  47. package/dist/src/exemptions/generated-file.js +241 -0
  48. package/dist/src/{injection-container.js → exemptions/injection-container.js} +20 -26
  49. package/dist/src/exemptions/installed-globals.js +173 -0
  50. package/dist/src/{interface-satisfaction.js → exemptions/interface-satisfaction.js} +52 -121
  51. package/dist/src/exemptions/lifecycle.js +150 -0
  52. package/dist/src/{reflective-lookup.js → exemptions/reflective-lookup.js} +3 -3
  53. package/dist/src/exemptions/serialization-contract.js +1276 -0
  54. package/dist/src/exemptions/sites.js +182 -0
  55. package/dist/src/{template-field.js → exemptions/template-field.js} +13 -23
  56. package/dist/src/{value-reach.js → exemptions/value-reach.js} +14 -7
  57. package/dist/src/exposure.js +400 -0
  58. package/dist/src/extensions.js +37 -0
  59. package/dist/src/facts.js +38 -0
  60. package/dist/src/failure.js +36 -0
  61. package/dist/src/file-facts.js +3 -26
  62. package/dist/src/findings/completion.js +109 -56
  63. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  64. package/dist/src/findings/emitters.js +27 -41
  65. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  66. package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
  67. package/dist/src/findings/interfaces.js +4 -5
  68. package/dist/src/findings/intra-function.js +16 -13
  69. package/dist/src/findings/non-code-artifacts.js +17 -12
  70. package/dist/src/findings/reads-and-writes.js +86 -27
  71. package/dist/src/findings/self-check.js +44 -30
  72. package/dist/src/findings/unused-declarations.js +29 -45
  73. package/dist/src/findings/visibility-narrowing.js +23 -31
  74. package/dist/src/findings-pass.js +13 -21
  75. package/dist/src/fs/document.js +52 -0
  76. package/dist/src/fs/manifest.js +67 -0
  77. package/dist/src/fs/tree.js +88 -0
  78. package/dist/src/git-ignore.js +39 -26
  79. package/dist/src/import-bindings.js +73 -28
  80. package/dist/src/index/sites.js +557 -0
  81. package/dist/src/index/values.js +124 -0
  82. package/dist/src/index.js +2 -2
  83. package/dist/src/indexed-access.js +523 -478
  84. package/dist/src/intra-function-parts.js +63 -43
  85. package/dist/src/inventory/commonjs.js +507 -0
  86. package/dist/src/inventory/enumerate.js +167 -0
  87. package/dist/src/inventory/syntax.js +236 -0
  88. package/dist/src/inventory.js +323 -724
  89. package/dist/src/javascript-file.js +48 -0
  90. package/dist/src/json-document.js +198 -67
  91. package/dist/src/keyof-comparisons.js +126 -107
  92. package/dist/src/kinds.js +3 -366
  93. package/dist/src/{components.js → liveness/components.js} +2 -3
  94. package/dist/src/{graph.js → liveness/graph.js} +52 -28
  95. package/dist/src/liveness/matrix.js +99 -0
  96. package/dist/src/liveness/sweep.js +558 -0
  97. package/dist/src/load/classify.js +289 -0
  98. package/dist/src/load/diagnostics.js +87 -0
  99. package/dist/src/load/discover.js +285 -0
  100. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  101. package/dist/src/load/expected-module.js +136 -0
  102. package/dist/src/load/load.js +27 -0
  103. package/dist/src/load/module-lookup.js +37 -0
  104. package/dist/src/load/package-scope.js +56 -0
  105. package/dist/src/load/plan.js +313 -0
  106. package/dist/src/load/specifiers.js +113 -0
  107. package/dist/src/load/synthesize.js +152 -0
  108. package/dist/src/load/test-globals.js +207 -0
  109. package/dist/src/load/test-joins.js +82 -0
  110. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  111. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  112. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
  113. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  114. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  115. package/dist/src/module-declarations.js +70 -85
  116. package/dist/src/overrides.js +134 -112
  117. package/dist/src/partial.js +2 -1
  118. package/dist/src/paths.js +82 -16
  119. package/dist/src/platform-calls.js +78 -0
  120. package/dist/src/platform-symbols.js +134 -0
  121. package/dist/src/position.js +43 -1
  122. package/dist/src/print.js +11 -79
  123. package/dist/src/product.js +13 -0
  124. package/dist/src/query.js +95 -0
  125. package/dist/src/ref.js +12 -20
  126. package/dist/src/references/read-rule.js +1 -0
  127. package/dist/src/references/read-rules.js +48 -0
  128. package/dist/src/references/sink.js +237 -0
  129. package/dist/src/references/sources.js +450 -0
  130. package/dist/src/references.js +117 -1074
  131. package/dist/src/report-schema.js +51 -0
  132. package/dist/src/report.js +57 -41
  133. package/dist/src/reporters/annotations.js +15 -8
  134. package/dist/src/reporters/sarif.js +16 -10
  135. package/dist/src/reporters/template.js +4 -19
  136. package/dist/src/resolve.js +246 -730
  137. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
  138. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
  139. package/dist/src/roots/manifest.js +216 -0
  140. package/dist/src/roots/published-reach.js +412 -0
  141. package/dist/src/roots/root-set.js +487 -0
  142. package/dist/src/roots/unseen-loads.js +236 -0
  143. package/dist/src/run.js +66 -77
  144. package/dist/src/schema.js +320 -343
  145. package/dist/src/scope.js +38 -115
  146. package/dist/src/session.js +37 -29
  147. package/dist/src/source-files.js +6 -10
  148. package/dist/src/stores.js +4 -2
  149. package/dist/src/suppress-file.js +25 -28
  150. package/dist/src/suppress-inline.js +36 -83
  151. package/dist/src/suppress.js +50 -71
  152. package/dist/src/symbol-keys.js +92 -88
  153. package/dist/src/tests/file-class.js +76 -0
  154. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  155. package/dist/src/{test-support.js → tests/support.js} +5 -12
  156. package/dist/src/text/compare.js +26 -0
  157. package/dist/src/text/glob.js +194 -0
  158. package/dist/src/text/named-files.js +298 -0
  159. package/dist/src/text/yaml.js +684 -0
  160. package/dist/src/type-errors.js +11 -232
  161. package/dist/src/type-parameter-reads.js +178 -139
  162. package/dist/src/unimplemented-callees.js +262 -242
  163. package/dist/src/unwrap.js +23 -0
  164. package/dist/src/usage.js +10 -0
  165. package/dist/src/vendor/unbash/ansi-c.js +132 -0
  166. package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
  167. package/dist/src/vendor/unbash/arithmetic.js +591 -0
  168. package/dist/src/vendor/unbash/assignment.js +131 -0
  169. package/dist/src/vendor/unbash/chars.js +48 -0
  170. package/dist/src/vendor/unbash/command.js +41 -0
  171. package/dist/src/vendor/unbash/expansion.js +80 -0
  172. package/dist/src/vendor/unbash/glob.js +268 -0
  173. package/dist/src/vendor/unbash/heredoc.js +27 -0
  174. package/dist/src/vendor/unbash/internal-types.js +1 -0
  175. package/dist/src/vendor/unbash/lexer.js +4274 -0
  176. package/dist/src/vendor/unbash/limits.js +3 -0
  177. package/dist/src/vendor/unbash/parser.js +1366 -0
  178. package/dist/src/vendor/unbash/parts.js +57 -0
  179. package/dist/src/vendor/unbash/substitution-context.js +8 -0
  180. package/dist/src/vendor/unbash/traversal.js +212 -0
  181. package/dist/src/vendor/unbash/types.js +1 -0
  182. package/dist/src/vendor/unbash/word-value.js +61 -0
  183. package/dist/src/vendor/unbash/word.js +40 -0
  184. package/dist/src/verbs/analyze.js +194 -127
  185. package/dist/src/verbs/describe.js +13 -18
  186. package/dist/src/verbs/explain.js +85 -139
  187. package/dist/src/verbs/print-config.js +2 -1
  188. package/dist/src/verbs/print-projects.js +6 -4
  189. package/dist/src/verbs/print-retained.js +30 -6
  190. package/dist/src/verbs/print-roots.js +4 -2
  191. package/dist/src/verbs/verb.js +1 -5
  192. package/dist/src/verbs/version.js +14 -3
  193. package/jsr.json +2 -1
  194. package/package.json +14 -8
  195. package/src/alias-chain.ts +40 -11
  196. package/src/amd.ts +130 -0
  197. package/src/analysis.ts +426 -733
  198. package/src/augmentations.ts +93 -4
  199. package/src/automatic-types.ts +12 -30
  200. package/src/bindings.ts +460 -0
  201. package/src/commands/held.ts +632 -0
  202. package/src/commands/read.ts +242 -0
  203. package/src/commands/shell.ts +228 -0
  204. package/src/commands/tools.ts +2382 -0
  205. package/src/component-files.ts +4 -2
  206. package/src/component-layer.ts +4 -2
  207. package/src/config.ts +31 -302
  208. package/src/conformance-record.ts +2 -2
  209. package/src/consumers.ts +16 -66
  210. package/src/contextual-uses.ts +66 -34
  211. package/src/contract/config.generated.ts +821 -0
  212. package/src/contract/contract.generated.ts +1453 -0
  213. package/src/contract/report.generated.ts +1241 -0
  214. package/src/dependencies.ts +223 -128
  215. package/src/destructuring.ts +1 -31
  216. package/src/edges.ts +41 -140
  217. package/src/element-access.ts +190 -187
  218. package/src/entries/build-scripts.ts +292 -0
  219. package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
  220. package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
  221. package/src/{conventions.ts → entries/conventions.ts} +367 -583
  222. package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
  223. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
  224. package/src/entries/run-directories.ts +108 -0
  225. package/src/entries/sources.ts +266 -0
  226. package/src/entries/static-module.ts +858 -0
  227. package/src/entries/test-runners.ts +835 -0
  228. package/src/entries/workflow-steps.ts +432 -0
  229. package/src/exemptions/argument-places.ts +198 -0
  230. package/src/exemptions/calls.ts +483 -0
  231. package/src/exemptions/classes.ts +49 -0
  232. package/src/exemptions/decorator.ts +56 -0
  233. package/src/exemptions/detectors.ts +75 -0
  234. package/src/{enum-group.ts → exemptions/enum-group.ts} +10 -19
  235. package/src/{erased-stores.ts → exemptions/erased-stores.ts} +7 -14
  236. package/src/{framework-lifecycle.ts → exemptions/framework-lifecycle.ts} +85 -66
  237. package/src/exemptions/generated-file.ts +318 -0
  238. package/src/{injection-container.ts → exemptions/injection-container.ts} +29 -34
  239. package/src/exemptions/installed-globals.ts +255 -0
  240. package/src/{interface-satisfaction.ts → exemptions/interface-satisfaction.ts} +69 -160
  241. package/src/exemptions/lifecycle.ts +286 -0
  242. package/src/{reflective-lookup.ts → exemptions/reflective-lookup.ts} +5 -5
  243. package/src/exemptions/serialization-contract.ts +1729 -0
  244. package/src/exemptions/sites.ts +293 -0
  245. package/src/{template-field.ts → exemptions/template-field.ts} +22 -32
  246. package/src/{value-reach.ts → exemptions/value-reach.ts} +16 -8
  247. package/src/exposure.ts +492 -0
  248. package/src/extensions.ts +45 -0
  249. package/src/facts.ts +46 -0
  250. package/src/failure.ts +63 -0
  251. package/src/file-facts.ts +15 -25
  252. package/src/finding.ts +10 -10
  253. package/src/findings/boundary.ts +11 -0
  254. package/src/findings/completion.ts +133 -64
  255. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  256. package/src/findings/emitter.ts +9 -10
  257. package/src/findings/emitters.ts +38 -52
  258. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  259. package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
  260. package/src/findings/interfaces.ts +7 -9
  261. package/src/findings/intra-function.ts +16 -14
  262. package/src/findings/non-code-artifacts.ts +24 -15
  263. package/src/findings/reads-and-writes.ts +118 -41
  264. package/src/findings/self-check.ts +51 -38
  265. package/src/findings/unused-declarations.ts +31 -49
  266. package/src/findings/visibility-narrowing.ts +36 -40
  267. package/src/findings-pass.ts +15 -31
  268. package/src/fs/document.ts +70 -0
  269. package/src/fs/manifest.ts +96 -0
  270. package/src/fs/tree.ts +110 -0
  271. package/src/git-ignore.ts +50 -26
  272. package/src/host.ts +12 -5
  273. package/src/import-bindings.ts +98 -29
  274. package/src/index/sites.ts +781 -0
  275. package/src/index/values.ts +170 -0
  276. package/src/index.ts +2 -2
  277. package/src/indexed-access.ts +570 -527
  278. package/src/intra-function-parts.ts +73 -44
  279. package/src/inventory/commonjs.ts +696 -0
  280. package/src/inventory/enumerate.ts +203 -0
  281. package/src/inventory/syntax.ts +311 -0
  282. package/src/inventory.ts +442 -895
  283. package/src/javascript-file.ts +54 -0
  284. package/src/json-document.ts +241 -76
  285. package/src/keyof-comparisons.ts +133 -122
  286. package/src/kinds.ts +5 -413
  287. package/src/{components.ts → liveness/components.ts} +4 -6
  288. package/src/{graph.ts → liveness/graph.ts} +100 -35
  289. package/src/liveness/matrix.ts +162 -0
  290. package/src/liveness/sweep.ts +855 -0
  291. package/src/load/classify.ts +433 -0
  292. package/src/load/diagnostics.ts +154 -0
  293. package/src/load/discover.ts +471 -0
  294. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  295. package/src/load/expected-module.ts +194 -0
  296. package/src/load/load.ts +73 -0
  297. package/src/load/module-lookup.ts +50 -0
  298. package/src/load/package-scope.ts +74 -0
  299. package/src/load/plan.ts +513 -0
  300. package/src/load/specifiers.ts +171 -0
  301. package/src/load/synthesize.ts +230 -0
  302. package/src/load/test-globals.ts +251 -0
  303. package/src/load/test-joins.ts +98 -0
  304. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  305. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  306. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
  307. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  308. package/src/{workspace.ts → load/workspace.ts} +90 -134
  309. package/src/module-declarations.ts +74 -98
  310. package/src/overrides.ts +162 -134
  311. package/src/partial.ts +3 -2
  312. package/src/paths.ts +92 -16
  313. package/src/platform-calls.ts +119 -0
  314. package/src/platform-symbols.ts +189 -0
  315. package/src/position.ts +44 -1
  316. package/src/print.ts +12 -92
  317. package/src/product.ts +18 -0
  318. package/src/query.ts +201 -10
  319. package/src/ref.ts +12 -20
  320. package/src/references/read-rule.ts +60 -0
  321. package/src/references/read-rules.ts +55 -0
  322. package/src/references/sink.ts +314 -0
  323. package/src/references/sources.ts +632 -0
  324. package/src/references.ts +187 -1450
  325. package/src/report-schema.ts +68 -0
  326. package/src/report.ts +103 -226
  327. package/src/reporters/annotations.ts +22 -11
  328. package/src/reporters/json.ts +1 -1
  329. package/src/reporters/reporter.ts +2 -4
  330. package/src/reporters/reporters.ts +1 -1
  331. package/src/reporters/sarif.ts +29 -16
  332. package/src/reporters/template.ts +4 -20
  333. package/src/reporters/text.ts +3 -3
  334. package/src/resolve.ts +284 -1115
  335. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +26 -29
  336. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
  337. package/src/roots/manifest.ts +303 -0
  338. package/src/roots/published-reach.ts +486 -0
  339. package/src/{roots.ts → roots/root-set.ts} +286 -469
  340. package/src/roots/unseen-loads.ts +345 -0
  341. package/src/run.ts +75 -91
  342. package/src/schema.ts +391 -388
  343. package/src/scope.ts +46 -138
  344. package/src/session.ts +87 -55
  345. package/src/source-files.ts +6 -11
  346. package/src/stores.ts +15 -3
  347. package/src/suppress-file.ts +24 -33
  348. package/src/suppress-inline.ts +55 -91
  349. package/src/suppress.ts +78 -79
  350. package/src/symbol-keys.ts +104 -107
  351. package/src/tests/file-class.ts +135 -0
  352. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  353. package/src/{test-support.ts → tests/support.ts} +15 -21
  354. package/src/text/compare.ts +27 -0
  355. package/src/text/glob.ts +210 -0
  356. package/src/text/named-files.ts +388 -0
  357. package/src/text/yaml.ts +747 -0
  358. package/src/type-errors.ts +18 -288
  359. package/src/type-parameter-reads.ts +187 -158
  360. package/src/unimplemented-callees.ts +297 -280
  361. package/src/unwrap.ts +34 -0
  362. package/src/usage.ts +10 -0
  363. package/src/vendor/unbash/LICENSE +15 -0
  364. package/src/vendor/unbash/VENDORED.md +16 -0
  365. package/src/vendor/unbash/ansi-c.ts +132 -0
  366. package/src/vendor/unbash/arithmetic-parts.ts +53 -0
  367. package/src/vendor/unbash/arithmetic.ts +641 -0
  368. package/src/vendor/unbash/assignment.ts +163 -0
  369. package/src/vendor/unbash/chars.ts +48 -0
  370. package/src/vendor/unbash/command.ts +47 -0
  371. package/src/vendor/unbash/expansion.ts +144 -0
  372. package/src/vendor/unbash/glob.ts +284 -0
  373. package/src/vendor/unbash/heredoc.ts +34 -0
  374. package/src/vendor/unbash/internal-types.ts +94 -0
  375. package/src/vendor/unbash/lexer.ts +4352 -0
  376. package/src/vendor/unbash/limits.ts +3 -0
  377. package/src/vendor/unbash/parser.ts +1612 -0
  378. package/src/vendor/unbash/parts.ts +96 -0
  379. package/src/vendor/unbash/substitution-context.ts +20 -0
  380. package/src/vendor/unbash/traversal.ts +182 -0
  381. package/src/vendor/unbash/types.ts +660 -0
  382. package/src/vendor/unbash/word-value.ts +64 -0
  383. package/src/vendor/unbash/word.ts +50 -0
  384. package/src/verbs/analyze.ts +255 -164
  385. package/src/verbs/describe.ts +19 -17
  386. package/src/verbs/explain.ts +93 -169
  387. package/src/verbs/print-config.ts +2 -1
  388. package/src/verbs/print-projects.ts +6 -4
  389. package/src/verbs/print-retained.ts +36 -6
  390. package/src/verbs/print-roots.ts +4 -2
  391. package/src/verbs/verb.ts +2 -8
  392. package/src/verbs/version.ts +15 -3
  393. package/dist/src/base-url.js +0 -18
  394. package/dist/src/calls.js +0 -155
  395. package/dist/src/conventions.js +0 -937
  396. package/dist/src/discover.js +0 -468
  397. package/dist/src/entry-points.js +0 -529
  398. package/dist/src/exempt-classes.js +0 -75
  399. package/dist/src/exempt.js +0 -209
  400. package/dist/src/generated-file.js +0 -95
  401. package/dist/src/glob.js +0 -65
  402. package/dist/src/manifest.js +0 -165
  403. package/dist/src/matrix.js +0 -246
  404. package/dist/src/pnpm-workspace.js +0 -120
  405. package/dist/src/roots.js +0 -672
  406. package/dist/src/serialization-contract.js +0 -611
  407. package/dist/src/setup-failure.js +0 -23
  408. package/dist/src/sweep.js +0 -224
  409. package/dist/src/test-joins.js +0 -101
  410. package/dist/src/value-flow.js +0 -74
  411. package/dist/src/version.js +0 -7
  412. package/dist/src/workflow-steps.js +0 -185
  413. package/src/base-url.ts +0 -24
  414. package/src/calls.ts +0 -225
  415. package/src/decorator.ts +0 -78
  416. package/src/discover.ts +0 -653
  417. package/src/entry-points.ts +0 -687
  418. package/src/exempt-classes.ts +0 -123
  419. package/src/exempt.ts +0 -323
  420. package/src/generated-file.ts +0 -111
  421. package/src/glob.ts +0 -67
  422. package/src/manifest.ts +0 -234
  423. package/src/matrix.ts +0 -423
  424. package/src/pnpm-workspace.ts +0 -135
  425. package/src/serialization-contract.ts +0 -849
  426. package/src/setup-failure.ts +0 -39
  427. package/src/sweep.ts +0 -347
  428. package/src/test-joins.ts +0 -120
  429. package/src/value-flow.ts +0 -104
  430. package/src/version.ts +0 -7
  431. package/src/workflow-steps.ts +0 -216
@@ -3,27 +3,20 @@
3
3
  * applied and the declared edges evaluated, and the stale suppressions, the totals and the
4
4
  * verdict a report carries beside them.
5
5
  */
6
+ import { EXIT_CLEAN, EXIT_FINDINGS, EXIT_PENDING } from "./contract/contract.generated.js";
6
7
  import { fails } from "./config.js";
7
8
  import { decidedFindings } from "./findings/emitters.js";
8
9
  import { fileRefsOf, staleSuppressions, } from "./findings/self-check.js";
9
- import { isDependencySubject, isRowSubject, pairs, suppressionCounts, } from "./suppress.js";
10
- import { EXIT_CLEAN, EXIT_FINDINGS } from "./verbs/verb.js";
11
- /** The exit code of a report holding at least one pending finding. */
12
- export const EXIT_PENDING = 4;
13
- /** Two strings ordered bytewise. */
14
- function compare(a, b) {
15
- if (a === b) {
16
- return 0;
17
- }
18
- return a < b ? -1 : 1;
19
- }
10
+ import { namesKind, pairs, suppressionCounts } from "./suppress.js";
11
+ import { bytewise } from "./text/compare.js";
12
+ import { PRODUCT } from "./product.js";
20
13
  /** The canonical order: path, line, column, code, then the symbol reference. */
21
14
  function canonical(a, b) {
22
- return (compare(a.position.path, b.position.path) ||
15
+ return (bytewise(a.position.path, b.position.path) ||
23
16
  a.position.line - b.position.line ||
24
17
  a.position.column - b.position.column ||
25
- compare(a.code, b.code) ||
26
- compare(a.symbol.ref, b.symbol.ref));
18
+ bytewise(a.code, b.code) ||
19
+ bytewise(a.symbol.ref, b.symbol.ref));
27
20
  }
28
21
  /**
29
22
  * The pass over one run. The emitter table decides every record against every finding the
@@ -73,20 +66,19 @@ export function verdictOf(result, config) {
73
66
  if (result.totals.staleSuppressions > 0) {
74
67
  return EXIT_FINDINGS;
75
68
  }
76
- const failing = result.findings.some((finding) => fails(finding.severity, config.reporters.failOn));
69
+ const failing = result.findings.some((finding) => fails(finding.severity, config.reporters.fail_on));
77
70
  return failing ? EXIT_FINDINGS : EXIT_CLEAN;
78
71
  }
79
72
  /**
80
73
  * The rows one round of a baseline write records from its findings, in their order. A
81
- * finding about a row of a document other than a dependency row is not recorded: no record
82
- * withholds one, so a row recording it would be stale on the first read back. Two findings
83
- * that would record the same row, two parts of one declaration under one code, record it
84
- * once.
74
+ * finding no baseline row can name is not recorded: a row recording it would be stale on
75
+ * the first read back. Two findings that would record the same row, two parts of one
76
+ * declaration under one code, record it once.
85
77
  */
86
78
  export function recordedFindings(findings) {
87
79
  const rows = new Map();
88
80
  for (const finding of findings) {
89
- if (isRowSubject(finding.symbol.kind) && !isDependencySubject(finding.symbol.kind)) {
81
+ if (!namesKind(finding.symbol.kind, "baseline")) {
90
82
  continue;
91
83
  }
92
84
  const row = { code: finding.code, symbol: finding.symbol.ref, path: finding.position.path };
@@ -100,5 +92,5 @@ export function rowKey(row) {
100
92
  }
101
93
  /** The analyzer identity a baseline this analyzer writes names as its rows' provenance. */
102
94
  export function analyzerProvenance(version) {
103
- return { analyzer: "deadset-ts", version };
95
+ return { analyzer: PRODUCT, version };
104
96
  }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The one read of a document the target holds at its root, which a checkout under analysis
3
+ * controls: the repository configuration, the ignore file, the baseline and the edges
4
+ * document. The read stays inside the target root, takes a regular file alone, and holds no
5
+ * more of it than the Contract's document bound.
6
+ */
7
+ import { CONFIG_MAX_BYTES } from "../contract/config.generated.js";
8
+ import { failureExit } from "../failure.js";
9
+ import { joinPath, relativePath } from "../paths.js";
10
+ import { message } from "../product.js";
11
+ import { utf8Bytes } from "../reporters/sha256.js";
12
+ import { UsageError } from "../usage.js";
13
+ function unreadable(label, reason) {
14
+ return failureExit("unreadable-document", `${label}: ${reason}: make it a regular file inside the target root that the run can read, or remove it`);
15
+ }
16
+ /** Refuses a document past the Contract's bound with the usage code, naming it `label`. */
17
+ export function refuseOverBound(label, text) {
18
+ if (utf8Bytes(text).length > CONFIG_MAX_BYTES) {
19
+ throw new UsageError(`${label}: holds more than ${String(CONFIG_MAX_BYTES)} bytes`);
20
+ }
21
+ }
22
+ /**
23
+ * The text of the document `name` at the absolute `targetRoot`, undefined where nothing is
24
+ * there. One whose name resolves outside the target root or to anything but a regular file,
25
+ * or whose read fails, is refused by `refuse` naming it `label`, nothing read from it. A
26
+ * document past the bound is read one byte past it and refused as {@link refuseOverBound} does.
27
+ */
28
+ export function readTargetDocument(host, targetRoot, name, label = name, refuse = unreadable) {
29
+ const attempt = (read) => {
30
+ try {
31
+ return read();
32
+ }
33
+ catch (error) {
34
+ throw refuse(label, message(error));
35
+ }
36
+ };
37
+ const path = joinPath(targetRoot, name);
38
+ const kind = attempt(() => host.kindOf(path));
39
+ if (kind === "absent") {
40
+ return undefined;
41
+ }
42
+ const real = attempt(() => host.realPath(path));
43
+ if (relativePath(attempt(() => host.realPath(targetRoot)), real) === undefined) {
44
+ throw refuse(label, `resolves to ${real}, outside the target root`);
45
+ }
46
+ if (kind !== "file") {
47
+ throw refuse(label, "is not a regular file");
48
+ }
49
+ const text = attempt(() => host.readFile(real, CONFIG_MAX_BYTES + 1));
50
+ refuseOverBound(label, text);
51
+ return text;
52
+ }
@@ -0,0 +1,67 @@
1
+ import { isRecord } from "../json-document.js";
2
+ import { joinPath } from "../paths.js";
3
+ import { message } from "../product.js";
4
+ /** The file a package's manifest is read from. */
5
+ export const MANIFEST = "package.json";
6
+ /** The directory a package manager installs packages into, whose files are no project's own. */
7
+ export const INSTALLED_PACKAGES = "node_modules";
8
+ /** The manifest members a package declares the packages it depends on under. */
9
+ export const DEPENDENCY_SECTIONS = [
10
+ "dependencies",
11
+ "devDependencies",
12
+ "peerDependencies",
13
+ "optionalDependencies",
14
+ ];
15
+ /** Whether one path passes through an installed-packages directory. */
16
+ export function inInstalledPackages(path) {
17
+ return path.split("/").includes(INSTALLED_PACKAGES);
18
+ }
19
+ /** One JSON file, read and parsed, as {@link JSONRead} tells its states apart. */
20
+ export function readJSONFile(host, path) {
21
+ let text;
22
+ try {
23
+ text = host.readFile(path);
24
+ }
25
+ catch (error) {
26
+ return { kind: "unread", reason: message(error) };
27
+ }
28
+ try {
29
+ return { kind: "read", text, value: JSON.parse(text) };
30
+ }
31
+ catch {
32
+ return { kind: "malformed" };
33
+ }
34
+ }
35
+ /** One JSON file's text and decoded value, or undefined where it cannot be read or parsed. */
36
+ export function readDocument(host, path) {
37
+ const read = readJSONFile(host, path);
38
+ return read.kind === "read" ? { text: read.text, value: read.value } : undefined;
39
+ }
40
+ /** One JSON file's decoded value, or undefined where it cannot be read or parsed. */
41
+ export function readJSON(host, path) {
42
+ return readDocument(host, path)?.value;
43
+ }
44
+ /**
45
+ * The manifest in one directory, decoded, or undefined where none reads as an object. A
46
+ * manifest this program cannot read declares nothing, the same answer as an absent one:
47
+ * the package manager owns the refusal of a manifest it rejects.
48
+ */
49
+ export function manifestAt(host, dir) {
50
+ const value = readJSON(host, joinPath(dir, MANIFEST));
51
+ return isRecord(value) ? value : undefined;
52
+ }
53
+ /** The manifest in one directory, as {@link ManifestRead} tells its states apart. */
54
+ export function readManifestAt(host, dir) {
55
+ if (!holdsManifest(host, dir)) {
56
+ return { kind: "absent" };
57
+ }
58
+ const read = readJSONFile(host, joinPath(dir, MANIFEST));
59
+ if (read.kind !== "read") {
60
+ return read;
61
+ }
62
+ return isRecord(read.value) ? { kind: "read", manifest: read.value } : { kind: "malformed" };
63
+ }
64
+ /** Whether one directory holds a manifest file. */
65
+ export function holdsManifest(host, dir) {
66
+ return host.kindOf(joinPath(dir, MANIFEST)) === "file";
67
+ }
@@ -0,0 +1,88 @@
1
+ import { ancestors, joinPath, resolvePath } from "../paths.js";
2
+ import { LANGUAGE_ROWS } from "../contract/contract.generated.js";
3
+ import { LANGUAGE } from "../product.js";
4
+ import { bytewise } from "../text/compare.js";
5
+ import { globExpression } from "../text/glob.js";
6
+ /** The directories no walk of the tree enters, by the patterns the language's row names. */
7
+ const SKIPPED_DIRECTORIES = LANGUAGE_ROWS[LANGUAGE].skippedDirectories.map(globExpression);
8
+ function skipped(name) {
9
+ return SKIPPED_DIRECTORIES.some((pattern) => pattern.test(name));
10
+ }
11
+ /** One file's text without its line ending, or undefined where it cannot be read. */
12
+ function lineOf(host, path) {
13
+ try {
14
+ return host.readFile(path).replace(/\r?\n$/u, "");
15
+ }
16
+ catch {
17
+ return undefined;
18
+ }
19
+ }
20
+ /**
21
+ * The repository whose working tree holds `dir`: the nearest directory at or above it with a
22
+ * `.git`. A `.git` file, which a linked worktree or a submodule holds, names the repository's
23
+ * directory on its `gitdir:` line; that directory's `commondir` file, where it has one, names
24
+ * the directory shared with the main worktree, which holds `info/exclude`:
25
+ * https://git-scm.com/docs/gitrepository-layout
26
+ */
27
+ export function repositoryOf(host, dir) {
28
+ for (const root of ancestors(dir)) {
29
+ const dotGit = joinPath(root, ".git");
30
+ const kind = host.kindOf(dotGit);
31
+ if (kind === "directory") {
32
+ return { root, exclude: joinPath(dotGit, "info/exclude") };
33
+ }
34
+ if (kind === "file") {
35
+ const named = /^gitdir: (.+)$/u.exec(lineOf(host, dotGit) ?? "")?.[1];
36
+ const gitDir = named === undefined ? undefined : resolvePath(root, named);
37
+ const common = gitDir === undefined ? undefined : lineOf(host, joinPath(gitDir, "commondir"));
38
+ const shared = gitDir === undefined || common === undefined ? gitDir : resolvePath(gitDir, common);
39
+ return { root, exclude: shared === undefined ? undefined : joinPath(shared, "info/exclude") };
40
+ }
41
+ }
42
+ return undefined;
43
+ }
44
+ /** The entries of one directory, none where it cannot be read. */
45
+ export function entriesOf(host, dir) {
46
+ try {
47
+ return host.readDirectory(dir);
48
+ }
49
+ catch {
50
+ return [];
51
+ }
52
+ }
53
+ /** The names of the files directly in `dir` whose name `accepts`, in bytewise order. */
54
+ export function filesIn(host, dir, accepts) {
55
+ return entriesOf(host, dir)
56
+ .filter((entry) => !entry.directory && accepts(entry.name))
57
+ .map((entry) => entry.name)
58
+ .sort(bytewise);
59
+ }
60
+ /** The names of the directories directly in `dir` a walk enters, in bytewise order. */
61
+ export function directoriesIn(host, dir) {
62
+ return entriesOf(host, dir)
63
+ .filter((entry) => entry.directory && !skipped(entry.name))
64
+ .map((entry) => entry.name)
65
+ .sort(bytewise);
66
+ }
67
+ /**
68
+ * Every file below `root` whose name `accepts`, by its path relative to `root` in bytewise
69
+ * order, read in no skipped directory.
70
+ */
71
+ export function filesBelow(host, root, accepts) {
72
+ const found = [];
73
+ const pending = [""];
74
+ for (let dir = pending.pop(); dir !== undefined; dir = pending.pop()) {
75
+ for (const entry of entriesOf(host, joinPath(root, dir))) {
76
+ const path = dir === "" ? entry.name : `${dir}/${entry.name}`;
77
+ if (!entry.directory) {
78
+ if (accepts(entry.name)) {
79
+ found.push(path);
80
+ }
81
+ }
82
+ else if (!skipped(entry.name)) {
83
+ pending.push(path);
84
+ }
85
+ }
86
+ }
87
+ return found.sort(bytewise);
88
+ }
@@ -1,10 +1,12 @@
1
1
  /**
2
- * Which files the `.gitignore` files of a tree ignore, read as git reads them:
2
+ * Which files git ignores below a tree's root, read as git reads its ignore files:
3
3
  * https://git-scm.com/docs/gitignore#_pattern_format
4
4
  */
5
- import { globExpression } from "./glob.js";
6
- import { dirnamePath, joinPath, relativePath } from "./paths.js";
7
- /** The rules one `.gitignore` text writes, in order. */
5
+ import { ancestors, dirnamePath, joinPath, relativePath } from "./paths.js";
6
+ import { message } from "./product.js";
7
+ import { gitignoreExpression } from "./text/glob.js";
8
+ import { repositoryOf } from "./fs/tree.js";
9
+ /** The rules one ignore file's text writes, in order. */
8
10
  function rulesOf(text) {
9
11
  const rules = [];
10
12
  for (const raw of text.split(/\r?\n/u)) {
@@ -13,7 +15,7 @@ function rulesOf(text) {
13
15
  continue;
14
16
  }
15
17
  const negated = line.startsWith("!");
16
- line = negated || line.startsWith("\\") ? line.slice(1) : line;
18
+ line = negated ? line.slice(1) : line;
17
19
  const directoryOnly = line.endsWith("/");
18
20
  line = line.replace(/\/+$/u, "");
19
21
  if (line === "") {
@@ -26,43 +28,54 @@ function rulesOf(text) {
26
28
  rules.push({
27
29
  negated,
28
30
  directoryOnly,
29
- expression: globExpression(anchored ? pattern : `**/${pattern}`),
31
+ expression: gitignoreExpression(anchored ? pattern : `**/${pattern}`),
30
32
  });
31
33
  }
32
34
  return rules;
33
35
  }
36
+ function rulesIn(host, path, unread) {
37
+ try {
38
+ return rulesOf(host.readFile(path));
39
+ }
40
+ catch (error) {
41
+ if (host.kindOf(path) !== "absent") {
42
+ unread(path, message(error));
43
+ }
44
+ return [];
45
+ }
46
+ }
34
47
  /**
35
- * Whether the `.gitignore` files at and below `root` ignore one absolute path. A path
36
- * outside `root` is not ignored, and a file below an ignored directory stays ignored
37
- * whatever a later pattern says, as git cannot re-include it.
48
+ * Whether git ignores one absolute path below `root`: by the repository's `info/exclude`, then
49
+ * the `.gitignore` files from its root down to the path's directory, a later pattern overriding
50
+ * an earlier one, though a file below an ignored directory stays ignored, as git cannot re-include
51
+ * it. A path outside `root` is not ignored. With no repository, the files at and below `root` are
52
+ * read; with one, the directories above `root` give patterns but are not tested. An unreadable
53
+ * ignore file ignores nothing, and `unread` is told it.
38
54
  */
39
- export function gitIgnored(host, root) {
55
+ export function gitIgnored(host, root, unread = () => undefined) {
56
+ const found = repositoryOf(host, root);
57
+ const repository = found?.root;
58
+ const above = repository === undefined ? [] : [...ancestors(dirnamePath(root), repository)].reverse();
59
+ const excluded = found?.exclude === undefined ? [] : rulesIn(host, found.exclude, unread);
40
60
  const read = new Map();
41
61
  const rulesAt = (dir) => {
42
62
  let rules = read.get(dir);
43
63
  if (rules === undefined) {
44
- try {
45
- rules = rulesOf(host.readFile(joinPath(dir, ".gitignore")));
46
- }
47
- catch {
48
- rules = [];
49
- }
64
+ rules = rulesIn(host, joinPath(dir, ".gitignore"), unread);
50
65
  read.set(dir, rules);
51
66
  }
52
67
  return rules;
53
68
  };
54
- /** Whether the rules of `root` and of each directory down to one path's own decide it ignored. */
55
69
  const decided = (path, directory) => {
56
- const dirs = [];
57
- for (let at = dirnamePath(path); relativePath(root, at) !== undefined; at = dirnamePath(at)) {
58
- dirs.unshift(at);
59
- }
60
- dirs.unshift(root);
70
+ const sources = [
71
+ ...(repository === undefined ? [] : [[repository, excluded]]),
72
+ ...[...above, ...[...ancestors(dirnamePath(path), root)].reverse()].map((dir) => [dir, rulesAt(dir)]),
73
+ ];
61
74
  let ignored = false;
62
- for (const dir of dirs) {
63
- const below = relativePath(dir, path);
64
- for (const rule of below === undefined ? [] : rulesAt(dir)) {
65
- if ((directory || !rule.directoryOnly) && rule.expression.test(below ?? "")) {
75
+ for (const [dir, rules] of sources) {
76
+ const below = relativePath(dir, path) ?? "";
77
+ for (const rule of rules) {
78
+ if ((directory || !rule.directoryOnly) && rule.expression.test(below)) {
66
79
  ignored = !rule.negated;
67
80
  }
68
81
  }
@@ -2,7 +2,7 @@
2
2
  * The import bindings of one file: the names its import declarations bind, which only
3
3
  * the file itself can read.
4
4
  */
5
- import { isExportSpecifier, isExternalModuleReference, isIdentifier, isImportDeclaration, isImportEqualsDeclaration, isJsxElement, isJsxFragment, isJsxSelfClosingElement, isNamespaceImport, SyntaxKind, } from "@typescript/native/ast";
5
+ import { isExportDeclaration, isExportSpecifier, isExternalModuleReference, isImportDeclaration, isImportEqualsDeclaration, isJsxElement, isJsxFragment, isJsxSelfClosingElement, isNamedExports, isNamespaceImport, SyntaxKind, } from "@typescript/native/ast";
6
6
  /** The extensions of the files whose import bindings are judged: no markup can read them. */
7
7
  const JUDGED = /\.(?:[mc]?ts|tsx|[mc]?js|jsx)$/u;
8
8
  /** The compiler's `jsx` settings whose emit calls no factory the file must hold. */
@@ -13,41 +13,86 @@ const DOC_COMMENT = /\/\*\*[\s\S]*?\*\//gu;
13
13
  const DOC_REFERENCE = /\{[^{}]*\}|@see\s+[A-Za-z_$][\w$.]*/gu;
14
14
  /** The factory a pragma comment names: `@jsx h` or `@jsxFrag Fragment`. */
15
15
  const PRAGMA = /@jsx(?:Frag)?\s+([A-Za-z_$][\w$]*)/gu;
16
+ const bindingsCache = new WeakMap();
16
17
  /**
17
- * The names one file's import declarations bind: the default, named and namespace names of
18
- * an `import` declaration, and the name of an `import x = require()` declaration that is
19
- * not exported. None is judged in a declaration file or a component file.
18
+ * Every name one import declaration binds, in source order: the default, named and
19
+ * namespace names of an `import` declaration and the name of an `import x = …` declaration.
20
+ * A namespace import and an import assignment bind a whole module.
20
21
  */
21
- export function importBindings(file) {
22
- if (file.isDeclarationFile || !JUDGED.test(file.fileName)) {
23
- return [];
22
+ export function declarationBindings(declaration) {
23
+ if (isImportEqualsDeclaration(declaration)) {
24
+ return [
25
+ {
26
+ name: declaration.name,
27
+ equals: {
28
+ exported: (declaration.modifiers ?? []).some((modifier) => modifier.kind === SyntaxKind.ExportKeyword),
29
+ external: isExternalModuleReference(declaration.moduleReference),
30
+ },
31
+ },
32
+ ];
24
33
  }
34
+ const clause = declaration.importClause;
25
35
  const found = [];
26
- for (const statement of file.statements) {
27
- if (isImportDeclaration(statement)) {
28
- const clause = statement.importClause;
29
- if (clause?.name !== undefined) {
30
- found.push(clause.name);
31
- }
32
- const named = clause?.namedBindings;
33
- if (named !== undefined && isNamespaceImport(named)) {
34
- found.push(named.name);
35
- }
36
- else if (named !== undefined) {
37
- for (const element of named.elements) {
38
- found.push(element.name);
39
- }
40
- }
41
- }
42
- else if (isImportEqualsDeclaration(statement) &&
43
- isExternalModuleReference(statement.moduleReference) &&
44
- isIdentifier(statement.name) &&
45
- !(statement.modifiers ?? []).some((modifier) => modifier.kind === SyntaxKind.ExportKeyword)) {
46
- found.push(statement.name);
36
+ if (clause?.name !== undefined) {
37
+ found.push({ name: clause.name, imported: "default" });
38
+ }
39
+ const named = clause?.namedBindings;
40
+ if (named !== undefined && isNamespaceImport(named)) {
41
+ found.push({ name: named.name });
42
+ }
43
+ else if (named !== undefined) {
44
+ for (const element of named.elements) {
45
+ found.push({ name: element.name, imported: element.propertyName?.text ?? element.name.text });
47
46
  }
48
47
  }
49
48
  return found;
50
49
  }
50
+ /** Every name one file's top-level import declarations bind, in source order. */
51
+ export function bindingsOf(file) {
52
+ const known = bindingsCache.get(file);
53
+ if (known !== undefined) {
54
+ return known;
55
+ }
56
+ const found = file.statements.flatMap((statement) => isImportDeclaration(statement) || isImportEqualsDeclaration(statement)
57
+ ? declarationBindings(statement)
58
+ : []);
59
+ bindingsCache.set(file, found);
60
+ return found;
61
+ }
62
+ /**
63
+ * The export names an import or a re-export declaration reads from the module it names,
64
+ * `undefined` standing for the whole module where a namespace or a star reads it; none for
65
+ * any other node.
66
+ */
67
+ export function importedNames(node) {
68
+ if (isImportDeclaration(node)) {
69
+ return declarationBindings(node).map((binding) => binding.imported);
70
+ }
71
+ if (!isExportDeclaration(node)) {
72
+ return [];
73
+ }
74
+ const clause = node.exportClause;
75
+ return clause === undefined || !isNamedExports(clause)
76
+ ? [undefined]
77
+ : clause.elements.map((one) => (one.propertyName ?? one.name).text);
78
+ }
79
+ /** The export names {@link importedNames} gives one node, without the whole module. */
80
+ export function namesImported(node) {
81
+ return importedNames(node).flatMap((name) => name ?? []);
82
+ }
83
+ /**
84
+ * The bindings of one file that are judged as imports: those of {@link bindingsOf} but an
85
+ * `import x = …` that is exported or names no external module. None is judged in a
86
+ * declaration file or a component file.
87
+ */
88
+ export function importBindings(file) {
89
+ if (file.isDeclarationFile || !JUDGED.test(file.fileName)) {
90
+ return [];
91
+ }
92
+ return bindingsOf(file).flatMap((binding) => binding.equals !== undefined && (binding.equals.exported || !binding.equals.external)
93
+ ? []
94
+ : [binding.name]);
95
+ }
51
96
  /** Whether one identifier names a binding in a local export, which reads it whatever it resolves to. */
52
97
  export function exportsLocally(use) {
53
98
  return isExportSpecifier(use.parent);