@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
@@ -37,12 +37,8 @@ import {
37
37
  type SourceFile,
38
38
  } from "@typescript/native/ast";
39
39
  import { SymbolFlags, type Symbol as TSSymbol, type Type } from "@typescript/native/sync";
40
- import type { AliasChains } from "./alias-chain.ts";
41
- import { nodeKey, type Inventory } from "./inventory.ts";
42
- import { renderPosition } from "./position.ts";
43
40
  import { UNANSWERED } from "./query.ts";
44
- import type { Reference } from "./references.ts";
45
- import type { ProjectView } from "./session.ts";
41
+ import type { Read, ReadRule } from "./references/read-rule.ts";
46
42
 
47
43
  /** One call or construction passing an object literal, and the declaration that writes it. */
48
44
  interface Passing {
@@ -118,294 +114,315 @@ function literalsOf(argument: Expression): readonly ObjectLiteralExpression[] {
118
114
  }
119
115
 
120
116
  /**
121
- * The reads the object-literal arguments of one project's own files make of the members of
122
- * the types they are checked against, where the callee has no implementation in the target.
117
+ * The reads the object-literal arguments of a side's files make of the members of the types
118
+ * they are checked against, where the callee has no implementation in the target, and the
119
+ * reads of every member of each target type an outside value is handed over as. A type the
120
+ * checker leaves unanswered holds what its answer could have read.
123
121
  */
124
- export function unimplementedCalleeReads<Brand>(
125
- project: ProjectView<Brand>,
126
- held: Inventory,
127
- chains: AliasChains,
128
- root: string,
129
- testFiles: ReadonlySet<string>,
130
- ): readonly Reference[] {
131
- const queries = project.queries;
132
- const own = project.ownPaths();
133
- const passing: Passing[] = [];
134
- const implementing: Node[] = [];
135
- const asserted: (HandedOver & { readonly operand: Expression })[] = [];
136
- const constructed: Passing[] = [];
137
- const handing: (CallExpression | NewExpression)[] = [];
138
- for (const file of project.ownSourceFiles()) {
139
- const fileId = held.declarations.get(nodeKey(file, file));
140
- if (fileId === undefined) {
141
- continue;
142
- }
143
- const visit = (node: Node, from: string): void => {
144
- const holder = held.declarations.get(nodeKey(file, node)) ?? from;
145
- if (
146
- (isCallExpression(node) || isNewExpression(node)) &&
147
- (node.arguments ?? []).some((argument) => isObjectLiteralExpression(argument))
148
- ) {
149
- passing.push({ file, from: holder, call: node });
150
- }
151
- if (isNewExpression(node)) {
152
- constructed.push({ file, from: holder, call: node });
153
- }
154
- if (
155
- (isCallExpression(node) || isNewExpression(node)) &&
156
- (node.arguments ?? []).some(
157
- (argument) => isFunctionLike(argument) || isIdentifier(argument),
158
- )
159
- ) {
160
- handing.push(node);
161
- }
162
- if (isAsExpression(node) && !isAsExpression(node.parent)) {
163
- asserted.push({ file, from: holder, node, operand: castOperand(node) });
164
- }
165
- if (isClassDeclaration(node) || isClassExpression(node)) {
166
- for (const clause of node.heritageClauses ?? []) {
167
- if (isHeritageClause(clause)) {
168
- implementing.push(
169
- ...clause.types.map((one) =>
170
- isTypeReferenceNode(one) ? one.typeName : one.expression,
171
- ),
172
- );
122
+ export const unimplementedCallees: ReadRule = {
123
+ start() {
124
+ const passing: Passing[] = [];
125
+ const implementing: Node[] = [];
126
+ const asserted: (HandedOver & { readonly operand: Expression })[] = [];
127
+ const constructed: Passing[] = [];
128
+ const handing: (CallExpression | NewExpression)[] = [];
129
+ return {
130
+ visit(node, { file, from }) {
131
+ if (
132
+ (isCallExpression(node) || isNewExpression(node)) &&
133
+ (node.arguments ?? []).some((argument) => isObjectLiteralExpression(argument))
134
+ ) {
135
+ passing.push({ file, from, call: node });
136
+ }
137
+ if (isNewExpression(node)) {
138
+ constructed.push({ file, from, call: node });
139
+ }
140
+ if (
141
+ (isCallExpression(node) || isNewExpression(node)) &&
142
+ (node.arguments ?? []).some(
143
+ (argument) => isFunctionLike(argument) || isIdentifier(argument),
144
+ )
145
+ ) {
146
+ handing.push(node);
147
+ }
148
+ if (isAsExpression(node) && !isAsExpression(node.parent)) {
149
+ asserted.push({ file, from, node, operand: castOperand(node) });
150
+ }
151
+ if (isClassDeclaration(node) || isClassExpression(node)) {
152
+ for (const clause of node.heritageClauses ?? []) {
153
+ if (isHeritageClause(clause)) {
154
+ implementing.push(
155
+ ...clause.types.map((one) =>
156
+ isTypeReferenceNode(one) ? one.typeName : one.expression,
157
+ ),
158
+ );
159
+ }
173
160
  }
174
161
  }
175
- }
176
- // An object literal typed as an interface implements that interface's methods.
177
- if (
178
- isVariableDeclaration(node) &&
179
- node.type !== undefined &&
180
- isTypeReferenceNode(node.type) &&
181
- node.initializer !== undefined &&
182
- isObjectLiteralExpression(node.initializer)
183
- ) {
184
- implementing.push(node.type.typeName);
185
- }
186
- if (
187
- (isSatisfiesExpression(node) || isAsExpression(node)) &&
188
- isObjectLiteralExpression(node.expression) &&
189
- isTypeReferenceNode(node.type)
190
- ) {
191
- implementing.push(node.type.typeName);
192
- }
193
- node.forEachChild((child) => {
194
- visit(child, holder);
195
- });
196
- };
197
- file.forEachChild((child) => {
198
- visit(child, fileId);
199
- });
200
- }
201
- if (passing.length === 0 && asserted.length === 0 && constructed.length === 0) {
202
- return [];
203
- }
204
-
205
- const resolved = (symbol: TSSymbol | undefined | typeof UNANSWERED): TSSymbol | undefined => {
206
- if (symbol === UNANSWERED || symbol === undefined) {
207
- return undefined;
208
- }
209
- if ((symbol.flags & SymbolFlags.Alias) === 0) {
210
- return symbol;
211
- }
212
- const target = queries.aliased(symbol);
213
- return target === UNANSWERED ? undefined : target;
214
- };
215
- const declarationsOf = (symbol: TSSymbol | undefined): readonly Node[] =>
216
- (symbol?.declarations ?? []).flatMap((handle) => {
217
- const node = project.declarationAt(handle)?.node;
218
- return node === undefined ? [] : [node];
219
- });
162
+ // An object literal typed as an interface implements that interface's methods.
163
+ if (
164
+ isVariableDeclaration(node) &&
165
+ node.type !== undefined &&
166
+ isTypeReferenceNode(node.type) &&
167
+ node.initializer !== undefined &&
168
+ isObjectLiteralExpression(node.initializer)
169
+ ) {
170
+ implementing.push(node.type.typeName);
171
+ }
172
+ if (
173
+ (isSatisfiesExpression(node) || isAsExpression(node)) &&
174
+ isObjectLiteralExpression(node.expression) &&
175
+ isTypeReferenceNode(node.type)
176
+ ) {
177
+ implementing.push(node.type.typeName);
178
+ }
179
+ },
180
+ reads({ project, chains }) {
181
+ const queries = project.queries;
182
+ const own = project.ownPaths();
183
+ const found: Read[] = [];
184
+ if (passing.length === 0 && asserted.length === 0 && constructed.length === 0) {
185
+ return found;
186
+ }
220
187
 
221
- const implemented = new Set<Node>(
222
- queries.symbolsAt(implementing).flatMap((symbol) => declarationsOf(resolved(symbol))),
223
- );
188
+ const resolved = (
189
+ symbol: TSSymbol | undefined | typeof UNANSWERED,
190
+ ): TSSymbol | undefined => {
191
+ if (symbol === UNANSWERED || symbol === undefined) {
192
+ return undefined;
193
+ }
194
+ if ((symbol.flags & SymbolFlags.Alias) === 0) {
195
+ return symbol;
196
+ }
197
+ const target = queries.aliased(symbol);
198
+ return target === UNANSWERED ? undefined : target;
199
+ };
200
+ const declarationsOf = (symbol: TSSymbol | undefined): readonly Node[] =>
201
+ (symbol?.declarations ?? []).flatMap((handle) => {
202
+ const node = project.declarationAt(handle)?.node;
203
+ return node === undefined ? [] : [node];
204
+ });
224
205
 
225
- /** Whether a declaration is a function or a class of the target, or a variable or property it initializes. */
226
- const ownFunction = (node: Node): boolean =>
227
- own.has(node.getSourceFile().fileName) &&
228
- (isFunctionLike(node) ||
229
- ((isVariableDeclaration(node) || isPropertyAssignment(node) || isPropertyDeclaration(node)) &&
230
- isFunctionLike(node.initializer)));
206
+ const implemented = new Set<Node>(
207
+ queries.symbolsAt(implementing).flatMap((symbol) => declarationsOf(resolved(symbol))),
208
+ );
231
209
 
232
- /**
233
- * Whether a function or a class of the target reaches one parameter of a function of the
234
- * target, passed for it by a call that names the function. A call through another name
235
- * is not followed, so its callee keeps no implementation and its literal reads more.
236
- */
237
- const reachedParameters = new Map<ParameterDeclaration, boolean>();
238
- const parameterReached = (parameter: ParameterDeclaration): boolean => {
239
- const known = reachedParameters.get(parameter);
240
- if (known !== undefined) {
241
- return known;
242
- }
243
- const fn = parameter.parent;
244
- const fnName = nameOf(fn) ?? (isVariableDeclaration(fn.parent) ? nameOf(fn.parent) : undefined);
245
- const at =
246
- (fn as { readonly parameters?: readonly Node[] }).parameters?.indexOf(parameter) ?? -1;
247
- const passed = handing.flatMap((call) => {
248
- const callee = call.expression;
249
- const name = isPropertyAccessExpression(callee) ? callee.name : callee;
250
- if (fnName === undefined || !isIdentifier(name) || name.text !== fnName) {
251
- return [];
252
- }
253
- const signature = queries.resolvedSignature(call);
254
- const handle =
255
- signature === UNANSWERED || signature === undefined ? undefined : signature.declaration;
256
- const argument =
257
- handle === undefined || project.declarationAt(handle)?.node !== fn
258
- ? undefined
259
- : (call.arguments ?? [])[at];
260
- return argument === undefined || at < 0 ? [] : [argument];
261
- });
262
- const named = passed.filter((argument) => isIdentifier(argument));
263
- const reached =
264
- passed.some((argument) => isFunctionLike(argument)) ||
265
- queries
266
- .symbolsAt(named)
267
- .some((symbol) => declarationsOf(resolved(symbol)).some((node) => ownFunction(node)));
268
- reachedParameters.set(parameter, reached);
269
- return reached;
270
- };
210
+ /** Whether a declaration is a function or a class of the target, or a variable or property it initializes. */
211
+ const ownFunction = (node: Node): boolean =>
212
+ own.has(node.getSourceFile().fileName) &&
213
+ (isFunctionLike(node) ||
214
+ ((isVariableDeclaration(node) ||
215
+ isPropertyAssignment(node) ||
216
+ isPropertyDeclaration(node)) &&
217
+ isFunctionLike(node.initializer)));
271
218
 
272
- /** Whether some function, class or object literal of the target stands for a signature. */
273
- const standsFor = (passed: Passing): boolean => {
274
- const signature = queries.resolvedSignature(passed.call);
275
- const handle =
276
- signature === UNANSWERED || signature === undefined ? undefined : signature.declaration;
277
- const declaration = handle === undefined ? undefined : project.declarationAt(handle)?.node;
278
- if (declaration === undefined) {
279
- return true;
280
- }
281
- if (hasBody(declaration) || overloadImplemented(declaration)) {
282
- return own.has(handle?.path ?? "");
283
- }
284
- const holder = declaration.parent as Node | undefined;
285
- if (holder !== undefined && implemented.has(holder)) {
286
- return true;
287
- }
288
- const callee = passed.call.expression;
289
- const name = isPropertyAccessExpression(callee) ? callee.name : callee;
290
- const [named] = queries.symbolsAt([name]);
291
- return declarationsOf(resolved(named)).some((node) =>
292
- isParameterDeclaration(node)
293
- ? own.has(node.getSourceFile().fileName) && parameterReached(node)
294
- : ownFunction(node) && !isFunctionLike(node),
295
- );
296
- };
219
+ /**
220
+ * Whether a function or a class of the target reaches one parameter of a function of the
221
+ * target, passed for it by a call that names the function. A call through another name
222
+ * is not followed, so its callee keeps no implementation and its literal reads more.
223
+ */
224
+ const reachedParameters = new Map<ParameterDeclaration, boolean>();
225
+ const parameterReached = (parameter: ParameterDeclaration): boolean => {
226
+ const known = reachedParameters.get(parameter);
227
+ if (known !== undefined) {
228
+ return known;
229
+ }
230
+ const fn = parameter.parent;
231
+ const fnName =
232
+ nameOf(fn) ?? (isVariableDeclaration(fn.parent) ? nameOf(fn.parent) : undefined);
233
+ const at =
234
+ (fn as { readonly parameters?: readonly Node[] }).parameters?.indexOf(parameter) ?? -1;
235
+ const passed = handing.flatMap((call) => {
236
+ const callee = call.expression;
237
+ const name = isPropertyAccessExpression(callee) ? callee.name : callee;
238
+ if (fnName === undefined || !isIdentifier(name) || name.text !== fnName) {
239
+ return [];
240
+ }
241
+ const signature = queries.resolvedSignature(call);
242
+ const handle =
243
+ signature === UNANSWERED || signature === undefined
244
+ ? undefined
245
+ : signature.declaration;
246
+ const argument =
247
+ handle === undefined || project.declarationAt(handle)?.node !== fn
248
+ ? undefined
249
+ : (call.arguments ?? [])[at];
250
+ return argument === undefined || at < 0 ? [] : [argument];
251
+ });
252
+ const named = passed.filter((argument) => isIdentifier(argument));
253
+ const reached =
254
+ passed.some((argument) => isFunctionLike(argument)) ||
255
+ queries
256
+ .symbolsAt(named)
257
+ .some((symbol) => declarationsOf(resolved(symbol)).some((node) => ownFunction(node)));
258
+ reachedParameters.set(parameter, reached);
259
+ return reached;
260
+ };
297
261
 
298
- const literals: { readonly passed: Passing; readonly literal: ObjectLiteralExpression }[] = [];
299
- for (const passed of passing) {
300
- if (standsFor(passed)) {
301
- continue;
302
- }
303
- for (const argument of passed.call.arguments ?? []) {
304
- literals.push(...literalsOf(argument).map((literal) => ({ passed, literal })));
305
- }
306
- }
307
- const contexts = queries.contextualTypes(literals.map((one) => one.literal));
262
+ /** Whether some function, class or object literal of the target stands for a signature. */
263
+ const standsFor = (passed: Passing): boolean => {
264
+ const signature = queries.resolvedSignature(passed.call);
265
+ // A callee the checker cannot resolve may be code the target cannot see.
266
+ if (signature === UNANSWERED) {
267
+ return false;
268
+ }
269
+ const handle = signature?.declaration;
270
+ const declaration =
271
+ handle === undefined ? undefined : project.declarationAt(handle)?.node;
272
+ if (declaration === undefined) {
273
+ return true;
274
+ }
275
+ if (hasBody(declaration) || overloadImplemented(declaration)) {
276
+ return own.has(handle?.path ?? "");
277
+ }
278
+ const holder = declaration.parent as Node | undefined;
279
+ if (holder !== undefined && implemented.has(holder)) {
280
+ return true;
281
+ }
282
+ const callee = passed.call.expression;
283
+ const name = isPropertyAccessExpression(callee) ? callee.name : callee;
284
+ const [named] = queries.symbolsAt([name]);
285
+ return declarationsOf(resolved(named)).some((node) =>
286
+ isParameterDeclaration(node)
287
+ ? own.has(node.getSourceFile().fileName) && parameterReached(node)
288
+ : ownFunction(node) && !isFunctionLike(node),
289
+ );
290
+ };
308
291
 
309
- const found: Reference[] = [];
310
- literals.forEach(({ passed, literal }, at) => {
311
- const context = contexts[at];
312
- if (context === UNANSWERED || context === undefined) {
313
- return;
314
- }
315
- const parts = queries.constituents(context);
316
- const position = renderPosition(passed.file, root, literal.getStart());
317
- for (const part of parts === UNANSWERED ? [context] : parts) {
318
- const properties = queries.propertiesOf(part);
319
- for (const property of properties === UNANSWERED ? [] : properties) {
320
- for (const to of chains.declarationsOf(property)) {
321
- found.push({
322
- from: passed.from,
323
- to,
324
- position,
325
- use: "read",
326
- resolution: "contextual",
327
- test: testFiles.has(position.path),
328
- });
292
+ const literals: { readonly passed: Passing; readonly literal: ObjectLiteralExpression }[] =
293
+ [];
294
+ for (const passed of passing) {
295
+ if (standsFor(passed)) {
296
+ continue;
297
+ }
298
+ for (const argument of passed.call.arguments ?? []) {
299
+ literals.push(...literalsOf(argument).map((literal) => ({ passed, literal })));
300
+ }
329
301
  }
330
- }
331
- }
332
- });
333
- found.push(...handedOver());
334
- return found;
302
+ const contexts = queries.contextualTypes(literals.map((one) => one.literal));
335
303
 
336
- /** Whether a type is an object no file of the project declares, a platform object's among them. */
337
- function outsideValue(type: Type): boolean {
338
- if (!type.isObjectType()) {
339
- return false;
340
- }
341
- const symbol = queries.symbolOfType(type);
342
- const declared = symbol === UNANSWERED ? undefined : symbol;
343
- return declared?.declarations.every((handle) => !own.has(handle.path)) === true;
344
- }
345
-
346
- /** Whether a type is an object type a file of the project declares. */
347
- function ownObject(type: Type | undefined | typeof UNANSWERED): type is Type {
348
- const known = type === UNANSWERED ? undefined : type;
349
- if (!known?.isObjectType()) {
350
- return false;
351
- }
352
- const symbol = queries.symbolOfType(known);
353
- const declared = symbol === UNANSWERED ? undefined : symbol;
354
- return declared?.declarations.some((handle) => own.has(handle.path)) === true;
355
- }
304
+ literals.forEach(({ passed, literal }, at) => {
305
+ const context = contexts[at];
306
+ if (context === UNANSWERED) {
307
+ found.push({ kind: "held", from: passed.from, names: propertyNames(literal) });
308
+ return;
309
+ }
310
+ if (context === undefined) {
311
+ return;
312
+ }
313
+ const parts = queries.constituents(context);
314
+ for (const part of parts === UNANSWERED ? [context] : parts) {
315
+ const properties = queries.propertiesOf(part);
316
+ if (properties === UNANSWERED) {
317
+ found.push({ kind: "held", from: passed.from, names: propertyNames(literal) });
318
+ continue;
319
+ }
320
+ for (const property of properties) {
321
+ for (const to of chains.declarationsOf(property)) {
322
+ found.push({
323
+ kind: "named",
324
+ from: passed.from,
325
+ to,
326
+ file: passed.file,
327
+ at: literal,
328
+ use: "read",
329
+ via: "contextual",
330
+ });
331
+ }
332
+ }
333
+ }
334
+ });
335
+ handedOver();
336
+ return found;
356
337
 
357
- /** The reads of every member of each target type an outside value is handed over as. */
358
- function handedOver(): readonly Reference[] {
359
- const operandTypes = queries.typesAt(asserted.map((one) => one.operand));
360
- const fromCasts: HandedOver[] = asserted.filter((_one, at) => {
361
- const type = operandTypes[at];
362
- return type !== UNANSWERED && type !== undefined && outsideValue(type);
363
- });
364
- const newTypes = queries.typesAt(constructed.map((one) => one.call));
365
- // A construct signature whose declared result is one of its type parameters names no
366
- // type the target declares, so only a result the signature itself names is handed over.
367
- const fromConstructors: HandedOver[] = constructed
368
- .filter((one, at) => {
369
- if (!ownObject(newTypes[at]) || standsFor(one)) {
370
- return false;
371
- }
372
- const signature = queries.resolvedSignature(one.call);
373
- const result =
374
- signature === UNANSWERED || signature === undefined
375
- ? undefined
376
- : queries.returnTypeOf(signature);
377
- return result !== UNANSWERED && result !== undefined && !result.isTypeParameter();
378
- })
379
- .map((one) => ({ file: one.file, from: one.from, node: one.call }));
380
- const handed = [...fromCasts, ...fromConstructors];
381
- const types = queries.typesAt(handed.map((one) => one.node));
382
- const reads: Reference[] = [];
383
- handed.forEach((one, at) => {
384
- const type = types[at];
385
- if (type === UNANSWERED || type === undefined) {
386
- return;
387
- }
388
- const position = renderPosition(one.file, root, one.node.getStart());
389
- const parts = queries.constituents(type);
390
- for (const part of parts === UNANSWERED ? [type] : parts) {
391
- if (!ownObject(part)) {
392
- continue;
338
+ /** Whether a type is an object no file of the project declares, a platform object's among them. */
339
+ function outsideValue(type: Type): boolean {
340
+ if (!type.isObjectType()) {
341
+ return false;
342
+ }
343
+ const symbol = queries.symbolOfType(type);
344
+ const declared = symbol === UNANSWERED ? undefined : symbol;
345
+ return declared?.declarations.every((handle) => !own.has(handle.path)) === true;
393
346
  }
394
- const properties = queries.propertiesOf(part);
395
- for (const property of properties === UNANSWERED ? [] : properties) {
396
- for (const to of chains.declarationsOf(property)) {
397
- reads.push({
398
- from: one.from,
399
- to,
400
- position,
401
- use: "read",
402
- resolution: "contextual",
403
- test: testFiles.has(position.path),
404
- });
347
+
348
+ /** Whether a type is an object type a file of the project declares. */
349
+ function ownObject(type: Type | undefined | typeof UNANSWERED): type is Type {
350
+ const known = type === UNANSWERED ? undefined : type;
351
+ if (!known?.isObjectType()) {
352
+ return false;
405
353
  }
354
+ const symbol = queries.symbolOfType(known);
355
+ const declared = symbol === UNANSWERED ? undefined : symbol;
356
+ return declared?.declarations.some((handle) => own.has(handle.path)) === true;
406
357
  }
407
- }
408
- });
409
- return reads;
410
- }
358
+
359
+ /** The reads of every member of each target type an outside value is handed over as. */
360
+ function handedOver(): void {
361
+ const operandTypes = queries.typesAt(asserted.map((one) => one.operand));
362
+ // An operand the checker cannot type may be an outside value.
363
+ const fromCasts: HandedOver[] = asserted.filter((_one, at) => {
364
+ const type = operandTypes[at];
365
+ return type === UNANSWERED || (type !== undefined && outsideValue(type));
366
+ });
367
+ const newTypes = queries.typesAt(constructed.map((one) => one.call));
368
+ // A construct signature whose declared result is one of its type parameters names no
369
+ // type the target declares, so only a result the signature itself names is handed over.
370
+ const fromConstructors: HandedOver[] = constructed
371
+ .filter((one, at) => {
372
+ if (!ownObject(newTypes[at]) || standsFor(one)) {
373
+ return false;
374
+ }
375
+ const signature = queries.resolvedSignature(one.call);
376
+ const result =
377
+ signature === UNANSWERED || signature === undefined
378
+ ? undefined
379
+ : queries.returnTypeOf(signature);
380
+ return result !== UNANSWERED && result !== undefined && !result.isTypeParameter();
381
+ })
382
+ .map((one) => ({ file: one.file, from: one.from, node: one.call }));
383
+ const handed = [...fromCasts, ...fromConstructors];
384
+ const types = queries.typesAt(handed.map((one) => one.node));
385
+ handed.forEach((one, at) => {
386
+ const type = types[at];
387
+ if (type === UNANSWERED) {
388
+ found.push({ kind: "held", from: one.from, members: true });
389
+ return;
390
+ }
391
+ if (type === undefined) {
392
+ return;
393
+ }
394
+ const parts = queries.constituents(type);
395
+ for (const part of parts === UNANSWERED ? [type] : parts) {
396
+ if (!ownObject(part)) {
397
+ continue;
398
+ }
399
+ const properties = queries.propertiesOf(part);
400
+ if (properties === UNANSWERED) {
401
+ found.push({ kind: "held", from: one.from, types: [part] });
402
+ continue;
403
+ }
404
+ for (const property of properties) {
405
+ for (const to of chains.declarationsOf(property)) {
406
+ found.push({
407
+ kind: "named",
408
+ from: one.from,
409
+ to,
410
+ file: one.file,
411
+ at: one.node,
412
+ use: "read",
413
+ via: "contextual",
414
+ });
415
+ }
416
+ }
417
+ }
418
+ });
419
+ }
420
+ },
421
+ };
422
+ },
423
+ };
424
+
425
+ /** The names an object literal's own properties spell. */
426
+ function propertyNames(literal: ObjectLiteralExpression): readonly string[] {
427
+ return literal.properties.flatMap((property) => nameOf(property) ?? []);
411
428
  }
package/src/unwrap.ts ADDED
@@ -0,0 +1,34 @@
1
+ import {
2
+ isAsExpression,
3
+ isNonNullExpression,
4
+ isParenthesizedExpression,
5
+ isSatisfiesExpression,
6
+ type Expression,
7
+ type Node,
8
+ } from "@typescript/native/ast";
9
+
10
+ /** The expression inside every pair of parentheses around `node`. */
11
+ export function parenthesesRemoved<T extends Node>(node: T): T | Expression {
12
+ let at: T | Expression = node;
13
+ while (isParenthesizedExpression(at)) {
14
+ at = at.expression;
15
+ }
16
+ return at;
17
+ }
18
+
19
+ /**
20
+ * The expression inside every wrapper around `node` that changes no value it evaluates to:
21
+ * parentheses, `as` and `satisfies` assertions and the non-null assertion.
22
+ */
23
+ export function unwrapped<T extends Node>(node: T): T | Expression {
24
+ let at: T | Expression = node;
25
+ while (
26
+ isParenthesizedExpression(at) ||
27
+ isAsExpression(at) ||
28
+ isSatisfiesExpression(at) ||
29
+ isNonNullExpression(at)
30
+ ) {
31
+ at = at.expression;
32
+ }
33
+ return at;
34
+ }
package/src/usage.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * A refusal of the invocation: the fix is to the command line or to a document it
3
+ * names, so the run ends with the usage code before any analysis.
4
+ */
5
+ export class UsageError extends Error {
6
+ constructor(message: string) {
7
+ super(message);
8
+ this.name = "UsageError";
9
+ }
10
+ }