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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/README.md +3 -1
  2. package/THIRD_PARTY_NOTICES.md +27 -0
  3. package/dist/bin/mapper-connection.js +2 -1
  4. package/dist/bin/node-host.js +24 -5
  5. package/dist/src/alias-chain.js +2 -7
  6. package/dist/src/amd.js +81 -0
  7. package/dist/src/analysis.js +269 -432
  8. package/dist/src/augmentations.js +64 -3
  9. package/dist/src/automatic-types.js +10 -29
  10. package/dist/src/bindings.js +382 -0
  11. package/dist/src/calls.js +279 -43
  12. package/dist/src/commands/held.js +499 -0
  13. package/dist/src/commands/read.js +161 -0
  14. package/dist/src/commands/shell.js +169 -0
  15. package/dist/src/commands/tools.js +1847 -0
  16. package/dist/src/component-files.js +3 -2
  17. package/dist/src/component-layer.js +4 -2
  18. package/dist/src/config.js +6 -82
  19. package/dist/src/conformance-record.js +1 -1
  20. package/dist/src/consumers.js +10 -38
  21. package/dist/src/contextual-uses.js +57 -26
  22. package/dist/src/contract/config.generated.js +561 -0
  23. package/dist/src/contract/contract.generated.js +1369 -0
  24. package/dist/src/contract/report.generated.js +866 -0
  25. package/dist/src/dependencies.js +164 -121
  26. package/dist/src/destructuring.js +1 -19
  27. package/dist/src/edges.js +38 -122
  28. package/dist/src/element-access.js +181 -168
  29. package/dist/src/entries/build-scripts.js +222 -0
  30. package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
  31. package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
  32. package/dist/src/entries/conventions.js +740 -0
  33. package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
  34. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
  35. package/dist/src/entries/run-directories.js +77 -0
  36. package/dist/src/entries/sources.js +144 -0
  37. package/dist/src/entries/static-module.js +670 -0
  38. package/dist/src/entries/test-runners.js +650 -0
  39. package/dist/src/entries/workflow-steps.js +345 -0
  40. package/dist/src/enum-group.js +3 -10
  41. package/dist/src/erased-stores.js +4 -6
  42. package/dist/src/exempt-classes.js +1 -63
  43. package/dist/src/exempt.js +21 -66
  44. package/dist/src/exposure.js +400 -0
  45. package/dist/src/extensions.js +37 -0
  46. package/dist/src/facts.js +38 -0
  47. package/dist/src/failure.js +36 -0
  48. package/dist/src/file-facts.js +3 -26
  49. package/dist/src/findings/completion.js +109 -56
  50. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  51. package/dist/src/findings/emitters.js +27 -41
  52. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  53. package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
  54. package/dist/src/findings/interfaces.js +4 -5
  55. package/dist/src/findings/intra-function.js +16 -13
  56. package/dist/src/findings/non-code-artifacts.js +17 -12
  57. package/dist/src/findings/reads-and-writes.js +86 -27
  58. package/dist/src/findings/self-check.js +44 -30
  59. package/dist/src/findings/unused-declarations.js +29 -45
  60. package/dist/src/findings/visibility-narrowing.js +23 -31
  61. package/dist/src/findings-pass.js +13 -21
  62. package/dist/src/framework-lifecycle.js +46 -19
  63. package/dist/src/fs/document.js +52 -0
  64. package/dist/src/fs/manifest.js +67 -0
  65. package/dist/src/fs/tree.js +88 -0
  66. package/dist/src/generated-file.js +174 -28
  67. package/dist/src/git-ignore.js +39 -26
  68. package/dist/src/import-bindings.js +73 -28
  69. package/dist/src/index/sites.js +557 -0
  70. package/dist/src/index.js +2 -2
  71. package/dist/src/indexed-access.js +523 -478
  72. package/dist/src/injection-container.js +2 -2
  73. package/dist/src/interface-satisfaction.js +1 -1
  74. package/dist/src/intra-function-parts.js +63 -43
  75. package/dist/src/inventory/commonjs.js +507 -0
  76. package/dist/src/inventory/enumerate.js +167 -0
  77. package/dist/src/inventory/syntax.js +236 -0
  78. package/dist/src/inventory.js +323 -724
  79. package/dist/src/javascript-file.js +48 -0
  80. package/dist/src/json-document.js +198 -67
  81. package/dist/src/keyof-comparisons.js +126 -107
  82. package/dist/src/kinds.js +3 -366
  83. package/dist/src/{components.js → liveness/components.js} +2 -3
  84. package/dist/src/{graph.js → liveness/graph.js} +52 -28
  85. package/dist/src/liveness/matrix.js +99 -0
  86. package/dist/src/liveness/sweep.js +558 -0
  87. package/dist/src/load/classify.js +289 -0
  88. package/dist/src/load/diagnostics.js +87 -0
  89. package/dist/src/load/discover.js +285 -0
  90. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  91. package/dist/src/load/expected-module.js +136 -0
  92. package/dist/src/load/load.js +27 -0
  93. package/dist/src/load/module-lookup.js +37 -0
  94. package/dist/src/load/package-scope.js +56 -0
  95. package/dist/src/load/plan.js +313 -0
  96. package/dist/src/load/specifiers.js +113 -0
  97. package/dist/src/load/synthesize.js +152 -0
  98. package/dist/src/load/test-globals.js +207 -0
  99. package/dist/src/load/test-joins.js +82 -0
  100. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  101. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  102. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
  103. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  104. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  105. package/dist/src/module-declarations.js +70 -85
  106. package/dist/src/overrides.js +134 -112
  107. package/dist/src/partial.js +2 -1
  108. package/dist/src/paths.js +82 -16
  109. package/dist/src/platform-calls.js +78 -0
  110. package/dist/src/platform-symbols.js +134 -0
  111. package/dist/src/position.js +43 -1
  112. package/dist/src/print.js +11 -79
  113. package/dist/src/product.js +13 -0
  114. package/dist/src/query.js +47 -0
  115. package/dist/src/ref.js +12 -20
  116. package/dist/src/references/read-rule.js +1 -0
  117. package/dist/src/references/read-rules.js +48 -0
  118. package/dist/src/references/sink.js +237 -0
  119. package/dist/src/references/sources.js +450 -0
  120. package/dist/src/references.js +117 -1074
  121. package/dist/src/report-schema.js +51 -0
  122. package/dist/src/report.js +57 -41
  123. package/dist/src/reporters/annotations.js +15 -8
  124. package/dist/src/reporters/sarif.js +16 -10
  125. package/dist/src/reporters/template.js +4 -19
  126. package/dist/src/resolve.js +246 -730
  127. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
  128. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
  129. package/dist/src/roots/manifest.js +216 -0
  130. package/dist/src/roots/published-reach.js +412 -0
  131. package/dist/src/roots/root-set.js +487 -0
  132. package/dist/src/roots/unseen-loads.js +236 -0
  133. package/dist/src/run.js +66 -77
  134. package/dist/src/schema.js +320 -343
  135. package/dist/src/scope.js +38 -115
  136. package/dist/src/serialization-contract.js +601 -22
  137. package/dist/src/session.js +37 -29
  138. package/dist/src/source-files.js +6 -10
  139. package/dist/src/stores.js +4 -2
  140. package/dist/src/suppress-file.js +25 -28
  141. package/dist/src/suppress-inline.js +36 -83
  142. package/dist/src/suppress.js +50 -71
  143. package/dist/src/symbol-keys.js +92 -88
  144. package/dist/src/template-field.js +9 -19
  145. package/dist/src/tests/file-class.js +76 -0
  146. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  147. package/dist/src/{test-support.js → tests/support.js} +5 -12
  148. package/dist/src/text/compare.js +26 -0
  149. package/dist/src/text/glob.js +194 -0
  150. package/dist/src/text/named-files.js +298 -0
  151. package/dist/src/text/yaml.js +684 -0
  152. package/dist/src/type-errors.js +11 -232
  153. package/dist/src/type-parameter-reads.js +178 -139
  154. package/dist/src/unimplemented-callees.js +262 -242
  155. package/dist/src/unwrap.js +23 -0
  156. package/dist/src/usage.js +10 -0
  157. package/dist/src/vendor/unbash/ansi-c.js +132 -0
  158. package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
  159. package/dist/src/vendor/unbash/arithmetic.js +591 -0
  160. package/dist/src/vendor/unbash/assignment.js +131 -0
  161. package/dist/src/vendor/unbash/chars.js +48 -0
  162. package/dist/src/vendor/unbash/command.js +41 -0
  163. package/dist/src/vendor/unbash/expansion.js +80 -0
  164. package/dist/src/vendor/unbash/glob.js +268 -0
  165. package/dist/src/vendor/unbash/heredoc.js +27 -0
  166. package/dist/src/vendor/unbash/internal-types.js +1 -0
  167. package/dist/src/vendor/unbash/lexer.js +4274 -0
  168. package/dist/src/vendor/unbash/limits.js +3 -0
  169. package/dist/src/vendor/unbash/parser.js +1366 -0
  170. package/dist/src/vendor/unbash/parts.js +57 -0
  171. package/dist/src/vendor/unbash/substitution-context.js +8 -0
  172. package/dist/src/vendor/unbash/traversal.js +212 -0
  173. package/dist/src/vendor/unbash/types.js +1 -0
  174. package/dist/src/vendor/unbash/word-value.js +61 -0
  175. package/dist/src/vendor/unbash/word.js +40 -0
  176. package/dist/src/verbs/analyze.js +194 -127
  177. package/dist/src/verbs/describe.js +13 -18
  178. package/dist/src/verbs/explain.js +85 -139
  179. package/dist/src/verbs/print-config.js +2 -1
  180. package/dist/src/verbs/print-projects.js +6 -4
  181. package/dist/src/verbs/print-retained.js +7 -5
  182. package/dist/src/verbs/print-roots.js +4 -2
  183. package/dist/src/verbs/verb.js +1 -5
  184. package/dist/src/verbs/version.js +14 -3
  185. package/jsr.json +2 -1
  186. package/package.json +14 -8
  187. package/src/alias-chain.ts +2 -9
  188. package/src/amd.ts +130 -0
  189. package/src/analysis.ts +424 -650
  190. package/src/augmentations.ts +93 -4
  191. package/src/automatic-types.ts +12 -30
  192. package/src/bindings.ts +460 -0
  193. package/src/calls.ts +338 -46
  194. package/src/commands/held.ts +632 -0
  195. package/src/commands/read.ts +242 -0
  196. package/src/commands/shell.ts +228 -0
  197. package/src/commands/tools.ts +2382 -0
  198. package/src/component-files.ts +4 -2
  199. package/src/component-layer.ts +4 -2
  200. package/src/config.ts +31 -302
  201. package/src/conformance-record.ts +1 -1
  202. package/src/consumers.ts +16 -66
  203. package/src/contextual-uses.ts +66 -34
  204. package/src/contract/config.generated.ts +821 -0
  205. package/src/contract/contract.generated.ts +1452 -0
  206. package/src/contract/report.generated.ts +1241 -0
  207. package/src/dependencies.ts +222 -127
  208. package/src/destructuring.ts +1 -31
  209. package/src/edges.ts +41 -140
  210. package/src/element-access.ts +190 -187
  211. package/src/entries/build-scripts.ts +292 -0
  212. package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
  213. package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
  214. package/src/{conventions.ts → entries/conventions.ts} +367 -583
  215. package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
  216. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
  217. package/src/entries/run-directories.ts +108 -0
  218. package/src/entries/sources.ts +266 -0
  219. package/src/entries/static-module.ts +858 -0
  220. package/src/entries/test-runners.ts +835 -0
  221. package/src/entries/workflow-steps.ts +432 -0
  222. package/src/enum-group.ts +2 -11
  223. package/src/erased-stores.ts +3 -7
  224. package/src/exempt-classes.ts +1 -75
  225. package/src/exempt.ts +70 -98
  226. package/src/exposure.ts +492 -0
  227. package/src/extensions.ts +45 -0
  228. package/src/facts.ts +46 -0
  229. package/src/failure.ts +63 -0
  230. package/src/file-facts.ts +15 -25
  231. package/src/finding.ts +10 -10
  232. package/src/findings/boundary.ts +11 -0
  233. package/src/findings/completion.ts +133 -64
  234. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  235. package/src/findings/emitter.ts +9 -10
  236. package/src/findings/emitters.ts +38 -52
  237. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  238. package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
  239. package/src/findings/interfaces.ts +7 -9
  240. package/src/findings/intra-function.ts +16 -14
  241. package/src/findings/non-code-artifacts.ts +24 -15
  242. package/src/findings/reads-and-writes.ts +118 -41
  243. package/src/findings/self-check.ts +51 -38
  244. package/src/findings/unused-declarations.ts +31 -49
  245. package/src/findings/visibility-narrowing.ts +36 -40
  246. package/src/findings-pass.ts +15 -31
  247. package/src/framework-lifecycle.ts +47 -19
  248. package/src/fs/document.ts +70 -0
  249. package/src/fs/manifest.ts +96 -0
  250. package/src/fs/tree.ts +110 -0
  251. package/src/generated-file.ts +242 -35
  252. package/src/git-ignore.ts +50 -26
  253. package/src/host.ts +12 -5
  254. package/src/import-bindings.ts +98 -29
  255. package/src/index/sites.ts +781 -0
  256. package/src/index.ts +2 -2
  257. package/src/indexed-access.ts +570 -527
  258. package/src/injection-container.ts +2 -2
  259. package/src/interface-satisfaction.ts +2 -2
  260. package/src/intra-function-parts.ts +73 -44
  261. package/src/inventory/commonjs.ts +696 -0
  262. package/src/inventory/enumerate.ts +203 -0
  263. package/src/inventory/syntax.ts +311 -0
  264. package/src/inventory.ts +442 -895
  265. package/src/javascript-file.ts +54 -0
  266. package/src/json-document.ts +241 -76
  267. package/src/keyof-comparisons.ts +133 -122
  268. package/src/kinds.ts +5 -413
  269. package/src/{components.ts → liveness/components.ts} +4 -6
  270. package/src/{graph.ts → liveness/graph.ts} +100 -35
  271. package/src/liveness/matrix.ts +162 -0
  272. package/src/liveness/sweep.ts +855 -0
  273. package/src/load/classify.ts +433 -0
  274. package/src/load/diagnostics.ts +154 -0
  275. package/src/load/discover.ts +471 -0
  276. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  277. package/src/load/expected-module.ts +194 -0
  278. package/src/load/load.ts +73 -0
  279. package/src/load/module-lookup.ts +50 -0
  280. package/src/load/package-scope.ts +74 -0
  281. package/src/load/plan.ts +513 -0
  282. package/src/load/specifiers.ts +171 -0
  283. package/src/load/synthesize.ts +230 -0
  284. package/src/load/test-globals.ts +251 -0
  285. package/src/load/test-joins.ts +98 -0
  286. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  287. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  288. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
  289. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  290. package/src/{workspace.ts → load/workspace.ts} +90 -134
  291. package/src/module-declarations.ts +74 -98
  292. package/src/overrides.ts +162 -134
  293. package/src/partial.ts +3 -2
  294. package/src/paths.ts +92 -16
  295. package/src/platform-calls.ts +119 -0
  296. package/src/platform-symbols.ts +189 -0
  297. package/src/position.ts +44 -1
  298. package/src/print.ts +12 -92
  299. package/src/product.ts +18 -0
  300. package/src/query.ts +92 -0
  301. package/src/ref.ts +12 -20
  302. package/src/references/read-rule.ts +60 -0
  303. package/src/references/read-rules.ts +55 -0
  304. package/src/references/sink.ts +314 -0
  305. package/src/references/sources.ts +632 -0
  306. package/src/references.ts +187 -1450
  307. package/src/report-schema.ts +68 -0
  308. package/src/report.ts +103 -226
  309. package/src/reporters/annotations.ts +22 -11
  310. package/src/reporters/json.ts +1 -1
  311. package/src/reporters/reporter.ts +2 -4
  312. package/src/reporters/reporters.ts +1 -1
  313. package/src/reporters/sarif.ts +29 -16
  314. package/src/reporters/template.ts +4 -20
  315. package/src/reporters/text.ts +3 -3
  316. package/src/resolve.ts +284 -1115
  317. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +27 -29
  318. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
  319. package/src/roots/manifest.ts +303 -0
  320. package/src/roots/published-reach.ts +486 -0
  321. package/src/{roots.ts → roots/root-set.ts} +286 -469
  322. package/src/roots/unseen-loads.ts +345 -0
  323. package/src/run.ts +75 -91
  324. package/src/schema.ts +391 -388
  325. package/src/scope.ts +46 -138
  326. package/src/serialization-contract.ts +769 -23
  327. package/src/session.ts +87 -55
  328. package/src/source-files.ts +6 -11
  329. package/src/stores.ts +15 -3
  330. package/src/suppress-file.ts +24 -33
  331. package/src/suppress-inline.ts +55 -91
  332. package/src/suppress.ts +78 -79
  333. package/src/symbol-keys.ts +104 -107
  334. package/src/template-field.ts +15 -25
  335. package/src/tests/file-class.ts +135 -0
  336. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  337. package/src/{test-support.ts → tests/support.ts} +15 -21
  338. package/src/text/compare.ts +27 -0
  339. package/src/text/glob.ts +210 -0
  340. package/src/text/named-files.ts +388 -0
  341. package/src/text/yaml.ts +747 -0
  342. package/src/type-errors.ts +18 -288
  343. package/src/type-parameter-reads.ts +187 -158
  344. package/src/unimplemented-callees.ts +297 -280
  345. package/src/unwrap.ts +34 -0
  346. package/src/usage.ts +10 -0
  347. package/src/vendor/unbash/LICENSE +15 -0
  348. package/src/vendor/unbash/VENDORED.md +16 -0
  349. package/src/vendor/unbash/ansi-c.ts +132 -0
  350. package/src/vendor/unbash/arithmetic-parts.ts +53 -0
  351. package/src/vendor/unbash/arithmetic.ts +641 -0
  352. package/src/vendor/unbash/assignment.ts +163 -0
  353. package/src/vendor/unbash/chars.ts +48 -0
  354. package/src/vendor/unbash/command.ts +47 -0
  355. package/src/vendor/unbash/expansion.ts +144 -0
  356. package/src/vendor/unbash/glob.ts +284 -0
  357. package/src/vendor/unbash/heredoc.ts +34 -0
  358. package/src/vendor/unbash/internal-types.ts +94 -0
  359. package/src/vendor/unbash/lexer.ts +4352 -0
  360. package/src/vendor/unbash/limits.ts +3 -0
  361. package/src/vendor/unbash/parser.ts +1612 -0
  362. package/src/vendor/unbash/parts.ts +96 -0
  363. package/src/vendor/unbash/substitution-context.ts +20 -0
  364. package/src/vendor/unbash/traversal.ts +182 -0
  365. package/src/vendor/unbash/types.ts +660 -0
  366. package/src/vendor/unbash/word-value.ts +64 -0
  367. package/src/vendor/unbash/word.ts +50 -0
  368. package/src/verbs/analyze.ts +255 -164
  369. package/src/verbs/describe.ts +19 -17
  370. package/src/verbs/explain.ts +93 -169
  371. package/src/verbs/print-config.ts +2 -1
  372. package/src/verbs/print-projects.ts +6 -4
  373. package/src/verbs/print-retained.ts +7 -5
  374. package/src/verbs/print-roots.ts +4 -2
  375. package/src/verbs/verb.ts +2 -8
  376. package/src/verbs/version.ts +15 -3
  377. package/dist/src/base-url.js +0 -18
  378. package/dist/src/conventions.js +0 -937
  379. package/dist/src/discover.js +0 -468
  380. package/dist/src/entry-points.js +0 -529
  381. package/dist/src/glob.js +0 -65
  382. package/dist/src/manifest.js +0 -165
  383. package/dist/src/matrix.js +0 -246
  384. package/dist/src/pnpm-workspace.js +0 -120
  385. package/dist/src/roots.js +0 -672
  386. package/dist/src/setup-failure.js +0 -23
  387. package/dist/src/sweep.js +0 -224
  388. package/dist/src/test-joins.js +0 -101
  389. package/dist/src/version.js +0 -7
  390. package/dist/src/workflow-steps.js +0 -185
  391. package/src/base-url.ts +0 -24
  392. package/src/discover.ts +0 -653
  393. package/src/entry-points.ts +0 -687
  394. package/src/glob.ts +0 -67
  395. package/src/manifest.ts +0 -234
  396. package/src/matrix.ts +0 -423
  397. package/src/pnpm-workspace.ts +0 -135
  398. package/src/setup-failure.ts +0 -39
  399. package/src/sweep.ts +0 -347
  400. package/src/test-joins.ts +0 -120
  401. package/src/version.ts +0 -7
  402. package/src/workflow-steps.ts +0 -216
@@ -10,8 +10,10 @@ import {
10
10
  isCaseClause,
11
11
  isElementAccessExpression,
12
12
  isIdentifier,
13
- isParenthesizedExpression,
13
+ isNoSubstitutionTemplateLiteral,
14
+ isNumericLiteral,
14
15
  isPropertyAccessExpression,
16
+ isStringLiteral,
15
17
  isSwitchStatement,
16
18
  isTypeOperatorNode,
17
19
  SyntaxKind,
@@ -21,12 +23,9 @@ import {
21
23
  type TypeNode,
22
24
  } from "@typescript/native/ast";
23
25
  import { SymbolFlags, type Type } from "@typescript/native/sync";
24
- import type { AliasChains } from "./alias-chain.ts";
25
- import { nodeKey, type Inventory } from "./inventory.ts";
26
- import { renderPosition } from "./position.ts";
27
26
  import { UNANSWERED } from "./query.ts";
28
- import type { Reference } from "./references.ts";
29
- import type { ProjectView } from "./session.ts";
27
+ import type { Read, ReadRule } from "./references/read-rule.ts";
28
+ import { parenthesesRemoved } from "./unwrap.ts";
30
29
 
31
30
  /** The operators that compare their operands for equality. */
32
31
  const EQUALITIES: ReadonlySet<SyntaxKind> = new Set([
@@ -44,13 +43,9 @@ interface Comparison {
44
43
  readonly other: Expression;
45
44
  }
46
45
 
47
- function unwrapped(node: Expression): Expression {
48
- return isParenthesizedExpression(node) ? unwrapped(node.expression) : node;
49
- }
50
-
51
46
  /** The name node an operand's symbol is read at: an identifier, or a property access's name. */
52
47
  function nameOf(node: Expression): Node | undefined {
53
- const at = unwrapped(node);
48
+ const at = parenthesesRemoved(node);
54
49
  if (isIdentifier(at)) {
55
50
  return at;
56
51
  }
@@ -87,125 +82,141 @@ function literalNames(parts: readonly Type[]): readonly string[] {
87
82
  }
88
83
 
89
84
  /**
90
- * The references the key comparisons of one project's own files make to the members their
91
- * literal side names, each made by the declaration holding the comparison.
85
+ * The reads the key comparisons of a side's files make of the members their literal side
86
+ * names, each made by the declaration holding the comparison. A question the checker leaves
87
+ * unanswered holds what its answer could have read.
92
88
  */
93
- export function keyofComparisonReferences<Brand>(
94
- project: ProjectView<Brand>,
95
- held: Inventory,
96
- chains: AliasChains,
97
- root: string,
98
- testFiles: ReadonlySet<string>,
99
- ): readonly Reference[] {
100
- const queries = project.queries;
101
- const comparisons: Comparison[] = [];
102
- for (const file of project.ownSourceFiles()) {
103
- const fileId = held.declarations.get(nodeKey(file, file));
104
- if (fileId === undefined) {
105
- continue;
106
- }
107
- const visit = (node: Node, from: string): void => {
108
- const holder = held.declarations.get(nodeKey(file, node)) ?? from;
109
- if (isBinaryExpression(node) && EQUALITIES.has(node.operatorToken.kind)) {
110
- comparisons.push({ file, from: holder, keyed: node.left, other: node.right });
111
- comparisons.push({ file, from: holder, keyed: node.right, other: node.left });
112
- }
113
- if (isSwitchStatement(node)) {
114
- for (const clause of node.caseBlock.clauses) {
115
- if (isCaseClause(clause)) {
116
- comparisons.push({
117
- file,
118
- from: holder,
119
- keyed: node.expression,
120
- other: clause.expression,
89
+ export const keyofComparisons: ReadRule = {
90
+ start() {
91
+ const comparisons: Comparison[] = [];
92
+ return {
93
+ visit(node, { file, from }) {
94
+ if (isBinaryExpression(node) && EQUALITIES.has(node.operatorToken.kind)) {
95
+ comparisons.push({ file, from, keyed: node.left, other: node.right });
96
+ comparisons.push({ file, from, keyed: node.right, other: node.left });
97
+ }
98
+ if (isSwitchStatement(node)) {
99
+ for (const clause of node.caseBlock.clauses) {
100
+ if (isCaseClause(clause)) {
101
+ comparisons.push({ file, from, keyed: node.expression, other: clause.expression });
102
+ }
103
+ }
104
+ }
105
+ },
106
+ reads({ project, chains }) {
107
+ const queries = project.queries;
108
+ const found: Read[] = [];
109
+ const named = comparisons.flatMap((one) => {
110
+ const name = nameOf(one.keyed);
111
+ return name === undefined || isElementAccessExpression(parenthesesRemoved(one.other))
112
+ ? []
113
+ : [{ ...one, name }];
114
+ });
115
+ if (named.length === 0) {
116
+ return found;
117
+ }
118
+ // The operand's own declaration states the key type, which the checker resolves to
119
+ // the literals it admits and so no longer names the type the key indexes.
120
+ const symbols = queries.symbolsAt(named.map((one) => one.name));
121
+ const keyed = named.flatMap((one, at) => {
122
+ const asked = symbols[at];
123
+ const symbol =
124
+ asked === UNANSWERED || asked === undefined || (asked.flags & SymbolFlags.Alias) === 0
125
+ ? asked
126
+ : queries.aliased(asked);
127
+ if (symbol === UNANSWERED) {
128
+ const text = literalText(one.other);
129
+ found.push({
130
+ kind: "held",
131
+ from: one.from,
132
+ ...(text === undefined ? {} : { names: [text] }),
121
133
  });
134
+ return [];
135
+ }
136
+ if (symbol === undefined) {
137
+ return [];
122
138
  }
139
+ const operands = symbol.declarations.flatMap((handle) => {
140
+ const declared = (
141
+ project.declarationAt(handle)?.node as { readonly type?: TypeNode } | undefined
142
+ )?.type;
143
+ return declared === undefined ? [] : keyofOperands(declared);
144
+ });
145
+ return operands.length === 0 ? [] : [{ ...one, operands }];
146
+ });
147
+ if (keyed.length === 0) {
148
+ return found;
123
149
  }
124
- }
125
- node.forEachChild((child) => {
126
- visit(child, holder);
127
- });
128
- };
129
- file.forEachChild((child) => {
130
- visit(child, fileId);
131
- });
132
- }
133
- const named = comparisons.flatMap((one) => {
134
- const name = nameOf(one.keyed);
135
- return name === undefined || isElementAccessExpression(unwrapped(one.other))
136
- ? []
137
- : [{ ...one, name }];
138
- });
139
- if (named.length === 0) {
140
- return [];
141
- }
142
-
143
- // The operand's own declaration states the key type, which the checker resolves to
144
- // the literals it admits and so no longer names the type the key indexes.
145
- const symbols = queries.symbolsAt(named.map((one) => one.name));
146
- const keyed = named.flatMap((one, at) => {
147
- const asked = symbols[at];
148
- const symbol =
149
- asked === UNANSWERED || asked === undefined || (asked.flags & SymbolFlags.Alias) === 0
150
- ? asked
151
- : queries.aliased(asked);
152
- if (symbol === UNANSWERED || symbol === undefined) {
153
- return [];
154
- }
155
- const operands = symbol.declarations.flatMap((handle) => {
156
- const declared = (
157
- project.declarationAt(handle)?.node as { readonly type?: TypeNode } | undefined
158
- )?.type;
159
- return declared === undefined ? [] : keyofOperands(declared);
160
- });
161
- return operands.length === 0 ? [] : [{ ...one, operands }];
162
- });
163
- if (keyed.length === 0) {
164
- return [];
165
- }
166
- const nodes = keyed.flatMap((one) => [one.other, ...one.operands]);
167
- const types = queries.typesAt(nodes);
168
- const typeOf = new Map<Node, Type>();
169
- nodes.forEach((node, at) => {
170
- const type = types[at];
171
- if (type !== UNANSWERED && type !== undefined) {
172
- typeOf.set(node, type);
173
- }
174
- });
175
- const partsOf = (type: Type): readonly Type[] => {
176
- const parts = queries.constituents(type);
177
- return parts === UNANSWERED ? [type] : parts;
178
- };
179
-
180
- const found: Reference[] = [];
181
- for (const one of keyed) {
182
- const literal = typeOf.get(one.other);
183
- const names = literal === undefined ? [] : literalNames(partsOf(literal));
184
- if (names.length === 0) {
185
- continue;
186
- }
187
- const position = renderPosition(one.file, root, one.other.getStart());
188
- for (const operand of one.operands) {
189
- const object = typeOf.get(operand);
190
- for (const part of object === undefined ? [] : partsOf(object)) {
191
- const properties = queries.propertiesOf(part);
192
- for (const property of properties === UNANSWERED ? [] : properties) {
193
- if (!names.includes(property.name)) {
194
- continue;
150
+ const nodes = keyed.flatMap((one) => [one.other, ...one.operands]);
151
+ const types = queries.typesAt(nodes);
152
+ const typeOf = new Map<Node, Type | typeof UNANSWERED>();
153
+ nodes.forEach((node, at) => {
154
+ const type = types[at];
155
+ if (type !== undefined) {
156
+ typeOf.set(node, type);
195
157
  }
196
- for (const to of chains.declarationsOf(property)) {
158
+ });
159
+ const partsOf = (type: Type): readonly Type[] => {
160
+ const parts = queries.constituents(type);
161
+ return parts === UNANSWERED ? [type] : parts;
162
+ };
163
+ for (const one of keyed) {
164
+ const literal = typeOf.get(one.other);
165
+ const objects = one.operands.map((operand) => typeOf.get(operand));
166
+ if (literal === UNANSWERED) {
167
+ const known = objects.filter((type) => type !== undefined && type !== UNANSWERED);
197
168
  found.push({
169
+ kind: "held",
198
170
  from: one.from,
199
- to,
200
- position,
201
- use: "read",
202
- resolution: "keyed",
203
- test: testFiles.has(position.path),
171
+ types: known.flatMap(partsOf),
172
+ ...(known.length < objects.length ? { members: true as const } : {}),
204
173
  });
174
+ continue;
175
+ }
176
+ const names = literal === undefined ? [] : literalNames(partsOf(literal));
177
+ if (names.length === 0) {
178
+ continue;
179
+ }
180
+ for (const object of objects) {
181
+ if (object === UNANSWERED) {
182
+ found.push({ kind: "held", from: one.from, names });
183
+ continue;
184
+ }
185
+ for (const part of object === undefined ? [] : partsOf(object)) {
186
+ const properties = queries.propertiesOf(part);
187
+ if (properties === UNANSWERED) {
188
+ found.push({ kind: "held", from: one.from, names });
189
+ continue;
190
+ }
191
+ for (const property of properties) {
192
+ if (!names.includes(property.name)) {
193
+ continue;
194
+ }
195
+ for (const to of chains.declarationsOf(property)) {
196
+ found.push({
197
+ kind: "named",
198
+ from: one.from,
199
+ to,
200
+ file: one.file,
201
+ at: one.other,
202
+ use: "read",
203
+ via: "keyed",
204
+ });
205
+ }
206
+ }
207
+ }
205
208
  }
206
209
  }
207
- }
208
- }
209
- }
210
- return found;
210
+ return found;
211
+ },
212
+ };
213
+ },
214
+ };
215
+
216
+ /** The text a string or number literal operand spells, where it is one. */
217
+ function literalText(node: Expression): string | undefined {
218
+ const at = parenthesesRemoved(node);
219
+ return isStringLiteral(at) || isNumericLiteral(at) || isNoSubstitutionTemplateLiteral(at)
220
+ ? at.text
221
+ : undefined;
211
222
  }