@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
@@ -12,6 +12,7 @@ import {
12
12
  isIdentifier,
13
13
  isNewExpression,
14
14
  isPropertyAccessExpression,
15
+ isSourceFile,
15
16
  isTypeParameterDeclaration,
16
17
  SyntaxKind,
17
18
  type CallExpression,
@@ -21,12 +22,8 @@ import {
21
22
  type SourceFile,
22
23
  } from "@typescript/native/ast";
23
24
  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
- import { isAnswered } from "./query.ts";
28
- import type { Reference } from "./references.ts";
29
- import type { ProjectView } from "./session.ts";
25
+ import { isAnswered, UNANSWERED } from "./query.ts";
26
+ import type { Read as RuleRead, ReadRule } from "./references/read-rule.ts";
30
27
 
31
28
  /** How deep a parameter's type is matched against the type a call passes: `readonly T[]` is one level. */
32
29
  const MATCH_DEPTH = 3;
@@ -61,167 +58,199 @@ function assignedTo(access: PropertyAccessExpression): boolean {
61
58
  );
62
59
  }
63
60
 
64
- /**
65
- * The references the reads through type-parameter-typed values of one project's own files
66
- * make to the members of the types its calls pass, each made by the declaration holding
67
- * the read.
68
- */
69
- export function typeParameterReads<Brand>(
70
- project: ProjectView<Brand>,
71
- held: Inventory,
72
- chains: AliasChains,
73
- root: string,
74
- testFiles: ReadonlySet<string>,
75
- ): readonly Reference[] {
76
- const queries = project.queries;
77
- const reads: Read[] = [];
78
- const calls: (CallExpression | NewExpression)[] = [];
79
- for (const file of project.ownSourceFiles()) {
80
- const fileId = held.declarations.get(nodeKey(file, file));
81
- if (fileId === undefined) {
82
- continue;
61
+ /** Whether one node is written inside a declaration that declares type parameters, itself included. */
62
+ function inGeneric(node: Node): boolean {
63
+ for (let at = node; !isSourceFile(at); at = at.parent) {
64
+ if ((at as { readonly typeParameters?: readonly Node[] }).typeParameters !== undefined) {
65
+ return true;
83
66
  }
84
- const visit = (node: Node, from: string, generic: boolean): void => {
85
- const holder = held.declarations.get(nodeKey(file, node)) ?? from;
86
- const inside =
87
- generic ||
88
- (node as { readonly typeParameters?: readonly Node[] }).typeParameters !== undefined;
89
- if (
90
- inside &&
91
- isPropertyAccessExpression(node) &&
92
- isIdentifier(node.name) &&
93
- !assignedTo(node)
94
- ) {
95
- reads.push({ file, from: holder, access: node });
96
- }
97
- if (isCallExpression(node) || isNewExpression(node)) {
98
- calls.push(node);
99
- }
100
- node.forEachChild((child) => {
101
- visit(child, holder, inside);
102
- });
103
- };
104
- file.forEachChild((child) => {
105
- visit(child, fileId, false);
106
- });
107
- }
108
- if (reads.length === 0) {
109
- return [];
110
67
  }
68
+ return false;
69
+ }
111
70
 
112
- // The reads whose receiver the checker types as a type parameter, by the generic declaring it.
113
- const receivers = queries.typesAt(reads.map((read) => read.access.expression));
114
- const byGeneric = new Map<Generic, { read: Read; parameter: Type }[]>();
115
- reads.forEach((read, at) => {
116
- const type = receivers[at];
117
- if (type === undefined || !isAnswered(type) || !type.isTypeParameter()) {
118
- return;
119
- }
120
- const symbol = queries.symbolOfType(type);
121
- const declaration =
122
- symbol === undefined || !isAnswered(symbol)
123
- ? undefined
124
- : symbol.declarations
125
- .map((handle) => project.declarationAt(handle)?.node)
126
- .find((node) => node !== undefined && isTypeParameterDeclaration(node));
127
- const generic = declaration?.parent as Generic | undefined;
128
- if (generic !== undefined) {
129
- byGeneric.set(generic, [...(byGeneric.get(generic) ?? []), { read, parameter: type }]);
130
- }
131
- });
132
- if (byGeneric.size === 0) {
133
- return [];
134
- }
71
+ /**
72
+ * The reads the reads through type-parameter-typed values of a side's files make of the
73
+ * members of the types its calls pass, each made by the declaration holding the read. A
74
+ * question the checker leaves unanswered holds every member the read's name spells.
75
+ */
76
+ export const typeParameterReads: ReadRule = {
77
+ start() {
78
+ const reads: Read[] = [];
79
+ const calls: (CallExpression | NewExpression)[] = [];
80
+ return {
81
+ visit(node, { file, from }) {
82
+ if (
83
+ isPropertyAccessExpression(node) &&
84
+ isIdentifier(node.name) &&
85
+ !assignedTo(node) &&
86
+ inGeneric(node)
87
+ ) {
88
+ reads.push({ file, from, access: node });
89
+ }
90
+ if (isCallExpression(node) || isNewExpression(node)) {
91
+ calls.push(node);
92
+ }
93
+ },
94
+ reads({ project, chains }) {
95
+ const out: RuleRead[] = [];
96
+ if (reads.length === 0) {
97
+ return out;
98
+ }
99
+ const queries = project.queries;
100
+ const hold = (read: Read): void => {
101
+ out.push({ kind: "held", from: read.from, names: [read.access.name.text] });
102
+ };
103
+ // The reads whose receiver the checker types as a type parameter, by the generic declaring it.
104
+ const receivers = queries.typesAt(reads.map((read) => read.access.expression));
105
+ const byGeneric = new Map<Generic, { read: Read; parameter: Type }[]>();
106
+ reads.forEach((read, at) => {
107
+ const type = receivers[at];
108
+ if (type === UNANSWERED) {
109
+ hold(read);
110
+ return;
111
+ }
112
+ if (type?.isTypeParameter() !== true) {
113
+ return;
114
+ }
115
+ const symbol = queries.symbolOfType(type);
116
+ if (symbol === UNANSWERED) {
117
+ hold(read);
118
+ return;
119
+ }
120
+ const declaration =
121
+ symbol === undefined
122
+ ? undefined
123
+ : symbol.declarations
124
+ .map((handle) => project.declarationAt(handle)?.node)
125
+ .find((node) => node !== undefined && isTypeParameterDeclaration(node));
126
+ const generic = declaration?.parent as Generic | undefined;
127
+ if (generic !== undefined) {
128
+ byGeneric.set(generic, [...(byGeneric.get(generic) ?? []), { read, parameter: type }]);
129
+ }
130
+ });
131
+ if (byGeneric.size === 0) {
132
+ return out;
133
+ }
135
134
 
136
- /** The types `instantiated` holds where `declared` holds `parameter`, matched part for part. */
137
- const passedFor = (
138
- parameter: Type,
139
- declared: Type,
140
- instantiated: Type,
141
- depth: number,
142
- ): readonly Type[] => {
143
- if (declared.id === parameter.id) {
144
- return [instantiated];
145
- }
146
- if (depth >= MATCH_DEPTH) {
147
- return [];
148
- }
149
- const a = queries.typeArguments(declared);
150
- const b = queries.typeArguments(instantiated);
151
- if (!isAnswered(a) || !isAnswered(b) || a.length !== b.length) {
152
- return [];
153
- }
154
- return a.flatMap((one, at) => {
155
- const other = b[at];
156
- return other === undefined ? [] : passedFor(parameter, one, other, depth + 1);
157
- });
158
- };
135
+ /** The types `instantiated` holds where `declared` holds `parameter`, matched part for part. */
136
+ const passedFor = (
137
+ read: Read,
138
+ parameter: Type,
139
+ declared: Type,
140
+ instantiated: Type,
141
+ depth: number,
142
+ ): readonly Type[] => {
143
+ if (declared.id === parameter.id) {
144
+ return [instantiated];
145
+ }
146
+ if (depth >= MATCH_DEPTH) {
147
+ return [];
148
+ }
149
+ const a = queries.typeArguments(declared);
150
+ const b = queries.typeArguments(instantiated);
151
+ if (!isAnswered(a) || !isAnswered(b)) {
152
+ hold(read);
153
+ return [];
154
+ }
155
+ if (a.length !== b.length) {
156
+ return [];
157
+ }
158
+ return a.flatMap((one, at) => {
159
+ const other = b[at];
160
+ return other === undefined ? [] : passedFor(read, parameter, one, other, depth + 1);
161
+ });
162
+ };
159
163
 
160
- // Only a call spelling a generic's name is resolved: one request each.
161
- const spelled = new Set([...byGeneric.keys()].flatMap((generic) => nameOf(generic) ?? []));
162
- const found = new Map<string, Reference>();
163
- for (const call of calls) {
164
- const callee = call.expression;
165
- const written = isIdentifier(callee)
166
- ? callee.text
167
- : isPropertyAccessExpression(callee) && isIdentifier(callee.name)
168
- ? callee.name.text
169
- : undefined;
170
- if (written === undefined || !spelled.has(written)) {
171
- continue;
172
- }
173
- const resolved = queries.resolvedSignature(call);
174
- if (resolved === undefined || !isAnswered(resolved) || resolved.declaration === undefined) {
175
- continue;
176
- }
177
- const generic = project.declarationAt(resolved.declaration)?.node as Generic | undefined;
178
- const pending = generic === undefined ? undefined : byGeneric.get(generic);
179
- const declared = pending === undefined ? undefined : queries.genericOf(resolved);
180
- if (pending === undefined || declared === undefined || !isAnswered(declared)) {
181
- continue;
182
- }
183
- const count = (generic?.parameters ?? []).length;
184
- for (const { read, parameter } of pending) {
185
- const passed: Type[] = [];
186
- for (let at = 0; at < count; at += 1) {
187
- const own = queries.parameterType(declared, at);
188
- const given = queries.typeAtPosition(resolved, at);
189
- if (own !== undefined && isAnswered(own) && isAnswered(given)) {
190
- passed.push(...passedFor(parameter, own, given, 0));
164
+ // Only a call spelling a generic's name is resolved: one request each.
165
+ const bySpelling = new Map<string, Read[]>();
166
+ for (const [generic, pending] of byGeneric) {
167
+ const name = nameOf(generic);
168
+ if (name !== undefined) {
169
+ bySpelling.set(name, [
170
+ ...(bySpelling.get(name) ?? []),
171
+ ...pending.map((one) => one.read),
172
+ ]);
173
+ }
191
174
  }
192
- }
193
- const name = read.access.name.text;
194
- const position = renderPosition(read.file, root, read.access.name.getStart());
195
- for (const type of passed) {
196
- const parts = type.isUnionType() ? queries.constituents(type) : [type];
197
- for (const part of isAnswered(parts) ? parts : []) {
198
- const owner = queries.symbolOfType(part);
199
- if (
200
- !isAnswered(owner) ||
201
- owner === undefined ||
202
- (owner.flags & SymbolFlags.Class) !== 0
203
- ) {
175
+ const found = new Map<string, RuleRead>();
176
+ for (const call of calls) {
177
+ const callee = call.expression;
178
+ const written = isIdentifier(callee)
179
+ ? callee.text
180
+ : isPropertyAccessExpression(callee) && isIdentifier(callee.name)
181
+ ? callee.name.text
182
+ : undefined;
183
+ const spelledBy = written === undefined ? undefined : bySpelling.get(written);
184
+ if (spelledBy === undefined) {
204
185
  continue;
205
186
  }
206
- const properties = queries.propertiesOf(part);
207
- for (const property of isAnswered(properties) ? properties : []) {
208
- if (property.name !== name) {
209
- continue;
187
+ const resolved = queries.resolvedSignature(call);
188
+ if (resolved === UNANSWERED) {
189
+ spelledBy.forEach(hold);
190
+ continue;
191
+ }
192
+ if (resolved?.declaration === undefined) {
193
+ continue;
194
+ }
195
+ const generic = project.declarationAt(resolved.declaration)?.node as Generic | undefined;
196
+ const pending = generic === undefined ? undefined : byGeneric.get(generic);
197
+ const declared = pending === undefined ? undefined : queries.genericOf(resolved);
198
+ if (declared === UNANSWERED) {
199
+ pending?.forEach((one) => {
200
+ hold(one.read);
201
+ });
202
+ continue;
203
+ }
204
+ if (pending === undefined || declared === undefined) {
205
+ continue;
206
+ }
207
+ const count = (generic?.parameters ?? []).length;
208
+ for (const { read, parameter } of pending) {
209
+ const passed: Type[] = [];
210
+ for (let at = 0; at < count; at += 1) {
211
+ const own = queries.parameterType(declared, at);
212
+ const given = queries.typeAtPosition(resolved, at);
213
+ if (own === UNANSWERED || given === UNANSWERED) {
214
+ hold(read);
215
+ } else if (own !== undefined) {
216
+ passed.push(...passedFor(read, parameter, own, given, 0));
217
+ }
210
218
  }
211
- for (const to of chains.declarationsOf(property)) {
212
- found.set(`${read.from}\u0000${to}\u0000${String(read.access.name.pos)}`, {
213
- from: read.from,
214
- to,
215
- position,
216
- use: "read",
217
- resolution: "batch",
218
- test: testFiles.has(position.path),
219
- });
219
+ const name = read.access.name.text;
220
+ for (const type of passed) {
221
+ const parts = type.isUnionType() ? queries.constituents(type) : [type];
222
+ for (const part of isAnswered(parts) ? parts : [type]) {
223
+ const owner = queries.symbolOfType(part);
224
+ const properties = queries.propertiesOf(part);
225
+ if (owner === UNANSWERED || properties === UNANSWERED) {
226
+ hold(read);
227
+ continue;
228
+ }
229
+ if (owner === undefined || (owner.flags & SymbolFlags.Class) !== 0) {
230
+ continue;
231
+ }
232
+ for (const property of properties) {
233
+ if (property.name !== name) {
234
+ continue;
235
+ }
236
+ for (const to of chains.declarationsOf(property)) {
237
+ found.set(`${read.from}\u0000${to}\u0000${String(read.access.name.pos)}`, {
238
+ kind: "named",
239
+ from: read.from,
240
+ to,
241
+ file: read.file,
242
+ at: read.access.name,
243
+ use: "read",
244
+ via: "batch",
245
+ });
246
+ }
247
+ }
248
+ }
220
249
  }
221
250
  }
222
251
  }
223
- }
224
- }
225
- }
226
- return [...found.values()];
227
- }
252
+ return [...out, ...found.values()];
253
+ },
254
+ };
255
+ },
256
+ };