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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/README.md +3 -1
  2. package/THIRD_PARTY_NOTICES.md +27 -0
  3. package/dist/bin/mapper-connection.js +2 -1
  4. package/dist/bin/node-host.js +24 -5
  5. package/dist/src/alias-chain.js +35 -9
  6. package/dist/src/amd.js +81 -0
  7. package/dist/src/analysis.js +274 -496
  8. package/dist/src/augmentations.js +64 -3
  9. package/dist/src/automatic-types.js +10 -29
  10. package/dist/src/bindings.js +382 -0
  11. package/dist/src/commands/held.js +499 -0
  12. package/dist/src/commands/read.js +161 -0
  13. package/dist/src/commands/shell.js +169 -0
  14. package/dist/src/commands/tools.js +1847 -0
  15. package/dist/src/component-files.js +3 -2
  16. package/dist/src/component-layer.js +4 -2
  17. package/dist/src/config.js +6 -82
  18. package/dist/src/conformance-record.js +2 -2
  19. package/dist/src/consumers.js +10 -38
  20. package/dist/src/contextual-uses.js +57 -26
  21. package/dist/src/contract/config.generated.js +561 -0
  22. package/dist/src/contract/contract.generated.js +1370 -0
  23. package/dist/src/contract/report.generated.js +866 -0
  24. package/dist/src/dependencies.js +165 -122
  25. package/dist/src/destructuring.js +1 -19
  26. package/dist/src/edges.js +38 -122
  27. package/dist/src/element-access.js +181 -168
  28. package/dist/src/entries/build-scripts.js +222 -0
  29. package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
  30. package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
  31. package/dist/src/entries/conventions.js +740 -0
  32. package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
  33. package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
  34. package/dist/src/entries/run-directories.js +77 -0
  35. package/dist/src/entries/sources.js +144 -0
  36. package/dist/src/entries/static-module.js +670 -0
  37. package/dist/src/entries/test-runners.js +650 -0
  38. package/dist/src/entries/workflow-steps.js +345 -0
  39. package/dist/src/exemptions/argument-places.js +131 -0
  40. package/dist/src/exemptions/calls.js +338 -0
  41. package/dist/src/exemptions/classes.js +13 -0
  42. package/dist/src/{decorator.js → exemptions/decorator.js} +19 -30
  43. package/dist/src/exemptions/detectors.js +48 -0
  44. package/dist/src/{enum-group.js → exemptions/enum-group.js} +9 -16
  45. package/dist/src/{erased-stores.js → exemptions/erased-stores.js} +7 -11
  46. package/dist/src/{framework-lifecycle.js → exemptions/framework-lifecycle.js} +76 -54
  47. package/dist/src/exemptions/generated-file.js +241 -0
  48. package/dist/src/{injection-container.js → exemptions/injection-container.js} +20 -26
  49. package/dist/src/exemptions/installed-globals.js +173 -0
  50. package/dist/src/{interface-satisfaction.js → exemptions/interface-satisfaction.js} +52 -121
  51. package/dist/src/exemptions/lifecycle.js +150 -0
  52. package/dist/src/{reflective-lookup.js → exemptions/reflective-lookup.js} +3 -3
  53. package/dist/src/exemptions/serialization-contract.js +1276 -0
  54. package/dist/src/exemptions/sites.js +182 -0
  55. package/dist/src/{template-field.js → exemptions/template-field.js} +13 -23
  56. package/dist/src/{value-reach.js → exemptions/value-reach.js} +14 -7
  57. package/dist/src/exposure.js +400 -0
  58. package/dist/src/extensions.js +37 -0
  59. package/dist/src/facts.js +38 -0
  60. package/dist/src/failure.js +36 -0
  61. package/dist/src/file-facts.js +3 -26
  62. package/dist/src/findings/completion.js +109 -56
  63. package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
  64. package/dist/src/findings/emitters.js +27 -41
  65. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  66. package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
  67. package/dist/src/findings/interfaces.js +4 -5
  68. package/dist/src/findings/intra-function.js +16 -13
  69. package/dist/src/findings/non-code-artifacts.js +17 -12
  70. package/dist/src/findings/reads-and-writes.js +86 -27
  71. package/dist/src/findings/self-check.js +44 -30
  72. package/dist/src/findings/unused-declarations.js +29 -45
  73. package/dist/src/findings/visibility-narrowing.js +23 -31
  74. package/dist/src/findings-pass.js +13 -21
  75. package/dist/src/fs/document.js +52 -0
  76. package/dist/src/fs/manifest.js +67 -0
  77. package/dist/src/fs/tree.js +88 -0
  78. package/dist/src/git-ignore.js +39 -26
  79. package/dist/src/import-bindings.js +73 -28
  80. package/dist/src/index/sites.js +557 -0
  81. package/dist/src/index/values.js +124 -0
  82. package/dist/src/index.js +2 -2
  83. package/dist/src/indexed-access.js +523 -478
  84. package/dist/src/intra-function-parts.js +63 -43
  85. package/dist/src/inventory/commonjs.js +507 -0
  86. package/dist/src/inventory/enumerate.js +167 -0
  87. package/dist/src/inventory/syntax.js +236 -0
  88. package/dist/src/inventory.js +323 -724
  89. package/dist/src/javascript-file.js +48 -0
  90. package/dist/src/json-document.js +198 -67
  91. package/dist/src/keyof-comparisons.js +126 -107
  92. package/dist/src/kinds.js +3 -366
  93. package/dist/src/{components.js → liveness/components.js} +2 -3
  94. package/dist/src/{graph.js → liveness/graph.js} +52 -28
  95. package/dist/src/liveness/matrix.js +99 -0
  96. package/dist/src/liveness/sweep.js +558 -0
  97. package/dist/src/load/classify.js +289 -0
  98. package/dist/src/load/diagnostics.js +87 -0
  99. package/dist/src/load/discover.js +285 -0
  100. package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
  101. package/dist/src/load/expected-module.js +136 -0
  102. package/dist/src/load/load.js +27 -0
  103. package/dist/src/load/module-lookup.js +37 -0
  104. package/dist/src/load/package-scope.js +56 -0
  105. package/dist/src/load/plan.js +313 -0
  106. package/dist/src/load/specifiers.js +113 -0
  107. package/dist/src/load/synthesize.js +152 -0
  108. package/dist/src/load/test-globals.js +207 -0
  109. package/dist/src/load/test-joins.js +82 -0
  110. package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
  111. package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
  112. package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
  113. package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
  114. package/dist/src/{workspace.js → load/workspace.js} +62 -124
  115. package/dist/src/module-declarations.js +70 -85
  116. package/dist/src/overrides.js +134 -112
  117. package/dist/src/partial.js +2 -1
  118. package/dist/src/paths.js +82 -16
  119. package/dist/src/platform-calls.js +78 -0
  120. package/dist/src/platform-symbols.js +134 -0
  121. package/dist/src/position.js +43 -1
  122. package/dist/src/print.js +11 -79
  123. package/dist/src/product.js +13 -0
  124. package/dist/src/query.js +95 -0
  125. package/dist/src/ref.js +12 -20
  126. package/dist/src/references/read-rule.js +1 -0
  127. package/dist/src/references/read-rules.js +48 -0
  128. package/dist/src/references/sink.js +237 -0
  129. package/dist/src/references/sources.js +450 -0
  130. package/dist/src/references.js +117 -1074
  131. package/dist/src/report-schema.js +51 -0
  132. package/dist/src/report.js +57 -41
  133. package/dist/src/reporters/annotations.js +15 -8
  134. package/dist/src/reporters/sarif.js +16 -10
  135. package/dist/src/reporters/template.js +4 -19
  136. package/dist/src/resolve.js +246 -730
  137. package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
  138. package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
  139. package/dist/src/roots/manifest.js +216 -0
  140. package/dist/src/roots/published-reach.js +412 -0
  141. package/dist/src/roots/root-set.js +487 -0
  142. package/dist/src/roots/unseen-loads.js +236 -0
  143. package/dist/src/run.js +66 -77
  144. package/dist/src/schema.js +320 -343
  145. package/dist/src/scope.js +38 -115
  146. package/dist/src/session.js +37 -29
  147. package/dist/src/source-files.js +6 -10
  148. package/dist/src/stores.js +4 -2
  149. package/dist/src/suppress-file.js +25 -28
  150. package/dist/src/suppress-inline.js +36 -83
  151. package/dist/src/suppress.js +50 -71
  152. package/dist/src/symbol-keys.js +92 -88
  153. package/dist/src/tests/file-class.js +76 -0
  154. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  155. package/dist/src/{test-support.js → tests/support.js} +5 -12
  156. package/dist/src/text/compare.js +26 -0
  157. package/dist/src/text/glob.js +194 -0
  158. package/dist/src/text/named-files.js +298 -0
  159. package/dist/src/text/yaml.js +684 -0
  160. package/dist/src/type-errors.js +11 -232
  161. package/dist/src/type-parameter-reads.js +178 -139
  162. package/dist/src/unimplemented-callees.js +262 -242
  163. package/dist/src/unwrap.js +23 -0
  164. package/dist/src/usage.js +10 -0
  165. package/dist/src/vendor/unbash/ansi-c.js +132 -0
  166. package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
  167. package/dist/src/vendor/unbash/arithmetic.js +591 -0
  168. package/dist/src/vendor/unbash/assignment.js +131 -0
  169. package/dist/src/vendor/unbash/chars.js +48 -0
  170. package/dist/src/vendor/unbash/command.js +41 -0
  171. package/dist/src/vendor/unbash/expansion.js +80 -0
  172. package/dist/src/vendor/unbash/glob.js +268 -0
  173. package/dist/src/vendor/unbash/heredoc.js +27 -0
  174. package/dist/src/vendor/unbash/internal-types.js +1 -0
  175. package/dist/src/vendor/unbash/lexer.js +4274 -0
  176. package/dist/src/vendor/unbash/limits.js +3 -0
  177. package/dist/src/vendor/unbash/parser.js +1366 -0
  178. package/dist/src/vendor/unbash/parts.js +57 -0
  179. package/dist/src/vendor/unbash/substitution-context.js +8 -0
  180. package/dist/src/vendor/unbash/traversal.js +212 -0
  181. package/dist/src/vendor/unbash/types.js +1 -0
  182. package/dist/src/vendor/unbash/word-value.js +61 -0
  183. package/dist/src/vendor/unbash/word.js +40 -0
  184. package/dist/src/verbs/analyze.js +194 -127
  185. package/dist/src/verbs/describe.js +13 -18
  186. package/dist/src/verbs/explain.js +85 -139
  187. package/dist/src/verbs/print-config.js +2 -1
  188. package/dist/src/verbs/print-projects.js +6 -4
  189. package/dist/src/verbs/print-retained.js +30 -6
  190. package/dist/src/verbs/print-roots.js +4 -2
  191. package/dist/src/verbs/verb.js +1 -5
  192. package/dist/src/verbs/version.js +14 -3
  193. package/jsr.json +2 -1
  194. package/package.json +14 -8
  195. package/src/alias-chain.ts +40 -11
  196. package/src/amd.ts +130 -0
  197. package/src/analysis.ts +426 -733
  198. package/src/augmentations.ts +93 -4
  199. package/src/automatic-types.ts +12 -30
  200. package/src/bindings.ts +460 -0
  201. package/src/commands/held.ts +632 -0
  202. package/src/commands/read.ts +242 -0
  203. package/src/commands/shell.ts +228 -0
  204. package/src/commands/tools.ts +2382 -0
  205. package/src/component-files.ts +4 -2
  206. package/src/component-layer.ts +4 -2
  207. package/src/config.ts +31 -302
  208. package/src/conformance-record.ts +2 -2
  209. package/src/consumers.ts +16 -66
  210. package/src/contextual-uses.ts +66 -34
  211. package/src/contract/config.generated.ts +821 -0
  212. package/src/contract/contract.generated.ts +1453 -0
  213. package/src/contract/report.generated.ts +1241 -0
  214. package/src/dependencies.ts +223 -128
  215. package/src/destructuring.ts +1 -31
  216. package/src/edges.ts +41 -140
  217. package/src/element-access.ts +190 -187
  218. package/src/entries/build-scripts.ts +292 -0
  219. package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
  220. package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
  221. package/src/{conventions.ts → entries/conventions.ts} +367 -583
  222. package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
  223. package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
  224. package/src/entries/run-directories.ts +108 -0
  225. package/src/entries/sources.ts +266 -0
  226. package/src/entries/static-module.ts +858 -0
  227. package/src/entries/test-runners.ts +835 -0
  228. package/src/entries/workflow-steps.ts +432 -0
  229. package/src/exemptions/argument-places.ts +198 -0
  230. package/src/exemptions/calls.ts +483 -0
  231. package/src/exemptions/classes.ts +49 -0
  232. package/src/exemptions/decorator.ts +56 -0
  233. package/src/exemptions/detectors.ts +75 -0
  234. package/src/{enum-group.ts → exemptions/enum-group.ts} +10 -19
  235. package/src/{erased-stores.ts → exemptions/erased-stores.ts} +7 -14
  236. package/src/{framework-lifecycle.ts → exemptions/framework-lifecycle.ts} +85 -66
  237. package/src/exemptions/generated-file.ts +318 -0
  238. package/src/{injection-container.ts → exemptions/injection-container.ts} +29 -34
  239. package/src/exemptions/installed-globals.ts +255 -0
  240. package/src/{interface-satisfaction.ts → exemptions/interface-satisfaction.ts} +69 -160
  241. package/src/exemptions/lifecycle.ts +286 -0
  242. package/src/{reflective-lookup.ts → exemptions/reflective-lookup.ts} +5 -5
  243. package/src/exemptions/serialization-contract.ts +1729 -0
  244. package/src/exemptions/sites.ts +293 -0
  245. package/src/{template-field.ts → exemptions/template-field.ts} +22 -32
  246. package/src/{value-reach.ts → exemptions/value-reach.ts} +16 -8
  247. package/src/exposure.ts +492 -0
  248. package/src/extensions.ts +45 -0
  249. package/src/facts.ts +46 -0
  250. package/src/failure.ts +63 -0
  251. package/src/file-facts.ts +15 -25
  252. package/src/finding.ts +10 -10
  253. package/src/findings/boundary.ts +11 -0
  254. package/src/findings/completion.ts +133 -64
  255. package/src/findings/dependencies-and-module-machinery.ts +4 -7
  256. package/src/findings/emitter.ts +9 -10
  257. package/src/findings/emitters.ts +38 -52
  258. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  259. package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
  260. package/src/findings/interfaces.ts +7 -9
  261. package/src/findings/intra-function.ts +16 -14
  262. package/src/findings/non-code-artifacts.ts +24 -15
  263. package/src/findings/reads-and-writes.ts +118 -41
  264. package/src/findings/self-check.ts +51 -38
  265. package/src/findings/unused-declarations.ts +31 -49
  266. package/src/findings/visibility-narrowing.ts +36 -40
  267. package/src/findings-pass.ts +15 -31
  268. package/src/fs/document.ts +70 -0
  269. package/src/fs/manifest.ts +96 -0
  270. package/src/fs/tree.ts +110 -0
  271. package/src/git-ignore.ts +50 -26
  272. package/src/host.ts +12 -5
  273. package/src/import-bindings.ts +98 -29
  274. package/src/index/sites.ts +781 -0
  275. package/src/index/values.ts +170 -0
  276. package/src/index.ts +2 -2
  277. package/src/indexed-access.ts +570 -527
  278. package/src/intra-function-parts.ts +73 -44
  279. package/src/inventory/commonjs.ts +696 -0
  280. package/src/inventory/enumerate.ts +203 -0
  281. package/src/inventory/syntax.ts +311 -0
  282. package/src/inventory.ts +442 -895
  283. package/src/javascript-file.ts +54 -0
  284. package/src/json-document.ts +241 -76
  285. package/src/keyof-comparisons.ts +133 -122
  286. package/src/kinds.ts +5 -413
  287. package/src/{components.ts → liveness/components.ts} +4 -6
  288. package/src/{graph.ts → liveness/graph.ts} +100 -35
  289. package/src/liveness/matrix.ts +162 -0
  290. package/src/liveness/sweep.ts +855 -0
  291. package/src/load/classify.ts +433 -0
  292. package/src/load/diagnostics.ts +154 -0
  293. package/src/load/discover.ts +471 -0
  294. package/src/{emit-map.ts → load/emit-map.ts} +1 -1
  295. package/src/load/expected-module.ts +194 -0
  296. package/src/load/load.ts +73 -0
  297. package/src/load/module-lookup.ts +50 -0
  298. package/src/load/package-scope.ts +74 -0
  299. package/src/load/plan.ts +513 -0
  300. package/src/load/specifiers.ts +171 -0
  301. package/src/load/synthesize.ts +230 -0
  302. package/src/load/test-globals.ts +251 -0
  303. package/src/load/test-joins.ts +98 -0
  304. package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
  305. package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
  306. package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
  307. package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
  308. package/src/{workspace.ts → load/workspace.ts} +90 -134
  309. package/src/module-declarations.ts +74 -98
  310. package/src/overrides.ts +162 -134
  311. package/src/partial.ts +3 -2
  312. package/src/paths.ts +92 -16
  313. package/src/platform-calls.ts +119 -0
  314. package/src/platform-symbols.ts +189 -0
  315. package/src/position.ts +44 -1
  316. package/src/print.ts +12 -92
  317. package/src/product.ts +18 -0
  318. package/src/query.ts +201 -10
  319. package/src/ref.ts +12 -20
  320. package/src/references/read-rule.ts +60 -0
  321. package/src/references/read-rules.ts +55 -0
  322. package/src/references/sink.ts +314 -0
  323. package/src/references/sources.ts +632 -0
  324. package/src/references.ts +187 -1450
  325. package/src/report-schema.ts +68 -0
  326. package/src/report.ts +103 -226
  327. package/src/reporters/annotations.ts +22 -11
  328. package/src/reporters/json.ts +1 -1
  329. package/src/reporters/reporter.ts +2 -4
  330. package/src/reporters/reporters.ts +1 -1
  331. package/src/reporters/sarif.ts +29 -16
  332. package/src/reporters/template.ts +4 -20
  333. package/src/reporters/text.ts +3 -3
  334. package/src/resolve.ts +284 -1115
  335. package/src/{configured-declarations.ts → roots/configured-declarations.ts} +26 -29
  336. package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
  337. package/src/roots/manifest.ts +303 -0
  338. package/src/roots/published-reach.ts +486 -0
  339. package/src/{roots.ts → roots/root-set.ts} +286 -469
  340. package/src/roots/unseen-loads.ts +345 -0
  341. package/src/run.ts +75 -91
  342. package/src/schema.ts +391 -388
  343. package/src/scope.ts +46 -138
  344. package/src/session.ts +87 -55
  345. package/src/source-files.ts +6 -11
  346. package/src/stores.ts +15 -3
  347. package/src/suppress-file.ts +24 -33
  348. package/src/suppress-inline.ts +55 -91
  349. package/src/suppress.ts +78 -79
  350. package/src/symbol-keys.ts +104 -107
  351. package/src/tests/file-class.ts +135 -0
  352. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  353. package/src/{test-support.ts → tests/support.ts} +15 -21
  354. package/src/text/compare.ts +27 -0
  355. package/src/text/glob.ts +210 -0
  356. package/src/text/named-files.ts +388 -0
  357. package/src/text/yaml.ts +747 -0
  358. package/src/type-errors.ts +18 -288
  359. package/src/type-parameter-reads.ts +187 -158
  360. package/src/unimplemented-callees.ts +297 -280
  361. package/src/unwrap.ts +34 -0
  362. package/src/usage.ts +10 -0
  363. package/src/vendor/unbash/LICENSE +15 -0
  364. package/src/vendor/unbash/VENDORED.md +16 -0
  365. package/src/vendor/unbash/ansi-c.ts +132 -0
  366. package/src/vendor/unbash/arithmetic-parts.ts +53 -0
  367. package/src/vendor/unbash/arithmetic.ts +641 -0
  368. package/src/vendor/unbash/assignment.ts +163 -0
  369. package/src/vendor/unbash/chars.ts +48 -0
  370. package/src/vendor/unbash/command.ts +47 -0
  371. package/src/vendor/unbash/expansion.ts +144 -0
  372. package/src/vendor/unbash/glob.ts +284 -0
  373. package/src/vendor/unbash/heredoc.ts +34 -0
  374. package/src/vendor/unbash/internal-types.ts +94 -0
  375. package/src/vendor/unbash/lexer.ts +4352 -0
  376. package/src/vendor/unbash/limits.ts +3 -0
  377. package/src/vendor/unbash/parser.ts +1612 -0
  378. package/src/vendor/unbash/parts.ts +96 -0
  379. package/src/vendor/unbash/substitution-context.ts +20 -0
  380. package/src/vendor/unbash/traversal.ts +182 -0
  381. package/src/vendor/unbash/types.ts +660 -0
  382. package/src/vendor/unbash/word-value.ts +64 -0
  383. package/src/vendor/unbash/word.ts +50 -0
  384. package/src/verbs/analyze.ts +255 -164
  385. package/src/verbs/describe.ts +19 -17
  386. package/src/verbs/explain.ts +93 -169
  387. package/src/verbs/print-config.ts +2 -1
  388. package/src/verbs/print-projects.ts +6 -4
  389. package/src/verbs/print-retained.ts +36 -6
  390. package/src/verbs/print-roots.ts +4 -2
  391. package/src/verbs/verb.ts +2 -8
  392. package/src/verbs/version.ts +15 -3
  393. package/dist/src/base-url.js +0 -18
  394. package/dist/src/calls.js +0 -155
  395. package/dist/src/conventions.js +0 -937
  396. package/dist/src/discover.js +0 -468
  397. package/dist/src/entry-points.js +0 -529
  398. package/dist/src/exempt-classes.js +0 -75
  399. package/dist/src/exempt.js +0 -209
  400. package/dist/src/generated-file.js +0 -95
  401. package/dist/src/glob.js +0 -65
  402. package/dist/src/manifest.js +0 -165
  403. package/dist/src/matrix.js +0 -246
  404. package/dist/src/pnpm-workspace.js +0 -120
  405. package/dist/src/roots.js +0 -672
  406. package/dist/src/serialization-contract.js +0 -611
  407. package/dist/src/setup-failure.js +0 -23
  408. package/dist/src/sweep.js +0 -224
  409. package/dist/src/test-joins.js +0 -101
  410. package/dist/src/value-flow.js +0 -74
  411. package/dist/src/version.js +0 -7
  412. package/dist/src/workflow-steps.js +0 -185
  413. package/src/base-url.ts +0 -24
  414. package/src/calls.ts +0 -225
  415. package/src/decorator.ts +0 -78
  416. package/src/discover.ts +0 -653
  417. package/src/entry-points.ts +0 -687
  418. package/src/exempt-classes.ts +0 -123
  419. package/src/exempt.ts +0 -323
  420. package/src/generated-file.ts +0 -111
  421. package/src/glob.ts +0 -67
  422. package/src/manifest.ts +0 -234
  423. package/src/matrix.ts +0 -423
  424. package/src/pnpm-workspace.ts +0 -135
  425. package/src/serialization-contract.ts +0 -849
  426. package/src/setup-failure.ts +0 -39
  427. package/src/sweep.ts +0 -347
  428. package/src/test-joins.ts +0 -120
  429. package/src/value-flow.ts +0 -104
  430. package/src/version.ts +0 -7
  431. package/src/workflow-steps.ts +0 -216
@@ -0,0 +1,338 @@
1
+ /**
2
+ * The calls and decorators of one project that the configured classes read: what each
3
+ * call invokes, a call through a method of `Function.prototype` included, and which of the
4
+ * target's classes a call passes or a decorator is attached to. A class is passed by each
5
+ * value an argument can carry ({@link carriedValues}), named directly or through
6
+ * variables, and a decorator written as a call is a call.
7
+ */
8
+ import { isArrayLiteralExpression, isArrowFunction, isBindingElement, isCallExpression, isDecorator, isFunctionDeclaration, isFunctionExpression, isIdentifier, isMethodDeclaration, isParameterDeclaration, isPropertyAccessExpression, isPropertyAssignment, isPropertyDeclaration, isShorthandPropertyAssignment, isSpreadElement, isVariableDeclaration, } from "@typescript/native/ast";
9
+ import { ObjectFlags, SymbolFlags, } from "@typescript/native/sync";
10
+ import { resolvedTargets } from "../alias-chain.js";
11
+ import { carriedValues, nameOf } from "../index/values.js";
12
+ import { must } from "../query.js";
13
+ import { parenthesesRemoved, unwrapped } from "../unwrap.js";
14
+ /** The callee one decorator names: its expression, or the callee of the call it writes. */
15
+ export function decoratorCallee(decorator) {
16
+ const expression = decorator.expression;
17
+ return nameOf(isCallExpression(expression) ? expression.expression : expression);
18
+ }
19
+ /** How one decorator is spelled in a record: its expression, without a call's arguments. */
20
+ export function spelledDecorator(decorator) {
21
+ const expression = decorator.expression;
22
+ const named = isCallExpression(expression) ? expression.expression : expression;
23
+ return `@${named.getText().replace(/\s+/gu, "")}`;
24
+ }
25
+ /** The decorators written on one declaration. */
26
+ export function decoratorsOf(node) {
27
+ return (node.modifiers ?? []).filter(isDecorator);
28
+ }
29
+ /** The methods of `Function.prototype` that invoke a function with arguments of their own. */
30
+ const FUNCTION_METHODS = new Set(["call", "apply", "bind"]);
31
+ /** The interfaces of the standard library that declare those methods for a function value. */
32
+ const FUNCTION_INTERFACES = new Set([
33
+ "Function",
34
+ "CallableFunction",
35
+ "NewableFunction",
36
+ ]);
37
+ /**
38
+ * The invocation a call writes through a method of `Function.prototype`, read from
39
+ * the syntax alone: `f.call(self, a)`, `f.apply(self, [a])`, `f.bind(self, a)`, which
40
+ * passes `a` though nothing calls the bound function there, because the bound function
41
+ * carries `a` to wherever it is called and that call is not followed, and
42
+ * `f.bind(self, a)(b)`, which passes `b` after it. An `apply` argument
43
+ * that is no array literal is the value of the first parameter, whose elements it
44
+ * carries. Whether the method is the prototype's is resolution's to say.
45
+ */
46
+ function throughMethod(call) {
47
+ const expression = parenthesesRemoved(call.expression);
48
+ if (isPropertyAccessExpression(expression) && FUNCTION_METHODS.has(expression.name.text)) {
49
+ const [, ...rest] = call.arguments;
50
+ let passed = rest;
51
+ let listed = false;
52
+ if (expression.name.text === "apply") {
53
+ const list = rest[0] === undefined ? undefined : parenthesesRemoved(rest[0]);
54
+ listed = list !== undefined && !isArrayLiteralExpression(list);
55
+ passed = list === undefined ? [] : isArrayLiteralExpression(list) ? list.elements : [list];
56
+ }
57
+ return {
58
+ method: expression.name,
59
+ invocation: { callee: expression.expression, arguments: passed, indirect: true, listed },
60
+ };
61
+ }
62
+ if (isCallExpression(expression)) {
63
+ const bound = parenthesesRemoved(expression.expression);
64
+ if (isPropertyAccessExpression(bound) && bound.name.text === "bind") {
65
+ return {
66
+ method: bound.name,
67
+ invocation: {
68
+ callee: bound.expression,
69
+ arguments: [...expression.arguments.slice(1), ...call.arguments],
70
+ indirect: true,
71
+ listed: false,
72
+ },
73
+ };
74
+ }
75
+ }
76
+ return undefined;
77
+ }
78
+ /**
79
+ * What each of a project's calls invokes. A call through `call`, `apply` or `bind`
80
+ * invokes the function the method is read from only where the method is the standard
81
+ * library's: the program's own `call` and `Reflect.apply` pass nothing on.
82
+ */
83
+ export function invocations(project, calls) {
84
+ const forms = new Map();
85
+ for (const call of calls) {
86
+ const form = throughMethod(call);
87
+ if (form !== undefined) {
88
+ forms.set(call, form);
89
+ }
90
+ }
91
+ const callees = resolvedTargets(project, [
92
+ ...calls.flatMap((call) => nameOf(call.expression) ?? []),
93
+ ...[...forms.values()].flatMap((form) => {
94
+ const name = nameOf(form.invocation.callee);
95
+ return name === undefined ? [form.method] : [form.method, name];
96
+ }),
97
+ ]);
98
+ const standard = (method) => method.declarations.some((handle) => project.program.getSourceFileMetadata(handle.path)?.isDefaultLibrary === true) && FUNCTION_INTERFACES.has(must(project.queries.parentOf(method))?.name ?? "");
99
+ const of = (call) => {
100
+ const form = forms.get(call);
101
+ const method = form === undefined ? undefined : callees.get(form.method);
102
+ return form !== undefined && method !== undefined && standard(method)
103
+ ? form.invocation
104
+ : { callee: call.expression, arguments: call.arguments, indirect: false, listed: false };
105
+ };
106
+ return {
107
+ of,
108
+ callee: (call) => {
109
+ const name = nameOf(of(call).callee);
110
+ return name === undefined ? undefined : callees.get(name);
111
+ },
112
+ };
113
+ }
114
+ /** The declaration a shorthand property's value resolves to, an import followed to what it names. */
115
+ function shorthandTarget(project, node) {
116
+ const value = must(project.shorthandValueAt(project.handle(node)));
117
+ if (value === undefined || (value.flags & SymbolFlags.Alias) === 0) {
118
+ return value;
119
+ }
120
+ const aliased = must(project.queries.aliased(value));
121
+ return aliased.declarations.length === 0 ? undefined : aliased;
122
+ }
123
+ /**
124
+ * What one carried value holds: the declaration its name resolves to, and the classes and
125
+ * functions the checker's type at it holds ({@link constructedAt}). `known` holds names
126
+ * already resolved in a batch.
127
+ */
128
+ function heldBy(project, value, known) {
129
+ const { name } = value;
130
+ if (name === undefined) {
131
+ return { named: undefined, typed: constructedAt(project, value.site) };
132
+ }
133
+ if (value.shorthand) {
134
+ return { named: shorthandTarget(project, name), typed: [] };
135
+ }
136
+ return {
137
+ named: known?.get(name) ?? resolvedTargets(project, [name]).get(name),
138
+ typed: constructedAt(project, value.site),
139
+ };
140
+ }
141
+ /** The classes of the target each call passes, by the call, as {@link classesCarried} reads its invocation's arguments. */
142
+ export function classesPassed(project, held, chains, sites, calls) {
143
+ const carried = classesCarried(project, held, chains, sites, calls.map((call) => sites.invocations.of(call).arguments));
144
+ return new Map(calls.map((call, at) => [call, carried[at] ?? []]));
145
+ }
146
+ /**
147
+ * The classes of the target each group of written values carries: each class a value
148
+ * can carry holds as a constructor, as the checker types it. A name whose type erases
149
+ * the class is followed through what its declaration binds ({@link boundTo}) and, for a
150
+ * parameter, through what each call of its function passes at its place, so a class
151
+ * handed to a wrapper is passed. A class is used at each value that carries it. A class
152
+ * of another program is carried by nothing.
153
+ */
154
+ export function classesCarried(project, held, chains, sites, groups) {
155
+ const { invocations: invoked } = sites;
156
+ const passed = groups.map((written) => written.flatMap(carriedValues));
157
+ const targets = resolvedTargets(project, passed.flat().flatMap((value) => (value.shorthand ? [] : (value.name ?? []))));
158
+ const classes = new Set(held.symbols.filter((symbol) => symbol.kind === "class").map((symbol) => symbol.id));
159
+ let calling;
160
+ const callsOfFunction = (symbol) => {
161
+ calling ??= callsByDeclaration(project, sites.calls.map((one) => one.call), invoked);
162
+ return symbol.declarations.flatMap((handle) => calling?.get(keyOf(handle)) ?? []);
163
+ };
164
+ const classesOf = (value, seen) => {
165
+ const { named, typed } = heldBy(project, value, targets);
166
+ return [
167
+ ...typed.flatMap((symbol) => chains.declarationsOf(symbol).filter((id) => classes.has(id))),
168
+ ...(named === undefined ? [] : reached(named, seen)),
169
+ ];
170
+ };
171
+ const reached = (symbol, seen) => {
172
+ const ids = chains.declarationsOf(symbol).filter((id) => classes.has(id));
173
+ if (ids.length > 0 || seen.has(symbol.id)) {
174
+ return ids;
175
+ }
176
+ seen.add(symbol.id);
177
+ const through = (written) => carriedValues(written).flatMap((value) => classesOf(value, seen));
178
+ return symbol.declarations.flatMap((handle) => {
179
+ const node = project.declarationAt(handle)?.node;
180
+ if (node === undefined) {
181
+ return [];
182
+ }
183
+ if (isParameterDeclaration(node)) {
184
+ return argumentsAt(project, node, callsOfFunction, invoked).flatMap(through);
185
+ }
186
+ const bound = boundTo(project, node);
187
+ return [
188
+ ...(bound.written === undefined ? [] : through(bound.written)),
189
+ ...bound.symbols.flatMap((next) => reached(next, seen)),
190
+ ];
191
+ });
192
+ };
193
+ return passed.map((values) => {
194
+ const uses = new Map();
195
+ for (const value of values) {
196
+ for (const id of classesOf(value, new Set())) {
197
+ uses.set(`${id}\u0000${String(value.site.pos)}`, { id, site: value.site });
198
+ }
199
+ }
200
+ return [...uses.values()];
201
+ });
202
+ }
203
+ /**
204
+ * The symbols of the classes and functions the checker's type at one expression holds as
205
+ * values, each member of a union: the static side of a class or a function is an
206
+ * anonymous type its declaration's symbol names, which an instance's type is not.
207
+ */
208
+ function constructedAt(project, written) {
209
+ return heldIn(project, must(project.queries.typeAt(unwrapped(written))));
210
+ }
211
+ /** The classes and functions one type holds as values, as {@link constructedAt} reads them. */
212
+ function heldIn(project, type) {
213
+ const { queries } = project;
214
+ return (type === undefined ? [] : must(queries.constituents(type))).flatMap((part) => {
215
+ if (!part.isObjectType() || (part.objectFlags & ObjectFlags.Anonymous) === 0) {
216
+ return [];
217
+ }
218
+ return must(queries.symbolOfType(part)) ?? [];
219
+ });
220
+ }
221
+ /**
222
+ * What a variable, a property or a destructured binding binds its name to: a variable's
223
+ * or a property's initializer, the value a shorthand property names, or the property of
224
+ * the destructured value a binding element reads.
225
+ */
226
+ function boundTo(project, node) {
227
+ if (isShorthandPropertyAssignment(node)) {
228
+ const value = shorthandTarget(project, node);
229
+ return { symbols: value === undefined ? [] : [value] };
230
+ }
231
+ if (isBindingElement(node)) {
232
+ const key = node.propertyName ?? node.name;
233
+ if (key === undefined || !isIdentifier(key)) {
234
+ return { symbols: [] };
235
+ }
236
+ const source = must(project.queries.typeAt(node.parent));
237
+ const property = source === undefined
238
+ ? undefined
239
+ : must(project.queries.propertiesOf(source)).find((one) => one.name === key.text);
240
+ return { symbols: property === undefined ? [] : [property] };
241
+ }
242
+ const written = initializerOf(node);
243
+ return written === undefined ? { symbols: [] } : { written, symbols: [] };
244
+ }
245
+ /** The value a variable or a property declaration binds its name to, where it writes one. */
246
+ function initializerOf(node) {
247
+ return isVariableDeclaration(node) || isPropertyAssignment(node) || isPropertyDeclaration(node)
248
+ ? node.initializer
249
+ : undefined;
250
+ }
251
+ /** The key of one declaration a symbol names, the same for each symbol the checker makes of it. */
252
+ function keyOf(handle) {
253
+ return `${handle.path}#${String(handle.index)}`;
254
+ }
255
+ /**
256
+ * Every call of the project by the declarations its invoked function can be: the function
257
+ * or the method it names, or else each function the checker's type at it holds, wherever
258
+ * that value came from. A name is also followed through what its binding copies
259
+ * ({@link boundTo}), which is how a call reaches a function an annotation erases.
260
+ * Only the target's own declarations are keys, as only its own functions are asked for.
261
+ */
262
+ function callsByDeclaration(project, calls, invoked) {
263
+ const own = project.ownPaths();
264
+ const named = new Map();
265
+ const keysOf = (symbol, seen) => {
266
+ const known = named.get(symbol.id);
267
+ if (known !== undefined || seen.has(symbol.id)) {
268
+ return known ?? [];
269
+ }
270
+ seen.add(symbol.id);
271
+ const keys = symbol.declarations
272
+ .filter((handle) => own.has(handle.path))
273
+ .flatMap((handle) => {
274
+ const node = project.declarationAt(handle)?.node;
275
+ const bound = node === undefined ? { symbols: [] } : boundTo(project, node);
276
+ const copied = [
277
+ ...bound.symbols,
278
+ ...(bound.written === undefined ? [] : carriedValues(bound.written)).flatMap((value) => {
279
+ const { named: next, typed } = heldBy(project, value);
280
+ return [...typed, ...(next === undefined ? [] : [next])];
281
+ }),
282
+ ];
283
+ return [keyOf(handle), ...copied.flatMap((next) => keysOf(next, seen))];
284
+ });
285
+ named.set(symbol.id, keys);
286
+ return keys;
287
+ };
288
+ const declared = (call) => ((invoked.callee(call)?.flags ?? 0) & (SymbolFlags.Function | SymbolFlags.Method)) !== 0;
289
+ const typed = calls.filter((call) => !declared(call));
290
+ const types = new Map(project.queries
291
+ .typesAt(typed.map((call) => unwrapped(invoked.of(call).callee)))
292
+ .map((type, index) => [typed[index], must(type)]));
293
+ const found = new Map();
294
+ for (const call of calls) {
295
+ const callee = invoked.callee(call);
296
+ const held = [
297
+ ...(callee === undefined ? [] : [callee]),
298
+ ...(types.has(call) ? heldIn(project, types.get(call)) : []),
299
+ ];
300
+ for (const key of new Set(held.flatMap((symbol) => keysOf(symbol, new Set())))) {
301
+ found.set(key, [...(found.get(key) ?? []), call]);
302
+ }
303
+ }
304
+ return found;
305
+ }
306
+ /**
307
+ * What each call of the function a parameter belongs to passes at the parameter's place,
308
+ * every argument from there on for a rest parameter, as the call's invocation binds them.
309
+ * The function is the one the checker's type at its own declaration names, so a function
310
+ * with no name of its own is called too. A `this` parameter takes no place, and an
311
+ * argument at or after a spread argument passes at every place the spread's length can
312
+ * move it to.
313
+ */
314
+ function argumentsAt(project, parameter, callsOfFunction, invoked) {
315
+ const owner = parameter.parent;
316
+ if (!isFunctionDeclaration(owner) &&
317
+ !isMethodDeclaration(owner) &&
318
+ !isArrowFunction(owner) &&
319
+ !isFunctionExpression(owner)) {
320
+ return [];
321
+ }
322
+ const calls = new Set(constructedAt(project, owner).flatMap(callsOfFunction));
323
+ const [first] = owner.parameters;
324
+ const erased = first !== undefined && isIdentifier(first.name) && first.name.text === "this";
325
+ const place = owner.parameters.indexOf(parameter) - (erased ? 1 : 0);
326
+ const rest = parameter.dotDotDotToken !== undefined;
327
+ return [...calls].flatMap((call) => {
328
+ let spreads = 0;
329
+ return invoked.of(call).arguments.flatMap((argument, index) => {
330
+ const spread = isSpreadElement(argument);
331
+ const earliest = index - spreads;
332
+ spreads += spread ? 1 : 0;
333
+ const open = spread || earliest < index;
334
+ const lands = open ? rest || earliest <= place : rest ? index >= place : index === place;
335
+ return lands ? [spread ? argument.expression : argument] : [];
336
+ });
337
+ });
338
+ }
@@ -0,0 +1,13 @@
1
+ import { EXEMPTION_CLASSES } from "../contract/contract.generated.js";
2
+ function runsOnTS(row) {
3
+ const languages = row.languages;
4
+ return languages.includes("ts");
5
+ }
6
+ const TS_ROWS = EXEMPTION_CLASSES.filter(runsOnTS);
7
+ /** The classes that run on TypeScript, in the vocabulary's order. */
8
+ export const TS_EXEMPTION_CLASSES = TS_ROWS.map((row) => row.class);
9
+ const VISIBILITY = new Map(TS_ROWS.map((row) => [row.class, row.typescriptVisibility]));
10
+ /** Which private members one class that runs on TypeScript may retain. */
11
+ export function typescriptVisibilityOf(exemptionClass) {
12
+ return VISIBILITY.get(exemptionClass) ?? { private: false, privateName: false };
13
+ }
@@ -7,8 +7,8 @@
7
7
  * static members of a decorated class included.
8
8
  */
9
9
  import { decoratorsOf, spelledDecorator } from "./calls.js";
10
- import { isParameterProperty, nodeKey, } from "./inventory.js";
11
- import { renderPosition } from "./position.js";
10
+ import { isParameterProperty } from "../inventory.js";
11
+ import { renderPosition } from "../position.js";
12
12
  /** The kinds of declaration a decorator is attached to and holds back. */
13
13
  const DECORATED = new Set(["class", "method", "class-member"]);
14
14
  /**
@@ -16,7 +16,7 @@ const DECORATED = new Set(["class", "method", "class-member"]);
16
16
  * class, recorded at the decorator.
17
17
  */
18
18
  export function decorator(input) {
19
- const { project, held, targetRoot } = input;
19
+ const { held, sites, targetRoot } = input;
20
20
  const byId = new Map(held.symbols.map((symbol) => [symbol.id, symbol]));
21
21
  const membersOf = new Map();
22
22
  for (const symbol of held.symbols) {
@@ -30,32 +30,21 @@ export function decorator(input) {
30
30
  }
31
31
  }
32
32
  }
33
- const decorated = [];
34
33
  // A decorated class's container passes each constructor argument, which keeps the
35
- // parameter, not the member a parameter property stores it in.
36
- const parameterMembers = new Set();
37
- for (const file of project.ownSourceFiles()) {
38
- const visit = (node) => {
39
- const id = held.declarations.get(nodeKey(file, node));
40
- const symbol = id === undefined ? undefined : byId.get(id);
41
- if (id !== undefined && isParameterProperty(node)) {
42
- parameterMembers.add(id);
43
- }
44
- // A parameter property's decorator is attached to its parameter, and to no member.
45
- if (symbol !== undefined && DECORATED.has(symbol.kind) && !isParameterProperty(node)) {
46
- for (const attached of decoratorsOf(node)) {
47
- decorated.push({
48
- symbol,
49
- detail: `decorated by ${spelledDecorator(attached)}`,
50
- site: renderPosition(file, targetRoot, attached.getStart()),
51
- });
52
- }
53
- }
54
- node.forEachChild(visit);
55
- };
56
- file.forEachChild(visit);
57
- }
58
- return decorated.flatMap(({ symbol, detail, site }) => (symbol.kind === "class"
59
- ? (membersOf.get(symbol.id) ?? []).filter((member) => !parameterMembers.has(member.id))
60
- : [symbol]).map((member) => ({ id: member.id, detail, site })));
34
+ // parameter, not the member a parameter property stores it in. A parameter property's
35
+ // decorator is attached to its parameter, and to no member.
36
+ return sites.decorated.flatMap(({ id, node }) => {
37
+ const symbol = byId.get(id);
38
+ if (symbol === undefined || !DECORATED.has(symbol.kind) || isParameterProperty(node)) {
39
+ return [];
40
+ }
41
+ const members = symbol.kind === "class"
42
+ ? (membersOf.get(symbol.id) ?? []).filter((member) => !sites.parameterProperties.has(member.id))
43
+ : [symbol];
44
+ return decoratorsOf(node).flatMap((attached) => {
45
+ const detail = `decorated by ${spelledDecorator(attached)}`;
46
+ const site = renderPosition(node.getSourceFile(), targetRoot, attached.getStart());
47
+ return members.map((member) => ({ id: member.id, detail, site }));
48
+ });
49
+ });
61
50
  }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The exemption classes this analyzer detects, each by its detector, and what their
3
+ * detection reads of the run once for every project. A class without a detector here
4
+ * retains nothing.
5
+ */
6
+ import { decorator } from "./decorator.js";
7
+ import { enumGroup } from "./enum-group.js";
8
+ import { frameworkLifecycle } from "./framework-lifecycle.js";
9
+ import { generatedFile } from "./generated-file.js";
10
+ import { injectionContainer } from "./injection-container.js";
11
+ import { interfaceSatisfaction } from "./interface-satisfaction.js";
12
+ import { detect } from "./lifecycle.js";
13
+ import { reflectiveLookup } from "./reflective-lookup.js";
14
+ import { serializationContract } from "./serialization-contract.js";
15
+ import { readTemplates, templateField } from "./template-field.js";
16
+ export const DETECTORS = new Map([
17
+ ["interface-satisfaction", interfaceSatisfaction],
18
+ ["enum-group", enumGroup],
19
+ ["generated-file", generatedFile],
20
+ ["template-field", templateField],
21
+ ["reflective-lookup", reflectiveLookup],
22
+ ["decorator", decorator],
23
+ ["injection-container", injectionContainer],
24
+ ["framework-lifecycle", frameworkLifecycle],
25
+ ["serialization-contract", serializationContract],
26
+ ]);
27
+ /**
28
+ * The detection of one run: what every project's detectors read of the run, read once,
29
+ * and a function that runs them over one project. A switched-off class reads nothing,
30
+ * its templates included, and generated files are held only where the configuration
31
+ * leaves them out of the analysis.
32
+ */
33
+ export function detection(host, targetRoot, config, consumers, detectors) {
34
+ const disabled = new Set(config.exemptions.disabled);
35
+ const templates = disabled.has("template-field")
36
+ ? { delimiters: config.analysis.template_delimiters, files: [] }
37
+ : readTemplates(host, targetRoot, config.analysis);
38
+ const included = config.analysis.generated_files === "include";
39
+ return ({ project, held, generated }) => detect({
40
+ project,
41
+ held,
42
+ targetRoot,
43
+ templates,
44
+ ts: config.ts,
45
+ consumers,
46
+ ...(included ? {} : { generated }),
47
+ }, detectors, disabled);
48
+ }
@@ -6,24 +6,17 @@
6
6
  * or `unknown` expression asserted to it, or bound to a variable or returned from a
7
7
  * function it annotates, where a number counts too. An enum's own value converts nothing.
8
8
  */
9
- import { isArrowFunction, isAsExpression, isElementAccessExpression, isEnumDeclaration, isFunctionDeclaration, isFunctionExpression, isGetAccessorDeclaration, isIdentifier, isMethodDeclaration, isNoSubstitutionTemplateLiteral, isParenthesizedExpression, isParenthesizedTypeNode, isPropertyAccessExpression, isReturnStatement, isStringLiteral, isVariableDeclaration, SyntaxKind, } from "@typescript/native/ast";
9
+ import { isArrowFunction, isAsExpression, isElementAccessExpression, isEnumDeclaration, isFunctionDeclaration, isFunctionExpression, isGetAccessorDeclaration, isIdentifier, isMethodDeclaration, isNoSubstitutionTemplateLiteral, isParenthesizedTypeNode, isPropertyAccessExpression, isReturnStatement, isStringLiteral, isVariableDeclaration, SyntaxKind, } from "@typescript/native/ast";
10
+ import { parenthesesRemoved } from "../unwrap.js";
10
11
  import { TypeFlags } from "@typescript/native/sync";
11
- import { aliasChains } from "./alias-chain.js";
12
- import { nodeKey } from "./inventory.js";
13
- import { renderPosition } from "./position.js";
14
- import { isAnswered, UNANSWERED } from "./query.js";
12
+ import { aliasChains } from "../alias-chain.js";
13
+ import { nodeKey } from "../inventory.js";
14
+ import { renderPosition } from "../position.js";
15
+ import { isAnswered, UNANSWERED } from "../query.js";
16
+ import { ERASED } from "./value-reach.js";
15
17
  /** The operand types a conversion produces an enum value from. */
16
18
  const NUMBER = TypeFlags.NumberLike;
17
19
  const STRING = TypeFlags.StringLike;
18
- const DECODED = TypeFlags.Any | TypeFlags.Unknown;
19
- /** The expression one node is, through however many parentheses are written around it. */
20
- function unparenthesized(node) {
21
- let held = node;
22
- while (isParenthesizedExpression(held)) {
23
- held = held.expression;
24
- }
25
- return held;
26
- }
27
20
  /**
28
21
  * The name node a type node names its declaration by: the identifier of a type
29
22
  * reference, the right side of a qualified one, through parentheses. A type that is no
@@ -45,7 +38,7 @@ function typeName(type) {
45
38
  }
46
39
  /** The name node an expression names an object by: an identifier, or a property access's name. */
47
40
  function objectName(expression) {
48
- const held = unparenthesized(expression);
41
+ const held = parenthesesRemoved(expression);
49
42
  if (isIdentifier(held)) {
50
43
  return held;
51
44
  }
@@ -135,7 +128,7 @@ function detailOf(project, site, enumName, operand) {
135
128
  if (parts.some((part) => (part.flags & STRING) !== 0)) {
136
129
  return site.form === "assertion" ? "converted from string" : undefined;
137
130
  }
138
- if (parts.some((part) => (part.flags & DECODED) !== 0)) {
131
+ if (parts.some((part) => (part.flags & ERASED) !== 0)) {
139
132
  return `decoded as ${enumName}`;
140
133
  }
141
134
  return undefined;
@@ -6,12 +6,11 @@
6
6
  * either stores. A store into an erased property of a type the analyzed program does not
7
7
  * declare hands the value to the code that declares it.
8
8
  */
9
- import { isArrayLiteralExpression, isBinaryExpression, isCallExpression, isElementAccessExpression, isIdentifier, isNoSubstitutionTemplateLiteral, isNumericLiteral, isObjectLiteralExpression, isParenthesizedExpression, isPropertyAccessExpression, isPropertyAssignment, isShorthandPropertyAssignment, isSpreadElement, isStringLiteral, isVariableDeclaration, SyntaxKind, } from "@typescript/native/ast";
10
- import { SymbolFlags, TypeFlags } from "@typescript/native/sync";
11
- import { must } from "./query.js";
12
- import { checkedTypes } from "./value-reach.js";
13
- /** The types that keep nothing of the value they are given. */
14
- const ERASED = TypeFlags.Any | TypeFlags.Unknown;
9
+ import { isArrayLiteralExpression, isBinaryExpression, isCallExpression, isElementAccessExpression, isIdentifier, isNoSubstitutionTemplateLiteral, isNumericLiteral, isObjectLiteralExpression, isPropertyAccessExpression, isPropertyAssignment, isShorthandPropertyAssignment, isSpreadElement, isStringLiteral, isVariableDeclaration, SyntaxKind, } from "@typescript/native/ast";
10
+ import { SymbolFlags } from "@typescript/native/sync";
11
+ import { must } from "../query.js";
12
+ import { checkedTypes, ERASED } from "./value-reach.js";
13
+ import { parenthesesRemoved } from "../unwrap.js";
15
14
  /** The array methods whose arguments become elements of the array they are called on. */
16
15
  const ELEMENT_STORES = new Set(["push", "unshift"]);
17
16
  /** The name an element access's literal index spells, or none. */
@@ -20,9 +19,6 @@ function literalKey(node) {
20
19
  ? node.text
21
20
  : undefined;
22
21
  }
23
- function unwrapped(node) {
24
- return isParenthesizedExpression(node) ? unwrapped(node.expression) : node;
25
- }
26
22
  /**
27
23
  * Whether a variable declaration's type can differ from what is stored in it: it carries an
28
24
  * annotation, or it has neither an annotation nor an initializer, so its type evolves.
@@ -76,8 +72,8 @@ function propertyAt(source, name) {
76
72
  * here, and a default value is stored in its target too.
77
73
  */
78
74
  function patternTargets(pattern, from, out) {
79
- const target = unwrapped(pattern);
80
- const source = from.path.length === 0 ? unwrapped(from.value) : from.value;
75
+ const target = parenthesesRemoved(pattern);
76
+ const source = from.path.length === 0 ? parenthesesRemoved(from.value) : from.value;
81
77
  const into = (element, step, literal) => {
82
78
  patternTargets(element, literal === undefined
83
79
  ? { value: from.value, path: [...from.path, step] }