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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/README.md +3 -1
  2. package/THIRD_PARTY_NOTICES.md +27 -0
  3. package/dist/bin/mapper-connection.js +2 -1
  4. package/dist/bin/node-host.js +24 -5
  5. package/dist/src/alias-chain.js +2 -7
  6. package/dist/src/amd.js +81 -0
  7. package/dist/src/analysis.js +269 -432
  8. package/dist/src/augmentations.js +64 -3
  9. package/dist/src/automatic-types.js +10 -29
  10. package/dist/src/bindings.js +382 -0
  11. package/dist/src/calls.js +279 -43
  12. package/dist/src/commands/held.js +499 -0
  13. package/dist/src/commands/read.js +161 -0
  14. package/dist/src/commands/shell.js +169 -0
  15. package/dist/src/commands/tools.js +1847 -0
  16. package/dist/src/component-files.js +3 -2
  17. package/dist/src/component-layer.js +4 -2
  18. package/dist/src/config.js +6 -82
  19. package/dist/src/conformance-record.js +1 -1
  20. package/dist/src/consumers.js +10 -38
  21. package/dist/src/contextual-uses.js +57 -26
  22. package/dist/src/contract/config.generated.js +561 -0
  23. package/dist/src/contract/contract.generated.js +1369 -0
  24. package/dist/src/contract/report.generated.js +866 -0
  25. package/dist/src/dependencies.js +164 -121
  26. package/dist/src/destructuring.js +1 -19
  27. package/dist/src/edges.js +38 -122
  28. package/dist/src/element-access.js +181 -168
  29. package/dist/src/entries/build-scripts.js +222 -0
  30. package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
  31. package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
  32. package/dist/src/entries/conventions.js +740 -0
  33. package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
  34. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
  35. package/dist/src/entries/run-directories.js +77 -0
  36. package/dist/src/entries/sources.js +144 -0
  37. package/dist/src/entries/static-module.js +670 -0
  38. package/dist/src/entries/test-runners.js +650 -0
  39. package/dist/src/entries/workflow-steps.js +345 -0
  40. package/dist/src/enum-group.js +3 -10
  41. package/dist/src/erased-stores.js +4 -6
  42. package/dist/src/exempt-classes.js +1 -63
  43. package/dist/src/exempt.js +21 -66
  44. package/dist/src/exposure.js +400 -0
  45. package/dist/src/extensions.js +37 -0
  46. package/dist/src/facts.js +38 -0
  47. package/dist/src/failure.js +36 -0
  48. package/dist/src/file-facts.js +3 -26
  49. package/dist/src/findings/completion.js +109 -56
  50. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  51. package/dist/src/findings/emitters.js +27 -41
  52. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  53. package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
  54. package/dist/src/findings/interfaces.js +4 -5
  55. package/dist/src/findings/intra-function.js +16 -13
  56. package/dist/src/findings/non-code-artifacts.js +17 -12
  57. package/dist/src/findings/reads-and-writes.js +86 -27
  58. package/dist/src/findings/self-check.js +44 -30
  59. package/dist/src/findings/unused-declarations.js +29 -45
  60. package/dist/src/findings/visibility-narrowing.js +23 -31
  61. package/dist/src/findings-pass.js +13 -21
  62. package/dist/src/framework-lifecycle.js +46 -19
  63. package/dist/src/fs/document.js +52 -0
  64. package/dist/src/fs/manifest.js +67 -0
  65. package/dist/src/fs/tree.js +88 -0
  66. package/dist/src/generated-file.js +174 -28
  67. package/dist/src/git-ignore.js +39 -26
  68. package/dist/src/import-bindings.js +73 -28
  69. package/dist/src/index/sites.js +557 -0
  70. package/dist/src/index.js +2 -2
  71. package/dist/src/indexed-access.js +523 -478
  72. package/dist/src/injection-container.js +2 -2
  73. package/dist/src/interface-satisfaction.js +1 -1
  74. package/dist/src/intra-function-parts.js +63 -43
  75. package/dist/src/inventory/commonjs.js +507 -0
  76. package/dist/src/inventory/enumerate.js +167 -0
  77. package/dist/src/inventory/syntax.js +236 -0
  78. package/dist/src/inventory.js +323 -724
  79. package/dist/src/javascript-file.js +48 -0
  80. package/dist/src/json-document.js +198 -67
  81. package/dist/src/keyof-comparisons.js +126 -107
  82. package/dist/src/kinds.js +3 -366
  83. package/dist/src/{components.js → liveness/components.js} +2 -3
  84. package/dist/src/{graph.js → liveness/graph.js} +52 -28
  85. package/dist/src/liveness/matrix.js +99 -0
  86. package/dist/src/liveness/sweep.js +558 -0
  87. package/dist/src/load/classify.js +289 -0
  88. package/dist/src/load/diagnostics.js +87 -0
  89. package/dist/src/load/discover.js +285 -0
  90. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  91. package/dist/src/load/expected-module.js +136 -0
  92. package/dist/src/load/load.js +27 -0
  93. package/dist/src/load/module-lookup.js +37 -0
  94. package/dist/src/load/package-scope.js +56 -0
  95. package/dist/src/load/plan.js +313 -0
  96. package/dist/src/load/specifiers.js +113 -0
  97. package/dist/src/load/synthesize.js +152 -0
  98. package/dist/src/load/test-globals.js +207 -0
  99. package/dist/src/load/test-joins.js +82 -0
  100. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  101. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  102. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
  103. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  104. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  105. package/dist/src/module-declarations.js +70 -85
  106. package/dist/src/overrides.js +134 -112
  107. package/dist/src/partial.js +2 -1
  108. package/dist/src/paths.js +82 -16
  109. package/dist/src/platform-calls.js +78 -0
  110. package/dist/src/platform-symbols.js +134 -0
  111. package/dist/src/position.js +43 -1
  112. package/dist/src/print.js +11 -79
  113. package/dist/src/product.js +13 -0
  114. package/dist/src/query.js +47 -0
  115. package/dist/src/ref.js +12 -20
  116. package/dist/src/references/read-rule.js +1 -0
  117. package/dist/src/references/read-rules.js +48 -0
  118. package/dist/src/references/sink.js +237 -0
  119. package/dist/src/references/sources.js +450 -0
  120. package/dist/src/references.js +117 -1074
  121. package/dist/src/report-schema.js +51 -0
  122. package/dist/src/report.js +57 -41
  123. package/dist/src/reporters/annotations.js +15 -8
  124. package/dist/src/reporters/sarif.js +16 -10
  125. package/dist/src/reporters/template.js +4 -19
  126. package/dist/src/resolve.js +246 -730
  127. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
  128. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
  129. package/dist/src/roots/manifest.js +216 -0
  130. package/dist/src/roots/published-reach.js +412 -0
  131. package/dist/src/roots/root-set.js +487 -0
  132. package/dist/src/roots/unseen-loads.js +236 -0
  133. package/dist/src/run.js +66 -77
  134. package/dist/src/schema.js +320 -343
  135. package/dist/src/scope.js +38 -115
  136. package/dist/src/serialization-contract.js +601 -22
  137. package/dist/src/session.js +37 -29
  138. package/dist/src/source-files.js +6 -10
  139. package/dist/src/stores.js +4 -2
  140. package/dist/src/suppress-file.js +25 -28
  141. package/dist/src/suppress-inline.js +36 -83
  142. package/dist/src/suppress.js +50 -71
  143. package/dist/src/symbol-keys.js +92 -88
  144. package/dist/src/template-field.js +9 -19
  145. package/dist/src/tests/file-class.js +76 -0
  146. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  147. package/dist/src/{test-support.js → tests/support.js} +5 -12
  148. package/dist/src/text/compare.js +26 -0
  149. package/dist/src/text/glob.js +194 -0
  150. package/dist/src/text/named-files.js +298 -0
  151. package/dist/src/text/yaml.js +684 -0
  152. package/dist/src/type-errors.js +11 -232
  153. package/dist/src/type-parameter-reads.js +178 -139
  154. package/dist/src/unimplemented-callees.js +262 -242
  155. package/dist/src/unwrap.js +23 -0
  156. package/dist/src/usage.js +10 -0
  157. package/dist/src/vendor/unbash/ansi-c.js +132 -0
  158. package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
  159. package/dist/src/vendor/unbash/arithmetic.js +591 -0
  160. package/dist/src/vendor/unbash/assignment.js +131 -0
  161. package/dist/src/vendor/unbash/chars.js +48 -0
  162. package/dist/src/vendor/unbash/command.js +41 -0
  163. package/dist/src/vendor/unbash/expansion.js +80 -0
  164. package/dist/src/vendor/unbash/glob.js +268 -0
  165. package/dist/src/vendor/unbash/heredoc.js +27 -0
  166. package/dist/src/vendor/unbash/internal-types.js +1 -0
  167. package/dist/src/vendor/unbash/lexer.js +4274 -0
  168. package/dist/src/vendor/unbash/limits.js +3 -0
  169. package/dist/src/vendor/unbash/parser.js +1366 -0
  170. package/dist/src/vendor/unbash/parts.js +57 -0
  171. package/dist/src/vendor/unbash/substitution-context.js +8 -0
  172. package/dist/src/vendor/unbash/traversal.js +212 -0
  173. package/dist/src/vendor/unbash/types.js +1 -0
  174. package/dist/src/vendor/unbash/word-value.js +61 -0
  175. package/dist/src/vendor/unbash/word.js +40 -0
  176. package/dist/src/verbs/analyze.js +194 -127
  177. package/dist/src/verbs/describe.js +13 -18
  178. package/dist/src/verbs/explain.js +85 -139
  179. package/dist/src/verbs/print-config.js +2 -1
  180. package/dist/src/verbs/print-projects.js +6 -4
  181. package/dist/src/verbs/print-retained.js +7 -5
  182. package/dist/src/verbs/print-roots.js +4 -2
  183. package/dist/src/verbs/verb.js +1 -5
  184. package/dist/src/verbs/version.js +14 -3
  185. package/jsr.json +2 -1
  186. package/package.json +14 -8
  187. package/src/alias-chain.ts +2 -9
  188. package/src/amd.ts +130 -0
  189. package/src/analysis.ts +424 -650
  190. package/src/augmentations.ts +93 -4
  191. package/src/automatic-types.ts +12 -30
  192. package/src/bindings.ts +460 -0
  193. package/src/calls.ts +338 -46
  194. package/src/commands/held.ts +632 -0
  195. package/src/commands/read.ts +242 -0
  196. package/src/commands/shell.ts +228 -0
  197. package/src/commands/tools.ts +2382 -0
  198. package/src/component-files.ts +4 -2
  199. package/src/component-layer.ts +4 -2
  200. package/src/config.ts +31 -302
  201. package/src/conformance-record.ts +1 -1
  202. package/src/consumers.ts +16 -66
  203. package/src/contextual-uses.ts +66 -34
  204. package/src/contract/config.generated.ts +821 -0
  205. package/src/contract/contract.generated.ts +1452 -0
  206. package/src/contract/report.generated.ts +1241 -0
  207. package/src/dependencies.ts +222 -127
  208. package/src/destructuring.ts +1 -31
  209. package/src/edges.ts +41 -140
  210. package/src/element-access.ts +190 -187
  211. package/src/entries/build-scripts.ts +292 -0
  212. package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
  213. package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
  214. package/src/{conventions.ts → entries/conventions.ts} +367 -583
  215. package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
  216. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
  217. package/src/entries/run-directories.ts +108 -0
  218. package/src/entries/sources.ts +266 -0
  219. package/src/entries/static-module.ts +858 -0
  220. package/src/entries/test-runners.ts +835 -0
  221. package/src/entries/workflow-steps.ts +432 -0
  222. package/src/enum-group.ts +2 -11
  223. package/src/erased-stores.ts +3 -7
  224. package/src/exempt-classes.ts +1 -75
  225. package/src/exempt.ts +70 -98
  226. package/src/exposure.ts +492 -0
  227. package/src/extensions.ts +45 -0
  228. package/src/facts.ts +46 -0
  229. package/src/failure.ts +63 -0
  230. package/src/file-facts.ts +15 -25
  231. package/src/finding.ts +10 -10
  232. package/src/findings/boundary.ts +11 -0
  233. package/src/findings/completion.ts +133 -64
  234. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  235. package/src/findings/emitter.ts +9 -10
  236. package/src/findings/emitters.ts +38 -52
  237. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  238. package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
  239. package/src/findings/interfaces.ts +7 -9
  240. package/src/findings/intra-function.ts +16 -14
  241. package/src/findings/non-code-artifacts.ts +24 -15
  242. package/src/findings/reads-and-writes.ts +118 -41
  243. package/src/findings/self-check.ts +51 -38
  244. package/src/findings/unused-declarations.ts +31 -49
  245. package/src/findings/visibility-narrowing.ts +36 -40
  246. package/src/findings-pass.ts +15 -31
  247. package/src/framework-lifecycle.ts +47 -19
  248. package/src/fs/document.ts +70 -0
  249. package/src/fs/manifest.ts +96 -0
  250. package/src/fs/tree.ts +110 -0
  251. package/src/generated-file.ts +242 -35
  252. package/src/git-ignore.ts +50 -26
  253. package/src/host.ts +12 -5
  254. package/src/import-bindings.ts +98 -29
  255. package/src/index/sites.ts +781 -0
  256. package/src/index.ts +2 -2
  257. package/src/indexed-access.ts +570 -527
  258. package/src/injection-container.ts +2 -2
  259. package/src/interface-satisfaction.ts +2 -2
  260. package/src/intra-function-parts.ts +73 -44
  261. package/src/inventory/commonjs.ts +696 -0
  262. package/src/inventory/enumerate.ts +203 -0
  263. package/src/inventory/syntax.ts +311 -0
  264. package/src/inventory.ts +442 -895
  265. package/src/javascript-file.ts +54 -0
  266. package/src/json-document.ts +241 -76
  267. package/src/keyof-comparisons.ts +133 -122
  268. package/src/kinds.ts +5 -413
  269. package/src/{components.ts → liveness/components.ts} +4 -6
  270. package/src/{graph.ts → liveness/graph.ts} +100 -35
  271. package/src/liveness/matrix.ts +162 -0
  272. package/src/liveness/sweep.ts +855 -0
  273. package/src/load/classify.ts +433 -0
  274. package/src/load/diagnostics.ts +154 -0
  275. package/src/load/discover.ts +471 -0
  276. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  277. package/src/load/expected-module.ts +194 -0
  278. package/src/load/load.ts +73 -0
  279. package/src/load/module-lookup.ts +50 -0
  280. package/src/load/package-scope.ts +74 -0
  281. package/src/load/plan.ts +513 -0
  282. package/src/load/specifiers.ts +171 -0
  283. package/src/load/synthesize.ts +230 -0
  284. package/src/load/test-globals.ts +251 -0
  285. package/src/load/test-joins.ts +98 -0
  286. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  287. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  288. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
  289. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  290. package/src/{workspace.ts → load/workspace.ts} +90 -134
  291. package/src/module-declarations.ts +74 -98
  292. package/src/overrides.ts +162 -134
  293. package/src/partial.ts +3 -2
  294. package/src/paths.ts +92 -16
  295. package/src/platform-calls.ts +119 -0
  296. package/src/platform-symbols.ts +189 -0
  297. package/src/position.ts +44 -1
  298. package/src/print.ts +12 -92
  299. package/src/product.ts +18 -0
  300. package/src/query.ts +92 -0
  301. package/src/ref.ts +12 -20
  302. package/src/references/read-rule.ts +60 -0
  303. package/src/references/read-rules.ts +55 -0
  304. package/src/references/sink.ts +314 -0
  305. package/src/references/sources.ts +632 -0
  306. package/src/references.ts +187 -1450
  307. package/src/report-schema.ts +68 -0
  308. package/src/report.ts +103 -226
  309. package/src/reporters/annotations.ts +22 -11
  310. package/src/reporters/json.ts +1 -1
  311. package/src/reporters/reporter.ts +2 -4
  312. package/src/reporters/reporters.ts +1 -1
  313. package/src/reporters/sarif.ts +29 -16
  314. package/src/reporters/template.ts +4 -20
  315. package/src/reporters/text.ts +3 -3
  316. package/src/resolve.ts +284 -1115
  317. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +27 -29
  318. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
  319. package/src/roots/manifest.ts +303 -0
  320. package/src/roots/published-reach.ts +486 -0
  321. package/src/{roots.ts → roots/root-set.ts} +286 -469
  322. package/src/roots/unseen-loads.ts +345 -0
  323. package/src/run.ts +75 -91
  324. package/src/schema.ts +391 -388
  325. package/src/scope.ts +46 -138
  326. package/src/serialization-contract.ts +769 -23
  327. package/src/session.ts +87 -55
  328. package/src/source-files.ts +6 -11
  329. package/src/stores.ts +15 -3
  330. package/src/suppress-file.ts +24 -33
  331. package/src/suppress-inline.ts +55 -91
  332. package/src/suppress.ts +78 -79
  333. package/src/symbol-keys.ts +104 -107
  334. package/src/template-field.ts +15 -25
  335. package/src/tests/file-class.ts +135 -0
  336. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  337. package/src/{test-support.ts → tests/support.ts} +15 -21
  338. package/src/text/compare.ts +27 -0
  339. package/src/text/glob.ts +210 -0
  340. package/src/text/named-files.ts +388 -0
  341. package/src/text/yaml.ts +747 -0
  342. package/src/type-errors.ts +18 -288
  343. package/src/type-parameter-reads.ts +187 -158
  344. package/src/unimplemented-callees.ts +297 -280
  345. package/src/unwrap.ts +34 -0
  346. package/src/usage.ts +10 -0
  347. package/src/vendor/unbash/LICENSE +15 -0
  348. package/src/vendor/unbash/VENDORED.md +16 -0
  349. package/src/vendor/unbash/ansi-c.ts +132 -0
  350. package/src/vendor/unbash/arithmetic-parts.ts +53 -0
  351. package/src/vendor/unbash/arithmetic.ts +641 -0
  352. package/src/vendor/unbash/assignment.ts +163 -0
  353. package/src/vendor/unbash/chars.ts +48 -0
  354. package/src/vendor/unbash/command.ts +47 -0
  355. package/src/vendor/unbash/expansion.ts +144 -0
  356. package/src/vendor/unbash/glob.ts +284 -0
  357. package/src/vendor/unbash/heredoc.ts +34 -0
  358. package/src/vendor/unbash/internal-types.ts +94 -0
  359. package/src/vendor/unbash/lexer.ts +4352 -0
  360. package/src/vendor/unbash/limits.ts +3 -0
  361. package/src/vendor/unbash/parser.ts +1612 -0
  362. package/src/vendor/unbash/parts.ts +96 -0
  363. package/src/vendor/unbash/substitution-context.ts +20 -0
  364. package/src/vendor/unbash/traversal.ts +182 -0
  365. package/src/vendor/unbash/types.ts +660 -0
  366. package/src/vendor/unbash/word-value.ts +64 -0
  367. package/src/vendor/unbash/word.ts +50 -0
  368. package/src/verbs/analyze.ts +255 -164
  369. package/src/verbs/describe.ts +19 -17
  370. package/src/verbs/explain.ts +93 -169
  371. package/src/verbs/print-config.ts +2 -1
  372. package/src/verbs/print-projects.ts +6 -4
  373. package/src/verbs/print-retained.ts +7 -5
  374. package/src/verbs/print-roots.ts +4 -2
  375. package/src/verbs/verb.ts +2 -8
  376. package/src/verbs/version.ts +15 -3
  377. package/dist/src/base-url.js +0 -18
  378. package/dist/src/conventions.js +0 -937
  379. package/dist/src/discover.js +0 -468
  380. package/dist/src/entry-points.js +0 -529
  381. package/dist/src/glob.js +0 -65
  382. package/dist/src/manifest.js +0 -165
  383. package/dist/src/matrix.js +0 -246
  384. package/dist/src/pnpm-workspace.js +0 -120
  385. package/dist/src/roots.js +0 -672
  386. package/dist/src/setup-failure.js +0 -23
  387. package/dist/src/sweep.js +0 -224
  388. package/dist/src/test-joins.js +0 -101
  389. package/dist/src/version.js +0 -7
  390. package/dist/src/workflow-steps.js +0 -185
  391. package/src/base-url.ts +0 -24
  392. package/src/discover.ts +0 -653
  393. package/src/entry-points.ts +0 -687
  394. package/src/glob.ts +0 -67
  395. package/src/manifest.ts +0 -234
  396. package/src/matrix.ts +0 -423
  397. package/src/pnpm-workspace.ts +0 -135
  398. package/src/setup-failure.ts +0 -39
  399. package/src/sweep.ts +0 -347
  400. package/src/test-joins.ts +0 -120
  401. package/src/version.ts +0 -7
  402. package/src/workflow-steps.ts +0 -216
@@ -1,177 +1,15 @@
1
1
  /**
2
- * What the errors a project's own files carry do to the run. An import of a module the
3
- * project expects and nothing provides is a setup failure. Any other error in an own file
4
- * is a type error: the function, method or file-level statement holding it is skipped,
5
- * which only ever withholds a finding. `projectErrors` decides, before any of these, which
6
- * errors the compiler places in no file leave the project unloaded.
2
+ * What a type error in a project's own file does: the function, method or file-level statement
3
+ * holding it is skipped, which only ever withholds a finding.
7
4
  */
8
- import { isClassDeclaration, isFunctionLikeDeclaration, isNoSubstitutionTemplateLiteral, isPropertyAccessExpression, isStringLiteral, } from "@typescript/native/ast";
9
- import { packageOfSpecifier } from "./dependencies.js";
5
+ import { isClassDeclaration, isFunctionLikeDeclaration, isPropertyAccessExpression, } from "@typescript/native/ast";
10
6
  import { nodeKey } from "./inventory.js";
11
- import { dirnamePath, isAbsolutePath, joinPath, relativePath, resolvePath } from "./paths.js";
7
+ import { relativePath } from "./paths.js";
12
8
  import { isAnswered } from "./query.js";
13
- import { findWorkspace } from "./workspace.js";
14
- /** The compiler's codes for an import whose module it cannot find. */
15
- const MODULE_NOT_FOUND = new Set([2307, 2792]);
16
- const MANIFEST = "package.json";
17
- const MANIFEST_SECTIONS = [
18
- "dependencies",
19
- "devDependencies",
20
- "peerDependencies",
21
- "optionalDependencies",
22
- ];
23
9
  /** Whether a finding's position falls inside a skipped unit. */
24
10
  export function insideSkipped(skipped, position) {
25
11
  return skipped.some((unit) => unit.path === position.path && unit.fromLine <= position.line && position.line <= unit.toLine);
26
12
  }
27
- /** The string literal holding one offset, innermost first, a doc comment's included. */
28
- function literalAt(file, offset) {
29
- let found;
30
- const visit = (node) => {
31
- if (offset < node.pos || offset >= node.end) {
32
- return;
33
- }
34
- if (isStringLiteral(node) || isNoSubstitutionTemplateLiteral(node)) {
35
- found = node.text;
36
- }
37
- // `forEachChild` does not enter a doc comment, where a JavaScript file imports types.
38
- for (const doc of node.jsDoc ?? []) {
39
- visit(doc);
40
- }
41
- node.forEachChild(visit);
42
- };
43
- file.forEachChild(visit);
44
- return found;
45
- }
46
- /**
47
- * What one `paths` key's `*` matches in one specifier, `""` for a key with no `*` that
48
- * is the specifier, or `undefined` where the key does not match it.
49
- */
50
- function mappedBy(key, specifier) {
51
- const star = key.indexOf("*");
52
- if (star < 0) {
53
- return key === specifier ? "" : undefined;
54
- }
55
- const prefix = key.slice(0, star);
56
- const suffix = key.slice(star + 1);
57
- return specifier.length >= prefix.length + suffix.length &&
58
- specifier.startsWith(prefix) &&
59
- specifier.endsWith(suffix)
60
- ? specifier.slice(prefix.length, specifier.length - suffix.length)
61
- : undefined;
62
- }
63
- /**
64
- * One `paths` target, its first `*` replaced by `star` taken literally, as the compiler does:
65
- * https://github.com/microsoft/typescript-go/blob/89d5d5b2849a0db0957065889ca58536fa6d2e4a/internal/module/resolver.go#L1282
66
- */
67
- function substituted(target, star) {
68
- const at = target.indexOf("*");
69
- return at < 0 ? target : target.slice(0, at) + star + target.slice(at + 1);
70
- }
71
- /**
72
- * Whether a path names something on disk, as written or with any extension; under
73
- * `fileOnly`, only a file counts.
74
- */
75
- function provided(host, path, fileOnly) {
76
- const counts = (at) => fileOnly ? host.kindOf(at) === "file" : host.kindOf(at) !== "absent";
77
- if (counts(path)) {
78
- return true;
79
- }
80
- const dir = dirnamePath(path);
81
- const stem = `${path.slice(dir.length + 1)}.`;
82
- try {
83
- return host
84
- .readDirectory(dir)
85
- .some((entry) => entry.name.startsWith(stem) && counts(joinPath(dir, entry.name)));
86
- }
87
- catch {
88
- return false;
89
- }
90
- }
91
- /** The manifest at or above `dir`, no higher than the target root, that declares `name`. */
92
- function declaringManifest(host, dir, targetRoot, name) {
93
- for (let at = dir;; at = dirnamePath(at)) {
94
- const path = joinPath(at, MANIFEST);
95
- let manifest;
96
- try {
97
- manifest = JSON.parse(host.readFile(path));
98
- }
99
- catch {
100
- manifest = undefined;
101
- }
102
- if (typeof manifest === "object" && manifest !== null) {
103
- const sections = manifest;
104
- for (const section of MANIFEST_SECTIONS) {
105
- const declared = sections[section];
106
- if (typeof declared === "object" && declared !== null && Object.hasOwn(declared, name)) {
107
- return path;
108
- }
109
- }
110
- }
111
- // The target root is not below itself, so the walk stops after reading its manifest.
112
- if (relativePath(targetRoot, at) === undefined) {
113
- return undefined;
114
- }
115
- }
116
- }
117
- /**
118
- * Whether a package is installed for an importer in `dir`: in the `node_modules` of
119
- * `dir` or of any ancestor, above the target root too, as Node and the compiler look.
120
- */
121
- function installed(host, dir, name) {
122
- for (let at = dir;; at = dirnamePath(at)) {
123
- if (host.kindOf(joinPath(at, "node_modules", name)) === "directory") {
124
- return true;
125
- }
126
- if (dirnamePath(at) === at) {
127
- return false;
128
- }
129
- }
130
- }
131
- /**
132
- * Why one import that the compiler cannot resolve names a module the project expects,
133
- * with the fix, or undefined where the module is one the project does not expect.
134
- */
135
- function expectedModule(context, importer, specifier) {
136
- const { host, targetRoot } = context;
137
- const fix = "run the generator or the build that writes it";
138
- if (specifier.startsWith(".") || isAbsolutePath(specifier)) {
139
- return provided(host, resolvePath(dirnamePath(importer), specifier), false)
140
- ? undefined
141
- : `which names no file of the target: ${fix}`;
142
- }
143
- if (specifier.startsWith("#")) {
144
- return `which the manifest's imports map to no file: ${fix}`;
145
- }
146
- const mapped = context.paths.entries.flatMap(({ key, targets }) => {
147
- const star = mappedBy(key, specifier);
148
- return star === undefined
149
- ? []
150
- : targets.map((target) => resolvePath(context.paths.base, substituted(target, star)));
151
- });
152
- const name = packageOfSpecifier(specifier);
153
- // The compiler looks up in `node_modules` what `paths` does not resolve, so the error
154
- // of an installed package's import is the import's own, a subpath its exports omit:
155
- // https://github.com/microsoft/typescript-go/blob/89d5d5b2849a0db0957065889ca58536fa6d2e4a/internal/module/resolver.go#L548-L575
156
- if (name !== undefined && installed(host, dirnamePath(importer), name)) {
157
- return undefined;
158
- }
159
- if (mapped.length > 0) {
160
- return mapped.some((path) => provided(host, path, true))
161
- ? undefined
162
- : `which the compiler configuration's paths map to no file: ${fix}`;
163
- }
164
- const manifest = name === undefined
165
- ? undefined
166
- : declaringManifest(host, dirnamePath(importer), targetRoot, name);
167
- // No run requires a nested package that is no workspace member to be installed.
168
- if (manifest === undefined ||
169
- (dirnamePath(manifest) !== targetRoot && !context.member(manifest))) {
170
- return undefined;
171
- }
172
- const where = relativePath(targetRoot, manifest) ?? manifest;
173
- return `a dependency ${where} declares that is not installed: run the package manager's install`;
174
- }
175
13
  /**
176
14
  * The unit a type error at one offset skips: the innermost function holding it, else the
177
15
  * class member holding it where a top-level class does, else the top-level statement.
@@ -202,53 +40,13 @@ function messageOf(text, targetRoot) {
202
40
  const line = text.split(`${targetRoot}/`).join("").split(/\s+/u).join(" ").trim();
203
41
  return line === "" ? "a type error" : line;
204
42
  }
205
- /**
206
- * Reads the errors one project's own files carry. A diagnostic marking unnecessary code
207
- * is no error here, and one in a file that is not the project's own is that file's
208
- * package's to answer for.
209
- */
210
- export function readErrors(project, errors, where) {
211
- let workspace = null;
212
- const context = {
213
- ...where,
214
- member: (manifest) => {
215
- if (workspace === null) {
216
- workspace = findWorkspace(where.host, where.targetRoot, () => undefined);
217
- }
218
- return workspace?.memberOf(manifest) !== undefined;
219
- },
220
- };
221
- const files = new Map(project.ownSourceFiles().map((file) => [file.fileName, file]));
222
- const missing = [];
223
- const skips = [];
224
- for (const { diagnostic, at } of errors) {
225
- const file = diagnostic.fileName === undefined ? undefined : files.get(diagnostic.fileName);
226
- if (file === undefined || diagnostic.reportsUnnecessary === true) {
227
- continue;
228
- }
229
- const path = relativePath(context.targetRoot, file.fileName) ?? file.fileName;
230
- const line = at?.line ?? 1;
231
- const specifier = MODULE_NOT_FOUND.has(diagnostic.code)
232
- ? literalAt(file, diagnostic.pos)
233
- : undefined;
234
- const expected = specifier === undefined ? undefined : expectedModule(context, file.fileName, specifier);
235
- if (specifier !== undefined && expected !== undefined) {
236
- missing.push({
237
- setupClass: "missing-module",
238
- detail: `${path}:${String(line)}: ${path} imports ${JSON.stringify(specifier)}, ${expected}`,
239
- });
240
- continue;
241
- }
242
- const unit = unitAt(file, diagnostic.pos);
243
- if (unit !== undefined) {
244
- skips.push({
245
- record: { path, line, message: messageOf(diagnostic.text, context.targetRoot) },
246
- file,
247
- unit,
248
- });
249
- }
250
- }
251
- return { missing, skips };
43
+ /** The skip one type error at `offset` of an own file makes, the root spelled relative to itself. */
44
+ export function skipAt(file, offset, line, text, targetRoot) {
45
+ const unit = unitAt(file, offset);
46
+ const path = relativePath(targetRoot, file.fileName) ?? file.fileName;
47
+ return unit === undefined
48
+ ? undefined
49
+ : { record: { path, line, message: messageOf(text, targetRoot) }, file, unit };
252
50
  }
253
51
  /** The lines each skip withholds, below the target root. */
254
52
  export function skippedUnits(skips, targetRoot) {
@@ -313,22 +111,3 @@ export function skippedRoots(project, held, skips) {
313
111
  }
314
112
  return [...kept];
315
113
  }
316
- /** One compiler configuration's `paths` mapping, empty where it cannot be read. */
317
- export function pathsOf(engine, configFile) {
318
- const base = dirnamePath(configFile);
319
- try {
320
- const { options } = engine.parseConfigFile(configFile);
321
- const { paths } = options;
322
- // The parse answers `pathsBasePath`, the directory of the configuration that writes
323
- // `paths` (an extended one included), though the client's option type omits it:
324
- // https://github.com/microsoft/typescript-go/blob/89d5d5b2849a0db0957065889ca58536fa6d2e4a/internal/tsoptions/tsconfigparsing.go#L1120
325
- const declaredAt = options.pathsBasePath;
326
- return {
327
- base: typeof declaredAt === "string" ? declaredAt : base,
328
- entries: Object.entries(paths ?? {}).map(([key, targets]) => ({ key, targets })),
329
- };
330
- }
331
- catch {
332
- return { base, entries: [] };
333
- }
334
- }
@@ -5,11 +5,9 @@
5
5
  * call's value is what the read reads, whatever member of the constraint the name resolves
6
6
  * to. A class's members a constraint requires are interface satisfaction's.
7
7
  */
8
- import { isBinaryExpression, isCallExpression, isIdentifier, isNewExpression, isPropertyAccessExpression, isTypeParameterDeclaration, SyntaxKind, } from "@typescript/native/ast";
8
+ import { isBinaryExpression, isCallExpression, isIdentifier, isNewExpression, isPropertyAccessExpression, isSourceFile, isTypeParameterDeclaration, SyntaxKind, } from "@typescript/native/ast";
9
9
  import { SymbolFlags } from "@typescript/native/sync";
10
- import { nodeKey } from "./inventory.js";
11
- import { renderPosition } from "./position.js";
12
- import { isAnswered } from "./query.js";
10
+ import { isAnswered, UNANSWERED } from "./query.js";
13
11
  /** How deep a parameter's type is matched against the type a call passes: `readonly T[]` is one level. */
14
12
  const MATCH_DEPTH = 3;
15
13
  /** The name a call reaches one generic by: its own, or that of what holds it. */
@@ -26,147 +24,188 @@ function assignedTo(access) {
26
24
  parent.operatorToken.kind === SyntaxKind.EqualsToken &&
27
25
  parent.left === access);
28
26
  }
29
- /**
30
- * The references the reads through type-parameter-typed values of one project's own files
31
- * make to the members of the types its calls pass, each made by the declaration holding
32
- * the read.
33
- */
34
- export function typeParameterReads(project, held, chains, root, testFiles) {
35
- const queries = project.queries;
36
- const reads = [];
37
- const calls = [];
38
- for (const file of project.ownSourceFiles()) {
39
- const fileId = held.declarations.get(nodeKey(file, file));
40
- if (fileId === undefined) {
41
- continue;
27
+ /** Whether one node is written inside a declaration that declares type parameters, itself included. */
28
+ function inGeneric(node) {
29
+ for (let at = node; !isSourceFile(at); at = at.parent) {
30
+ if (at.typeParameters !== undefined) {
31
+ return true;
42
32
  }
43
- const visit = (node, from, generic) => {
44
- const holder = held.declarations.get(nodeKey(file, node)) ?? from;
45
- const inside = generic ||
46
- node.typeParameters !== undefined;
47
- if (inside &&
48
- isPropertyAccessExpression(node) &&
49
- isIdentifier(node.name) &&
50
- !assignedTo(node)) {
51
- reads.push({ file, from: holder, access: node });
52
- }
53
- if (isCallExpression(node) || isNewExpression(node)) {
54
- calls.push(node);
55
- }
56
- node.forEachChild((child) => {
57
- visit(child, holder, inside);
58
- });
59
- };
60
- file.forEachChild((child) => {
61
- visit(child, fileId, false);
62
- });
63
33
  }
64
- if (reads.length === 0) {
65
- return [];
66
- }
67
- // The reads whose receiver the checker types as a type parameter, by the generic declaring it.
68
- const receivers = queries.typesAt(reads.map((read) => read.access.expression));
69
- const byGeneric = new Map();
70
- reads.forEach((read, at) => {
71
- const type = receivers[at];
72
- if (type === undefined || !isAnswered(type) || !type.isTypeParameter()) {
73
- return;
74
- }
75
- const symbol = queries.symbolOfType(type);
76
- const declaration = symbol === undefined || !isAnswered(symbol)
77
- ? undefined
78
- : symbol.declarations
79
- .map((handle) => project.declarationAt(handle)?.node)
80
- .find((node) => node !== undefined && isTypeParameterDeclaration(node));
81
- const generic = declaration?.parent;
82
- if (generic !== undefined) {
83
- byGeneric.set(generic, [...(byGeneric.get(generic) ?? []), { read, parameter: type }]);
84
- }
85
- });
86
- if (byGeneric.size === 0) {
87
- return [];
88
- }
89
- /** The types `instantiated` holds where `declared` holds `parameter`, matched part for part. */
90
- const passedFor = (parameter, declared, instantiated, depth) => {
91
- if (declared.id === parameter.id) {
92
- return [instantiated];
93
- }
94
- if (depth >= MATCH_DEPTH) {
95
- return [];
96
- }
97
- const a = queries.typeArguments(declared);
98
- const b = queries.typeArguments(instantiated);
99
- if (!isAnswered(a) || !isAnswered(b) || a.length !== b.length) {
100
- return [];
101
- }
102
- return a.flatMap((one, at) => {
103
- const other = b[at];
104
- return other === undefined ? [] : passedFor(parameter, one, other, depth + 1);
105
- });
106
- };
107
- // Only a call spelling a generic's name is resolved: one request each.
108
- const spelled = new Set([...byGeneric.keys()].flatMap((generic) => nameOf(generic) ?? []));
109
- const found = new Map();
110
- for (const call of calls) {
111
- const callee = call.expression;
112
- const written = isIdentifier(callee)
113
- ? callee.text
114
- : isPropertyAccessExpression(callee) && isIdentifier(callee.name)
115
- ? callee.name.text
116
- : undefined;
117
- if (written === undefined || !spelled.has(written)) {
118
- continue;
119
- }
120
- const resolved = queries.resolvedSignature(call);
121
- if (resolved === undefined || !isAnswered(resolved) || resolved.declaration === undefined) {
122
- continue;
123
- }
124
- const generic = project.declarationAt(resolved.declaration)?.node;
125
- const pending = generic === undefined ? undefined : byGeneric.get(generic);
126
- const declared = pending === undefined ? undefined : queries.genericOf(resolved);
127
- if (pending === undefined || declared === undefined || !isAnswered(declared)) {
128
- continue;
129
- }
130
- const count = (generic?.parameters ?? []).length;
131
- for (const { read, parameter } of pending) {
132
- const passed = [];
133
- for (let at = 0; at < count; at += 1) {
134
- const own = queries.parameterType(declared, at);
135
- const given = queries.typeAtPosition(resolved, at);
136
- if (own !== undefined && isAnswered(own) && isAnswered(given)) {
137
- passed.push(...passedFor(parameter, own, given, 0));
34
+ return false;
35
+ }
36
+ /**
37
+ * The reads the reads through type-parameter-typed values of a side's files make of the
38
+ * members of the types its calls pass, each made by the declaration holding the read. A
39
+ * question the checker leaves unanswered holds every member the read's name spells.
40
+ */
41
+ export const typeParameterReads = {
42
+ start() {
43
+ const reads = [];
44
+ const calls = [];
45
+ return {
46
+ visit(node, { file, from }) {
47
+ if (isPropertyAccessExpression(node) &&
48
+ isIdentifier(node.name) &&
49
+ !assignedTo(node) &&
50
+ inGeneric(node)) {
51
+ reads.push({ file, from, access: node });
138
52
  }
139
- }
140
- const name = read.access.name.text;
141
- const position = renderPosition(read.file, root, read.access.name.getStart());
142
- for (const type of passed) {
143
- const parts = type.isUnionType() ? queries.constituents(type) : [type];
144
- for (const part of isAnswered(parts) ? parts : []) {
145
- const owner = queries.symbolOfType(part);
146
- if (!isAnswered(owner) ||
147
- owner === undefined ||
148
- (owner.flags & SymbolFlags.Class) !== 0) {
53
+ if (isCallExpression(node) || isNewExpression(node)) {
54
+ calls.push(node);
55
+ }
56
+ },
57
+ reads({ project, chains }) {
58
+ const out = [];
59
+ if (reads.length === 0) {
60
+ return out;
61
+ }
62
+ const queries = project.queries;
63
+ const hold = (read) => {
64
+ out.push({ kind: "held", from: read.from, names: [read.access.name.text] });
65
+ };
66
+ // The reads whose receiver the checker types as a type parameter, by the generic declaring it.
67
+ const receivers = queries.typesAt(reads.map((read) => read.access.expression));
68
+ const byGeneric = new Map();
69
+ reads.forEach((read, at) => {
70
+ const type = receivers[at];
71
+ if (type === UNANSWERED) {
72
+ hold(read);
73
+ return;
74
+ }
75
+ if (type?.isTypeParameter() !== true) {
76
+ return;
77
+ }
78
+ const symbol = queries.symbolOfType(type);
79
+ if (symbol === UNANSWERED) {
80
+ hold(read);
81
+ return;
82
+ }
83
+ const declaration = symbol === undefined
84
+ ? undefined
85
+ : symbol.declarations
86
+ .map((handle) => project.declarationAt(handle)?.node)
87
+ .find((node) => node !== undefined && isTypeParameterDeclaration(node));
88
+ const generic = declaration?.parent;
89
+ if (generic !== undefined) {
90
+ byGeneric.set(generic, [...(byGeneric.get(generic) ?? []), { read, parameter: type }]);
91
+ }
92
+ });
93
+ if (byGeneric.size === 0) {
94
+ return out;
95
+ }
96
+ /** The types `instantiated` holds where `declared` holds `parameter`, matched part for part. */
97
+ const passedFor = (read, parameter, declared, instantiated, depth) => {
98
+ if (declared.id === parameter.id) {
99
+ return [instantiated];
100
+ }
101
+ if (depth >= MATCH_DEPTH) {
102
+ return [];
103
+ }
104
+ const a = queries.typeArguments(declared);
105
+ const b = queries.typeArguments(instantiated);
106
+ if (!isAnswered(a) || !isAnswered(b)) {
107
+ hold(read);
108
+ return [];
109
+ }
110
+ if (a.length !== b.length) {
111
+ return [];
112
+ }
113
+ return a.flatMap((one, at) => {
114
+ const other = b[at];
115
+ return other === undefined ? [] : passedFor(read, parameter, one, other, depth + 1);
116
+ });
117
+ };
118
+ // Only a call spelling a generic's name is resolved: one request each.
119
+ const bySpelling = new Map();
120
+ for (const [generic, pending] of byGeneric) {
121
+ const name = nameOf(generic);
122
+ if (name !== undefined) {
123
+ bySpelling.set(name, [
124
+ ...(bySpelling.get(name) ?? []),
125
+ ...pending.map((one) => one.read),
126
+ ]);
127
+ }
128
+ }
129
+ const found = new Map();
130
+ for (const call of calls) {
131
+ const callee = call.expression;
132
+ const written = isIdentifier(callee)
133
+ ? callee.text
134
+ : isPropertyAccessExpression(callee) && isIdentifier(callee.name)
135
+ ? callee.name.text
136
+ : undefined;
137
+ const spelledBy = written === undefined ? undefined : bySpelling.get(written);
138
+ if (spelledBy === undefined) {
139
+ continue;
140
+ }
141
+ const resolved = queries.resolvedSignature(call);
142
+ if (resolved === UNANSWERED) {
143
+ spelledBy.forEach(hold);
149
144
  continue;
150
145
  }
151
- const properties = queries.propertiesOf(part);
152
- for (const property of isAnswered(properties) ? properties : []) {
153
- if (property.name !== name) {
154
- continue;
146
+ if (resolved?.declaration === undefined) {
147
+ continue;
148
+ }
149
+ const generic = project.declarationAt(resolved.declaration)?.node;
150
+ const pending = generic === undefined ? undefined : byGeneric.get(generic);
151
+ const declared = pending === undefined ? undefined : queries.genericOf(resolved);
152
+ if (declared === UNANSWERED) {
153
+ pending?.forEach((one) => {
154
+ hold(one.read);
155
+ });
156
+ continue;
157
+ }
158
+ if (pending === undefined || declared === undefined) {
159
+ continue;
160
+ }
161
+ const count = (generic?.parameters ?? []).length;
162
+ for (const { read, parameter } of pending) {
163
+ const passed = [];
164
+ for (let at = 0; at < count; at += 1) {
165
+ const own = queries.parameterType(declared, at);
166
+ const given = queries.typeAtPosition(resolved, at);
167
+ if (own === UNANSWERED || given === UNANSWERED) {
168
+ hold(read);
169
+ }
170
+ else if (own !== undefined) {
171
+ passed.push(...passedFor(read, parameter, own, given, 0));
172
+ }
155
173
  }
156
- for (const to of chains.declarationsOf(property)) {
157
- found.set(`${read.from}\u0000${to}\u0000${String(read.access.name.pos)}`, {
158
- from: read.from,
159
- to,
160
- position,
161
- use: "read",
162
- resolution: "batch",
163
- test: testFiles.has(position.path),
164
- });
174
+ const name = read.access.name.text;
175
+ for (const type of passed) {
176
+ const parts = type.isUnionType() ? queries.constituents(type) : [type];
177
+ for (const part of isAnswered(parts) ? parts : [type]) {
178
+ const owner = queries.symbolOfType(part);
179
+ const properties = queries.propertiesOf(part);
180
+ if (owner === UNANSWERED || properties === UNANSWERED) {
181
+ hold(read);
182
+ continue;
183
+ }
184
+ if (owner === undefined || (owner.flags & SymbolFlags.Class) !== 0) {
185
+ continue;
186
+ }
187
+ for (const property of properties) {
188
+ if (property.name !== name) {
189
+ continue;
190
+ }
191
+ for (const to of chains.declarationsOf(property)) {
192
+ found.set(`${read.from}\u0000${to}\u0000${String(read.access.name.pos)}`, {
193
+ kind: "named",
194
+ from: read.from,
195
+ to,
196
+ file: read.file,
197
+ at: read.access.name,
198
+ use: "read",
199
+ via: "batch",
200
+ });
201
+ }
202
+ }
203
+ }
165
204
  }
166
205
  }
167
206
  }
168
- }
169
- }
170
- }
171
- return [...found.values()];
172
- }
207
+ return [...out, ...found.values()];
208
+ },
209
+ };
210
+ },
211
+ };