@geastack/compiler 1.0.15

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 (966) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +149 -0
  3. package/dist/cli-analyze.d.ts +1 -0
  4. package/dist/cli-analyze.js +61 -0
  5. package/dist/cli-coverage.d.ts +1 -0
  6. package/dist/cli-coverage.js +329 -0
  7. package/dist/cli-emit.d.ts +10 -0
  8. package/dist/cli-emit.js +398 -0
  9. package/dist/cli-module-graph.d.ts +18 -0
  10. package/dist/cli-module-graph.js +123 -0
  11. package/dist/cli-package-source.d.ts +5 -0
  12. package/dist/cli-package-source.js +116 -0
  13. package/dist/cli-project.d.ts +2 -0
  14. package/dist/cli-project.js +60 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +199 -0
  17. package/dist/compiler.d.ts +228 -0
  18. package/dist/compiler.js +1029 -0
  19. package/dist/conversion/algebra.d.ts +218 -0
  20. package/dist/conversion/algebra.js +155 -0
  21. package/dist/conversion/build.d.ts +67 -0
  22. package/dist/conversion/build.js +1378 -0
  23. package/dist/conversion/derive.d.ts +37 -0
  24. package/dist/conversion/derive.js +260 -0
  25. package/dist/conversion/graph-validation.d.ts +8 -0
  26. package/dist/conversion/graph-validation.js +97 -0
  27. package/dist/conversion/native-callable-adapter.d.ts +13 -0
  28. package/dist/conversion/native-callable-adapter.js +53 -0
  29. package/dist/conversion/native-class-reference.d.ts +12 -0
  30. package/dist/conversion/native-class-reference.js +39 -0
  31. package/dist/conversion/native-payload-transport.d.ts +25 -0
  32. package/dist/conversion/native-payload-transport.js +33 -0
  33. package/dist/conversion/native-selection.d.ts +49 -0
  34. package/dist/conversion/native-selection.js +135 -0
  35. package/dist/conversion/native-sum.d.ts +42 -0
  36. package/dist/conversion/native-sum.js +115 -0
  37. package/dist/conversion/nodes.d.ts +55 -0
  38. package/dist/conversion/nodes.js +91 -0
  39. package/dist/conversion/operand-view.d.ts +14 -0
  40. package/dist/conversion/operand-view.js +20 -0
  41. package/dist/conversion/record-view.d.ts +157 -0
  42. package/dist/conversion/record-view.js +273 -0
  43. package/dist/conversion/registry.d.ts +217 -0
  44. package/dist/conversion/registry.js +1 -0
  45. package/dist/diagnostics/model.d.ts +76 -0
  46. package/dist/diagnostics/model.js +60 -0
  47. package/dist/diagnostics/sweep.d.ts +31 -0
  48. package/dist/diagnostics/sweep.js +112 -0
  49. package/dist/identity/ids.d.ts +179 -0
  50. package/dist/identity/ids.js +212 -0
  51. package/dist/ir/absent-class-arm.d.ts +48 -0
  52. package/dist/ir/absent-class-arm.js +157 -0
  53. package/dist/ir/borrow-effects.d.ts +23 -0
  54. package/dist/ir/borrow-effects.js +151 -0
  55. package/dist/ir/borrowed-call-arguments.d.ts +40 -0
  56. package/dist/ir/borrowed-call-arguments.js +117 -0
  57. package/dist/ir/build.d.ts +168 -0
  58. package/dist/ir/build.js +459 -0
  59. package/dist/ir/call-dispatch.d.ts +38 -0
  60. package/dist/ir/call-dispatch.js +502 -0
  61. package/dist/ir/call-entry.d.ts +142 -0
  62. package/dist/ir/call-entry.js +386 -0
  63. package/dist/ir/callable-class-flow.d.ts +27 -0
  64. package/dist/ir/callable-class-flow.js +1386 -0
  65. package/dist/ir/callable-field-slots.d.ts +22 -0
  66. package/dist/ir/callable-field-slots.js +166 -0
  67. package/dist/ir/callable-identity-demand.d.ts +52 -0
  68. package/dist/ir/callable-identity-demand.js +460 -0
  69. package/dist/ir/callable-member-candidates.d.ts +9 -0
  70. package/dist/ir/callable-member-candidates.js +39 -0
  71. package/dist/ir/callable-records.d.ts +21 -0
  72. package/dist/ir/callable-records.js +411 -0
  73. package/dist/ir/captures.d.ts +26 -0
  74. package/dist/ir/captures.js +335 -0
  75. package/dist/ir/certificate.d.ts +45 -0
  76. package/dist/ir/certificate.js +47 -0
  77. package/dist/ir/certify/carrier-keys.d.ts +73 -0
  78. package/dist/ir/certify/carrier-keys.js +221 -0
  79. package/dist/ir/certify/function-source.d.ts +4 -0
  80. package/dist/ir/certify/function-source.js +28 -0
  81. package/dist/ir/certify/has-property-key.d.ts +88 -0
  82. package/dist/ir/certify/has-property-key.js +116 -0
  83. package/dist/ir/certify/instanceof-key.d.ts +24 -0
  84. package/dist/ir/certify/instanceof-key.js +35 -0
  85. package/dist/ir/certify/property-access-keys.d.ts +172 -0
  86. package/dist/ir/certify/property-access-keys.js +291 -0
  87. package/dist/ir/certify/property-access.d.ts +3 -0
  88. package/dist/ir/certify/property-access.js +597 -0
  89. package/dist/ir/certify/runtime-helper.d.ts +3 -0
  90. package/dist/ir/certify/runtime-helper.js +326 -0
  91. package/dist/ir/certify/typeof-operand.d.ts +14 -0
  92. package/dist/ir/certify/typeof-operand.js +16 -0
  93. package/dist/ir/certify.d.ts +123 -0
  94. package/dist/ir/certify.js +481 -0
  95. package/dist/ir/class-evaluation.d.ts +26 -0
  96. package/dist/ir/class-evaluation.js +50 -0
  97. package/dist/ir/class-static-fields.d.ts +60 -0
  98. package/dist/ir/class-static-fields.js +108 -0
  99. package/dist/ir/construct-entry.d.ts +26 -0
  100. package/dist/ir/construct-entry.js +117 -0
  101. package/dist/ir/dead-values.d.ts +90 -0
  102. package/dist/ir/dead-values.js +184 -0
  103. package/dist/ir/deferral.d.ts +99 -0
  104. package/dist/ir/deferral.js +409 -0
  105. package/dist/ir/dense-loops.d.ts +230 -0
  106. package/dist/ir/dense-loops.js +697 -0
  107. package/dist/ir/dominance.d.ts +82 -0
  108. package/dist/ir/dominance.js +268 -0
  109. package/dist/ir/emission-representations.d.ts +71 -0
  110. package/dist/ir/emission-representations.js +350 -0
  111. package/dist/ir/facts.d.ts +218 -0
  112. package/dist/ir/facts.js +181 -0
  113. package/dist/ir/fixed-data-definition.d.ts +19 -0
  114. package/dist/ir/fixed-data-definition.js +49 -0
  115. package/dist/ir/generator-split.d.ts +38 -0
  116. package/dist/ir/generator-split.js +329 -0
  117. package/dist/ir/hoist.d.ts +55 -0
  118. package/dist/ir/hoist.js +375 -0
  119. package/dist/ir/instantiation.d.ts +61 -0
  120. package/dist/ir/instantiation.js +137 -0
  121. package/dist/ir/integer-storage.d.ts +170 -0
  122. package/dist/ir/integer-storage.js +822 -0
  123. package/dist/ir/integers.d.ts +161 -0
  124. package/dist/ir/integers.js +539 -0
  125. package/dist/ir/integrity-restrictions.d.ts +50 -0
  126. package/dist/ir/integrity-restrictions.js +118 -0
  127. package/dist/ir/local-iterators.d.ts +4 -0
  128. package/dist/ir/local-iterators.js +27 -0
  129. package/dist/ir/lower-allocation.d.ts +4 -0
  130. package/dist/ir/lower-allocation.js +325 -0
  131. package/dist/ir/lower-completion.d.ts +15 -0
  132. package/dist/ir/lower-completion.js +25 -0
  133. package/dist/ir/lower-destructuring.d.ts +5 -0
  134. package/dist/ir/lower-destructuring.js +693 -0
  135. package/dist/ir/lower-element.d.ts +29 -0
  136. package/dist/ir/lower-element.js +111 -0
  137. package/dist/ir/lower-exceptions.d.ts +47 -0
  138. package/dist/ir/lower-exceptions.js +92 -0
  139. package/dist/ir/lower-flow.d.ts +137 -0
  140. package/dist/ir/lower-flow.js +600 -0
  141. package/dist/ir/lower-graph.d.ts +218 -0
  142. package/dist/ir/lower-graph.js +687 -0
  143. package/dist/ir/lower-invocation.d.ts +4 -0
  144. package/dist/ir/lower-invocation.js +514 -0
  145. package/dist/ir/lower-narrow.d.ts +53 -0
  146. package/dist/ir/lower-narrow.js +320 -0
  147. package/dist/ir/lower-operands.d.ts +272 -0
  148. package/dist/ir/lower-operands.js +461 -0
  149. package/dist/ir/lower-property.d.ts +21 -0
  150. package/dist/ir/lower-property.js +132 -0
  151. package/dist/ir/lower-protocol.d.ts +11 -0
  152. package/dist/ir/lower-protocol.js +118 -0
  153. package/dist/ir/lower-short-circuit.d.ts +41 -0
  154. package/dist/ir/lower-short-circuit.js +63 -0
  155. package/dist/ir/lower.d.ts +82 -0
  156. package/dist/ir/lower.js +1346 -0
  157. package/dist/ir/model.d.ts +1474 -0
  158. package/dist/ir/model.js +6 -0
  159. package/dist/ir/native-absent-property.d.ts +3 -0
  160. package/dist/ir/native-absent-property.js +13 -0
  161. package/dist/ir/native-array-transport.d.ts +7 -0
  162. package/dist/ir/native-array-transport.js +46 -0
  163. package/dist/ir/native-callable-bind.d.ts +9 -0
  164. package/dist/ir/native-callable-bind.js +30 -0
  165. package/dist/ir/native-carrier-predicate.d.ts +34 -0
  166. package/dist/ir/native-carrier-predicate.js +49 -0
  167. package/dist/ir/native-class-accessor.d.ts +18 -0
  168. package/dist/ir/native-class-accessor.js +52 -0
  169. package/dist/ir/native-class-construction.d.ts +16 -0
  170. package/dist/ir/native-class-construction.js +71 -0
  171. package/dist/ir/native-class-initialization.d.ts +15 -0
  172. package/dist/ir/native-class-initialization.js +56 -0
  173. package/dist/ir/native-class-origins.d.ts +13 -0
  174. package/dist/ir/native-class-origins.js +237 -0
  175. package/dist/ir/native-dictionary-transport.d.ts +6 -0
  176. package/dist/ir/native-dictionary-transport.js +37 -0
  177. package/dist/ir/native-enumeration.d.ts +14 -0
  178. package/dist/ir/native-enumeration.js +26 -0
  179. package/dist/ir/native-equality.d.ts +10 -0
  180. package/dist/ir/native-equality.js +18 -0
  181. package/dist/ir/native-field-owner.d.ts +37 -0
  182. package/dist/ir/native-field-owner.js +183 -0
  183. package/dist/ir/native-fixed-layout.d.ts +41 -0
  184. package/dist/ir/native-fixed-layout.js +232 -0
  185. package/dist/ir/native-host-construction.d.ts +53 -0
  186. package/dist/ir/native-host-construction.js +62 -0
  187. package/dist/ir/native-key-query.d.ts +4 -0
  188. package/dist/ir/native-key-query.js +38 -0
  189. package/dist/ir/native-merge-transport.d.ts +25 -0
  190. package/dist/ir/native-merge-transport.js +71 -0
  191. package/dist/ir/native-record-index-transport.d.ts +11 -0
  192. package/dist/ir/native-record-index-transport.js +34 -0
  193. package/dist/ir/native-record-index.d.ts +12 -0
  194. package/dist/ir/native-record-index.js +27 -0
  195. package/dist/ir/native-reflect-field.d.ts +5 -0
  196. package/dist/ir/native-reflect-field.js +33 -0
  197. package/dist/ir/native-sequence-transport.d.ts +7 -0
  198. package/dist/ir/native-sequence-transport.js +53 -0
  199. package/dist/ir/numeric-intrinsics.d.ts +13 -0
  200. package/dist/ir/numeric-intrinsics.js +57 -0
  201. package/dist/ir/object-value-conversions.d.ts +20 -0
  202. package/dist/ir/object-value-conversions.js +50 -0
  203. package/dist/ir/physical-class-reflection.d.ts +9 -0
  204. package/dist/ir/physical-class-reflection.js +57 -0
  205. package/dist/ir/presence-proof.d.ts +42 -0
  206. package/dist/ir/presence-proof.js +490 -0
  207. package/dist/ir/program-facts.d.ts +106 -0
  208. package/dist/ir/program-facts.js +319 -0
  209. package/dist/ir/proven-branches.d.ts +16 -0
  210. package/dist/ir/proven-branches.js +219 -0
  211. package/dist/ir/queries.d.ts +41 -0
  212. package/dist/ir/queries.js +213 -0
  213. package/dist/ir/reflection-demand.d.ts +64 -0
  214. package/dist/ir/reflection-demand.js +1394 -0
  215. package/dist/ir/refusal.d.ts +43 -0
  216. package/dist/ir/refusal.js +28 -0
  217. package/dist/ir/shake.d.ts +37 -0
  218. package/dist/ir/shake.js +1078 -0
  219. package/dist/ir/static-callables.d.ts +11 -0
  220. package/dist/ir/static-callables.js +163 -0
  221. package/dist/ir/string-layout-reuse.d.ts +13 -0
  222. package/dist/ir/string-layout-reuse.js +39 -0
  223. package/dist/ir/string-length-reuse.d.ts +8 -0
  224. package/dist/ir/string-length-reuse.js +47 -0
  225. package/dist/ir/transfer.d.ts +78 -0
  226. package/dist/ir/transfer.js +270 -0
  227. package/dist/ir/type-query-results.d.ts +25 -0
  228. package/dist/ir/type-query-results.js +96 -0
  229. package/dist/ir/typed-property-access.d.ts +100 -0
  230. package/dist/ir/typed-property-access.js +161 -0
  231. package/dist/ir/verify.d.ts +19 -0
  232. package/dist/ir/verify.js +355 -0
  233. package/dist/plugins/apple/constructors.d.ts +112 -0
  234. package/dist/plugins/apple/constructors.js +217 -0
  235. package/dist/plugins/apple/host.d.ts +181 -0
  236. package/dist/plugins/apple/host.js +262 -0
  237. package/dist/plugins/apple/jsx.d.ts +2 -0
  238. package/dist/plugins/apple/jsx.js +293 -0
  239. package/dist/plugins/apple/members.d.ts +16 -0
  240. package/dist/plugins/apple/members.js +190 -0
  241. package/dist/plugins/apple/plugin.d.ts +2 -0
  242. package/dist/plugins/apple/plugin.js +156 -0
  243. package/dist/plugins/gea/component-classes.d.ts +25 -0
  244. package/dist/plugins/gea/component-classes.js +162 -0
  245. package/dist/plugins/gea/component-inline.d.ts +13 -0
  246. package/dist/plugins/gea/component-inline.js +532 -0
  247. package/dist/plugins/gea/constructors.d.ts +23 -0
  248. package/dist/plugins/gea/constructors.js +100 -0
  249. package/dist/plugins/gea/contract.d.ts +150 -0
  250. package/dist/plugins/gea/contract.js +195 -0
  251. package/dist/plugins/gea/element-ref.d.ts +31 -0
  252. package/dist/plugins/gea/element-ref.js +45 -0
  253. package/dist/plugins/gea/host.d.ts +520 -0
  254. package/dist/plugins/gea/host.js +762 -0
  255. package/dist/plugins/gea/lower.d.ts +6 -0
  256. package/dist/plugins/gea/lower.js +195 -0
  257. package/dist/plugins/gea/members.d.ts +22 -0
  258. package/dist/plugins/gea/members.js +221 -0
  259. package/dist/plugins/gea/plugin.d.ts +22 -0
  260. package/dist/plugins/gea/plugin.js +307 -0
  261. package/dist/plugins/gea/prelude.d.ts +78 -0
  262. package/dist/plugins/gea/prelude.js +153 -0
  263. package/dist/plugins/gea/producer.d.ts +5 -0
  264. package/dist/plugins/gea/producer.js +52 -0
  265. package/dist/plugins/gea/reactive-slots.d.ts +49 -0
  266. package/dist/plugins/gea/reactive-slots.js +578 -0
  267. package/dist/plugins/gea/render-bridge.d.ts +6 -0
  268. package/dist/plugins/gea/render-bridge.js +281 -0
  269. package/dist/plugins/gea/slots.d.ts +15 -0
  270. package/dist/plugins/gea/slots.js +36 -0
  271. package/dist/plugins/gea/template-analysis.d.ts +151 -0
  272. package/dist/plugins/gea/template-analysis.js +346 -0
  273. package/dist/plugins/gea/user-agent-styles.d.ts +9 -0
  274. package/dist/plugins/gea/user-agent-styles.js +94 -0
  275. package/dist/plugins/installed.d.ts +19 -0
  276. package/dist/plugins/installed.js +21 -0
  277. package/dist/plugins/load.d.ts +7 -0
  278. package/dist/plugins/load.js +207 -0
  279. package/dist/plugins/model.d.ts +735 -0
  280. package/dist/plugins/model.js +47 -0
  281. package/dist/plugins/webgl/host.d.ts +77 -0
  282. package/dist/plugins/webgl/host.js +162 -0
  283. package/dist/plugins/webgl/plugin.d.ts +40 -0
  284. package/dist/plugins/webgl/plugin.js +99 -0
  285. package/dist/preflight/obligations.d.ts +206 -0
  286. package/dist/preflight/obligations.js +36 -0
  287. package/dist/preflight/report.d.ts +20 -0
  288. package/dist/preflight/report.js +61 -0
  289. package/dist/preflight/run.d.ts +39 -0
  290. package/dist/preflight/run.js +403 -0
  291. package/dist/project-preparation.d.ts +33 -0
  292. package/dist/project-preparation.js +314 -0
  293. package/dist/projection/abi.d.ts +82 -0
  294. package/dist/projection/abi.js +349 -0
  295. package/dist/projection/apply-arguments.d.ts +12 -0
  296. package/dist/projection/apply-arguments.js +20 -0
  297. package/dist/projection/bindings.d.ts +250 -0
  298. package/dist/projection/bindings.js +340 -0
  299. package/dist/projection/callee.d.ts +196 -0
  300. package/dist/projection/callee.js +444 -0
  301. package/dist/projection/class-property-presence.d.ts +28 -0
  302. package/dist/projection/class-property-presence.js +58 -0
  303. package/dist/projection/class-prototype.d.ts +5 -0
  304. package/dist/projection/class-prototype.js +23 -0
  305. package/dist/projection/class-storage.d.ts +26 -0
  306. package/dist/projection/class-storage.js +236 -0
  307. package/dist/projection/classes.d.ts +283 -0
  308. package/dist/projection/classes.js +944 -0
  309. package/dist/projection/coercions.d.ts +20 -0
  310. package/dist/projection/coercions.js +33 -0
  311. package/dist/projection/dispatch.d.ts +167 -0
  312. package/dist/projection/dispatch.js +379 -0
  313. package/dist/projection/fields.d.ts +123 -0
  314. package/dist/projection/fields.js +383 -0
  315. package/dist/projection/instance-test.d.ts +78 -0
  316. package/dist/projection/instance-test.js +156 -0
  317. package/dist/projection/slots.d.ts +146 -0
  318. package/dist/projection/slots.js +663 -0
  319. package/dist/projection/synthesized-abi.d.ts +61 -0
  320. package/dist/projection/synthesized-abi.js +94 -0
  321. package/dist/representation/array-index.d.ts +14 -0
  322. package/dist/representation/array-index.js +17 -0
  323. package/dist/representation/callable-object.d.ts +3 -0
  324. package/dist/representation/callable-object.js +6 -0
  325. package/dist/representation/collections.d.ts +84 -0
  326. package/dist/representation/collections.js +139 -0
  327. package/dist/representation/derive.d.ts +159 -0
  328. package/dist/representation/derive.js +2546 -0
  329. package/dist/representation/difference.d.ts +30 -0
  330. package/dist/representation/difference.js +240 -0
  331. package/dist/representation/field-descriptor-policy.d.ts +19 -0
  332. package/dist/representation/field-descriptor-policy.js +39 -0
  333. package/dist/representation/function-constructor.d.ts +13 -0
  334. package/dist/representation/function-constructor.js +9 -0
  335. package/dist/representation/host-abi.d.ts +32 -0
  336. package/dist/representation/host-abi.js +97 -0
  337. package/dist/representation/host-templates.d.ts +67 -0
  338. package/dist/representation/host-templates.js +94 -0
  339. package/dist/representation/intersection.d.ts +84 -0
  340. package/dist/representation/intersection.js +149 -0
  341. package/dist/representation/literal-destination.d.ts +43 -0
  342. package/dist/representation/literal-destination.js +133 -0
  343. package/dist/representation/merge.d.ts +18 -0
  344. package/dist/representation/merge.js +83 -0
  345. package/dist/representation/model.d.ts +1160 -0
  346. package/dist/representation/model.js +1019 -0
  347. package/dist/representation/numeric-index.d.ts +13 -0
  348. package/dist/representation/numeric-index.js +29 -0
  349. package/dist/representation/object-shape.d.ts +109 -0
  350. package/dist/representation/object-shape.js +123 -0
  351. package/dist/representation/optional.d.ts +12 -0
  352. package/dist/representation/optional.js +87 -0
  353. package/dist/representation/plan.d.ts +60 -0
  354. package/dist/representation/plan.js +78 -0
  355. package/dist/representation/policies.d.ts +589 -0
  356. package/dist/representation/policies.js +107 -0
  357. package/dist/representation/primitive-domain.d.ts +1 -0
  358. package/dist/representation/primitive-domain.js +1 -0
  359. package/dist/representation/primitives.d.ts +44 -0
  360. package/dist/representation/primitives.js +78 -0
  361. package/dist/representation/publish.d.ts +49 -0
  362. package/dist/representation/publish.js +648 -0
  363. package/dist/representation/record-fields.d.ts +96 -0
  364. package/dist/representation/record-fields.js +116 -0
  365. package/dist/representation/template-object.d.ts +11 -0
  366. package/dist/representation/template-object.js +26 -0
  367. package/dist/representation/union.d.ts +30 -0
  368. package/dist/representation/union.js +324 -0
  369. package/dist/representation/value-records.d.ts +3 -0
  370. package/dist/representation/value-records.js +307 -0
  371. package/dist/representation/verify.d.ts +17 -0
  372. package/dist/representation/verify.js +221 -0
  373. package/dist/semantics/alias-this-field-declaration-transform.d.ts +4 -0
  374. package/dist/semantics/alias-this-field-declaration-transform.js +207 -0
  375. package/dist/semantics/ambient-type-realization-transform.d.ts +62 -0
  376. package/dist/semantics/ambient-type-realization-transform.js +168 -0
  377. package/dist/semantics/ambient.d.ts +24 -0
  378. package/dist/semantics/ambient.js +119 -0
  379. package/dist/semantics/borrowed-builtin-call-bind-source-transform.d.ts +4 -0
  380. package/dist/semantics/borrowed-builtin-call-bind-source-transform.js +341 -0
  381. package/dist/semantics/callable-origins.d.ts +46 -0
  382. package/dist/semantics/callable-origins.js +354 -0
  383. package/dist/semantics/class-alias.d.ts +7 -0
  384. package/dist/semantics/class-alias.js +37 -0
  385. package/dist/semantics/class-heritage.d.ts +34 -0
  386. package/dist/semantics/class-heritage.js +104 -0
  387. package/dist/semantics/commonjs-wrapper.d.ts +69 -0
  388. package/dist/semantics/commonjs-wrapper.js +231 -0
  389. package/dist/semantics/constructor-slot-subclasses.d.ts +28 -0
  390. package/dist/semantics/constructor-slot-subclasses.js +112 -0
  391. package/dist/semantics/declaration-overlay-transform.d.ts +35 -0
  392. package/dist/semantics/declaration-overlay-transform.js +2157 -0
  393. package/dist/semantics/define-property-source-transform.d.ts +4 -0
  394. package/dist/semantics/define-property-source-transform.js +437 -0
  395. package/dist/semantics/diagnostic-source-preparation.d.ts +24 -0
  396. package/dist/semantics/diagnostic-source-preparation.js +82 -0
  397. package/dist/semantics/documentation-ranges.d.ts +22 -0
  398. package/dist/semantics/documentation-ranges.js +36 -0
  399. package/dist/semantics/dynamic-fallback.d.ts +86 -0
  400. package/dist/semantics/dynamic-fallback.js +249 -0
  401. package/dist/semantics/frontend-timing.d.ts +6 -0
  402. package/dist/semantics/frontend-timing.js +35 -0
  403. package/dist/semantics/frontend.d.ts +504 -0
  404. package/dist/semantics/frontend.js +1157 -0
  405. package/dist/semantics/host-declaration-provenance.d.ts +11 -0
  406. package/dist/semantics/host-declaration-provenance.js +18 -0
  407. package/dist/semantics/host-methods.d.ts +24 -0
  408. package/dist/semantics/host-methods.js +74 -0
  409. package/dist/semantics/host-protocols.d.ts +429 -0
  410. package/dist/semantics/host-protocols.js +1501 -0
  411. package/dist/semantics/inherited-accessor.d.ts +7 -0
  412. package/dist/semantics/inherited-accessor.js +48 -0
  413. package/dist/semantics/interface-families.d.ts +70 -0
  414. package/dist/semantics/interface-families.js +180 -0
  415. package/dist/semantics/interface-implementors.d.ts +53 -0
  416. package/dist/semantics/interface-implementors.js +87 -0
  417. package/dist/semantics/jsdoc-namepath-transform.d.ts +4 -0
  418. package/dist/semantics/jsdoc-namepath-transform.js +85 -0
  419. package/dist/semantics/model/coverage.d.ts +68 -0
  420. package/dist/semantics/model/coverage.js +73 -0
  421. package/dist/semantics/model/edges.d.ts +103 -0
  422. package/dist/semantics/model/edges.js +20 -0
  423. package/dist/semantics/model/graph.d.ts +55 -0
  424. package/dist/semantics/model/graph.js +129 -0
  425. package/dist/semantics/model/operands.d.ts +159 -0
  426. package/dist/semantics/model/operands.js +26 -0
  427. package/dist/semantics/model/operations.d.ts +496 -0
  428. package/dist/semantics/model/operations.js +2 -0
  429. package/dist/semantics/model/primitive-domain.d.ts +26 -0
  430. package/dist/semantics/model/primitive-domain.js +38 -0
  431. package/dist/semantics/model/selected-signature.d.ts +261 -0
  432. package/dist/semantics/model/selected-signature.js +55 -0
  433. package/dist/semantics/model/structural-type-table.d.ts +93 -0
  434. package/dist/semantics/model/structural-type-table.js +237 -0
  435. package/dist/semantics/model/structural-types.d.ts +367 -0
  436. package/dist/semantics/model/structural-types.js +200 -0
  437. package/dist/semantics/module-resolution.d.ts +23 -0
  438. package/dist/semantics/module-resolution.js +227 -0
  439. package/dist/semantics/new-callee-class-tag-source-transform.d.ts +4 -0
  440. package/dist/semantics/new-callee-class-tag-source-transform.js +64 -0
  441. package/dist/semantics/node-project.d.ts +13 -0
  442. package/dist/semantics/node-project.js +107 -0
  443. package/dist/semantics/node-source-hooks.d.ts +1 -0
  444. package/dist/semantics/node-source-hooks.js +63 -0
  445. package/dist/semantics/normalize/absent-globals.d.ts +143 -0
  446. package/dist/semantics/normalize/absent-globals.js +191 -0
  447. package/dist/semantics/normalize/arguments-objects.d.ts +43 -0
  448. package/dist/semantics/normalize/arguments-objects.js +60 -0
  449. package/dist/semantics/normalize/asserted-arm-absence.d.ts +28 -0
  450. package/dist/semantics/normalize/asserted-arm-absence.js +61 -0
  451. package/dist/semantics/normalize/assignment-patterns.d.ts +70 -0
  452. package/dist/semantics/normalize/assignment-patterns.js +147 -0
  453. package/dist/semantics/normalize/bag-absence.d.ts +8 -0
  454. package/dist/semantics/normalize/bag-absence.js +42 -0
  455. package/dist/semantics/normalize/binding-fixpoint.d.ts +36 -0
  456. package/dist/semantics/normalize/binding-fixpoint.js +140 -0
  457. package/dist/semantics/normalize/callback-parameter-contracts.d.ts +16 -0
  458. package/dist/semantics/normalize/callback-parameter-contracts.js +91 -0
  459. package/dist/semantics/normalize/cells/agreement.d.ts +46 -0
  460. package/dist/semantics/normalize/cells/agreement.js +34 -0
  461. package/dist/semantics/normalize/cells/candidates.d.ts +17 -0
  462. package/dist/semantics/normalize/cells/candidates.js +35 -0
  463. package/dist/semantics/normalize/cells/facts.d.ts +19 -0
  464. package/dist/semantics/normalize/cells/facts.js +90 -0
  465. package/dist/semantics/normalize/cells/index.d.ts +10 -0
  466. package/dist/semantics/normalize/cells/index.js +6 -0
  467. package/dist/semantics/normalize/cells/model.d.ts +98 -0
  468. package/dist/semantics/normalize/cells/model.js +2 -0
  469. package/dist/semantics/normalize/cells/policies/bag.d.ts +44 -0
  470. package/dist/semantics/normalize/cells/policies/bag.js +114 -0
  471. package/dist/semantics/normalize/cells/policies/collection.d.ts +42 -0
  472. package/dist/semantics/normalize/cells/policies/collection.js +218 -0
  473. package/dist/semantics/normalize/cells/policies/field.d.ts +28 -0
  474. package/dist/semantics/normalize/cells/policies/field.js +40 -0
  475. package/dist/semantics/normalize/cells/policies/index.d.ts +49 -0
  476. package/dist/semantics/normalize/cells/policies/index.js +58 -0
  477. package/dist/semantics/normalize/cells/policies/local.d.ts +18 -0
  478. package/dist/semantics/normalize/cells/policies/local.js +37 -0
  479. package/dist/semantics/normalize/cells/policies/parameter.d.ts +28 -0
  480. package/dist/semantics/normalize/cells/policies/parameter.js +39 -0
  481. package/dist/semantics/normalize/cells/policies/return.d.ts +26 -0
  482. package/dist/semantics/normalize/cells/policies/return.js +45 -0
  483. package/dist/semantics/normalize/cells/policies/shared.d.ts +33 -0
  484. package/dist/semantics/normalize/cells/policies/shared.js +45 -0
  485. package/dist/semantics/normalize/cells/policy.d.ts +72 -0
  486. package/dist/semantics/normalize/cells/policy.js +18 -0
  487. package/dist/semantics/normalize/cells/registry.d.ts +14 -0
  488. package/dist/semantics/normalize/cells/registry.js +17 -0
  489. package/dist/semantics/normalize/census-refusal.d.ts +62 -0
  490. package/dist/semantics/normalize/census-refusal.js +27 -0
  491. package/dist/semantics/normalize/census.d.ts +109 -0
  492. package/dist/semantics/normalize/census.js +667 -0
  493. package/dist/semantics/normalize/collection-bindings.d.ts +278 -0
  494. package/dist/semantics/normalize/collection-bindings.js +677 -0
  495. package/dist/semantics/normalize/commonjs-module-record.d.ts +21 -0
  496. package/dist/semantics/normalize/commonjs-module-record.js +289 -0
  497. package/dist/semantics/normalize/commonjs-require.d.ts +13 -0
  498. package/dist/semantics/normalize/commonjs-require.js +1527 -0
  499. package/dist/semantics/normalize/contribution.d.ts +63 -0
  500. package/dist/semantics/normalize/contribution.js +172 -0
  501. package/dist/semantics/normalize/dead-typeof-guards.d.ts +64 -0
  502. package/dist/semantics/normalize/dead-typeof-guards.js +152 -0
  503. package/dist/semantics/normalize/deferred-intrinsic-protocols.d.ts +57 -0
  504. package/dist/semantics/normalize/deferred-intrinsic-protocols.js +109 -0
  505. package/dist/semantics/normalize/derived-expression-type.d.ts +1070 -0
  506. package/dist/semantics/normalize/derived-expression-type.js +3463 -0
  507. package/dist/semantics/normalize/evaluation-order.d.ts +16 -0
  508. package/dist/semantics/normalize/evaluation-order.js +37 -0
  509. package/dist/semantics/normalize/field-bindings.d.ts +167 -0
  510. package/dist/semantics/normalize/field-bindings.js +1125 -0
  511. package/dist/semantics/normalize/flow/array-element-continuation.d.ts +27 -0
  512. package/dist/semantics/normalize/flow/array-element-continuation.js +1452 -0
  513. package/dist/semantics/normalize/flow/callable-array-origins.d.ts +42 -0
  514. package/dist/semantics/normalize/flow/callable-array-origins.js +318 -0
  515. package/dist/semantics/normalize/flow/callable-completions.d.ts +45 -0
  516. package/dist/semantics/normalize/flow/callable-completions.js +82 -0
  517. package/dist/semantics/normalize/flow/callable-reach.d.ts +237 -0
  518. package/dist/semantics/normalize/flow/callable-reach.js +7174 -0
  519. package/dist/semantics/normalize/flow/class-family-member-read.d.ts +16 -0
  520. package/dist/semantics/normalize/flow/class-family-member-read.js +992 -0
  521. package/dist/semantics/normalize/flow/collection-value-continuation.d.ts +21 -0
  522. package/dist/semantics/normalize/flow/collection-value-continuation.js +192 -0
  523. package/dist/semantics/normalize/flow/component-solver.d.ts +199 -0
  524. package/dist/semantics/normalize/flow/component-solver.js +587 -0
  525. package/dist/semantics/normalize/flow/computed-key-set.d.ts +84 -0
  526. package/dist/semantics/normalize/flow/computed-key-set.js +660 -0
  527. package/dist/semantics/normalize/flow/export-importers.d.ts +24 -0
  528. package/dist/semantics/normalize/flow/export-importers.js +269 -0
  529. package/dist/semantics/normalize/flow/host-text-sink.d.ts +25 -0
  530. package/dist/semantics/normalize/flow/host-text-sink.js +87 -0
  531. package/dist/semantics/normalize/flow/intrinsic-array-callback-frames.d.ts +84 -0
  532. package/dist/semantics/normalize/flow/intrinsic-array-callback-frames.js +180 -0
  533. package/dist/semantics/normalize/flow/intrinsic-data-definition.d.ts +35 -0
  534. package/dist/semantics/normalize/flow/intrinsic-data-definition.js +140 -0
  535. package/dist/semantics/normalize/flow/invocation-facts.d.ts +98 -0
  536. package/dist/semantics/normalize/flow/invocation-facts.js +257 -0
  537. package/dist/semantics/normalize/flow/member-call-forwarding.d.ts +122 -0
  538. package/dist/semantics/normalize/flow/member-call-forwarding.js +835 -0
  539. package/dist/semantics/normalize/flow/model.d.ts +357 -0
  540. package/dist/semantics/normalize/flow/model.js +177 -0
  541. package/dist/semantics/normalize/flow/native-collection-protocol.d.ts +24 -0
  542. package/dist/semantics/normalize/flow/native-collection-protocol.js +252 -0
  543. package/dist/semantics/normalize/flow/node-path-token.d.ts +3 -0
  544. package/dist/semantics/normalize/flow/node-path-token.js +53 -0
  545. package/dist/semantics/normalize/flow/object-binding-continuation.d.ts +11 -0
  546. package/dist/semantics/normalize/flow/object-binding-continuation.js +42 -0
  547. package/dist/semantics/normalize/flow/origin-authority.d.ts +56 -0
  548. package/dist/semantics/normalize/flow/origin-authority.js +2 -0
  549. package/dist/semantics/normalize/flow/owned-class-receivers.d.ts +35 -0
  550. package/dist/semantics/normalize/flow/owned-class-receivers.js +191 -0
  551. package/dist/semantics/normalize/flow/parameter-values.d.ts +27 -0
  552. package/dist/semantics/normalize/flow/parameter-values.js +251 -0
  553. package/dist/semantics/normalize/flow/proof-hypotheses.d.ts +66 -0
  554. package/dist/semantics/normalize/flow/proof-hypotheses.js +162 -0
  555. package/dist/semantics/normalize/flow/record-alias-closure.d.ts +27 -0
  556. package/dist/semantics/normalize/flow/record-alias-closure.js +298 -0
  557. package/dist/semantics/normalize/flow/seeded-origins.d.ts +43 -0
  558. package/dist/semantics/normalize/flow/seeded-origins.js +54 -0
  559. package/dist/semantics/normalize/flow/source-class-data.d.ts +132 -0
  560. package/dist/semantics/normalize/flow/source-class-data.js +838 -0
  561. package/dist/semantics/normalize/flow/source-class-instanceof.d.ts +13 -0
  562. package/dist/semantics/normalize/flow/source-class-instanceof.js +37 -0
  563. package/dist/semantics/normalize/flow/source-class-static-data.d.ts +16 -0
  564. package/dist/semantics/normalize/flow/source-class-static-data.js +47 -0
  565. package/dist/semantics/normalize/flow/source-construction-frames.d.ts +12 -0
  566. package/dist/semantics/normalize/flow/source-construction-frames.js +118 -0
  567. package/dist/semantics/normalize/flow/source-invocation-frame-layout.d.ts +34 -0
  568. package/dist/semantics/normalize/flow/source-invocation-frame-layout.js +78 -0
  569. package/dist/semantics/normalize/flow/source-invocation-receiver.d.ts +37 -0
  570. package/dist/semantics/normalize/flow/source-invocation-receiver.js +95 -0
  571. package/dist/semantics/normalize/flow/source-prototype-method-identity.d.ts +23 -0
  572. package/dist/semantics/normalize/flow/source-prototype-method-identity.js +81 -0
  573. package/dist/semantics/normalize/flow/source-record-data.d.ts +29 -0
  574. package/dist/semantics/normalize/flow/source-record-data.js +626 -0
  575. package/dist/semantics/normalize/flow/source-value-session.d.ts +77 -0
  576. package/dist/semantics/normalize/flow/source-value-session.js +3089 -0
  577. package/dist/semantics/normalize/flow/targets.d.ts +118 -0
  578. package/dist/semantics/normalize/flow/targets.js +405 -0
  579. package/dist/semantics/normalize/flow/value-flow.d.ts +36 -0
  580. package/dist/semantics/normalize/flow/value-flow.js +823 -0
  581. package/dist/semantics/normalize/flow/value-provenance.d.ts +31 -0
  582. package/dist/semantics/normalize/flow/value-provenance.js +112 -0
  583. package/dist/semantics/normalize/gating.d.ts +51 -0
  584. package/dist/semantics/normalize/gating.js +560 -0
  585. package/dist/semantics/normalize/generic-function-choice.d.ts +31 -0
  586. package/dist/semantics/normalize/generic-function-choice.js +115 -0
  587. package/dist/semantics/normalize/global-host-mutations.d.ts +51 -0
  588. package/dist/semantics/normalize/global-host-mutations.js +5989 -0
  589. package/dist/semantics/normalize/host-effect-contracts.d.ts +77 -0
  590. package/dist/semantics/normalize/host-effect-contracts.js +143 -0
  591. package/dist/semantics/normalize/host-mutation-computed-keys.d.ts +38 -0
  592. package/dist/semantics/normalize/host-mutation-computed-keys.js +26 -0
  593. package/dist/semantics/normalize/host-mutation-key-reader.d.ts +66 -0
  594. package/dist/semantics/normalize/host-mutation-key-reader.js +192 -0
  595. package/dist/semantics/normalize/host-mutation-keys.d.ts +114 -0
  596. package/dist/semantics/normalize/host-mutation-keys.js +183 -0
  597. package/dist/semantics/normalize/identities.d.ts +172 -0
  598. package/dist/semantics/normalize/identities.js +426 -0
  599. package/dist/semantics/normalize/implicit-arguments-tuple.d.ts +97 -0
  600. package/dist/semantics/normalize/implicit-arguments-tuple.js +197 -0
  601. package/dist/semantics/normalize/implicit-arguments.d.ts +11 -0
  602. package/dist/semantics/normalize/implicit-arguments.js +39 -0
  603. package/dist/semantics/normalize/instantiation.d.ts +73 -0
  604. package/dist/semantics/normalize/instantiation.js +399 -0
  605. package/dist/semantics/normalize/intrinsic-property-call.d.ts +18 -0
  606. package/dist/semantics/normalize/intrinsic-property-call.js +69 -0
  607. package/dist/semantics/normalize/intrinsic-prototype.d.ts +41 -0
  608. package/dist/semantics/normalize/intrinsic-prototype.js +87 -0
  609. package/dist/semantics/normalize/intrinsic-static-member.d.ts +14 -0
  610. package/dist/semantics/normalize/intrinsic-static-member.js +23 -0
  611. package/dist/semantics/normalize/jsdoc-type-names.d.ts +32 -0
  612. package/dist/semantics/normalize/jsdoc-type-names.js +512 -0
  613. package/dist/semantics/normalize/keyof.d.ts +32 -0
  614. package/dist/semantics/normalize/keyof.js +110 -0
  615. package/dist/semantics/normalize/local-bindings.d.ts +176 -0
  616. package/dist/semantics/normalize/local-bindings.js +1826 -0
  617. package/dist/semantics/normalize/logical-result-type.d.ts +16 -0
  618. package/dist/semantics/normalize/logical-result-type.js +102 -0
  619. package/dist/semantics/normalize/namespace-paths.d.ts +57 -0
  620. package/dist/semantics/normalize/namespace-paths.js +108 -0
  621. package/dist/semantics/normalize/normalize.d.ts +57 -0
  622. package/dist/semantics/normalize/normalize.js +68 -0
  623. package/dist/semantics/normalize/object-bag-bindings.d.ts +305 -0
  624. package/dist/semantics/normalize/object-bag-bindings.js +1290 -0
  625. package/dist/semantics/normalize/omitted-stated-parameter.d.ts +53 -0
  626. package/dist/semantics/normalize/omitted-stated-parameter.js +59 -0
  627. package/dist/semantics/normalize/open-type-form.d.ts +10 -0
  628. package/dist/semantics/normalize/open-type-form.js +32 -0
  629. package/dist/semantics/normalize/parameter-bindings.d.ts +361 -0
  630. package/dist/semantics/normalize/parameter-bindings.js +3339 -0
  631. package/dist/semantics/normalize/parameter-slot.d.ts +264 -0
  632. package/dist/semantics/normalize/parameter-slot.js +491 -0
  633. package/dist/semantics/normalize/physical-overload-result.d.ts +77 -0
  634. package/dist/semantics/normalize/physical-overload-result.js +99 -0
  635. package/dist/semantics/normalize/primitive-property-absence.d.ts +12 -0
  636. package/dist/semantics/normalize/primitive-property-absence.js +60 -0
  637. package/dist/semantics/normalize/producer-context.d.ts +376 -0
  638. package/dist/semantics/normalize/producer-context.js +1 -0
  639. package/dist/semantics/normalize/producers/allocations.d.ts +3 -0
  640. package/dist/semantics/normalize/producers/allocations.js +863 -0
  641. package/dist/semantics/normalize/producers/binding-kind.d.ts +37 -0
  642. package/dist/semantics/normalize/producers/binding-kind.js +36 -0
  643. package/dist/semantics/normalize/producers/bindings.d.ts +85 -0
  644. package/dist/semantics/normalize/producers/bindings.js +710 -0
  645. package/dist/semantics/normalize/producers/boundary.d.ts +34 -0
  646. package/dist/semantics/normalize/producers/boundary.js +123 -0
  647. package/dist/semantics/normalize/producers/class-lifecycle.d.ts +3 -0
  648. package/dist/semantics/normalize/producers/class-lifecycle.js +902 -0
  649. package/dist/semantics/normalize/producers/computations.d.ts +3 -0
  650. package/dist/semantics/normalize/producers/computations.js +613 -0
  651. package/dist/semantics/normalize/producers/control-loops.d.ts +30 -0
  652. package/dist/semantics/normalize/producers/control-loops.js +91 -0
  653. package/dist/semantics/normalize/producers/control.d.ts +30 -0
  654. package/dist/semantics/normalize/producers/control.js +923 -0
  655. package/dist/semantics/normalize/producers/declaration-lifecycle.d.ts +3 -0
  656. package/dist/semantics/normalize/producers/declaration-lifecycle.js +390 -0
  657. package/dist/semantics/normalize/producers/destructuring.d.ts +45 -0
  658. package/dist/semantics/normalize/producers/destructuring.js +1180 -0
  659. package/dist/semantics/normalize/producers/dynamic-language.d.ts +3 -0
  660. package/dist/semantics/normalize/producers/dynamic-language.js +70 -0
  661. package/dist/semantics/normalize/producers/erasure.d.ts +51 -0
  662. package/dist/semantics/normalize/producers/erasure.js +90 -0
  663. package/dist/semantics/normalize/producers/installed.d.ts +3 -0
  664. package/dist/semantics/normalize/producers/installed.js +55 -0
  665. package/dist/semantics/normalize/producers/invocations.d.ts +35 -0
  666. package/dist/semantics/normalize/producers/invocations.js +1796 -0
  667. package/dist/semantics/normalize/producers/iteration-yield.d.ts +59 -0
  668. package/dist/semantics/normalize/producers/iteration-yield.js +235 -0
  669. package/dist/semantics/normalize/producers/jsx.d.ts +3 -0
  670. package/dist/semantics/normalize/producers/jsx.js +360 -0
  671. package/dist/semantics/normalize/producers/mint.d.ts +39 -0
  672. package/dist/semantics/normalize/producers/mint.js +44 -0
  673. package/dist/semantics/normalize/producers/nullish.d.ts +16 -0
  674. package/dist/semantics/normalize/producers/nullish.js +27 -0
  675. package/dist/semantics/normalize/producers/object-assignment.d.ts +8 -0
  676. package/dist/semantics/normalize/producers/object-assignment.js +204 -0
  677. package/dist/semantics/normalize/producers/object-tag.d.ts +9 -0
  678. package/dist/semantics/normalize/producers/object-tag.js +119 -0
  679. package/dist/semantics/normalize/producers/optional-chain.d.ts +44 -0
  680. package/dist/semantics/normalize/producers/optional-chain.js +75 -0
  681. package/dist/semantics/normalize/producers/properties.d.ts +21 -0
  682. package/dist/semantics/normalize/producers/properties.js +1053 -0
  683. package/dist/semantics/normalize/producers/protocol.d.ts +67 -0
  684. package/dist/semantics/normalize/producers/protocol.js +695 -0
  685. package/dist/semantics/normalize/producers/references.d.ts +53 -0
  686. package/dist/semantics/normalize/producers/references.js +1027 -0
  687. package/dist/semantics/normalize/producers/shared.d.ts +561 -0
  688. package/dist/semantics/normalize/producers/shared.js +1683 -0
  689. package/dist/semantics/normalize/producers/spread-arguments.d.ts +72 -0
  690. package/dist/semantics/normalize/producers/spread-arguments.js +375 -0
  691. package/dist/semantics/normalize/producers/tagged-template.d.ts +5 -0
  692. package/dist/semantics/normalize/producers/tagged-template.js +307 -0
  693. package/dist/semantics/normalize/producers/tuple-spread.d.ts +189 -0
  694. package/dist/semantics/normalize/producers/tuple-spread.js +279 -0
  695. package/dist/semantics/normalize/property-key-domain.d.ts +36 -0
  696. package/dist/semantics/normalize/property-key-domain.js +150 -0
  697. package/dist/semantics/normalize/reachability.d.ts +189 -0
  698. package/dist/semantics/normalize/reachability.js +1057 -0
  699. package/dist/semantics/normalize/reassigned-bindings.d.ts +13 -0
  700. package/dist/semantics/normalize/reassigned-bindings.js +41 -0
  701. package/dist/semantics/normalize/record-storage-families.d.ts +11 -0
  702. package/dist/semantics/normalize/record-storage-families.js +109 -0
  703. package/dist/semantics/normalize/return-bindings.d.ts +260 -0
  704. package/dist/semantics/normalize/return-bindings.js +1311 -0
  705. package/dist/semantics/normalize/return-paths.d.ts +2 -0
  706. package/dist/semantics/normalize/return-paths.js +28 -0
  707. package/dist/semantics/normalize/script-global-redefinition.d.ts +44 -0
  708. package/dist/semantics/normalize/script-global-redefinition.js +75 -0
  709. package/dist/semantics/normalize/specialization.d.ts +201 -0
  710. package/dist/semantics/normalize/specialization.js +1824 -0
  711. package/dist/semantics/normalize/structural-array-element.d.ts +176 -0
  712. package/dist/semantics/normalize/structural-array-element.js +700 -0
  713. package/dist/semantics/normalize/structural-array-read.d.ts +13 -0
  714. package/dist/semantics/normalize/structural-array-read.js +124 -0
  715. package/dist/semantics/normalize/structural-callable.d.ts +12 -0
  716. package/dist/semantics/normalize/structural-callable.js +82 -0
  717. package/dist/semantics/normalize/structural-creation-order.d.ts +32 -0
  718. package/dist/semantics/normalize/structural-creation-order.js +111 -0
  719. package/dist/semantics/normalize/structural-declarations.d.ts +395 -0
  720. package/dist/semantics/normalize/structural-declarations.js +968 -0
  721. package/dist/semantics/normalize/structural-declared-body.d.ts +25 -0
  722. package/dist/semantics/normalize/structural-declared-body.js +147 -0
  723. package/dist/semantics/normalize/structural-generics.d.ts +56 -0
  724. package/dist/semantics/normalize/structural-generics.js +120 -0
  725. package/dist/semantics/normalize/structural-indexed-access.d.ts +11 -0
  726. package/dist/semantics/normalize/structural-indexed-access.js +126 -0
  727. package/dist/semantics/normalize/structural-instantiated-member.d.ts +64 -0
  728. package/dist/semantics/normalize/structural-instantiated-member.js +407 -0
  729. package/dist/semantics/normalize/structural-joins.d.ts +44 -0
  730. package/dist/semantics/normalize/structural-joins.js +143 -0
  731. package/dist/semantics/normalize/structural-layout-relevance.d.ts +29 -0
  732. package/dist/semantics/normalize/structural-layout-relevance.js +391 -0
  733. package/dist/semantics/normalize/structural-layout-type.d.ts +11 -0
  734. package/dist/semantics/normalize/structural-layout-type.js +1468 -0
  735. package/dist/semantics/normalize/structural-leaves.d.ts +49 -0
  736. package/dist/semantics/normalize/structural-leaves.js +125 -0
  737. package/dist/semantics/normalize/structural-local-union.d.ts +13 -0
  738. package/dist/semantics/normalize/structural-local-union.js +133 -0
  739. package/dist/semantics/normalize/structural-members.d.ts +26 -0
  740. package/dist/semantics/normalize/structural-members.js +84 -0
  741. package/dist/semantics/normalize/structural-mutable-method.d.ts +15 -0
  742. package/dist/semantics/normalize/structural-mutable-method.js +109 -0
  743. package/dist/semantics/normalize/structural-parts.d.ts +131 -0
  744. package/dist/semantics/normalize/structural-parts.js +737 -0
  745. package/dist/semantics/normalize/structural-receiver.d.ts +66 -0
  746. package/dist/semantics/normalize/structural-receiver.js +551 -0
  747. package/dist/semantics/normalize/structural-rules.d.ts +112 -0
  748. package/dist/semantics/normalize/structural-rules.js +93 -0
  749. package/dist/semantics/normalize/structural-self-reference.d.ts +150 -0
  750. package/dist/semantics/normalize/structural-self-reference.js +494 -0
  751. package/dist/semantics/normalize/structural.d.ts +202 -0
  752. package/dist/semantics/normalize/structural.js +4218 -0
  753. package/dist/semantics/normalize/unreduced-type-form.d.ts +41 -0
  754. package/dist/semantics/normalize/unreduced-type-form.js +53 -0
  755. package/dist/semantics/normalize/unresolvable-names.d.ts +56 -0
  756. package/dist/semantics/normalize/unresolvable-names.js +140 -0
  757. package/dist/semantics/package-sources.d.ts +16 -0
  758. package/dist/semantics/package-sources.js +365 -0
  759. package/dist/semantics/program.d.ts +151 -0
  760. package/dist/semantics/program.js +667 -0
  761. package/dist/semantics/prototype-install-source-transform.d.ts +4 -0
  762. package/dist/semantics/prototype-install-source-transform.js +341 -0
  763. package/dist/semantics/prototype-object-class-source-transform.d.ts +4 -0
  764. package/dist/semantics/prototype-object-class-source-transform.js +525 -0
  765. package/dist/semantics/prototype-reparenting.d.ts +50 -0
  766. package/dist/semantics/prototype-reparenting.js +317 -0
  767. package/dist/semantics/stable-checker.d.ts +10 -0
  768. package/dist/semantics/stable-checker.js +148 -0
  769. package/dist/semantics/subclass-member-overlay-transform.d.ts +35 -0
  770. package/dist/semantics/subclass-member-overlay-transform.js +1418 -0
  771. package/dist/semantics/symbol-keyed-expando-source-transform.d.ts +4 -0
  772. package/dist/semantics/symbol-keyed-expando-source-transform.js +66 -0
  773. package/dist/semantics/this-constructor-source-transform.d.ts +4 -0
  774. package/dist/semantics/this-constructor-source-transform.js +122 -0
  775. package/dist/semantics/uninstantiable-classes.d.ts +22 -0
  776. package/dist/semantics/uninstantiable-classes.js +75 -0
  777. package/dist/targets/cpp/balanced-units.d.ts +3 -0
  778. package/dist/targets/cpp/balanced-units.js +58 -0
  779. package/dist/targets/cpp/borrowed-call-entry.d.ts +30 -0
  780. package/dist/targets/cpp/borrowed-call-entry.js +68 -0
  781. package/dist/targets/cpp/captures.d.ts +68 -0
  782. package/dist/targets/cpp/captures.js +269 -0
  783. package/dist/targets/cpp/class-layout.d.ts +313 -0
  784. package/dist/targets/cpp/class-layout.js +483 -0
  785. package/dist/targets/cpp/class-properties/computed-method-value.d.ts +25 -0
  786. package/dist/targets/cpp/class-properties/computed-method-value.js +22 -0
  787. package/dist/targets/cpp/class-properties/emit-class-properties.d.ts +216 -0
  788. package/dist/targets/cpp/class-properties/emit-class-properties.js +917 -0
  789. package/dist/targets/cpp/class-properties/native-prototype.d.ts +11 -0
  790. package/dist/targets/cpp/class-properties/native-prototype.js +101 -0
  791. package/dist/targets/cpp/class-ref-transport.d.ts +12 -0
  792. package/dist/targets/cpp/class-ref-transport.js +32 -0
  793. package/dist/targets/cpp/conversions.d.ts +3 -0
  794. package/dist/targets/cpp/conversions.js +2027 -0
  795. package/dist/targets/cpp/deferral-safety.d.ts +82 -0
  796. package/dist/targets/cpp/deferral-safety.js +86 -0
  797. package/dist/targets/cpp/direct-call-receivers.d.ts +37 -0
  798. package/dist/targets/cpp/direct-call-receivers.js +79 -0
  799. package/dist/targets/cpp/document.d.ts +74 -0
  800. package/dist/targets/cpp/document.js +106 -0
  801. package/dist/targets/cpp/emit-allocation.d.ts +60 -0
  802. package/dist/targets/cpp/emit-allocation.js +573 -0
  803. package/dist/targets/cpp/emit-arrays.d.ts +119 -0
  804. package/dist/targets/cpp/emit-arrays.js +1047 -0
  805. package/dist/targets/cpp/emit-binding-reference.d.ts +17 -0
  806. package/dist/targets/cpp/emit-binding-reference.js +120 -0
  807. package/dist/targets/cpp/emit-bindings.d.ts +158 -0
  808. package/dist/targets/cpp/emit-bindings.js +769 -0
  809. package/dist/targets/cpp/emit-buffers.d.ts +156 -0
  810. package/dist/targets/cpp/emit-buffers.js +573 -0
  811. package/dist/targets/cpp/emit-callable.d.ts +230 -0
  812. package/dist/targets/cpp/emit-callable.js +2154 -0
  813. package/dist/targets/cpp/emit-carrier-members.d.ts +406 -0
  814. package/dist/targets/cpp/emit-carrier-members.js +1224 -0
  815. package/dist/targets/cpp/emit-coercion.d.ts +26 -0
  816. package/dist/targets/cpp/emit-coercion.js +39 -0
  817. package/dist/targets/cpp/emit-context.d.ts +1882 -0
  818. package/dist/targets/cpp/emit-context.js +904 -0
  819. package/dist/targets/cpp/emit-dynamic-properties.d.ts +174 -0
  820. package/dist/targets/cpp/emit-dynamic-properties.js +1249 -0
  821. package/dist/targets/cpp/emit-equality.d.ts +39 -0
  822. package/dist/targets/cpp/emit-equality.js +472 -0
  823. package/dist/targets/cpp/emit-exceptions.d.ts +104 -0
  824. package/dist/targets/cpp/emit-exceptions.js +513 -0
  825. package/dist/targets/cpp/emit-field-owner.d.ts +4 -0
  826. package/dist/targets/cpp/emit-field-owner.js +27 -0
  827. package/dist/targets/cpp/emit-in.d.ts +31 -0
  828. package/dist/targets/cpp/emit-in.js +426 -0
  829. package/dist/targets/cpp/emit-instanceof.d.ts +19 -0
  830. package/dist/targets/cpp/emit-instanceof.js +601 -0
  831. package/dist/targets/cpp/emit-integers.d.ts +68 -0
  832. package/dist/targets/cpp/emit-integers.js +184 -0
  833. package/dist/targets/cpp/emit-iterator.d.ts +100 -0
  834. package/dist/targets/cpp/emit-iterator.js +1137 -0
  835. package/dist/targets/cpp/emit-json.d.ts +73 -0
  836. package/dist/targets/cpp/emit-json.js +823 -0
  837. package/dist/targets/cpp/emit-jsx.d.ts +74 -0
  838. package/dist/targets/cpp/emit-jsx.js +806 -0
  839. package/dist/targets/cpp/emit-mixed-binary.d.ts +51 -0
  840. package/dist/targets/cpp/emit-mixed-binary.js +60 -0
  841. package/dist/targets/cpp/emit-namespaces.d.ts +101 -0
  842. package/dist/targets/cpp/emit-namespaces.js +133 -0
  843. package/dist/targets/cpp/emit-narrowing.d.ts +738 -0
  844. package/dist/targets/cpp/emit-narrowing.js +3967 -0
  845. package/dist/targets/cpp/emit-native-equality.d.ts +3 -0
  846. package/dist/targets/cpp/emit-native-equality.js +14 -0
  847. package/dist/targets/cpp/emit-native-selection.d.ts +5 -0
  848. package/dist/targets/cpp/emit-native-selection.js +37 -0
  849. package/dist/targets/cpp/emit-object-tag.d.ts +4 -0
  850. package/dist/targets/cpp/emit-object-tag.js +108 -0
  851. package/dist/targets/cpp/emit-owned-record.d.ts +2 -0
  852. package/dist/targets/cpp/emit-owned-record.js +15 -0
  853. package/dist/targets/cpp/emit-presence.d.ts +78 -0
  854. package/dist/targets/cpp/emit-presence.js +376 -0
  855. package/dist/targets/cpp/emit-properties.d.ts +105 -0
  856. package/dist/targets/cpp/emit-properties.js +1640 -0
  857. package/dist/targets/cpp/emit-record-view.d.ts +20 -0
  858. package/dist/targets/cpp/emit-record-view.js +354 -0
  859. package/dist/targets/cpp/emit-return.d.ts +5 -0
  860. package/dist/targets/cpp/emit-return.js +237 -0
  861. package/dist/targets/cpp/emit-sum-widening.d.ts +10 -0
  862. package/dist/targets/cpp/emit-sum-widening.js +69 -0
  863. package/dist/targets/cpp/emit-tonumber.d.ts +38 -0
  864. package/dist/targets/cpp/emit-tonumber.js +177 -0
  865. package/dist/targets/cpp/emit-tostring.d.ts +92 -0
  866. package/dist/targets/cpp/emit-tostring.js +556 -0
  867. package/dist/targets/cpp/emit-typeof.d.ts +49 -0
  868. package/dist/targets/cpp/emit-typeof.js +317 -0
  869. package/dist/targets/cpp/emit-union-properties.d.ts +181 -0
  870. package/dist/targets/cpp/emit-union-properties.js +1281 -0
  871. package/dist/targets/cpp/emit.d.ts +45 -0
  872. package/dist/targets/cpp/emit.js +2225 -0
  873. package/dist/targets/cpp/error-types.d.ts +4 -0
  874. package/dist/targets/cpp/error-types.js +11 -0
  875. package/dist/targets/cpp/function-source-reads.d.ts +72 -0
  876. package/dist/targets/cpp/function-source-reads.js +148 -0
  877. package/dist/targets/cpp/host/atomics.d.ts +25 -0
  878. package/dist/targets/cpp/host/atomics.js +63 -0
  879. package/dist/targets/cpp/host/core-globals.d.ts +108 -0
  880. package/dist/targets/cpp/host/core-globals.js +158 -0
  881. package/dist/targets/cpp/host/dynamic-argument-members.d.ts +42 -0
  882. package/dist/targets/cpp/host/dynamic-argument-members.js +61 -0
  883. package/dist/targets/cpp/host/emit-host-arity.d.ts +139 -0
  884. package/dist/targets/cpp/host/emit-host-arity.js +232 -0
  885. package/dist/targets/cpp/host/emit-host-invoke.d.ts +91 -0
  886. package/dist/targets/cpp/host/emit-host-invoke.js +1105 -0
  887. package/dist/targets/cpp/host/emit-host-object.d.ts +55 -0
  888. package/dist/targets/cpp/host/emit-host-object.js +2206 -0
  889. package/dist/targets/cpp/host/emit-host-properties.d.ts +69 -0
  890. package/dist/targets/cpp/host/emit-host-properties.js +533 -0
  891. package/dist/targets/cpp/host/emit-host-reflect.d.ts +4 -0
  892. package/dist/targets/cpp/host/emit-host-reflect.js +180 -0
  893. package/dist/targets/cpp/host/emit-host-value.d.ts +120 -0
  894. package/dist/targets/cpp/host/emit-host-value.js +392 -0
  895. package/dist/targets/cpp/host/host-members.d.ts +505 -0
  896. package/dist/targets/cpp/host/host-members.js +819 -0
  897. package/dist/targets/cpp/host/host-method-aliases.d.ts +30 -0
  898. package/dist/targets/cpp/host/host-method-aliases.js +76 -0
  899. package/dist/targets/cpp/host/native-protocols.d.ts +47 -0
  900. package/dist/targets/cpp/host/native-protocols.js +183 -0
  901. package/dist/targets/cpp/host/object-protocol.d.ts +351 -0
  902. package/dist/targets/cpp/host/object-protocol.js +671 -0
  903. package/dist/targets/cpp/host-namespace-reads.d.ts +83 -0
  904. package/dist/targets/cpp/host-namespace-reads.js +113 -0
  905. package/dist/targets/cpp/manifest/capabilities.d.ts +39 -0
  906. package/dist/targets/cpp/manifest/capabilities.js +1484 -0
  907. package/dist/targets/cpp/manifest.d.ts +23 -0
  908. package/dist/targets/cpp/manifest.js +113 -0
  909. package/dist/targets/cpp/native-error-base.d.ts +38 -0
  910. package/dist/targets/cpp/native-error-base.js +74 -0
  911. package/dist/targets/cpp/native-narrowing-transport.d.ts +12 -0
  912. package/dist/targets/cpp/native-narrowing-transport.js +151 -0
  913. package/dist/targets/cpp/native-selection-helpers.d.ts +11 -0
  914. package/dist/targets/cpp/native-selection-helpers.js +46 -0
  915. package/dist/targets/cpp/native-symbol-keys.d.ts +8 -0
  916. package/dist/targets/cpp/native-symbol-keys.js +34 -0
  917. package/dist/targets/cpp/ownership.d.ts +43 -0
  918. package/dist/targets/cpp/ownership.js +38 -0
  919. package/dist/targets/cpp/owning-conversion-input.d.ts +14 -0
  920. package/dist/targets/cpp/owning-conversion-input.js +12 -0
  921. package/dist/targets/cpp/property-read-claims.d.ts +62 -0
  922. package/dist/targets/cpp/property-read-claims.js +23 -0
  923. package/dist/targets/cpp/property-store-claims.d.ts +62 -0
  924. package/dist/targets/cpp/property-store-claims.js +26 -0
  925. package/dist/targets/cpp/prototype/emit-prototype-array.d.ts +111 -0
  926. package/dist/targets/cpp/prototype/emit-prototype-array.js +602 -0
  927. package/dist/targets/cpp/prototype/emit-prototype-date.d.ts +133 -0
  928. package/dist/targets/cpp/prototype/emit-prototype-date.js +515 -0
  929. package/dist/targets/cpp/prototype/emit-prototype-error.d.ts +13 -0
  930. package/dist/targets/cpp/prototype/emit-prototype-error.js +54 -0
  931. package/dist/targets/cpp/prototype/emit-prototype-invoke.d.ts +34 -0
  932. package/dist/targets/cpp/prototype/emit-prototype-invoke.js +1003 -0
  933. package/dist/targets/cpp/prototype/emit-prototype-iterator.d.ts +47 -0
  934. package/dist/targets/cpp/prototype/emit-prototype-iterator.js +250 -0
  935. package/dist/targets/cpp/prototype/emit-prototype-promise.d.ts +46 -0
  936. package/dist/targets/cpp/prototype/emit-prototype-promise.js +143 -0
  937. package/dist/targets/cpp/prototype/emit-prototype-regexp.d.ts +335 -0
  938. package/dist/targets/cpp/prototype/emit-prototype-regexp.js +853 -0
  939. package/dist/targets/cpp/prototype/emit-prototype-string.d.ts +42 -0
  940. package/dist/targets/cpp/prototype/emit-prototype-string.js +252 -0
  941. package/dist/targets/cpp/prototype/prototype-method-reads.d.ts +25 -0
  942. package/dist/targets/cpp/prototype/prototype-method-reads.js +182 -0
  943. package/dist/targets/cpp/reactive-dependencies.d.ts +140 -0
  944. package/dist/targets/cpp/reactive-dependencies.js +432 -0
  945. package/dist/targets/cpp/reactive-origins.d.ts +44 -0
  946. package/dist/targets/cpp/reactive-origins.js +82 -0
  947. package/dist/targets/cpp/records.d.ts +277 -0
  948. package/dist/targets/cpp/records.js +2427 -0
  949. package/dist/targets/cpp/recursive-containers.d.ts +43 -0
  950. package/dist/targets/cpp/recursive-containers.js +144 -0
  951. package/dist/targets/cpp/regexp-types.d.ts +56 -0
  952. package/dist/targets/cpp/regexp-types.js +59 -0
  953. package/dist/targets/cpp/substrate.d.ts +125 -0
  954. package/dist/targets/cpp/substrate.js +12 -0
  955. package/dist/targets/cpp/translation-unit.d.ts +219 -0
  956. package/dist/targets/cpp/translation-unit.js +2063 -0
  957. package/dist/targets/cpp/types.d.ts +280 -0
  958. package/dist/targets/cpp/types.js +1135 -0
  959. package/dist/targets/cpp/virtual-methods.d.ts +95 -0
  960. package/dist/targets/cpp/virtual-methods.js +264 -0
  961. package/package.json +95 -0
  962. package/src/targets/cpp/runtime/gea_dynamic_proxy.h +824 -0
  963. package/src/targets/cpp/runtime/gea_eval.h +1376 -0
  964. package/src/targets/cpp/runtime/gea_native_class_prototype.h +44 -0
  965. package/src/targets/cpp/runtime/gea_runtime.h +29222 -0
  966. package/src/targets/cpp/runtime/gea_runtime_builtins.cpp +55 -0
@@ -0,0 +1,3089 @@
1
+ import ts from 'typescript';
2
+ import { isClassSpelledSourceClass } from './model.js';
3
+ import { dependencyFactSolver } from './component-solver.js';
4
+ import { classConstructorKeepsInstanceOf, exactSourceConstructionOf, sourceConstructorSelectionsOf } from './member-call-forwarding.js';
5
+ import { sourceClassCallableMemberPlanOf, sourceClassDataMemberPlanOf, sourceClassKeyReadPlanOf } from './source-class-data.js';
6
+ import { sourceClassFamilyOf } from './owned-class-receivers.js';
7
+ import { isGlobalObjectAssign } from './value-flow.js';
8
+ import { intrinsicDataDefinitionTargetOf } from './intrinsic-data-definition.js';
9
+ import { callableCompletionSummaryOf, constructionYieldsCompletionOf } from './callable-completions.js';
10
+ import { sourceInvocationFrameLayoutOf } from './source-invocation-frame-layout.js';
11
+ import { localBindingValuesOf, localBindingWritesAreComplete } from './value-provenance.js';
12
+ import { collectionStoredValuesOf, collectionValueContinuationsOf } from './collection-value-continuation.js';
13
+ import { isTypePositionReference, runtimeParametersOf, unwrapNaming } from './targets.js';
14
+ import { outermostErasureOf, unwrapErasedExpression } from '../producers/erasure.js';
15
+ import { deferredIntrinsicProtocolLedgerOf } from '../deferred-intrinsic-protocols.js';
16
+ import { censusArgumentsObjects } from '../arguments-objects.js';
17
+ import { exportIsUnimported } from './targets.js';
18
+ import { inProgramImportReferencesOf } from './export-importers.js';
19
+ import { sourceConstructionFramesOf } from './source-construction-frames.js';
20
+ import { isSourceInstanceMethod } from './source-prototype-method-identity.js';
21
+ /**
22
+ * Walk two lists as one without building a third.
23
+ *
24
+ * Every caller is inside a transfer, and a transfer runs once per
25
+ * re-evaluation of its node -- so a spread that reads as a convenience is an
26
+ * allocation and a copy priced per transfer, not per program.
27
+ */
28
+ const both = (first, second) => first === undefined || first.length === 0 ? second : second.length === 0 ? first : [...first, ...second];
29
+ const refusalDebug = process.env['GEA_SESSION_REFUSALS'] !== undefined;
30
+ /** The query kinds whose facts are values and therefore need a grounding witness. */
31
+ const VALUE_CARRYING_KINDS = new Set([
32
+ 'value',
33
+ 'slot',
34
+ 'parameter',
35
+ 'binding-element',
36
+ 'super-targets',
37
+ 'receiver',
38
+ 'completion',
39
+ 'frame-receiver',
40
+ 'frame-argument',
41
+ 'frame-parameter',
42
+ 'frame-value',
43
+ 'frame-completion'
44
+ ]);
45
+ const VALUE_ORIGIN = 'source-value-origin';
46
+ // Read once at load, not per value transfer: `process.env` is a native interceptor.
47
+ const noArrayKeys = process.env['GEA_NO_ARRAY_KEYS'] !== undefined;
48
+ /**
49
+ * The element slot of an array root: every position at once. A computed
50
+ * index names no single key (`this.textures[ i ]` in three's RenderTarget,
51
+ * with the loop counter as the index), so a store or read through one is
52
+ * filed under this key, and a literal-index slot and this one alias each
53
+ * other -- `slot(root, '0')` includes what `[ i ]` stored, and `[ i ]` reads
54
+ * what `[ 0 ]` stored. Before this the unbounded index published nothing and
55
+ * read nothing, and every render target's textures were unresolvable.
56
+ */
57
+ const ELEMENT_KEY = '[]';
58
+ const CANONICAL_INDEX = /^(?:0|[1-9][0-9]*)$/;
59
+ const isCanonicalIndex = (key) => CANONICAL_INDEX.test(key);
60
+ /** Whether a store or read filed under `stored` can reach the slot `key` of `root`. */
61
+ const keyReaches = (root, stored, key) => stored.includes(key) ||
62
+ (ts.isArrayLiteralExpression(root) &&
63
+ ((key === ELEMENT_KEY && stored.some(isCanonicalIndex)) || (isCanonicalIndex(key) && stored.includes(ELEMENT_KEY))));
64
+ const isObjectRoot = (node) => ts.isNewExpression(node) || ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node);
65
+ const isBody = (node) => ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node);
66
+ const accessKey = (access) => ts.isPropertyAccessExpression(access) ? access.name.text : literalKey(access.argumentExpression);
67
+ const literalKey = (node) => {
68
+ const value = unwrapErasedExpression(node);
69
+ return ts.isStringLiteralLike(value) || ts.isNumericLiteral(value) ? value.text : null;
70
+ };
71
+ const declarationKey = (name) => ts.isComputedPropertyName(name) ? literalKey(name.expression) : ts.isPrivateIdentifier(name) ? null : name.text;
72
+ /**
73
+ * The slot a binding element reads out of the object being destructured.
74
+ *
75
+ * `{ app }` and `{ app: local }` both read `app` -- the PROPERTY name is the
76
+ * slot and the bound name is only what the cell is called afterwards, which is
77
+ * the same distinction `declarationKey` makes for a property. An array pattern
78
+ * reads by position, and an omitted element still occupies one, so the index
79
+ * comes from the element list rather than from a running count of the elements
80
+ * that bind something.
81
+ */
82
+ const bindingElementKey = (element) => {
83
+ const pattern = element.parent;
84
+ if (ts.isArrayBindingPattern(pattern))
85
+ return String(pattern.elements.indexOf(element));
86
+ if (element.propertyName)
87
+ return declarationKey(element.propertyName);
88
+ return ts.isIdentifier(element.name) ? element.name.text : null;
89
+ };
90
+ const sessions = new WeakMap();
91
+ export const sourceValueSessionOf = (checker, flow) => {
92
+ const known = sessions.get(flow);
93
+ if (known)
94
+ return known;
95
+ const session = createSession(checker, flow);
96
+ sessions.set(flow, session);
97
+ return session;
98
+ };
99
+ const createSession = (checker, flow) => {
100
+ // A closed native Map is only closed while `Map.prototype`'s `get`/`set`
101
+ // are the intrinsics: a finite root walk is not that proof
102
+ // (`native-collection-protocol.ts`), so only the deferred obligation -- an
103
+ // intrinsic-protocol requirement the final sealed census discharges -- is
104
+ // accepted here, and a plan with no ledger to file it with is refused.
105
+ const nativeProtocolClosed = (plan) => plan.deferred &&
106
+ deferredIntrinsicProtocolLedgerOf(flow)?.requirePrototypeKeys(plan.intrinsic, plan.prototypeKeys, plan.location) === true;
107
+ const unary = new Map();
108
+ const slots = new Map();
109
+ const uses = new Map();
110
+ const publications = new Map();
111
+ const frameQueries = new Map();
112
+ const requirements = new Map();
113
+ const argumentsByFile = new Map();
114
+ const argumentsUsesAt = (body) => {
115
+ const file = body.getSourceFile();
116
+ let census = argumentsByFile.get(file);
117
+ if (!census)
118
+ argumentsByFile.set(file, (census = censusArgumentsObjects(checker, [file])));
119
+ return census.usesByOwner.get(body);
120
+ };
121
+ const undefinedValue = ts.factory.createVoidZero();
122
+ const arrayLengths = new Map();
123
+ const sites = new Map(flow.calls.map((site) => [site.call, site]));
124
+ const isNullish = (held) => held === undefinedValue || held.kind === ts.SyntaxKind.NullKeyword || ts.isVoidExpression(held);
125
+ const constructionFrames = sourceConstructionFramesOf(checker, flow);
126
+ // Destructuring is the other spelling of a slot read, so the enumeration of
127
+ // "everything that can read this key" has to hold both. A key no element
128
+ // states -- a rest element, or a computed property name -- can read any key
129
+ // at all and joins the unknown side, exactly as an unresolved element access
130
+ // does.
131
+ const patternReadsByKey = new Map();
132
+ const unknownPatternReads = [];
133
+ for (const element of flow.bindingPatternReads) {
134
+ const key = bindingElementKey(element);
135
+ if (element.dotDotDotToken || key === null)
136
+ unknownPatternReads.push(element);
137
+ else {
138
+ let reads = patternReadsByKey.get(key);
139
+ if (!reads)
140
+ patternReadsByKey.set(key, (reads = []));
141
+ reads.push(element);
142
+ }
143
+ }
144
+ const nodeQuery = (kind, node) => {
145
+ let nodes = unary.get(kind);
146
+ if (!nodes)
147
+ unary.set(kind, (nodes = new Map()));
148
+ let query = nodes.get(node);
149
+ if (!query)
150
+ nodes.set(node, (query = { kind, node }));
151
+ return query;
152
+ };
153
+ const value = (expression) => nodeQuery('value', unwrapErasedExpression(expression));
154
+ const frameQuery = (kind, call, body, subject = null) => {
155
+ let calls = frameQueries.get(kind);
156
+ if (!calls)
157
+ frameQueries.set(kind, (calls = new Map()));
158
+ let bodies = calls.get(call);
159
+ if (!bodies)
160
+ calls.set(call, (bodies = new Map()));
161
+ let subjects = bodies.get(body);
162
+ if (!subjects)
163
+ bodies.set(body, (subjects = new Map()));
164
+ let query = subjects.get(subject);
165
+ if (!query)
166
+ subjects.set(subject, (query = { kind, node: call, body, subject }));
167
+ return query;
168
+ };
169
+ const closure = (root) => nodeQuery('closure', root);
170
+ /**
171
+ * The plain source function `new F( ... )` runs when `F` is an identifier
172
+ * naming an unwritten, non-generator, non-async function declaration
173
+ * with ordinary formals, or null. Its completions are proven separately
174
+ * (`constructionYieldsCompletionOf`); this only names the body.
175
+ */
176
+ const thisConstructorReceiverOf = (call) => {
177
+ const callee = unwrapErasedExpression(call.expression);
178
+ if (!ts.isPropertyAccessExpression(callee) || callee.name.text !== 'constructor')
179
+ return null;
180
+ const receiver = unwrapErasedExpression(callee.expression);
181
+ return receiver.kind === ts.SyntaxKind.ThisKeyword ? receiver : null;
182
+ };
183
+ const constructorFunctionCalleeOf = (call) => {
184
+ if (call.arguments?.some(ts.isSpreadElement))
185
+ return null;
186
+ const callee = unwrapErasedExpression(call.expression);
187
+ if (!ts.isIdentifier(callee))
188
+ return null;
189
+ const named = flow.targetOf(callee);
190
+ const target = aliasedDeclarationOf(named?.symbol ?? undefined) ?? named?.declaration;
191
+ if (!target || !ts.isFunctionDeclaration(target) || !target.body || target.getSourceFile().isDeclarationFile)
192
+ return null;
193
+ if (target.asteriskToken || target.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword))
194
+ return null;
195
+ if (target.parameters.some((parameter) => parameter.dotDotDotToken || !ts.isIdentifier(parameter.name)))
196
+ return null;
197
+ if (flow.writesToDeclaration(target).some((write) => write.slot === 'whole' && write.edge !== 'return' && write.edge !== 'yield'))
198
+ return null;
199
+ return target;
200
+ };
201
+ /**
202
+ * The computed-key reads that can be reading THIS container.
203
+ *
204
+ * A read whose key the program does not spell -- `o[ k ]` -- can publish
205
+ * any key of any container its receiver reaches, so every publication had
206
+ * to test all 968 of the three.js app's unknown reads against its own container.
207
+ * That test does not depend on the key, and a container publishes many
208
+ * keys, so the same 968-entry scan was subscribed once PER KEY: this one
209
+ * loop is the largest single source of the 11.3M observe edges the solver
210
+ * carries on the three.js app. It is one node's fact, asked once per container.
211
+ */
212
+ const unknownReadsOf = (container) => nodeQuery('unknown-reads', container);
213
+ const targets = (call) => nodeQuery('targets', call);
214
+ const superTargets = (call) => nodeQuery('super-targets', call);
215
+ /**
216
+ * The method a lexical `super.<key>` selects, walking `extends` from the
217
+ * home class the way the prototype chain does.
218
+ *
219
+ * `super` is a LOOKUP ORIGIN, not a receiver: the object used as `this` is
220
+ * the instance, but the search for the callable starts one link up the
221
+ * chain, so an override on the instance's own class is exactly what it skips.
222
+ * Without this the graph's use walk read a `super` mention of the instance as
223
+ * an ordinary member call on it, asked for the targets of a dispatch it
224
+ * declines, and refused -- taking the enclosing ORDINARY call down with it,
225
+ * because a method whose body contains `super.copy(v)` is a method whose
226
+ * receiver closure could not be proven.
227
+ *
228
+ * Integrity is not re-derived here. Every class the walk visits must satisfy
229
+ * `classConstructorKeepsInstanceOf`, the same authority the receiver family
230
+ * already rests on, which is what refuses a program that writes
231
+ * `Base.prototype.copy`.
232
+ */
233
+ const superLookup = (home, key, seen) => {
234
+ if (!isClassSpelledSourceClass(home) || seen.has(home))
235
+ return null;
236
+ seen.add(home);
237
+ const heritage = home.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword);
238
+ if (!heritage || heritage.types.length !== 1)
239
+ return null;
240
+ const bases = sourceConstructorSelectionsOf(checker, flow, heritage.types[0].expression);
241
+ if (!bases || bases.length === 0)
242
+ return null;
243
+ const found = [];
244
+ for (const base of bases) {
245
+ const own = ownSuperSlot(base, key, seen);
246
+ if (own === null)
247
+ return null;
248
+ found.push(...own);
249
+ }
250
+ return found;
251
+ };
252
+ const ownSuperSlot = (owner, key, seen) => {
253
+ if (!isClassSpelledSourceClass(owner))
254
+ return null;
255
+ const symbol = owner.name ? checker.getSymbolAtLocation(owner.name) : checker.getTypeAtLocation(owner).getSymbol();
256
+ const instance = symbol && checker.getDeclaredTypeOfSymbol(symbol);
257
+ if (!instance?.isClassOrInterface() || !classConstructorKeepsInstanceOf(checker, flow, instance))
258
+ return null;
259
+ const own = [];
260
+ for (const member of owner.members) {
261
+ if (!member.name || (ts.getCombinedModifierFlags(member) & ts.ModifierFlags.Static) !== 0)
262
+ continue;
263
+ if (ts.isPrivateIdentifier(member.name))
264
+ continue;
265
+ // An instance field lives on the RECEIVER, and a constructor is not on
266
+ // the prototype at all: neither is where this lookup starts.
267
+ if (ts.isPropertyDeclaration(member) || ts.isConstructorDeclaration(member))
268
+ continue;
269
+ const memberKey = declarationKey(member.name);
270
+ // One computed member name makes the whole prototype's key set unknown,
271
+ // so the absence of this key on this class is no longer a fact.
272
+ if (memberKey === null)
273
+ return null;
274
+ if (memberKey !== key)
275
+ continue;
276
+ if (!ts.isMethodDeclaration(member) || member.body === undefined)
277
+ return null;
278
+ own.push(member);
279
+ }
280
+ return own.length > 0 ? own : superLookup(owner, key, seen);
281
+ };
282
+ /**
283
+ * The key is absent from this class's whole prototype chain.
284
+ *
285
+ * Absence is a chain-wide fact, so every step must be spelled: a computed
286
+ * member name anywhere makes the key set unknown, a constructor the graph
287
+ * cannot keep hold of its instance can add the key at run time, and a chain
288
+ * that does not end at a class with no `extends` never reaches the point
289
+ * where `Object.prototype` is the only thing left to ask about. Any of
290
+ * those, and the key is not PROVEN absent -- which is a different answer
291
+ * from proven present, and the caller must treat it as neither.
292
+ */
293
+ const chainAbsences = new Map();
294
+ const absentThroughChain = (owner, key, seen) => {
295
+ // The chain is syntax and a constructor proof, neither of which changes as
296
+ // the graph settles -- but it is asked once per (root, key) reaching an
297
+ // unspelled name, which on three's Object3D chain is a class-keeps-its-
298
+ // instance proof per access. Memoized on the pair it actually depends on.
299
+ let byKey = chainAbsences.get(owner);
300
+ if (!byKey)
301
+ chainAbsences.set(owner, (byKey = new Map()));
302
+ const known = byKey.get(key);
303
+ if (known !== undefined)
304
+ return known;
305
+ // Only a walk that starts here is memoized: one entered mid-chain carries
306
+ // the classes already visited, and its answer is about that path.
307
+ const top = seen.size === 0;
308
+ const answer = absentThroughChainUncached(owner, key, seen);
309
+ if (top)
310
+ byKey.set(key, answer);
311
+ return answer;
312
+ };
313
+ const absentThroughChainUncached = (owner, key, seen) => {
314
+ if (!isClassSpelledSourceClass(owner) || seen.has(owner))
315
+ return false;
316
+ seen.add(owner);
317
+ const symbol = owner.name ? checker.getSymbolAtLocation(owner.name) : checker.getTypeAtLocation(owner).getSymbol();
318
+ const instance = symbol && checker.getDeclaredTypeOfSymbol(symbol);
319
+ if (!instance?.isClassOrInterface() || !classConstructorKeepsInstanceOf(checker, flow, instance))
320
+ return false;
321
+ for (const member of owner.members) {
322
+ if (!member.name || (ts.getCombinedModifierFlags(member) & ts.ModifierFlags.Static) !== 0)
323
+ continue;
324
+ if (ts.isPrivateIdentifier(member.name))
325
+ continue;
326
+ const memberKey = declarationKey(member.name);
327
+ if (memberKey === null || memberKey === key)
328
+ return false;
329
+ }
330
+ const heritage = owner.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword);
331
+ if (!heritage)
332
+ return true;
333
+ if (heritage.types.length !== 1)
334
+ return false;
335
+ const bases = sourceConstructorSelectionsOf(checker, flow, heritage.types[0].expression);
336
+ if (!bases || bases.length === 0)
337
+ return false;
338
+ return bases.every((base) => absentThroughChain(base, key, new Set(seen)));
339
+ };
340
+ /**
341
+ * A key an object provably does not have -- for an instance, anywhere on
342
+ * its chain; for a literal, among the keys it spells.
343
+ *
344
+ * `for ( const key in values ) this[ key ] = values[ key ]` -- three's
345
+ * `setValues` -- stores to keys the class never declares. That is not an
346
+ * unmodelled descriptor: with the key absent from the chain the store
347
+ * creates a FRESH own data property, runs no accessor, and disturbs no slot
348
+ * the graph tracks. What it is NOT is a readable cell: `slot` keeps refusing
349
+ * the key, so a program that reads it back is opaque, and the value stored
350
+ * into it can only be reached through the instance itself.
351
+ *
352
+ * The last link in the chain is `Object.prototype`, which is an obligation
353
+ * rather than an observation -- registered here under exactly the key asked
354
+ * about, and discharged later by the sealed host-mutation census. With no
355
+ * ledger to carry it there is nothing that will ever discharge it, so the
356
+ * absence does not hold.
357
+ */
358
+ const absentOwnKey = (root, key, at, descriptorOf, hasUnnamedWrite) => {
359
+ if (ts.isObjectLiteralExpression(root)) {
360
+ // A literal that spells every key it has proves the absence of every
361
+ // key it does not. This is asked while walking the literal's OWN uses,
362
+ // so a store that added an unspelled key is a refusal in the same walk.
363
+ if (literalSpelledKeys(root) === null || descriptorOf(root, key) || hasUnnamedWrite(root))
364
+ return false;
365
+ }
366
+ else if (ts.isNewExpression(root)) {
367
+ const fact = construction(root);
368
+ if (!fact || fact.alternatives.length === 0)
369
+ return false;
370
+ if (!fact.alternatives.every((owner) => absentThroughChain(owner, key, new Set())))
371
+ return false;
372
+ }
373
+ else
374
+ return false;
375
+ return deferredIntrinsicProtocolLedgerOf(flow)?.requirePrototypeKeys('Object', { names: [key] }, at) === true;
376
+ };
377
+ const readsByKey = new Map();
378
+ const unknownReads = [];
379
+ for (const access of flow.propertyAccesses) {
380
+ const key = accessKey(access);
381
+ const entry = { access, receiver: value(access.expression) };
382
+ if (key === null)
383
+ unknownReads.push(entry);
384
+ else {
385
+ let reads = readsByKey.get(key);
386
+ if (!reads)
387
+ readsByKey.set(key, (reads = []));
388
+ reads.push(entry);
389
+ }
390
+ }
391
+ /**
392
+ * `unknownReads`, indexed by the query that answers what its RECEIVER
393
+ * holds -- the one hop `case 'unknown-reads'` needs from a holder key (a
394
+ * `Query`, handed back by `holdersOf`) to the access it belongs to.
395
+ *
396
+ * Built once, beside the list it indexes, for the same reason `readsByKey`,
397
+ * `writeEdgeByAccess` and `constructionSitesByTarget` are: the mapping is
398
+ * syntax and never changes as the graph solves, so computing it inside the
399
+ * transfer would be paying a whole-list rebuild on every re-evaluation of
400
+ * every container -- exactly the cost this inversion exists to remove.
401
+ */
402
+ const unknownReadsByReceiver = new Map();
403
+ for (const entry of unknownReads) {
404
+ let entries = unknownReadsByReceiver.get(entry.receiver);
405
+ if (!entries)
406
+ unknownReadsByReceiver.set(entry.receiver, (entries = []));
407
+ entries.push(entry);
408
+ }
409
+ /**
410
+ * Writes that go THROUGH some object, grouped by the name they write.
411
+ *
412
+ * Which root a write reaches is a solved question and changes as the graph
413
+ * settles; which NAME it writes is syntax and never changes. Splitting the
414
+ * two lets a descriptor ask about one key without walking every write in
415
+ * the program -- the difference between a scan per key and a scan per
416
+ * (key, root) pair, which is what made three's Material unfinishable.
417
+ */
418
+ const namedWrites = new Map();
419
+ const computedWrites = [];
420
+ const namedWriteReceivers = new Map();
421
+ /** The receiver queries of every computed write, for `hasUnnamedWrite`'s reverse lookup. */
422
+ const computedWriteReceiverQueries = new Set();
423
+ const writeEdgeByAccess = new Map();
424
+ for (const write of flow.allWrites) {
425
+ const access = write.propertyAccess;
426
+ if (!access)
427
+ continue;
428
+ const key = accessKey(access);
429
+ const edge = { access, receiver: value(access.expression), key, write };
430
+ writeEdgeByAccess.set(access, edge);
431
+ if (key === null) {
432
+ computedWrites.push(write);
433
+ computedWriteReceiverQueries.add(edge.receiver);
434
+ }
435
+ else {
436
+ let entries = namedWrites.get(key);
437
+ if (!entries)
438
+ namedWrites.set(key, (entries = []));
439
+ entries.push(write);
440
+ let edges = namedWriteReceivers.get(key);
441
+ if (!edges)
442
+ namedWriteReceivers.set(key, (edges = []));
443
+ edges.push(edge);
444
+ }
445
+ }
446
+ /**
447
+ * The declaration an import actually names.
448
+ *
449
+ * `import { inspect } from './m'` declares an ALIAS, whose own declaration
450
+ * is the import specifier -- a name for a name. Every consumer here wants
451
+ * the thing named: the function, the class, the binding in the other file.
452
+ * A barrel re-export is that same question asked twice, so the checker's own
453
+ * alias resolution does the walking rather than one hop of it.
454
+ *
455
+ * A namespace import is deliberately NOT resolved: `import * as api` names
456
+ * an object carrying every export as a slot, which is a different value
457
+ * from any one of them, and collapsing it would let a namespace that
458
+ * escaped look like a callable that did not.
459
+ */
460
+ const aliasedDeclarationOf = (symbol) => {
461
+ if (!symbol || (symbol.flags & ts.SymbolFlags.Alias) === 0)
462
+ return null;
463
+ const named = symbol.declarations ?? [];
464
+ if (named.length === 0)
465
+ return null;
466
+ if (!named.every((declaration) => ts.isImportSpecifier(declaration) || ts.isImportClause(declaration) || ts.isExportSpecifier(declaration)))
467
+ return null;
468
+ const aliased = checker.getAliasedSymbol(symbol).declarations ?? [];
469
+ return aliased.length === 1 ? aliased[0] : null;
470
+ };
471
+ const slot = (root, key) => {
472
+ let keys = slots.get(root);
473
+ if (!keys)
474
+ slots.set(root, (keys = new Map()));
475
+ let query = keys.get(key);
476
+ if (!query)
477
+ keys.set(key, (query = { kind: 'slot', node: root, key }));
478
+ return query;
479
+ };
480
+ const use = (root, reference) => {
481
+ let refs = uses.get(root);
482
+ if (!refs)
483
+ uses.set(root, (refs = new Map()));
484
+ let query = refs.get(reference);
485
+ if (!query)
486
+ refs.set(reference, (query = { kind: 'use', root, node: reference }));
487
+ return query;
488
+ };
489
+ const publication = (root, container, key) => {
490
+ let containers = publications.get(root);
491
+ if (!containers)
492
+ publications.set(root, (containers = new Map()));
493
+ let keys = containers.get(container);
494
+ if (!keys)
495
+ containers.set(container, (keys = new Map()));
496
+ let query = keys.get(key);
497
+ if (!query)
498
+ keys.set(key, (query = { kind: 'publication', root, node: container, key }));
499
+ return query;
500
+ };
501
+ /** The cell holding the object a binding element takes apart, as a query. */
502
+ const bindingContainer = (element) => {
503
+ const holder = element.parent.parent;
504
+ if (ts.isParameter(holder))
505
+ return holder.dotDotDotToken ? null : nodeQuery('parameter', holder);
506
+ if (ts.isBindingElement(holder))
507
+ return nodeQuery('binding-element', holder);
508
+ return ts.isVariableDeclaration(holder) && holder.initializer ? value(holder.initializer) : null;
509
+ };
510
+ const construction = (root) => exactSourceConstructionOf(checker, flow, root);
511
+ /**
512
+ * What a key names on this construction: its data member, or the method the
513
+ * call through it dispatches to.
514
+ *
515
+ * Both, because a slot is a slot. Asking only for data meant
516
+ * `descriptor(new App(), 'go')` was false, so the simplest class call in the
517
+ * language -- `const a = new App(); a.go()` -- resolved its receiver and then
518
+ * had no slot to read the callee out of.
519
+ */
520
+ const classMembers = (root, key) => {
521
+ const fact = construction(root);
522
+ if (!fact)
523
+ return null;
524
+ const found = new Set();
525
+ for (const owner of fact.alternatives) {
526
+ const symbol = owner.name ? checker.getSymbolAtLocation(owner.name) : checker.getTypeAtLocation(owner).getSymbol();
527
+ if (!symbol)
528
+ return null;
529
+ const query = { kind: 'declared', receiver: checker.getDeclaredTypeOfSymbol(symbol) };
530
+ const plan = sourceClassDataMemberPlanOf(checker, flow, query, key) ?? sourceClassCallableMemberPlanOf(checker, flow, query, key);
531
+ if (!plan)
532
+ return null;
533
+ for (const declaration of plan.declarations)
534
+ found.add(declaration);
535
+ }
536
+ return [...found];
537
+ };
538
+ const classSymbolOf = (owner) => owner.name ? checker.getSymbolAtLocation(owner.name) : checker.getTypeAtLocation(owner).getSymbol();
539
+ /**
540
+ * A read of `key` on this construction by the key-read plan of every class
541
+ * it can be: the source getter bodies it can enter, the data declarations
542
+ * the key selects, and whether some class lacks the key (the read is then
543
+ * `undefined` there). Null when some class's read is opaque -- a method,
544
+ * a bodiless getter, an unseen member kind. `classMembers` answers first
545
+ * for the all-data and all-method keys; this covers the mixed and the
546
+ * accessor families it refuses.
547
+ *
548
+ * `source.depthTexture` in three's `RenderTarget.copy`: the key is a getter
549
+ * over `this._depthTexture`, and the read was an unmodelled descriptor --
550
+ * which made every value reaching a render target's depth texture opaque,
551
+ * `current.renderTarget = this` in its setter included.
552
+ */
553
+ const familyReadOf = (root, key) => {
554
+ const fact = construction(root);
555
+ if (!fact || fact.alternatives.length === 0)
556
+ return null;
557
+ const getters = new Set();
558
+ const carriers = new Set();
559
+ let absent = false;
560
+ for (const owner of fact.alternatives) {
561
+ const symbol = classSymbolOf(owner);
562
+ if (!symbol)
563
+ return null;
564
+ const plan = sourceClassKeyReadPlanOf(checker, flow, { kind: 'declared', receiver: checker.getDeclaredTypeOfSymbol(symbol) }, key);
565
+ if (!plan || plan.readBodies === null)
566
+ return null;
567
+ for (const body of plan.readBodies)
568
+ getters.add(body);
569
+ for (const carrier of plan.carriers)
570
+ carriers.add(carrier.declaration);
571
+ if (plan.needsDefaultPrototype)
572
+ absent = true;
573
+ }
574
+ return { getters: [...getters], carriers: [...carriers], absent };
575
+ };
576
+ /**
577
+ * Whether a plain store to `key` on this construction writes DATA on every
578
+ * class it can be -- an own data member, or a key the class lacks and so
579
+ * creates (with `Object.prototype` proven to hold no setter for it, which
580
+ * the key-read plan registers). `this.isWebGLRenderTarget = true` in
581
+ * three's `WebGLRenderTarget` constructor, reached through a
582
+ * `new this.constructor()` whose alternatives include the base class that
583
+ * has no such member: the data-member plan refuses a key absent on any
584
+ * owner, and the store was an unmodelled descriptor.
585
+ */
586
+ const dataStoreOf = (root, key) => {
587
+ const fact = construction(root);
588
+ if (!fact || fact.alternatives.length === 0)
589
+ return false;
590
+ for (const owner of fact.alternatives) {
591
+ const symbol = classSymbolOf(owner);
592
+ if (!symbol)
593
+ return false;
594
+ const plan = sourceClassKeyReadPlanOf(checker, flow, { kind: 'declared', receiver: checker.getDeclaredTypeOfSymbol(symbol) }, key);
595
+ if (!plan || !plan.codeFree)
596
+ return false;
597
+ }
598
+ return true;
599
+ };
600
+ /** The complete set of source setters a plain store to `key` on this construction runs, or null when that is opaque. */
601
+ const settersOf = (root, key) => {
602
+ const fact = construction(root);
603
+ if (!fact || fact.alternatives.length === 0)
604
+ return null;
605
+ const bodies = new Set();
606
+ for (const owner of fact.alternatives) {
607
+ const symbol = classSymbolOf(owner);
608
+ if (!symbol)
609
+ return null;
610
+ const plan = sourceClassKeyReadPlanOf(checker, flow, { kind: 'declared', receiver: checker.getDeclaredTypeOfSymbol(symbol) }, key);
611
+ if (!plan?.writeBodies || plan.writeBodies.length === 0)
612
+ return null;
613
+ for (const setter of plan.writeBodies)
614
+ bodies.add(setter);
615
+ }
616
+ return [...bodies];
617
+ };
618
+ /**
619
+ * `Object.assign( target, ...sources )` on the intact intrinsic: the one
620
+ * bulk write this graph models. The call evaluates to its target, and each
621
+ * source's own slot values are copied into the target's slots -- three's
622
+ * `RenderTarget` builds its `options` exactly this way.
623
+ */
624
+ const bulkAssignOf = (call) => {
625
+ if (!isGlobalObjectAssign(checker, call))
626
+ return null;
627
+ const [target, ...sources] = call.arguments;
628
+ if (!target || call.arguments.some(ts.isSpreadElement))
629
+ return null;
630
+ if (deferredIntrinsicProtocolLedgerOf(flow)?.requireMember('Object', 'assign', call) !== true)
631
+ return null;
632
+ return { target, sources };
633
+ };
634
+ /**
635
+ * `Object.defineProperty( target, key, { value } )` on the intact intrinsic:
636
+ * a store of the descriptor's `value` into `key` of the target, running no
637
+ * code of the target's. Three's `Texture` and `Material` define `id` this
638
+ * way in their constructors, and the target's use as the call's argument
639
+ * was a call with no source target -- so every texture was opaque.
640
+ * `defineProperties` is lowered to this form by the source transform and is
641
+ * not modelled here.
642
+ */
643
+ const definitionPlans = new Map();
644
+ const definitionReceivers = new Map();
645
+ for (const site of flow.calls) {
646
+ const call = site.call;
647
+ if (!ts.isCallExpression(call) || call.arguments.length < 2)
648
+ continue;
649
+ const plan = intrinsicDataDefinitionTargetOf(checker, call.arguments[0], (declaration, argument) => flow.referencesToDeclaration(declaration).every((mention) => mention === declaration.name || mention === argument));
650
+ if (plan === null || plan.member !== 'defineProperty')
651
+ continue;
652
+ definitionPlans.set(call, plan);
653
+ for (const key of plan.keys) {
654
+ let entries = definitionReceivers.get(key);
655
+ if (!entries)
656
+ definitionReceivers.set(key, (entries = []));
657
+ entries.push({ receiver: value(call.arguments[0]) });
658
+ }
659
+ }
660
+ const definitionOf = (call) => {
661
+ const plan = definitionPlans.get(call);
662
+ if (!plan)
663
+ return null;
664
+ const ledger = deferredIntrinsicProtocolLedgerOf(flow);
665
+ if (ledger?.requireMember(plan.owner, plan.member, call) !== true)
666
+ return null;
667
+ if (plan.descriptorPrototypeKeys.length > 0 && !ledger.requirePrototypeKeys('Object', { names: plan.descriptorPrototypeKeys }, call))
668
+ return null;
669
+ return plan;
670
+ };
671
+ const ownEntries = (root, key) => {
672
+ const entries = [];
673
+ for (const entry of root.properties) {
674
+ if (ts.isSpreadAssignment(entry))
675
+ return null;
676
+ const name = declarationKey(entry.name);
677
+ if (name === null || name === '__proto__')
678
+ return null;
679
+ if (name !== key)
680
+ continue;
681
+ if (ts.isGetAccessorDeclaration(entry) || ts.isSetAccessorDeclaration(entry))
682
+ return null;
683
+ entries.push(entry);
684
+ }
685
+ return entries.length > 0 ? entries : null;
686
+ };
687
+ const descriptor = (root, key) => {
688
+ if (ts.isNewExpression(root))
689
+ return classMembers(root, key) !== null;
690
+ if (ts.isObjectLiteralExpression(root))
691
+ return ownEntries(root, key) !== null;
692
+ if (key === 'length')
693
+ return true;
694
+ // An index the literal does not spell is still the array's own: it reads
695
+ // `undefined` until an index store fills it, and `case 'slot'` reads the
696
+ // stores through `keyReaches`. three's `RenderTarget` starts with
697
+ // `this.textures = []`, fills it by index in the constructor, and its
698
+ // `texture` getter reads `this.textures[ 0 ]`.
699
+ return (key === ELEMENT_KEY || isCanonicalIndex(key)) && !root.elements.some(ts.isSpreadElement);
700
+ };
701
+ const ownersOf = (root) => constructionFrames.receiverOwnersOf(root) ?? [];
702
+ /**
703
+ * Every construction of each owning class, built once.
704
+ *
705
+ * `belongsTo` is decided by `receiverOwnersOf`, which reads the index and
706
+ * nothing a solve revises, so the whole relation is known before the first
707
+ * query. Two transfers were rediscovering it by walking every call in the
708
+ * program per query.
709
+ */
710
+ /**
711
+ * The calls that can dispatch to a body, decided by NAME before any solving.
712
+ *
713
+ * A call's targets are its callee's VALUES, and a body enters a value set
714
+ * only as the name it is declared or stored under: `value` of a property
715
+ * access reads `slot(root, key)`, and a store into that slot is spelled with
716
+ * the same key, so a callee spelling some OTHER name cannot produce this body
717
+ * however the graph solves. Three transfers -- a parameter's frame, a
718
+ * receiver's frame and a completion's use -- asked anyway, by observing
719
+ * `targets` of EVERY call in the program, per query. That forced the entire
720
+ * program's dispatch graph from each of them and was the three.js app's compile time:
721
+ * the fan-out, not any one answer. `callersOf` below is the fix for the
722
+ * fan-out; this function is unchanged and still returns the same
723
+ * whole-program list for an unnamed body -- only how many times that list
724
+ * gets walked has changed.
725
+ *
726
+ * `unspelledCallees` is every call this layer cannot name -- a computed
727
+ * element access, a call result, anything but an identifier or a static key
728
+ * -- and is a candidate for every body, so the restriction only ever removes
729
+ * calls that were already impossible. A body whose own names cannot be
730
+ * enumerated falls back to the whole list rather than to a guess.
731
+ *
732
+ * That fallback fires for the three.js app's ~156 anonymous bodies handed straight to
733
+ * a host/intrinsic callee -- `[].map(x => ...)`, `setTimeout(() => ...)` --
734
+ * because `ValueWrite.naming` only spells "the parameter's name for a call
735
+ * argument" when the callee is a SOURCE function; a host callee's parameter
736
+ * is never spelled, so `namesOf` meets an unnamed write and returns null.
737
+ * It is tempting to narrow this to just the receiving call site, since the
738
+ * body is never stored under a name and so cannot be READ back and called
739
+ * from anywhere this layer's write census would see. That is not the same
740
+ * as proving no OTHER call reaches it: a host function is free to retain the
741
+ * callback it was handed and invoke it again later through a binding this
742
+ * layer never inventories (a memoized comparator, a registered listener), so
743
+ * "receiving call site only" is not provably a superset. Left as the whole
744
+ * list rather than landing an unsound narrowing.
745
+ */
746
+ let calleeNames = null;
747
+ let unspelledCallees = [];
748
+ const buildCalleeIndex = () => {
749
+ if (calleeNames !== null)
750
+ return calleeNames;
751
+ const index = new Map();
752
+ const unspelled = [];
753
+ for (const site of flow.calls) {
754
+ // `new F( ... )` is indexed under F's spelling too: on a plain function it
755
+ // is a caller frame (`case 'callers'`), which the construction domain
756
+ // never names.
757
+ if (!ts.isCallExpression(site.call) && !ts.isNewExpression(site.call))
758
+ continue;
759
+ const callee = site.operands ? unwrapErasedExpression(site.operands.callee) : null;
760
+ const name = callee
761
+ ? ts.isIdentifier(callee)
762
+ ? callee.text
763
+ : ts.isPropertyAccessExpression(callee) || ts.isElementAccessExpression(callee)
764
+ ? accessKey(callee)
765
+ : null
766
+ : null;
767
+ if (name === null)
768
+ unspelled.push(site);
769
+ else {
770
+ let held = index.get(name);
771
+ if (!held)
772
+ index.set(name, (held = []));
773
+ held.push(site);
774
+ }
775
+ }
776
+ unspelledCallees = unspelled;
777
+ calleeNames = index;
778
+ return index;
779
+ };
780
+ /** Every name a body can be reached by: its own, and every cell it is stored in. */
781
+ const bodyNames = new Map();
782
+ const namesOf = (body) => {
783
+ const known = bodyNames.get(body);
784
+ if (known !== undefined)
785
+ return known;
786
+ const names = new Set();
787
+ const declared = ts.getNameOfDeclaration(body);
788
+ if (declared) {
789
+ const key = ts.isIdentifier(declared) || ts.isStringLiteralLike(declared) ? declared.text : declarationKey(declared);
790
+ if (key === null) {
791
+ bodyNames.set(body, null);
792
+ return null;
793
+ }
794
+ names.add(key);
795
+ }
796
+ // A function expression or arrow is reached by whatever holds it. Every
797
+ // write whose VALUE is this body names one such cell; a write this layer
798
+ // cannot name means the body can be reached by a name it cannot enumerate.
799
+ if (!declared || ts.isFunctionExpression(body) || ts.isArrowFunction(body))
800
+ for (const write of flow.allWrites) {
801
+ if (write.value === undefined || write.value === null || unwrapErasedExpression(write.value) !== body)
802
+ continue;
803
+ const named = write.member ?? (write.naming && ts.isIdentifier(write.naming) ? write.naming.text : null);
804
+ if (named === null) {
805
+ bodyNames.set(body, null);
806
+ return null;
807
+ }
808
+ names.add(named);
809
+ }
810
+ const answer = names.size > 0 ? [...names] : null;
811
+ bodyNames.set(body, answer);
812
+ return answer;
813
+ };
814
+ /** The declared instance type of a class member's holder; null for anything a stated type cannot exclude callers of. */
815
+ const ownerInstanceTypeOf = (owner) => {
816
+ if (!ts.isClassElement(owner) || !ts.isClassLike(owner.parent))
817
+ return null;
818
+ if ((ts.getCombinedModifierFlags(owner) & ts.ModifierFlags.Static) !== 0)
819
+ return null;
820
+ const symbol = classSymbolOf(owner.parent);
821
+ if (!symbol)
822
+ return null;
823
+ const declared = checker.getDeclaredTypeOfSymbol(symbol);
824
+ return declared.isClassOrInterface() ? declared : null;
825
+ };
826
+ const statedTypeAdmits = (stated, instance) => {
827
+ if ((stated.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.TypeParameter)) !== 0)
828
+ return true;
829
+ if (stated.isUnion())
830
+ return stated.types.some((member) => statedTypeAdmits(member, instance));
831
+ if ((stated.flags & ts.TypeFlags.Object) === 0)
832
+ return false;
833
+ return checker.isTypeAssignableTo(instance, stated);
834
+ };
835
+ const candidateCallersOf = (body) => {
836
+ const index = buildCalleeIndex();
837
+ const names = namesOf(body);
838
+ if (names === null)
839
+ return flow.calls;
840
+ // `unspelledCallees` is a whole-program list and this runs once per
841
+ // TRANSFER, not once per program -- `[...unspelledCallees]` copied it on
842
+ // every call just to push a handful of named matches on top. `both`
843
+ // hands it back by reference when there is nothing to add.
844
+ const named = [];
845
+ for (const name of names)
846
+ for (const site of index.get(name) ?? [])
847
+ named.push(site);
848
+ return both(unspelledCallees, named);
849
+ };
850
+ /**
851
+ * The calls that actually target this body -- the same question
852
+ * `candidateCallersOf(owner)` plus a `targets` filter answers, asked ONCE
853
+ * per body instead of once per consumer.
854
+ *
855
+ * A parameter's frame, a receiver's frame and a return statement's
856
+ * completion each used to run that filter themselves, inside their own
857
+ * transfer: `for (const site of candidateCallersOf(owner)) if (...
858
+ * observe(targets(site.call)).has(owner)) ...`. For a NAMED body
859
+ * `candidateCallersOf` is already small and the repetition was cheap. For
860
+ * one of the three.js app's ~156 anonymous bodies handed to a host callee it is
861
+ * `flow.calls` -- 5,543 sites -- and every parameter of such a body, plus
862
+ * its receiver, plus every one of its return statements, walked and
863
+ * `observe`d that entire list separately. 844 `parameter` states alone
864
+ * carried 605,547 observe edges this way, 717 per state on average, almost
865
+ * all of it the same whole-program filter re-run for the same owner.
866
+ *
867
+ * This is `unknownReadsOf`'s shape exactly: a whole-program list, tested
868
+ * against one thing, wanted by many consumers of that one thing. Giving the
869
+ * filter its own node means the solver runs it once per owner and caches
870
+ * the (small) result; every consumer then pays one `observe` edge to reach
871
+ * it, discovery-only exactly as the inline `observe(targets(...))` was, so
872
+ * none of them is required to wait for `callers` to settle before they
873
+ * report what they already know.
874
+ */
875
+ //
876
+ // Consumers `read` it, not `observe` it: the node carries the closure
877
+ // requirements that make its caller set complete, and a frame built from
878
+ // the discovered calls alone would be complete over an open caller set.
879
+ const callersOf = (owner) => nodeQuery('callers', owner);
880
+ let constructionsByOwner = null;
881
+ /**
882
+ * Every site that constructs: a `new`, or a `super(...)` standing in for one.
883
+ *
884
+ * The predicate is syntax and never moves, but it was asked inside the
885
+ * `parameter` transfer, so proving one parameter's frame walked every call in
886
+ * the program -- and did it again on every re-evaluation.
887
+ *
888
+ * Worse than the walk was what the walk SUBSCRIBED to. `construct-targets`
889
+ * neither reads nor observes: it is `constructionFrames.targetsOf` and
890
+ * nothing else, fixed before the first transfer runs. So the 854 edges a
891
+ * parameter registered were edges to constants -- they could never carry a
892
+ * wake-up, and they existed only to force the leaf's state into being. Asked
893
+ * the other way round, as an index from target to the sites that construct
894
+ * it, the answer is the same set and the edges are none.
895
+ */
896
+ const NO_READS = [];
897
+ const NO_SITES = [];
898
+ let constructionSitesByTarget = null;
899
+ const constructionSitesTargeting = (owner) => {
900
+ if (constructionSitesByTarget === null) {
901
+ constructionSitesByTarget = new Map();
902
+ for (const site of flow.calls) {
903
+ if (!ts.isNewExpression(site.call) && site.operands.dispatch.kind !== 'super-constructor')
904
+ continue;
905
+ for (const target of constructionFrames.targetsOf(site.call) ?? []) {
906
+ let held = constructionSitesByTarget.get(target);
907
+ if (!held)
908
+ constructionSitesByTarget.set(target, (held = []));
909
+ held.push(site);
910
+ }
911
+ }
912
+ }
913
+ return constructionSitesByTarget.get(owner) ?? NO_SITES;
914
+ };
915
+ /**
916
+ * The `new` sites the construction domain cannot place, found once. A
917
+ * class member's instances are `constructionsOf` its family, and that list
918
+ * is complete only while none of these names a family class: `new Owner()`
919
+ * after `Owner.prototype.take = replacement` is an Owner the domain refused,
920
+ * not a non-Owner. Only the stated instance type can say which class such a
921
+ * site names; a site typed `any` names none, and the class value's own
922
+ * closure (the family inventory) already says it flows into no table.
923
+ */
924
+ let opaqueConstructions = null;
925
+ const opaqueConstructionsOf = () => {
926
+ if (opaqueConstructions === null) {
927
+ const found = [];
928
+ for (const site of flow.calls)
929
+ if (ts.isNewExpression(site.call) && constructionFrames.receiverOwnersOf(site.call) === null)
930
+ found.push(site.call);
931
+ opaqueConstructions = found;
932
+ }
933
+ return opaqueConstructions;
934
+ };
935
+ const constructionsOf = (owner) => {
936
+ if (constructionsByOwner === null) {
937
+ constructionsByOwner = new Map();
938
+ for (const site of flow.calls) {
939
+ if (!ts.isNewExpression(site.call))
940
+ continue;
941
+ for (const candidate of ownersOf(site.call)) {
942
+ let held = constructionsByOwner.get(candidate);
943
+ if (!held)
944
+ constructionsByOwner.set(candidate, (held = []));
945
+ held.push(site.call);
946
+ }
947
+ }
948
+ }
949
+ const own = constructionsByOwner.get(owner) ?? [];
950
+ const inherited = owner.parent ? (constructionsByOwner.get(owner.parent) ?? []) : [];
951
+ return inherited.length === 0 ? own : own.length === 0 ? inherited : [...new Set([...own, ...inherited])];
952
+ };
953
+ const isCallableValue = (node) => isBody(node);
954
+ /**
955
+ * The enumerated expression, when this key expression is a `for-in` head.
956
+ *
957
+ * `for ( const key in values ) this[ key ] = values[ key ]` -- three's
958
+ * `setValues`, and the three.js app's single largest computed-store family. `key`
959
+ * names no VALUE the graph can carry, so `value(key)` correctly answers
960
+ * nothing and the access refuses on an unresolved key. What the graph CAN
961
+ * answer is what `values` holds, and an object literal spells its own keys.
962
+ *
963
+ * The head is a fresh binding each round. A body that assigns to it is
964
+ * naming something other than the enumerated key, so any write disqualifies
965
+ * the whole head rather than being folded into the set.
966
+ */
967
+ const enumerationHeads = new Map();
968
+ const enumerationHeadOf = (expression) => {
969
+ const known = enumerationHeads.get(expression);
970
+ if (known !== undefined)
971
+ return known;
972
+ const answer = enumerationHeadUncached(expression);
973
+ enumerationHeads.set(expression, answer);
974
+ return answer;
975
+ };
976
+ const enumerationHeadUncached = (expression) => {
977
+ const reference = unwrapErasedExpression(expression);
978
+ if (!ts.isIdentifier(reference))
979
+ return null;
980
+ const declaration = flow.targetOf(reference)?.declaration;
981
+ if (!declaration || !ts.isVariableDeclaration(declaration) || !ts.isIdentifier(declaration.name))
982
+ return null;
983
+ const list = declaration.parent;
984
+ if (!ts.isVariableDeclarationList(list) || list.declarations.length !== 1)
985
+ return null;
986
+ const statement = list.parent;
987
+ if (!ts.isForInStatement(statement) || statement.initializer !== list)
988
+ return null;
989
+ if (flow.writesToDeclaration(declaration).some((write) => write.edge !== 'iteration-binding'))
990
+ return null;
991
+ return statement.expression;
992
+ };
993
+ /** The own keys an object literal spells, or nothing when a spread or a
994
+ * computed name means the literal does not spell them all. Under-reporting a
995
+ * key set is not a smaller answer, it is a wrong one: it would leave a slot
996
+ * the program actually stores into looking untouched. */
997
+ const literalSpelledKeys = (root) => {
998
+ if (!ts.isObjectLiteralExpression(root))
999
+ return null;
1000
+ const keys = [];
1001
+ for (const property of root.properties) {
1002
+ if (ts.isSpreadAssignment(property))
1003
+ return null;
1004
+ const key = declarationKey(property.name);
1005
+ if (key === null || key === '__proto__')
1006
+ return null;
1007
+ keys.push(key);
1008
+ }
1009
+ return keys;
1010
+ };
1011
+ /**
1012
+ * The keys a `for-in` head binds: the own keys of every root the enumerated
1013
+ * expression can hold. The dependency goes into the graph -- `value(...)` on
1014
+ * the enumerated expression -- rather than to a second key-set authority
1015
+ * asking the same question a different way.
1016
+ *
1017
+ * `Object.prototype` must carry no enumerable string key of its own, or the
1018
+ * head walks keys no root spells. That obligation is deferred to the ledger,
1019
+ * exactly as the legacy key-set authority defers it; with no ledger to carry
1020
+ * it there is nothing to discharge it later, so the enumeration refuses.
1021
+ */
1022
+ const enumeratedKeysOf = (access, enumerated, read, fail, sealing, ownKeysOf) => {
1023
+ if (!deferredIntrinsicProtocolLedgerOf(flow)?.require('Object', access)) {
1024
+ fail('undeferrable-enumeration-protocol', access);
1025
+ return [];
1026
+ }
1027
+ const keys = new Set();
1028
+ const roots = read(value(enumerated));
1029
+ for (const root of roots) {
1030
+ // `for ( key in undefined )` binds nothing: three's `Material` runs
1031
+ // `setValues( parameters )` for a bare `new MeshDepthMaterial()`.
1032
+ if (isNullish(root))
1033
+ continue;
1034
+ const own = ownKeysOf(root);
1035
+ if (own === null) {
1036
+ fail('unspelled-enumeration-root', isObjectRoot(root) ? root : enumerated);
1037
+ continue;
1038
+ }
1039
+ // A literal spells its keys only while nothing else adds one, and the
1040
+ // graph already refuses a store to a key an object literal does not
1041
+ // declare -- so the root's own closure IS that proof. It is required
1042
+ // here rather than assumed: an under-reported key set leaves a slot the
1043
+ // program actually writes looking untouched, which is a wrong answer
1044
+ // wearing a smaller one's clothes.
1045
+ read(closure(root));
1046
+ for (const key of own)
1047
+ keys.add(key);
1048
+ }
1049
+ if (sealing && roots.size === 0)
1050
+ fail('unresolved-enumeration', enumerated);
1051
+ return [...keys];
1052
+ };
1053
+ const define = (query) => {
1054
+ let finalCauses = [];
1055
+ let finalGrounding = [];
1056
+ let seeded = false;
1057
+ const ownKeysAnswers = new Map();
1058
+ const evaluate = (required, observe, holdersOf, sealing) => {
1059
+ const facts = new Set();
1060
+ const causes = [];
1061
+ const grounding = new Set();
1062
+ const fail = (reason, node = query.node) => {
1063
+ causes.push({ reason, node });
1064
+ if (refusalDebug) {
1065
+ const file = node.getSourceFile();
1066
+ const { line } = file.getLineAndCharacterOfPosition(node.getStart(file));
1067
+ const text = node.getText(file).replace(/\s+/g, ' ');
1068
+ console.error(`[SESSION-REFUSAL] ${reason} ${query.kind} ${file.fileName.split('/').pop()}:${line + 1} ${text.slice(0, 90)}`);
1069
+ }
1070
+ };
1071
+ // No edge ledger of our own: the solver records every required edge, and
1072
+ // `obligations` walks its copy. Keeping a second one cost a map lookup
1073
+ // and a set insert on every edge read in the program -- the largest
1074
+ // single self-time entry in the three.js app's profile once the state lookup
1075
+ // beside it was gone -- and a duplicate of the whole proof graph in a
1076
+ // solve that was already running out of heap.
1077
+ const read = required;
1078
+ const carry = (dependency) => {
1079
+ grounding.add(dependency);
1080
+ return read(dependency);
1081
+ };
1082
+ const add = (values) => {
1083
+ for (const held of values)
1084
+ facts.add(held);
1085
+ };
1086
+ /**
1087
+ * A member call whose receiver holds nothing but `null`/`undefined`
1088
+ * throws at the lookup: no target, no frame, no completion -- and no
1089
+ * refusal, since the throw is the program's own answer. three's
1090
+ * `RenderTarget.copy` runs `source.depthTexture.clone()` under a guard
1091
+ * this graph does not read, and every value `depthTexture` holds in
1092
+ * the fixture is `null`.
1093
+ */
1094
+ const lookupThrows = (call) => {
1095
+ const site = sites.get(call);
1096
+ if (!site?.operands || site.explicitThis || site.operands.dispatch.kind !== 'member' || site.operands.receiver === null)
1097
+ return false;
1098
+ const held = read(value(site.operands.receiver));
1099
+ return held.size > 0 && [...held].every(isNullish);
1100
+ };
1101
+ /**
1102
+ * The keys a named write through a root adds to it.
1103
+ *
1104
+ * `const values = { minFilter: 1, flipY: false }; values.wrapS = w` --
1105
+ * three's RenderTarget. The literal SPELLS two keys and the program
1106
+ * gives it a third, so the spelling is not the key set. `case 'slot'`
1107
+ * already reads those writes; without them in the descriptor the very
1108
+ * slot they write was refused before it could be read -- the descriptor
1109
+ * answering about the LITERAL when it was asked about the OBJECT.
1110
+ *
1111
+ * Only literals are asked. A class instance's absent keys are a chain
1112
+ * proof rather than a spelling, and `this[ key ] = v` inside a method
1113
+ * would otherwise leave every instance's key set unknown.
1114
+ */
1115
+ /**
1116
+ * The keys a named write through a root adds to it.
1117
+ *
1118
+ * `const values = { minFilter: 1, flipY: false }; values.wrapS = w` --
1119
+ * three's RenderTarget. The literal SPELLS two keys and the program
1120
+ * gives it a third, so the spelling is not the key set. `case 'slot'`
1121
+ * already reads those writes; without them in the descriptor the very
1122
+ * slot they write was refused before it could be read -- the descriptor
1123
+ * answering about the LITERAL when it was asked about the OBJECT.
1124
+ *
1125
+ * Only literals are asked. A class instance's absent keys are a chain
1126
+ * proof rather than a spelling, and `this[ key ] = v` inside a method
1127
+ * would otherwise leave every instance's key set unknown.
1128
+ *
1129
+ * This scan is asked about ONE key's writes, or about the computed ones,
1130
+ * and stays here for that reason. Routing it through `written-keys` was
1131
+ * measured and reverted: that query depends on every named write in the
1132
+ * program, so a per-key descriptor question -- asked about most roots in
1133
+ * the program, not just the enumerated ones -- pulled a whole-program
1134
+ * dependency set into each of them and put the three.js app into GC death at
1135
+ * 8m31s. A whole-program walk becomes a query only where the consumer
1136
+ * genuinely wants the whole program, which here is enumeration alone.
1137
+ */
1138
+ const writesTo = (root, edges) => edges.some((edge) => observe(edge.receiver).has(root));
1139
+ /**
1140
+ * A write under a key this graph cannot name leaves the key set unknown
1141
+ * -- reported as unknown, never as a smaller set. Asked in reverse:
1142
+ * which states hold this root, and is any of them a computed write's
1143
+ * receiver -- one lookup per root instead of observing all of the three.js app's
1144
+ * computed-write receivers per root per re-evaluation. `holdersOf`
1145
+ * subscribes this node to the root's future holders exactly as the
1146
+ * observe edges did, and the receivers are seeded below so each exists.
1147
+ */
1148
+ const unknownKeys = new Map();
1149
+ const holderStampLists = [];
1150
+ const hasUnnamedWrite = (root) => {
1151
+ const known = unknownKeys.get(root);
1152
+ if (known !== undefined)
1153
+ return known;
1154
+ let found = false;
1155
+ let count = 0;
1156
+ for (const holder of holdersOf(root)) {
1157
+ count++;
1158
+ if (computedWriteReceiverQueries.has(holder))
1159
+ found = true;
1160
+ }
1161
+ for (const stamps of holderStampLists)
1162
+ stamps.push([root, count]);
1163
+ unknownKeys.set(root, found);
1164
+ return found;
1165
+ };
1166
+ /** Every cell a root has: what it spells, plus what was written into it. */
1167
+ const ownKeys = new Map();
1168
+ const activeOwnKeys = new Set();
1169
+ const stampLists = [];
1170
+ const watched = (dependency) => {
1171
+ const held = observe(dependency);
1172
+ for (const stamps of stampLists)
1173
+ stamps.push([held, held.size]);
1174
+ return held;
1175
+ };
1176
+ const holdersUnchanged = (stamps) => {
1177
+ for (const [root, count] of stamps) {
1178
+ let now = 0;
1179
+ for (const _holder of holdersOf(root))
1180
+ now++;
1181
+ if (now !== count)
1182
+ return false;
1183
+ }
1184
+ return true;
1185
+ };
1186
+ const ownKeysOf = (root) => {
1187
+ const known = ownKeys.get(root);
1188
+ if (known !== undefined)
1189
+ return known;
1190
+ // A bulk assign whose source's keys come back to this root -- two
1191
+ // records merged into each other -- names no finite set on the way
1192
+ // round; the re-entry is unknown, and only the outer answer is kept.
1193
+ if (activeOwnKeys.has(root))
1194
+ return null;
1195
+ const kept = ownKeysAnswers.get(root);
1196
+ if (kept !== undefined && kept.stamps.every(([held, size]) => held.size === size) && holdersUnchanged(kept.holderStamps)) {
1197
+ for (const stamps of stampLists)
1198
+ stamps.push(...kept.stamps);
1199
+ for (const stamps of holderStampLists)
1200
+ stamps.push(...kept.holderStamps);
1201
+ ownKeys.set(root, kept.keys);
1202
+ return kept.keys;
1203
+ }
1204
+ activeOwnKeys.add(root);
1205
+ const stamps = [];
1206
+ const holderStamps = [];
1207
+ stampLists.push(stamps);
1208
+ holderStampLists.push(holderStamps);
1209
+ try {
1210
+ const answer = ownKeysUncached(root);
1211
+ ownKeys.set(root, answer);
1212
+ ownKeysAnswers.set(root, { keys: answer, stamps, holderStamps });
1213
+ return answer;
1214
+ }
1215
+ finally {
1216
+ stampLists.pop();
1217
+ holderStampLists.pop();
1218
+ activeOwnKeys.delete(root);
1219
+ }
1220
+ };
1221
+ const ownKeysUncached = (root) => {
1222
+ const spelled = literalSpelledKeys(root);
1223
+ if (spelled === null || !isObjectRoot(root))
1224
+ return spelled;
1225
+ if (hasUnnamedWrite(root))
1226
+ return null;
1227
+ const keys = new Set(spelled);
1228
+ for (const stored of watched(closure(root))) {
1229
+ if (ts.isCallExpression(stored) && definitionPlans.has(stored)) {
1230
+ if (watched(value(stored.arguments[0])).has(root))
1231
+ for (const key of definitionPlans.get(stored).keys)
1232
+ keys.add(key);
1233
+ continue;
1234
+ }
1235
+ if (ts.isCallExpression(stored)) {
1236
+ // A bulk assign onto this root gives it every key its sources have.
1237
+ const bulk = bulkAssignOf(stored);
1238
+ if (bulk === null || !watched(value(bulk.target)).has(root))
1239
+ continue;
1240
+ for (const source of bulk.sources)
1241
+ for (const held of watched(value(source))) {
1242
+ if (held === undefinedValue || held.kind === ts.SyntaxKind.NullKeyword || ts.isVoidExpression(held))
1243
+ continue;
1244
+ const sourceKeys = ownKeysOf(held);
1245
+ if (sourceKeys === null)
1246
+ return null;
1247
+ for (const written of sourceKeys)
1248
+ keys.add(written);
1249
+ }
1250
+ continue;
1251
+ }
1252
+ if (!ts.isPropertyAccessExpression(stored) && !ts.isElementAccessExpression(stored))
1253
+ continue;
1254
+ const written = accessKey(stored);
1255
+ if (written !== null)
1256
+ keys.add(written);
1257
+ }
1258
+ return [...keys];
1259
+ };
1260
+ const descriptorOf = (root, key) => descriptor(root, key) ||
1261
+ (ts.isObjectLiteralExpression(root) && writesTo(root, namedWriteReceivers.get(key) ?? [])) ||
1262
+ writesTo(root, definitionReceivers.get(key) ?? []);
1263
+ /**
1264
+ * Every element key of the arrays an access could be reaching.
1265
+ *
1266
+ * `this.textures[ i ]` -- three's RenderTarget, and every loop over a
1267
+ * field array. The index is a counter no value bounds, so asking what
1268
+ * `i` HOLDS correctly answers nothing; but the access still names some
1269
+ * element, and an array literal spells all of them. Their union is a
1270
+ * true superset where a single key is not available. `length` is not an
1271
+ * element and is not in it, and nothing is inferred from list order --
1272
+ * the keys are the positions the literal actually has.
1273
+ *
1274
+ * The container is read WITHOUT requiring it: the caller requires it
1275
+ * anyway, and a bounded index must stay exact rather than widening to
1276
+ * the whole array, so this answers only where no key is available.
1277
+ */
1278
+ const numericIndex = (index) => {
1279
+ const numeric = (type) => type.isUnion() ? type.types.every(numeric) : (type.flags & ts.TypeFlags.NumberLike) !== 0 && !type.isNumberLiteral();
1280
+ return numeric(checker.getTypeAtLocation(index));
1281
+ };
1282
+ const arrayElementKeys = (access) => {
1283
+ const roots = observe(value(access.expression));
1284
+ if (roots.size === 0)
1285
+ return null;
1286
+ for (const root of roots)
1287
+ if (!ts.isArrayLiteralExpression(root) || root.elements.some(ts.isSpreadElement))
1288
+ return null;
1289
+ const bounded = observe(value(access.argumentExpression));
1290
+ if (bounded.size > 0 && [...bounded].every((candidate) => ts.isStringLiteralLike(candidate) || ts.isNumericLiteral(candidate)))
1291
+ return null;
1292
+ // `bounded` empty is ambiguous: on the FIRST transfer of any node it
1293
+ // means the index's own state was only just created and has not been
1294
+ // transferred yet, not that no bound exists -- `enumeratedKeysOf` and
1295
+ // `keysOf`'s own `unresolved-property-key` meet the identical shape
1296
+ // and both defer the empty-vs-opaque call to `sealing` for that
1297
+ // reason. Widening here before the fixpoint published a PERMANENT
1298
+ // fact per element (`case 'value'` -> `carry(slot(root, key))`) that
1299
+ // the index's later, exact resolution to a single literal could never
1300
+ // retract: `arr[k]` read every element forever because pass one saw
1301
+ // `k` before its own value had transferred. Defer instead of guessing
1302
+ // -- returning null falls through to `keysOf`'s own index read, which
1303
+ // already requires the argument and applies the same `sealing` gate.
1304
+ if (!sealing && bounded.size === 0)
1305
+ return null;
1306
+ return [ELEMENT_KEY];
1307
+ };
1308
+ const keysOf = (access) => {
1309
+ const direct = accessKey(access);
1310
+ if (direct !== null)
1311
+ return [direct];
1312
+ if (!ts.isElementAccessExpression(access))
1313
+ return [];
1314
+ const enumerated = enumerationHeadOf(access.argumentExpression);
1315
+ if (enumerated !== null)
1316
+ return enumeratedKeysOf(access, enumerated, read, fail, sealing, ownKeysOf);
1317
+ // A counter names a POSITION, never a key: `this.textures[ i ]` with
1318
+ // `let i` in three's RenderTarget. The checker calls it `number`, and
1319
+ // asking what the counter holds only ever refused (`i++` is no value
1320
+ // this graph states) and made the access opaque; the element slot is
1321
+ // the answer, and it is a superset whatever the counter holds.
1322
+ if (numericIndex(access.argumentExpression))
1323
+ return [ELEMENT_KEY];
1324
+ const elements = noArrayKeys ? null : arrayElementKeys(access);
1325
+ if (elements !== null)
1326
+ return elements;
1327
+ const keys = new Set();
1328
+ const candidates = read(value(access.argumentExpression));
1329
+ for (const candidate of candidates) {
1330
+ if (ts.isStringLiteralLike(candidate) || ts.isNumericLiteral(candidate))
1331
+ keys.add(candidate.text);
1332
+ else
1333
+ fail('coercing-or-unbounded-property-key', access);
1334
+ }
1335
+ if (sealing && candidates.size === 0)
1336
+ fail('unresolved-property-key', access);
1337
+ return [...keys];
1338
+ };
1339
+ /**
1340
+ * Mentions of an exported cell in the modules that import it, or null
1341
+ * when the set of modules that can read it is not enumerable.
1342
+ *
1343
+ * `export const taurus = new TaurusStore()` -- taurus-display's entire
1344
+ * store, and the receiver of every `this.<method>()` in it. An export
1345
+ * was refused outright unless NOTHING imported it, which reads "someone
1346
+ * imports this" as "this escaped". It is not an escape while every
1347
+ * module that can read the name is enumerated: the importers' mentions
1348
+ * are then simply more uses of the same cell. They are also mentions
1349
+ * `referencesToDeclaration` does not carry -- an importing file's
1350
+ * identifier resolves to the import specifier, not to the declaration --
1351
+ * so a caller that widens the predicate must walk these too, or it has
1352
+ * called a cell closed on the strength of uses it never looked at.
1353
+ */
1354
+ const importerMentions = (declaration) => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) === 0
1355
+ ? []
1356
+ : inProgramImportReferencesOf(checker, flow, declaration);
1357
+ /** The refusal a cell earns, or null when it is closed -- named, because
1358
+ * "exposed" covered three different facts and each has its own fix. */
1359
+ const bindingClosed = (declaration) => {
1360
+ if (!localBindingWritesAreComplete(flow, declaration))
1361
+ return 'binding-writes-incomplete';
1362
+ if ((ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) === 0)
1363
+ return null;
1364
+ if (exportIsUnimported(checker, flow, declaration))
1365
+ return null;
1366
+ return importerMentions(declaration) !== null ? null : 'export-importers-unenumerable';
1367
+ };
1368
+ const refs = (root, declaration) => {
1369
+ for (const reference of flow.referencesToDeclaration(declaration)) {
1370
+ if (reference === ts.getNameOfDeclaration(declaration) || isTypePositionReference(reference))
1371
+ continue;
1372
+ add(read(use(root, reference)));
1373
+ }
1374
+ for (const reference of importerMentions(declaration) ?? [])
1375
+ add(read(use(root, reference)));
1376
+ };
1377
+ /**
1378
+ * A binding pattern taken apart over this value: every element reads one
1379
+ * slot and nothing reads the object itself.
1380
+ *
1381
+ * Destructuring is a property READ, and `visitUse` already states that a
1382
+ * property read of a tracked object is not a publication of it. Refusing
1383
+ * the pattern spelling made the two disagree -- `p.app.go()` proved its
1384
+ * receiver and `const { app } = p; app.go()` did not, though the object
1385
+ * never left the program either way. A rest element stays refused: it
1386
+ * builds a FRESH object out of whatever keys nothing else took, and that
1387
+ * object is not modelled here.
1388
+ */
1389
+ const patternReadsSlots = (root, pattern) => {
1390
+ if (!isObjectRoot(root)) {
1391
+ fail('non-object-destructured-container', pattern);
1392
+ return;
1393
+ }
1394
+ for (const element of pattern.elements) {
1395
+ if (ts.isOmittedExpression(element))
1396
+ continue;
1397
+ const key = bindingElementKey(element);
1398
+ if (element.dotDotDotToken)
1399
+ fail('rest-binding-element', element);
1400
+ else if (key === null)
1401
+ fail('computed-binding-element', element);
1402
+ else if (!descriptorOf(root, key))
1403
+ fail('unmodelled-descriptor', element);
1404
+ }
1405
+ };
1406
+ /**
1407
+ * The complete set of source setters a plain store to `key` executes.
1408
+ *
1409
+ * `class Base { constructor() { this.type = 'Base' } }` with a subclass
1410
+ * declaring `get type` / `set type`: the base constructor's plain store
1411
+ * runs the SUBCLASS's setter. The plan already names every setter such
1412
+ * a store can reach, or says the effects are opaque -- this only has to
1413
+ * put the receiver into each of those bodies, which is what a member
1414
+ * call does with its own frame.
1415
+ */
1416
+ const storeRunsSetters = (root, key) => {
1417
+ if (!ts.isNewExpression(root))
1418
+ return false;
1419
+ const bodies = settersOf(root, key);
1420
+ if (bodies === null)
1421
+ return false;
1422
+ for (const setter of bodies)
1423
+ for (const reference of flow.receiverReferencesToDeclaration(setter))
1424
+ add(read(use(root, reference)));
1425
+ return true;
1426
+ };
1427
+ /**
1428
+ * Every value a setter's parameter receives: the right-hand side of each
1429
+ * store that runs the setter -- a store to its key on a construction of
1430
+ * its class's family. A setter has no call sites, so `callersOf` names
1431
+ * nothing for it and the parameter was an unindexed frame: three's
1432
+ * `RenderTarget` `set depthTexture( current )`. The family is by
1433
+ * heritage; a descendant's own override is over-counted, which only
1434
+ * widens the answer. A bulk `Object.assign` onto one of ours names no
1435
+ * key to compare and refuses.
1436
+ */
1437
+ /**
1438
+ * Every instance a class member can run on: the constructions of its
1439
+ * heritage family, refused when the family is open or when a `new`
1440
+ * naming a family class could not be placed.
1441
+ */
1442
+ const familyInstancesOf = (holder, reason) => {
1443
+ const family = sourceClassFamilyOf(checker, flow, new Set([holder]));
1444
+ if (family === null) {
1445
+ fail(reason, holder);
1446
+ return null;
1447
+ }
1448
+ const instances = new Set();
1449
+ for (const owner of family.keys())
1450
+ for (const instance of constructionsOf(owner))
1451
+ instances.add(instance);
1452
+ for (const call of opaqueConstructionsOf()) {
1453
+ const declarations = checker.getTypeAtLocation(call).getSymbol()?.declarations ?? [];
1454
+ if (declarations.some((declaration) => family.has(declaration)))
1455
+ fail('opaque-construction', call);
1456
+ }
1457
+ return [...instances];
1458
+ };
1459
+ /**
1460
+ * A value a getter returns is used wherever the getter is READ: every
1461
+ * access spelling its key on one of its class family's constructions,
1462
+ * from the instances outward like `setterStores`. A getter has no call
1463
+ * sites, so `callersOf` names nothing for it; three's `RenderTarget`
1464
+ * `get texture()` returns `this.textures[ 0 ]`, and the element is used
1465
+ * at every `target.texture` in the program. A descendant's override is
1466
+ * over-counted, which only widens.
1467
+ */
1468
+ const getterReturns = (root, getter) => {
1469
+ const holder = getter.parent;
1470
+ if ((!ts.isClassDeclaration(holder) && !ts.isClassExpression(holder)) ||
1471
+ (ts.getCombinedModifierFlags(getter) & ts.ModifierFlags.Static) !== 0) {
1472
+ fail('unmodelled-getter-owner', getter);
1473
+ return;
1474
+ }
1475
+ const key = declarationKey(getter.name);
1476
+ if (key === null) {
1477
+ fail('computed-getter-key', getter);
1478
+ return;
1479
+ }
1480
+ const instances = familyInstancesOf(holder, 'getter-family-open');
1481
+ if (instances === null)
1482
+ return;
1483
+ for (const instance of instances)
1484
+ for (const fact of read(closure(instance))) {
1485
+ if (!ts.isPropertyAccessExpression(fact) && !ts.isElementAccessExpression(fact))
1486
+ continue;
1487
+ if (writeEdgeByAccess.has(fact) || !keysOf(fact).includes(key))
1488
+ continue;
1489
+ add(read(use(root, fact)));
1490
+ }
1491
+ };
1492
+ const setterStores = (setter) => {
1493
+ const holder = setter.parent;
1494
+ if ((!ts.isClassDeclaration(holder) && !ts.isClassExpression(holder)) ||
1495
+ (ts.getCombinedModifierFlags(setter) & ts.ModifierFlags.Static) !== 0) {
1496
+ fail('unmodelled-setter-owner', setter);
1497
+ return;
1498
+ }
1499
+ const key = declarationKey(setter.name);
1500
+ if (key === null) {
1501
+ fail('computed-setter-key', setter);
1502
+ return;
1503
+ }
1504
+ const instances = familyInstancesOf(holder, 'setter-family-open');
1505
+ if (instances === null)
1506
+ return;
1507
+ // From the instances outward, never from every write inward. The
1508
+ // stores that can run this setter go through one of the family's
1509
+ // constructions, and a construction's closure already lists every
1510
+ // store through it (`case 'slot'` reads the same facts). Placing the
1511
+ // receiver of every write naming the key instead read cells that
1512
+ // had nothing to do with this family -- EventDispatcher's
1513
+ // `listeners[ type ] = []` resolves `this._listeners` on every
1514
+ // dispatcher in the program, Material's included, and Material's
1515
+ // computed stores hang on the very `setValues` parameter this
1516
+ // question is part of establishing. Their opacity became this
1517
+ // parameter's.
1518
+ for (const root of instances)
1519
+ for (const stored of read(closure(root))) {
1520
+ if (ts.isCallExpression(stored)) {
1521
+ if (bulkAssignOf(stored) !== null && read(value(stored.arguments[0])).has(root))
1522
+ fail('bulk-assign-runs-setter', stored);
1523
+ continue;
1524
+ }
1525
+ if (!ts.isPropertyAccessExpression(stored) && !ts.isElementAccessExpression(stored))
1526
+ continue;
1527
+ const edge = writeEdgeByAccess.get(stored);
1528
+ if (edge === undefined || !keysOf(stored).includes(key))
1529
+ continue;
1530
+ const write = edge.write;
1531
+ if (write.value === null || !['property-assignment', 'index-assignment', 'logical-assignment'].includes(write.edge))
1532
+ fail('unmodelled-setter-store', write.site);
1533
+ else
1534
+ add(carry(value(write.value)));
1535
+ }
1536
+ };
1537
+ /**
1538
+ * Every read of an argument through the `arguments` object.
1539
+ *
1540
+ * three's `Object3D.add( object )` walks its own `arguments` to add
1541
+ * several children at once, so a value handed to it arrives at a
1542
+ * PARAMETER and, on some index, at `arguments[ i ]` as well. Refusing
1543
+ * the whole frame for that gave up on the entire Object3D family --
1544
+ * every `onBeforeRender` callback's `renderer` hung on this one
1545
+ * refusal.
1546
+ *
1547
+ * The index is not resolved and does not need to be: one that names any
1548
+ * position means every argument reaches every read, which is the
1549
+ * superset. `arguments.length` is a number and carries nothing. Any
1550
+ * other mention -- a spread, the object handed on whole -- is a use this
1551
+ * graph cannot follow, and stays a refusal.
1552
+ */
1553
+ const argumentsReads = (body) => {
1554
+ const reads = [];
1555
+ for (const mention of argumentsUsesAt(body) ?? []) {
1556
+ const parent = mention.parent;
1557
+ if (ts.isPropertyAccessExpression(parent) && parent.expression === mention && parent.name.text === 'length')
1558
+ continue;
1559
+ if (ts.isElementAccessExpression(parent) && parent.expression === mention)
1560
+ reads.push(parent);
1561
+ else
1562
+ return null;
1563
+ }
1564
+ return reads;
1565
+ };
1566
+ const forward = (root, site, receiver, position) => {
1567
+ if (ts.isNewExpression(site.call) || site.operands.dispatch.kind === 'super-constructor') {
1568
+ for (const body of read(nodeQuery('construct-targets', site.call))) {
1569
+ if (!ts.isConstructorDeclaration(body) && !isBody(body)) {
1570
+ fail('non-constructor-target', body);
1571
+ continue;
1572
+ }
1573
+ const spread = argumentsReads(body);
1574
+ if (spread === null) {
1575
+ fail('arguments-object-frame', body);
1576
+ continue;
1577
+ }
1578
+ for (const mention of spread)
1579
+ add(read(use(root, mention)));
1580
+ const parameter = runtimeParametersOf(body)[position];
1581
+ if (parameter?.dotDotDotToken)
1582
+ fail('rest-frame', parameter);
1583
+ else if (parameter && ts.isIdentifier(parameter.name))
1584
+ refs(root, parameter);
1585
+ else if (parameter)
1586
+ patternReadsSlots(root, parameter.name);
1587
+ }
1588
+ return;
1589
+ }
1590
+ const selected = read(targets(site.call));
1591
+ if (sealing && selected.size === 0)
1592
+ fail('no-source-call-target', site.call);
1593
+ for (const body of selected) {
1594
+ if (!isCallableValue(body)) {
1595
+ fail('non-callable-target', body);
1596
+ continue;
1597
+ }
1598
+ if (receiver) {
1599
+ // `arguments` never holds the receiver, so an arguments-using body
1600
+ // says nothing about where `this` goes.
1601
+ if (!ts.isArrowFunction(body))
1602
+ for (const reference of flow.receiverReferencesToDeclaration(body))
1603
+ add(read(use(root, reference)));
1604
+ }
1605
+ else {
1606
+ const mentions = argumentsReads(body);
1607
+ if (mentions === null) {
1608
+ fail('arguments-object-frame', body);
1609
+ continue;
1610
+ }
1611
+ for (const mention of mentions)
1612
+ add(read(use(root, mention)));
1613
+ const parameter = runtimeParametersOf(body)[position];
1614
+ if (parameter?.dotDotDotToken)
1615
+ fail('rest-frame', parameter);
1616
+ else if (parameter && ts.isIdentifier(parameter.name))
1617
+ refs(root, parameter);
1618
+ else if (parameter)
1619
+ patternReadsSlots(root, parameter.name);
1620
+ }
1621
+ }
1622
+ };
1623
+ const visitUse = (root, reference) => {
1624
+ if (isTypePositionReference(reference))
1625
+ return;
1626
+ const parent = reference.parent;
1627
+ if (!parent) {
1628
+ fail('unindexed-use', reference);
1629
+ return;
1630
+ }
1631
+ const erased = unwrapErasedExpression(parent);
1632
+ if (ts.isExpression(parent) && erased === reference && parent !== reference) {
1633
+ add(read(use(root, parent)));
1634
+ return;
1635
+ }
1636
+ if (ts.isVariableDeclaration(parent) || ts.isParameter(parent)) {
1637
+ if (parent.name === reference)
1638
+ return;
1639
+ if (parent.initializer !== reference) {
1640
+ fail('binding-pattern', parent);
1641
+ return;
1642
+ }
1643
+ if (!ts.isIdentifier(parent.name)) {
1644
+ patternReadsSlots(root, parent.name);
1645
+ return;
1646
+ }
1647
+ const exposure = ts.isVariableDeclaration(parent) ? bindingClosed(parent) : null;
1648
+ if (exposure !== null) {
1649
+ fail(`exposed-binding:${exposure}`, parent);
1650
+ return;
1651
+ }
1652
+ refs(root, parent);
1653
+ return;
1654
+ }
1655
+ if (ts.isBinaryExpression(parent)) {
1656
+ if (parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
1657
+ if (parent.left === reference)
1658
+ return;
1659
+ const left = unwrapNaming(parent.left);
1660
+ if (ts.isIdentifier(left)) {
1661
+ const declaration = flow.targetOf(left)?.declaration;
1662
+ if (!declaration || (!ts.isVariableDeclaration(declaration) && !ts.isParameter(declaration))) {
1663
+ fail('external-binding-store', left);
1664
+ return;
1665
+ }
1666
+ // `bindingClosed` names the REFUSAL, null when the cell is closed
1667
+ // (its other reader above spells the same test). Read as a boolean
1668
+ // it refused every store into a closed local and admitted every
1669
+ // store into an exposed one -- `entry = makeRecord()` inside a
1670
+ // closed factory was the 'exposed-binding' that kept the cache
1671
+ // `.get()` receiver from ever being proven.
1672
+ const exposure = ts.isVariableDeclaration(declaration) ? bindingClosed(declaration) : null;
1673
+ if (exposure !== null) {
1674
+ fail(`exposed-binding:${exposure}`, declaration);
1675
+ return;
1676
+ }
1677
+ refs(root, declaration);
1678
+ }
1679
+ else if (ts.isPropertyAccessExpression(left) || ts.isElementAccessExpression(left)) {
1680
+ const keys = keysOf(left);
1681
+ const containers = read(value(left.expression));
1682
+ if (sealing && containers.size === 0)
1683
+ fail('unresolved-container', left);
1684
+ for (const container of containers) {
1685
+ // A store on `null`/`undefined` throws before it lands: an
1686
+ // element slot read through a counter carries `undefined` for
1687
+ // the positions never written (`this.textures[ i ]` in three's
1688
+ // RenderTarget), and that is no container.
1689
+ if (container === undefinedValue || container.kind === ts.SyntaxKind.NullKeyword || ts.isVoidExpression(container))
1690
+ continue;
1691
+ if (!isObjectRoot(container)) {
1692
+ fail('opaque-container-store', left);
1693
+ continue;
1694
+ }
1695
+ for (const key of keys) {
1696
+ if (descriptorOf(container, key)) {
1697
+ add(read(publication(root, container, key)));
1698
+ continue;
1699
+ }
1700
+ // A store to an accessor key hands the value to the
1701
+ // SETTER's parameter, never to a slot of the container.
1702
+ if (ts.isNewExpression(container) && dataStoreOf(container, key)) {
1703
+ add(read(publication(root, container, key)));
1704
+ continue;
1705
+ }
1706
+ const setters = ts.isNewExpression(container) ? settersOf(container, key) : null;
1707
+ if (setters === null)
1708
+ fail('opaque-container-store', left);
1709
+ else
1710
+ for (const setter of setters) {
1711
+ const parameter = setter.parameters[0];
1712
+ if (!parameter || !ts.isIdentifier(parameter.name))
1713
+ fail('unmodelled-setter-parameter', setter);
1714
+ else
1715
+ refs(root, parameter);
1716
+ }
1717
+ }
1718
+ }
1719
+ }
1720
+ else
1721
+ fail('unmodelled-store', left);
1722
+ add(read(use(root, parent)));
1723
+ return;
1724
+ }
1725
+ if (parent.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
1726
+ parent.operatorToken.kind === ts.SyntaxKind.BarBarToken ||
1727
+ parent.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken ||
1728
+ parent.operatorToken.kind === ts.SyntaxKind.CommaToken) {
1729
+ add(read(use(root, parent)));
1730
+ return;
1731
+ }
1732
+ if (parent.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken ||
1733
+ parent.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken)
1734
+ return;
1735
+ fail('coercing-value-use', parent);
1736
+ return;
1737
+ }
1738
+ if (ts.isConditionalExpression(parent)) {
1739
+ if (parent.condition !== reference)
1740
+ add(read(use(root, parent)));
1741
+ return;
1742
+ }
1743
+ if (ts.isPropertyAssignment(parent) && parent.initializer === reference) {
1744
+ const key = declarationKey(parent.name);
1745
+ if (key === null || key === '__proto__')
1746
+ fail('computed-publication', parent);
1747
+ else
1748
+ add(read(publication(root, parent.parent, key)));
1749
+ return;
1750
+ }
1751
+ if (ts.isShorthandPropertyAssignment(parent)) {
1752
+ add(read(publication(root, parent.parent, parent.name.text)));
1753
+ return;
1754
+ }
1755
+ if (ts.isPropertyDeclaration(parent) && parent.initializer === reference) {
1756
+ const key = declarationKey(parent.name);
1757
+ if (key === null || (ts.getCombinedModifierFlags(parent) & ts.ModifierFlags.Static) !== 0) {
1758
+ fail('static-or-computed-publication', parent);
1759
+ return;
1760
+ }
1761
+ for (const construction of constructionsOf(parent))
1762
+ add(read(publication(root, construction, key)));
1763
+ return;
1764
+ }
1765
+ if (ts.isArrayLiteralExpression(parent)) {
1766
+ if (parent.elements.some(ts.isSpreadElement))
1767
+ fail('spread-publication', parent);
1768
+ else
1769
+ add(read(publication(root, parent, String(parent.elements.indexOf(reference)))));
1770
+ return;
1771
+ }
1772
+ if (ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent)) {
1773
+ if (parent.expression !== reference) {
1774
+ // The reference is the access's NAME, not its object: `a.go`
1775
+ // MENTIONS the method `go`, and `flow.referencesToDeclaration`
1776
+ // hands that mention back when the tracked value is the method's
1777
+ // own declaration. What is used is the access's result. Without
1778
+ // this branch every class method's closure proof read its own call
1779
+ // sites as a key coercion, so `this.run()` had no callable slot at
1780
+ // all -- the one place a member name is not a key being coerced.
1781
+ if (ts.isPropertyAccessExpression(parent) && parent.name === reference) {
1782
+ add(read(use(root, parent)));
1783
+ return;
1784
+ }
1785
+ fail('coercing-property-key', reference);
1786
+ return;
1787
+ }
1788
+ const keys = keysOf(parent);
1789
+ // `new ( /** @type {new (...args: any[]) => this} */ ( this.constructor ) )()`
1790
+ // -- three's own spelling of the clone idiom wherever it JSDoc-casts
1791
+ // the read (Texture.js, BufferGeometry.js, Object3D.js, Camera.js) --
1792
+ // sits a ParenthesizedExpression between the access and the `new` that
1793
+ // actually invokes it, purely to anchor the cast comment. Plain
1794
+ // `parent.parent` lands on that paren, not the `new`, so the
1795
+ // `constructor-slot-read` exception below never matched and every
1796
+ // family member's `copy` override the census could not otherwise index
1797
+ // came back an unmodelled frame. `outermostErasureOf` is the same
1798
+ // erasure-aware "which node occupies the syntactic position" walk this
1799
+ // graph already uses for `use`/`visitUse`; for the unparenthesized
1800
+ // spelling it is a no-op (`parent.parent` unchanged).
1801
+ const positioned = outermostErasureOf(parent);
1802
+ const invocation = positioned.parent;
1803
+ const callee = ts.isCallExpression(invocation) && invocation.expression === positioned;
1804
+ const stored = ts.isBinaryExpression(invocation) &&
1805
+ invocation.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
1806
+ invocation.left === positioned;
1807
+ // `delete holder.field`, `holder.n += 1`, `holder.n++`, `holder.f ??=
1808
+ // g`: the slot is rewritten without a plain `=`. Reading these as
1809
+ // mere mentions of the slot left every one of them invisible to the
1810
+ // slot's own value set -- a deleted field still "held" its
1811
+ // initializer. They are stores; the slot decides what each edge
1812
+ // means, and refuses the ones it cannot model.
1813
+ const mutated = (ts.isDeleteExpression(invocation) && invocation.expression === positioned) ||
1814
+ (ts.isBinaryExpression(invocation) &&
1815
+ invocation.left === positioned &&
1816
+ invocation.operatorToken.kind !== ts.SyntaxKind.EqualsToken &&
1817
+ invocation.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
1818
+ invocation.operatorToken.kind <= ts.SyntaxKind.LastAssignment) ||
1819
+ ((ts.isPrefixUnaryExpression(invocation) || ts.isPostfixUnaryExpression(invocation)) &&
1820
+ (invocation.operator === ts.SyntaxKind.PlusPlusToken || invocation.operator === ts.SyntaxKind.MinusMinusToken));
1821
+ if (mutated && !writeEdgeByAccess.has(parent)) {
1822
+ fail('unmodelled-property-write', parent);
1823
+ return;
1824
+ }
1825
+ // A store through this root is a key the root gains, and THIS walk is
1826
+ // where the program says so. Asking the write index instead -- "of
1827
+ // every write in the program, which ones reach this root" -- is the
1828
+ // same fact derived a second way, at O(all writes) per re-evaluation
1829
+ // instead of O(uses of the root); on the three.js app that was the compile.
1830
+ // `enumeratedKeysOf` already requires this closure, so the key set
1831
+ // costs it no dependency it was not already holding.
1832
+ if (stored || mutated)
1833
+ facts.add(parent);
1834
+ /**
1835
+ * Whether this graph can say what reaching `key` through this root
1836
+ * does. A declared cell it can. A key proven absent from the chain
1837
+ * it can -- except in a CALLEE position, where absence names no
1838
+ * callable. And a plain store to a key the family declares as an
1839
+ * accessor it can, because the store runs that accessor's SETTER:
1840
+ * a frame, not an unmodelled descriptor. The getter is never
1841
+ * evaluated -- a store does not read -- so a getter that hands its
1842
+ * receiver out says nothing about this store.
1843
+ */
1844
+ const modelled = (held, key) => {
1845
+ if (descriptorOf(held, key))
1846
+ return true;
1847
+ if (callee)
1848
+ return false;
1849
+ if (stored && storeRunsSetters(held, key))
1850
+ return true;
1851
+ if (ts.isNewExpression(held)) {
1852
+ if (!stored && !mutated && familyReadOf(held, key) !== null)
1853
+ return true;
1854
+ if (stored && dataStoreOf(held, key))
1855
+ return true;
1856
+ }
1857
+ return absentOwnKey(held, key, parent, descriptorOf, hasUnnamedWrite);
1858
+ };
1859
+ // `instance.constructor` READS the class object off the prototype
1860
+ // -- a value this graph does not carry, and one whose escape opens
1861
+ // the family: `unknown( value.constructor )` can construct and
1862
+ // retarget Base from anywhere. Only `new this.constructor()` is a
1863
+ // modelled use of it (`case 'value'` places the construction).
1864
+ if (ts.isNewExpression(root) &&
1865
+ keys.includes('constructor') &&
1866
+ !stored &&
1867
+ !mutated &&
1868
+ !(ts.isNewExpression(invocation) && invocation.expression === positioned)) {
1869
+ fail('constructor-slot-read', parent);
1870
+ return;
1871
+ }
1872
+ if (!isObjectRoot(root) || keys.some((key) => !modelled(root, key))) {
1873
+ fail('unmodelled-descriptor', parent);
1874
+ return;
1875
+ }
1876
+ if (callee) {
1877
+ const site = sites.get(invocation);
1878
+ if (!site)
1879
+ fail('unindexed-call', invocation);
1880
+ else
1881
+ forward(root, site, true, -1);
1882
+ }
1883
+ return;
1884
+ }
1885
+ if (ts.isCallExpression(parent) || ts.isNewExpression(parent)) {
1886
+ if (parent.expression === reference) {
1887
+ if (reference.kind === ts.SyntaxKind.SuperKeyword && ts.isCallExpression(parent) && ts.isNewExpression(root)) {
1888
+ read(nodeQuery('construct-targets', parent));
1889
+ return;
1890
+ }
1891
+ if (!isBody(root))
1892
+ fail('non-callable-use', reference);
1893
+ return;
1894
+ }
1895
+ if (ts.isCallExpression(parent) && definitionPlans.has(parent)) {
1896
+ const plan = definitionOf(parent);
1897
+ if (plan === null)
1898
+ fail('intrinsic-definition-unproven', parent);
1899
+ else if (parent.arguments[0] === reference) {
1900
+ // The target gains the key (`case 'slot'` reads the value
1901
+ // through this fact) and is handed to nobody but, when the
1902
+ // intrinsic returns it, whoever reads the call.
1903
+ facts.add(parent);
1904
+ if (plan.returnsTarget && !ts.isExpressionStatement(parent.parent))
1905
+ add(read(use(root, parent)));
1906
+ }
1907
+ else if (parent.arguments[2] === reference) {
1908
+ // The descriptor literal: its `value` is copied into the target
1909
+ // (`case 'publication'` forwards it); the literal goes nowhere.
1910
+ facts.add(parent);
1911
+ }
1912
+ else if (parent.arguments[1] === reference)
1913
+ fail('coercing-property-key', reference);
1914
+ else
1915
+ fail('unmodelled-invocation-frame', parent);
1916
+ return;
1917
+ }
1918
+ if (ts.isCallExpression(parent)) {
1919
+ const bulk = bulkAssignOf(parent);
1920
+ if (bulk !== null && parent.arguments.includes(reference)) {
1921
+ // The call evaluates to its target, so a target root is used
1922
+ // wherever the call's result is; a source's own slot values are
1923
+ // copied into it (`case 'slot'` reads them through this fact),
1924
+ // and a source literal itself goes nowhere. A source that is
1925
+ // not a literal could run getters, which this does not enter.
1926
+ facts.add(parent);
1927
+ if (bulk.target === reference)
1928
+ add(read(use(root, parent)));
1929
+ else if (!ts.isObjectLiteralExpression(root))
1930
+ fail('bulk-assign-source-unmodelled', reference);
1931
+ return;
1932
+ }
1933
+ }
1934
+ const site = sites.get(parent);
1935
+ // `f.call( receiver, ... )` writes the receiver in an ARGUMENT
1936
+ // position of the syntax and reads it in the RECEIVER position of
1937
+ // the frame. The operands already say which is which -- reading the
1938
+ // syntax instead made every value handed to `.call` an argument no
1939
+ // parameter had a slot for.
1940
+ if (site?.explicitThis && site.operands.receiver === reference) {
1941
+ forward(root, site, true, -1);
1942
+ return;
1943
+ }
1944
+ // A value stored into a closed native Map (`store.set( key, value )`)
1945
+ // is not handed to unknown code: the map's only way out is its
1946
+ // `.get()` reads, and the value continues at each of them exactly
1947
+ // as it would at a parameter. `case 'completion'` above reads the
1948
+ // same stores back from the `.get()` side.
1949
+ if (ts.isCallExpression(parent)) {
1950
+ const continuations = collectionValueContinuationsOf(checker, flow, parent, reference, nativeProtocolClosed);
1951
+ if (continuations !== null) {
1952
+ for (const continued of continuations)
1953
+ add(read(use(root, continued)));
1954
+ return;
1955
+ }
1956
+ }
1957
+ const position = site?.operands?.args.indexOf(reference) ?? -1;
1958
+ if (!site || position < 0 || site.operands?.args.some(ts.isSpreadElement))
1959
+ fail('unmodelled-invocation-frame', parent);
1960
+ else
1961
+ forward(root, site, false, position);
1962
+ return;
1963
+ }
1964
+ if (ts.isReturnStatement(parent)) {
1965
+ const body = ts.findAncestor(parent, ts.isFunctionLike);
1966
+ if (body && ts.isGetAccessorDeclaration(body)) {
1967
+ getterReturns(root, body);
1968
+ return;
1969
+ }
1970
+ if (!body || !isBody(body) || callableCompletionSummaryOf(flow, body)?.execution !== 'sync') {
1971
+ fail('deferred-completion', parent);
1972
+ return;
1973
+ }
1974
+ read(closure(body));
1975
+ for (const call of read(callersOf(body)))
1976
+ if (ts.isCallExpression(call))
1977
+ add(read(use(root, call)));
1978
+ return;
1979
+ }
1980
+ // Enumerating an object reads its KEY SET and nothing else: no slot is
1981
+ // read, nothing escapes, and the object is not even coerced. What the
1982
+ // bound key then does is a question asked where the head is USED, not
1983
+ // here -- and without this branch the enumerated object was opaque, so
1984
+ // the key set could never be proven closed.
1985
+ if (ts.isForInStatement(parent) && parent.expression === reference)
1986
+ return;
1987
+ if (ts.isExpressionStatement(parent) ||
1988
+ ts.isTypeOfExpression(parent) ||
1989
+ ts.isVoidExpression(parent) ||
1990
+ (ts.isPrefixUnaryExpression(parent) && parent.operator === ts.SyntaxKind.ExclamationToken) ||
1991
+ (ts.isIfStatement(parent) && parent.expression === reference))
1992
+ return;
1993
+ fail('opaque-value-use', reference);
1994
+ };
1995
+ seeded = false;
1996
+ switch (query.kind) {
1997
+ case 'value': {
1998
+ const expression = query.node;
1999
+ if (isObjectRoot(expression)) {
2000
+ if (ts.isNewExpression(expression) && construction(expression) === null) {
2001
+ // `new WebGLState()` on a plain function that returns an object
2002
+ // from every completion and never mentions `this` yields THAT
2003
+ // completion, never the fresh allocation (`new` discards it):
2004
+ // the value is the call's completion, solved through the same
2005
+ // frame a call would be. Anything else under `new` that is not
2006
+ // a source construction stays opaque.
2007
+ if (constructorFunctionCalleeOf(expression) !== null)
2008
+ add(carry(nodeQuery('completion', expression)));
2009
+ else
2010
+ fail('opaque-construction');
2011
+ }
2012
+ else {
2013
+ facts.add(expression);
2014
+ seeded = true;
2015
+ // `new this.constructor()` is a construction of one of the owned
2016
+ // family `thisConstructorFamilyOf` named (its construction fact's
2017
+ // alternatives) only while `this` itself holds nothing but such
2018
+ // constructions. A method invoked with an explicit foreign
2019
+ // receiver would make the fresh object a foreign instance, and
2020
+ // that is decided here, by what `this` holds, not by the
2021
+ // static fact.
2022
+ if (ts.isNewExpression(expression)) {
2023
+ const receiver = thisConstructorReceiverOf(expression);
2024
+ if (receiver !== null) {
2025
+ const alternatives = construction(expression)?.alternatives ?? [];
2026
+ for (const root of read(value(receiver))) {
2027
+ if (!ts.isNewExpression(root) || !construction(root)?.alternatives.every((owner) => alternatives.includes(owner))) {
2028
+ fail('opaque-construction', root);
2029
+ continue;
2030
+ }
2031
+ // The read is of the INSTANCE's `constructor`, which an
2032
+ // own store or definition on that instance replaces:
2033
+ // `value.constructor = function () {}` makes the fresh
2034
+ // object whatever that function builds.
2035
+ for (const stored of read(closure(root))) {
2036
+ if (ts.isCallExpression(stored) && definitionPlans.has(stored)) {
2037
+ const plan = definitionOf(stored);
2038
+ if (plan === null || (plan.keys.includes('constructor') && read(value(stored.arguments[0])).has(root)))
2039
+ fail('constructor-slot-written', stored);
2040
+ continue;
2041
+ }
2042
+ if (!ts.isPropertyAccessExpression(stored) && !ts.isElementAccessExpression(stored))
2043
+ continue;
2044
+ if (writeEdgeByAccess.has(stored) && keysOf(stored).includes('constructor'))
2045
+ fail('constructor-slot-written', stored);
2046
+ }
2047
+ }
2048
+ }
2049
+ }
2050
+ }
2051
+ }
2052
+ else if (isBody(expression)) {
2053
+ facts.add(expression);
2054
+ seeded = true;
2055
+ }
2056
+ else if (ts.isIdentifier(expression)) {
2057
+ const target = flow.targetOf(expression);
2058
+ const declaration = aliasedDeclarationOf(target?.symbol ?? undefined) ?? target?.declaration;
2059
+ if (declaration && isBody(declaration) && flow.callableBodyIsIndexed(declaration)) {
2060
+ facts.add(declaration);
2061
+ seeded = true;
2062
+ if (ts.isFunctionDeclaration(declaration) && ts.isSourceFile(declaration.parent) && !ts.isExternalModule(declaration.parent))
2063
+ fail('global-object-callable', declaration);
2064
+ for (const write of flow.writesToDeclaration(declaration)) {
2065
+ if (write.slot !== 'whole' || write.edge === 'return' || write.edge === 'yield')
2066
+ continue;
2067
+ if (write.value && ['identifier-assignment', 'logical-assignment'].includes(write.edge))
2068
+ add(carry(value(write.value)));
2069
+ else
2070
+ fail('unmodelled-callable-binding-write', write.site);
2071
+ }
2072
+ }
2073
+ else if (declaration && ts.isVariableDeclaration(declaration)) {
2074
+ const incoming = localBindingValuesOf(flow, declaration);
2075
+ if (incoming === null)
2076
+ fail('unaccounted-binding-write', declaration);
2077
+ else
2078
+ for (const entry of incoming)
2079
+ add(carry(value(entry)));
2080
+ }
2081
+ else if (declaration && ts.isParameter(declaration))
2082
+ add(carry(nodeQuery('parameter', declaration)));
2083
+ else if (declaration && ts.isBindingElement(declaration))
2084
+ add(carry(nodeQuery('binding-element', declaration)));
2085
+ else if (expression.text === 'undefined' && (!declaration || declaration.getSourceFile().hasNoDefaultLib)) {
2086
+ facts.add(undefinedValue);
2087
+ seeded = true;
2088
+ }
2089
+ else
2090
+ fail('opaque-binding');
2091
+ }
2092
+ else if (expression.kind === ts.SyntaxKind.ThisKeyword || expression.kind === ts.SyntaxKind.SuperKeyword) {
2093
+ const owner = flow.receiverOwnerOf(expression);
2094
+ if (!owner)
2095
+ fail('unindexed-receiver');
2096
+ else
2097
+ add(carry(nodeQuery('receiver', owner)));
2098
+ }
2099
+ else if (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression)) {
2100
+ const keys = keysOf(expression);
2101
+ const roots = read(value(expression.expression));
2102
+ for (const root of roots) {
2103
+ // An element read off an array literal is answered by the
2104
+ // literal only while `Array.prototype` is the original: the
2105
+ // obligation goes to the ledger, as the legacy element authority
2106
+ // (`nativeArrayProtocolPlanOf`) registered it, and refuses with
2107
+ // nothing to carry it.
2108
+ if (ts.isArrayLiteralExpression(root) && deferredIntrinsicProtocolLedgerOf(flow)?.require('Array', expression) !== true) {
2109
+ fail('undeferrable-array-protocol', expression);
2110
+ continue;
2111
+ }
2112
+ if (isObjectRoot(root))
2113
+ for (const key of keys)
2114
+ add(carry(slot(root, key)));
2115
+ else if (!isNullish(root))
2116
+ fail('non-object-receiver');
2117
+ }
2118
+ // Every receiver nullish: the read throws, so the cell provably
2119
+ // holds nothing. Empty is the answer, witnessed here, not a
2120
+ // value still waiting on some origin.
2121
+ if (roots.size > 0 && [...roots].every(isNullish))
2122
+ seeded = true;
2123
+ }
2124
+ else if (ts.isCallExpression(expression))
2125
+ add(carry(nodeQuery('completion', expression)));
2126
+ else if (ts.isConditionalExpression(expression)) {
2127
+ add(carry(value(expression.whenTrue)));
2128
+ add(carry(value(expression.whenFalse)));
2129
+ }
2130
+ else if (ts.isBinaryExpression(expression) &&
2131
+ [ts.SyntaxKind.EqualsToken, ts.SyntaxKind.CommaToken].includes(expression.operatorToken.kind))
2132
+ add(carry(value(expression.right)));
2133
+ else if (ts.isBinaryExpression(expression) &&
2134
+ [ts.SyntaxKind.BarBarToken, ts.SyntaxKind.AmpersandAmpersandToken, ts.SyntaxKind.QuestionQuestionToken].includes(expression.operatorToken.kind)) {
2135
+ add(carry(value(expression.left)));
2136
+ add(carry(value(expression.right)));
2137
+ }
2138
+ else if (ts.isLiteralExpression(expression) ||
2139
+ expression.kind === ts.SyntaxKind.NullKeyword ||
2140
+ expression.kind === ts.SyntaxKind.TrueKeyword ||
2141
+ expression.kind === ts.SyntaxKind.FalseKeyword ||
2142
+ ts.isTypeOfExpression(expression) ||
2143
+ ts.isVoidExpression(expression) ||
2144
+ ts.isBinaryExpression(expression)) {
2145
+ facts.add(expression);
2146
+ seeded = true;
2147
+ }
2148
+ else
2149
+ fail('unmodelled-value-origin');
2150
+ break;
2151
+ }
2152
+ case 'slot': {
2153
+ const root = query.node;
2154
+ const key = query.key;
2155
+ const getterRead = ts.isNewExpression(root) && !descriptorOf(root, key) ? familyReadOf(root, key) : null;
2156
+ if (!descriptorOf(root, key) && getterRead === null) {
2157
+ // A literal that spells every key it has and holds no key this
2158
+ // graph cannot name reads `undefined` for the ones it lacks:
2159
+ // `options.depthTexture` on the `{}` a parameter defaults to.
2160
+ if (ts.isObjectLiteralExpression(root) && absentOwnKey(root, key, root, descriptorOf, hasUnnamedWrite)) {
2161
+ read(closure(root));
2162
+ facts.add(undefinedValue);
2163
+ seeded = true;
2164
+ break;
2165
+ }
2166
+ fail('unmodelled-descriptor');
2167
+ break;
2168
+ }
2169
+ read(closure(root));
2170
+ if (ts.isObjectLiteralExpression(root)) {
2171
+ for (const entry of ownEntries(root, key) ?? []) {
2172
+ if (ts.isPropertyAssignment(entry))
2173
+ add(carry(value(entry.initializer)));
2174
+ else if (ts.isShorthandPropertyAssignment(entry))
2175
+ add(carry(value(entry.name)));
2176
+ else if (ts.isMethodDeclaration(entry)) {
2177
+ facts.add(entry);
2178
+ seeded = true;
2179
+ }
2180
+ }
2181
+ }
2182
+ else if (ts.isArrayLiteralExpression(root)) {
2183
+ if (key === ELEMENT_KEY) {
2184
+ // Every position at once; an index never written reads undefined.
2185
+ for (const element of root.elements)
2186
+ if (!ts.isOmittedExpression(element))
2187
+ add(carry(value(element)));
2188
+ facts.add(undefinedValue);
2189
+ seeded = true;
2190
+ }
2191
+ else if (key === 'length') {
2192
+ let length = arrayLengths.get(root);
2193
+ if (!length)
2194
+ arrayLengths.set(root, (length = ts.factory.createNumericLiteral(root.elements.length)));
2195
+ facts.add(length);
2196
+ seeded = true;
2197
+ }
2198
+ else {
2199
+ const element = root.elements[Number(key)];
2200
+ if (element !== undefined && !ts.isOmittedExpression(element))
2201
+ add(carry(value(element)));
2202
+ else {
2203
+ facts.add(undefinedValue);
2204
+ seeded = true;
2205
+ }
2206
+ }
2207
+ }
2208
+ else {
2209
+ for (const declaration of [...(classMembers(root, key) ?? []), ...(getterRead?.carriers ?? [])]) {
2210
+ if (ts.isMethodDeclaration(declaration)) {
2211
+ facts.add(declaration);
2212
+ seeded = true;
2213
+ }
2214
+ if (ts.isPropertyDeclaration(declaration)) {
2215
+ if (declaration.initializer)
2216
+ add(carry(value(declaration.initializer)));
2217
+ else {
2218
+ facts.add(undefinedValue);
2219
+ seeded = true;
2220
+ }
2221
+ }
2222
+ if (ts.isParameter(declaration))
2223
+ add(carry(nodeQuery('parameter', declaration)));
2224
+ }
2225
+ if (getterRead !== null) {
2226
+ // The getter runs with this construction as its receiver, and
2227
+ // the read yields what the getter's completions yield.
2228
+ for (const getter of getterRead.getters) {
2229
+ for (const reference of flow.receiverReferencesToDeclaration(getter))
2230
+ add(read(use(root, reference)));
2231
+ const summary = callableCompletionSummaryOf(flow, getter);
2232
+ if (summary === null || summary.execution !== 'sync')
2233
+ fail('unmodelled-getter-completion', getter);
2234
+ else {
2235
+ for (const completion of summary.values)
2236
+ add(carry(value(completion)));
2237
+ if (summary.mayCompleteUndefined) {
2238
+ facts.add(undefinedValue);
2239
+ seeded = true;
2240
+ }
2241
+ }
2242
+ }
2243
+ if (getterRead.absent) {
2244
+ facts.add(undefinedValue);
2245
+ seeded = true;
2246
+ }
2247
+ }
2248
+ }
2249
+ // Only the writes that could name THIS key: the ones that spell it,
2250
+ // and the ones that spell no key at all. Walking every write in the
2251
+ // program here cost O(all writes) per (root, key) -- fine while
2252
+ // computed slots were rare, and quadratic the moment a `for-in` head
2253
+ // started naming a key set, which is what stopped three's
2254
+ // WebGLRenderer finishing.
2255
+ // The stores that go through this root are the root's own closure's
2256
+ // facts -- `visitUse` publishes each one as it walks -- and this
2257
+ // transfer already requires that closure above. Asking the write
2258
+ // index instead meant subscribing to every write naming this key
2259
+ // PLUS every computed write in the program, per slot, permanently:
2260
+ // ~320 edges on each of the three.js app's ~20,000 slot states, and by far
2261
+ // the largest contributor to a 14.7M-edge graph. Same answer, no
2262
+ // dependency this node was not already holding.
2263
+ for (const stored of read(closure(root))) {
2264
+ if (ts.isCallExpression(stored) && definitionPlans.has(stored)) {
2265
+ const plan = definitionOf(stored);
2266
+ if (plan === null || !plan.keys.includes(key) || !read(value(stored.arguments[0])).has(root))
2267
+ continue;
2268
+ if (plan.values.length === 0) {
2269
+ facts.add(undefinedValue);
2270
+ seeded = true;
2271
+ }
2272
+ for (const defined of plan.values)
2273
+ add(carry(value(defined)));
2274
+ continue;
2275
+ }
2276
+ if (ts.isCallExpression(stored)) {
2277
+ // `Object.assign( root, ...sources )`: each source's own value
2278
+ // under this key lands in the root. Only a literal whose keys
2279
+ // are all spelled says what it holds; `null`/`undefined`
2280
+ // sources are skipped by the intrinsic itself.
2281
+ const bulk = bulkAssignOf(stored);
2282
+ if (bulk === null || !read(value(bulk.target)).has(root))
2283
+ continue;
2284
+ for (const source of bulk.sources)
2285
+ for (const held of read(value(source))) {
2286
+ if (held === undefinedValue || held.kind === ts.SyntaxKind.NullKeyword || ts.isVoidExpression(held))
2287
+ continue;
2288
+ if (!ts.isObjectLiteralExpression(held))
2289
+ fail('bulk-assign-source-unmodelled', source);
2290
+ else if (literalSpelledKeys(held) === null || hasUnnamedWrite(held))
2291
+ fail('bulk-assign-source-keys-open', source);
2292
+ else if (descriptorOf(held, key))
2293
+ add(carry(slot(held, key)));
2294
+ }
2295
+ continue;
2296
+ }
2297
+ if (!ts.isPropertyAccessExpression(stored) && !ts.isElementAccessExpression(stored))
2298
+ continue;
2299
+ const edge = writeEdgeByAccess.get(stored);
2300
+ if (edge === undefined)
2301
+ continue;
2302
+ if (!keyReaches(root, keysOf(stored), key))
2303
+ continue;
2304
+ const write = edge.write;
2305
+ if (write.value === null || !['property-assignment', 'index-assignment', 'class-field-initializer'].includes(write.edge)) {
2306
+ fail('unmodelled-property-write', stored);
2307
+ continue;
2308
+ }
2309
+ add(carry(value(write.value)));
2310
+ }
2311
+ break;
2312
+ }
2313
+ case 'construct-targets': {
2314
+ const selected = constructionFrames.targetsOf(query.node);
2315
+ if (selected === null)
2316
+ fail('opaque-construction-frame');
2317
+ else {
2318
+ add(selected);
2319
+ seeded = selected.length > 0;
2320
+ }
2321
+ break;
2322
+ }
2323
+ case 'super-targets': {
2324
+ const dispatch = sites.get(query.node)?.operands.dispatch;
2325
+ // An object-literal home has no `extends` chain to walk, and a
2326
+ // static home starts its lookup on the constructor object, not the
2327
+ // prototype: both are other domains, named rather than mishandled.
2328
+ const home = dispatch?.kind === 'lexical-super' && dispatch.home !== null && !ts.isObjectLiteralExpression(dispatch.home)
2329
+ ? dispatch.home
2330
+ : null;
2331
+ if (dispatch?.kind !== 'lexical-super' || dispatch.static || dispatch.key === null || home === null) {
2332
+ fail('unmodelled-super-lookup');
2333
+ break;
2334
+ }
2335
+ const selected = superLookup(home, dispatch.key, new Set());
2336
+ if (selected === null)
2337
+ fail('unresolved-super-lookup', home);
2338
+ else {
2339
+ add(selected);
2340
+ seeded = selected.length > 0;
2341
+ }
2342
+ break;
2343
+ }
2344
+ case 'targets': {
2345
+ const site = sites.get(query.node);
2346
+ if (site?.operands && !site.explicitThis && site.operands.dispatch.kind === 'lexical-super') {
2347
+ add(carry(superTargets(query.node)));
2348
+ break;
2349
+ }
2350
+ // `super()` selects a BASE CONSTRUCTOR, which is the construction
2351
+ // domain's question and already answered there -- the same selection
2352
+ // `new Base()` makes, reached from the subclass's heritage instead of
2353
+ // from a spelled callee.
2354
+ if (site?.operands && !site.explicitThis && site.operands.dispatch.kind === 'super-constructor') {
2355
+ add(carry(nodeQuery('construct-targets', query.node)));
2356
+ break;
2357
+ }
2358
+ // `.call`/`.apply` needs no separate resolver here: `operands.callee`
2359
+ // is already the executable callee with the wrapper removed, and the
2360
+ // thisArg is already out of `args`. What made this dispatch special
2361
+ // was carrying the receiver, which is a FRAME question answered where
2362
+ // frames are projected.
2363
+ if (!site?.operands) {
2364
+ fail('unmodelled-dispatch');
2365
+ break;
2366
+ }
2367
+ for (const candidate of read(value(site.operands.callee))) {
2368
+ if (isBody(candidate) && flow.callableBodyIsIndexed(candidate)) {
2369
+ facts.add(candidate);
2370
+ seeded = true;
2371
+ }
2372
+ else if (candidate.kind !== ts.SyntaxKind.NullKeyword && !ts.isVoidExpression(candidate))
2373
+ fail('opaque-call-target', candidate);
2374
+ }
2375
+ if (sealing && facts.size === 0 && !lookupThrows(query.node))
2376
+ fail('no-source-call-target');
2377
+ break;
2378
+ }
2379
+ case 'completion': {
2380
+ if (ts.isCallExpression(query.node)) {
2381
+ const bulk = bulkAssignOf(query.node);
2382
+ if (bulk !== null) {
2383
+ add(carry(value(bulk.target)));
2384
+ break;
2385
+ }
2386
+ // `store.get( key )` on a native Map this program alone fills:
2387
+ // the completion is one of the values `store.set( _, value )`
2388
+ // stored, whichever key -- the same closed-map proof
2389
+ // (`collectionValueFlowOf`) that refuses the moment the map or
2390
+ // its values leave through anything but these reads. Asked before
2391
+ // `targets`, because a native method has no source body to
2392
+ // select, and the receiver walk would otherwise end at `new Map()`
2393
+ // as an opaque construction. The stores themselves continue at
2394
+ // these reads (`visitUse` below), so the two are one graph.
2395
+ const stored = collectionStoredValuesOf(checker, flow, query.node, nativeProtocolClosed);
2396
+ if (stored !== null) {
2397
+ for (const candidate of stored)
2398
+ add(carry(value(candidate)));
2399
+ break;
2400
+ }
2401
+ }
2402
+ if (ts.isNewExpression(query.node)) {
2403
+ for (const candidate of read(value(query.node.expression))) {
2404
+ if (ts.isFunctionDeclaration(candidate) &&
2405
+ flow.callableBodyIsIndexed(candidate) &&
2406
+ candidate === constructorFunctionCalleeOf(query.node) &&
2407
+ constructionYieldsCompletionOf(flow, candidate))
2408
+ add(carry(frameQuery('frame-completion', query.node, candidate)));
2409
+ else
2410
+ fail('opaque-construction', candidate);
2411
+ }
2412
+ break;
2413
+ }
2414
+ for (const body of read(targets(query.node))) {
2415
+ if (!isBody(body))
2416
+ fail('unindexed-body', body);
2417
+ else
2418
+ add(carry(frameQuery('frame-completion', query.node, body)));
2419
+ }
2420
+ if (ts.isCallExpression(query.node) && lookupThrows(query.node))
2421
+ seeded = true;
2422
+ break;
2423
+ }
2424
+ case 'frame-receiver':
2425
+ case 'frame-argument':
2426
+ case 'frame-parameter':
2427
+ case 'frame-value':
2428
+ case 'frame-completion': {
2429
+ const layout = sourceInvocationFrameLayoutOf(flow, query.node, query.body);
2430
+ if (!layout) {
2431
+ fail('unindexed-source-frame');
2432
+ break;
2433
+ }
2434
+ const contextual = (expression) => frameQuery('frame-value', query.node, query.body, unwrapErasedExpression(expression));
2435
+ if (query.kind === 'frame-receiver') {
2436
+ const receiver = layout.receiver;
2437
+ if (receiver.kind === 'undefined') {
2438
+ facts.add(undefinedValue);
2439
+ seeded = true;
2440
+ }
2441
+ else if (receiver.kind === 'expression') {
2442
+ const memberCall = !sites.get(query.node)?.explicitThis;
2443
+ for (const candidate of carry(value(receiver.expression))) {
2444
+ // `source.depthTexture.clone()` with no depth texture set:
2445
+ // the member lookup on `null` throws and the frame never runs
2446
+ // with that receiver. Only an explicit `f.call( null )` binds
2447
+ // a nullish receiver.
2448
+ if (memberCall && isNullish(candidate))
2449
+ continue;
2450
+ if (receiver.conversion === 'identity' || isObjectRoot(candidate) || isBody(candidate))
2451
+ facts.add(candidate);
2452
+ else
2453
+ fail(ts.isVoidExpression(candidate) || candidate.kind === ts.SyntaxKind.NullKeyword
2454
+ ? 'global-object-receiver-origin'
2455
+ : 'primitive-receiver-conversion', receiver.expression);
2456
+ }
2457
+ }
2458
+ else if (receiver.kind === 'constructed')
2459
+ add(carry(value(receiver.call)));
2460
+ else if (receiver.kind === 'lexical' && receiver.owner) {
2461
+ if (ts.isSourceFile(receiver.owner)) {
2462
+ if (ts.isExternalModule(receiver.owner)) {
2463
+ facts.add(undefinedValue);
2464
+ seeded = true;
2465
+ }
2466
+ else
2467
+ fail('global-object-receiver-origin', receiver.owner);
2468
+ }
2469
+ else
2470
+ add(carry(nodeQuery('receiver', receiver.owner)));
2471
+ }
2472
+ else
2473
+ fail(receiver.kind === 'unsupported' ? receiver.reason : 'global-object-receiver-origin');
2474
+ }
2475
+ else if (query.kind === 'frame-argument' || query.kind === 'frame-parameter') {
2476
+ const parameter = query.subject;
2477
+ if (!parameter || !ts.isParameter(parameter) || parameter.parent !== query.body) {
2478
+ fail('unindexed-parameter-frame');
2479
+ break;
2480
+ }
2481
+ if (query.kind === 'frame-parameter') {
2482
+ add(carry(frameQuery('frame-argument', query.node, query.body, parameter)));
2483
+ for (const write of flow.writesToDeclaration(parameter)) {
2484
+ if (write.edge === 'call-argument' || write.edge === 'super-argument' || write.edge === 'default-parameter')
2485
+ continue;
2486
+ if (write.slot !== 'whole')
2487
+ continue;
2488
+ if (!['identifier-assignment', 'logical-assignment'].includes(write.edge) || !write.value)
2489
+ fail('unmodelled-parameter-write', write.site);
2490
+ else
2491
+ add(carry(contextual(write.value)));
2492
+ }
2493
+ break;
2494
+ }
2495
+ if (layout.arguments.kind === 'spread') {
2496
+ fail('spread-arguments');
2497
+ break;
2498
+ }
2499
+ const slot = layout.arguments.slots.find((candidate) => candidate.parameter === parameter);
2500
+ if (!slot || slot.kind === 'rest') {
2501
+ fail('unmodelled-parameter-frame', parameter);
2502
+ break;
2503
+ }
2504
+ if (slot.actual) {
2505
+ for (const candidate of carry(value(slot.actual))) {
2506
+ if (ts.isVoidExpression(candidate) && slot.defaultValue)
2507
+ add(carry(contextual(slot.defaultValue)));
2508
+ else
2509
+ facts.add(candidate);
2510
+ }
2511
+ }
2512
+ else if (slot.defaultValue)
2513
+ add(carry(contextual(slot.defaultValue)));
2514
+ else {
2515
+ facts.add(undefinedValue);
2516
+ seeded = true;
2517
+ }
2518
+ }
2519
+ else if (query.kind === 'frame-completion') {
2520
+ const summary = callableCompletionSummaryOf(flow, query.body);
2521
+ if (!summary || summary.execution !== 'sync')
2522
+ fail('deferred-completion', query.body);
2523
+ else {
2524
+ for (const expression of summary.values)
2525
+ add(carry(contextual(expression)));
2526
+ if (summary.mayCompleteUndefined || (ts.isCallExpression(query.node) && ts.isCallChain(query.node))) {
2527
+ facts.add(undefinedValue);
2528
+ seeded = true;
2529
+ }
2530
+ }
2531
+ }
2532
+ else {
2533
+ const expression = query.subject;
2534
+ if (!expression || ts.isParameter(expression)) {
2535
+ fail('unindexed-frame-value');
2536
+ break;
2537
+ }
2538
+ const declaration = ts.isIdentifier(expression) ? flow.targetOf(expression)?.declaration : null;
2539
+ if (declaration && ts.isParameter(declaration) && declaration.parent === query.body)
2540
+ add(carry(frameQuery('frame-parameter', query.node, query.body, declaration)));
2541
+ else if (declaration &&
2542
+ ts.isVariableDeclaration(declaration) &&
2543
+ ts.findAncestor(declaration, ts.isFunctionLike) === query.body) {
2544
+ const incoming = localBindingValuesOf(flow, declaration);
2545
+ if (incoming === null)
2546
+ fail('unaccounted-binding-write', declaration);
2547
+ else
2548
+ for (const entry of incoming)
2549
+ add(carry(contextual(entry)));
2550
+ }
2551
+ else if ((expression.kind === ts.SyntaxKind.ThisKeyword || expression.kind === ts.SyntaxKind.SuperKeyword) &&
2552
+ (ts.isArrowFunction(query.body) || flow.receiverOwnerOf(expression) === query.body))
2553
+ add(carry(frameQuery('frame-receiver', query.node, query.body)));
2554
+ else if (ts.isConditionalExpression(expression)) {
2555
+ add(carry(contextual(expression.whenTrue)));
2556
+ add(carry(contextual(expression.whenFalse)));
2557
+ }
2558
+ else if (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression)) {
2559
+ const keys = keysOf(expression);
2560
+ for (const root of read(contextual(expression.expression))) {
2561
+ if (isObjectRoot(root))
2562
+ for (const key of keys)
2563
+ add(carry(slot(root, key)));
2564
+ else if (root.kind !== ts.SyntaxKind.NullKeyword && !ts.isVoidExpression(root))
2565
+ fail('non-object-receiver');
2566
+ }
2567
+ }
2568
+ else if (ts.isBinaryExpression(expression) &&
2569
+ [ts.SyntaxKind.EqualsToken, ts.SyntaxKind.CommaToken].includes(expression.operatorToken.kind))
2570
+ add(carry(contextual(expression.right)));
2571
+ else if (ts.isBinaryExpression(expression) &&
2572
+ [ts.SyntaxKind.BarBarToken, ts.SyntaxKind.AmpersandAmpersandToken, ts.SyntaxKind.QuestionQuestionToken].includes(expression.operatorToken.kind)) {
2573
+ add(carry(contextual(expression.left)));
2574
+ add(carry(contextual(expression.right)));
2575
+ }
2576
+ else
2577
+ add(carry(value(expression)));
2578
+ }
2579
+ break;
2580
+ }
2581
+ case 'parameter': {
2582
+ const parameter = query.node;
2583
+ const owner = parameter.parent;
2584
+ if (ts.isSetAccessorDeclaration(owner)) {
2585
+ setterStores(owner);
2586
+ // The enumeration is exhaustive -- every store through every
2587
+ // instance -- so a setter nothing stores through has an EMPTY
2588
+ // parameter, witnessed here, not one pending some origin.
2589
+ seeded = true;
2590
+ break;
2591
+ }
2592
+ if (!isBody(owner) && !ts.isConstructorDeclaration(owner)) {
2593
+ fail('unindexed-parameter-frame');
2594
+ break;
2595
+ }
2596
+ // A binding pattern names no cell of its own, but the parameter DOES
2597
+ // hold the whole argument -- that value is what each binding element
2598
+ // then reads a slot of. Refusing here made the pattern's container
2599
+ // unknowable, so every receiver destructured out of a parameter was
2600
+ // opaque however completely the program built the object.
2601
+ if (parameter.dotDotDotToken) {
2602
+ fail('unmodelled-parameter-frame');
2603
+ break;
2604
+ }
2605
+ if (isBody(owner))
2606
+ read(closure(owner));
2607
+ for (const site of constructionSitesTargeting(owner))
2608
+ add(carry(frameQuery('frame-argument', site.call, owner, parameter)));
2609
+ for (const call of read(callersOf(owner)))
2610
+ if (ts.isCallExpression(call) || ts.isNewExpression(call))
2611
+ add(carry(frameQuery('frame-argument', call, owner, parameter)));
2612
+ for (const write of flow.writesToDeclaration(parameter)) {
2613
+ if (write.edge === 'call-argument' || write.edge === 'super-argument' || write.edge === 'default-parameter')
2614
+ continue;
2615
+ // A member or element write goes THROUGH the cell into the object
2616
+ // it holds; it never rebinds the cell, so it is no evidence about
2617
+ // what this parameter's value set is. Whether the object can still
2618
+ // be described afterwards is that object's own closure to answer,
2619
+ // and refusing here answered it in the wrong place -- turning
2620
+ // `values[ k ] = 1` into "this parameter holds nothing".
2621
+ if (write.slot !== 'whole')
2622
+ continue;
2623
+ if (!['identifier-assignment', 'logical-assignment'].includes(write.edge) || !write.value) {
2624
+ fail('unmodelled-parameter-write', write.site);
2625
+ continue;
2626
+ }
2627
+ add(carry(value(write.value)));
2628
+ }
2629
+ break;
2630
+ }
2631
+ case 'binding-element': {
2632
+ const element = query.node;
2633
+ const pattern = element.parent;
2634
+ const holder = pattern.parent;
2635
+ const key = bindingElementKey(element);
2636
+ // A rest element holds a FRESH object built from the keys nothing
2637
+ // else took -- unmodelled regardless of presence.
2638
+ if (element.dotDotDotToken)
2639
+ fail('rest-binding-element', element);
2640
+ else if (key === null)
2641
+ fail('computed-binding-element', element);
2642
+ else {
2643
+ // The container is whatever cell holds the object being taken
2644
+ // apart, and every form of it is already a query: a parameter, an
2645
+ // outer binding element of a nested pattern, or the initializer of
2646
+ // a destructuring declaration.
2647
+ const container = bindingContainer(element);
2648
+ if (container === null)
2649
+ fail('unmodelled-binding-container', holder);
2650
+ else {
2651
+ const roots = read(container);
2652
+ // A default makes the cell's value depend on whether the slot
2653
+ // was present -- a presence fact this graph does not otherwise
2654
+ // carry, EXCEPT for the one shape `ownEntries` already answers:
2655
+ // an object-literal root that OWNS this key outright (a plain
2656
+ // property, no spread, no accessor). JS only consults a
2657
+ // destructuring default when the read is exactly `undefined`,
2658
+ // and a literal's own stated property is never that by
2659
+ // omission -- so when every root the container resolves to is
2660
+ // such a literal, the default is dead code and the slot reads
2661
+ // below are the whole, sound answer. Every host-options literal
2662
+ // three passes (`new WebGLRenderer({ canvas, context, depth:
2663
+ // true, ... })`) states every field its constructor destructures
2664
+ // with a default, so refusing EVERY defaulted binding element
2665
+ // unconditionally made `_gl` -- and everything downstream of it,
2666
+ // the whole WebGL host surface -- permanently unenumerable no
2667
+ // matter what the program actually wrote at the call site.
2668
+ const defaultIsLive = element.initializer !== undefined &&
2669
+ (roots.size === 0 || [...roots].some((root) => !ts.isObjectLiteralExpression(root) || ownEntries(root, key) === null));
2670
+ if (defaultIsLive)
2671
+ fail('defaulted-binding-element', element);
2672
+ else
2673
+ for (const root of roots) {
2674
+ if (isObjectRoot(root))
2675
+ add(carry(slot(root, key)));
2676
+ else
2677
+ fail('non-object-destructured-container', element);
2678
+ }
2679
+ }
2680
+ }
2681
+ break;
2682
+ }
2683
+ case 'receiver': {
2684
+ const owner = query.node;
2685
+ if (ts.isSourceFile(owner) && ts.isExternalModule(owner)) {
2686
+ facts.add(undefinedValue);
2687
+ seeded = true;
2688
+ }
2689
+ else if (ts.isConstructorDeclaration(owner) ||
2690
+ ts.isPropertyDeclaration(owner) ||
2691
+ ts.isGetAccessorDeclaration(owner) ||
2692
+ ts.isSetAccessorDeclaration(owner)) {
2693
+ for (const construction of constructionsOf(owner))
2694
+ add(carry(value(construction)));
2695
+ }
2696
+ else if (isBody(owner)) {
2697
+ read(closure(owner));
2698
+ for (const construction of constructionsOf(owner))
2699
+ add(carry(value(construction)));
2700
+ for (const call of read(callersOf(owner)))
2701
+ if (ts.isCallExpression(call))
2702
+ add(carry(frameQuery('frame-receiver', call, owner)));
2703
+ }
2704
+ else
2705
+ fail('unmodelled-receiver-owner');
2706
+ break;
2707
+ }
2708
+ case 'callers': {
2709
+ // The exact filter every inline caller used to run for itself --
2710
+ // moved here so the whole-program walk it does for an unnamed body
2711
+ // is paid once per OWNER, not once per (owner, consumer) pair. See
2712
+ // `callersOf`'s comment for the shape and the measured cost this
2713
+ // replaces.
2714
+ // Discovery by name, soundness by CLOSURE. The spelled calls that
2715
+ // resolve to this owner are its callers only while the owner can
2716
+ // be reached from nowhere else: the body's own closure says where
2717
+ // the callable value goes, and for a class member each instance's
2718
+ // closure says where the receivers go -- an instance handed to
2719
+ // unknown code can be called through from there with arguments no
2720
+ // site spells. A spelled call whose targets are opaque is then
2721
+ // either a call through one of those closures, which already
2722
+ // refused, or a call on something that never holds this owner.
2723
+ // Requiring every candidate's targets instead made `Material.copy`
2724
+ // wait on `targetMatrix.copy( ... )` in three's ColorManagement, a
2725
+ // Matrix3 the graph never places.
2726
+ const owner = query.node;
2727
+ // A constructor is never CALLED: its frames are its construction
2728
+ // sites, which `constructionSitesTargeting` names from the
2729
+ // construction domain, so it has no closure to read here.
2730
+ if (ts.isConstructorDeclaration(owner))
2731
+ break;
2732
+ read(closure(owner));
2733
+ if (ts.isClassElement(owner) && ts.isClassLike(owner.parent)) {
2734
+ if ((ts.getCombinedModifierFlags(owner) & ts.ModifierFlags.Static) !== 0)
2735
+ fail('static-member-callers-open', owner);
2736
+ else
2737
+ for (const instance of familyInstancesOf(owner.parent, 'member-family-open') ?? [])
2738
+ read(closure(instance));
2739
+ }
2740
+ const ownerType = ownerInstanceTypeOf(owner);
2741
+ for (const site of candidateCallersOf(owner)) {
2742
+ // `new WebGLTextures( state )` on a plain function enters the
2743
+ // function's own argument frame exactly as a call would; the
2744
+ // construction domain names no class for it, so it is a caller.
2745
+ if (ts.isNewExpression(site.call)) {
2746
+ if (ts.isFunctionDeclaration(owner) && constructorFunctionCalleeOf(site.call) === owner)
2747
+ facts.add(site.call);
2748
+ continue;
2749
+ }
2750
+ if (!ts.isCallExpression(site.call))
2751
+ continue;
2752
+ if (ownerType !== null && !site.explicitThis && site.operands.dispatch.kind === 'member' && site.operands.receiver !== null) {
2753
+ if (!statedTypeAdmits(checker.getTypeAtLocation(site.operands.receiver), ownerType))
2754
+ continue;
2755
+ }
2756
+ if (observe(targets(site.call)).has(owner))
2757
+ facts.add(site.call);
2758
+ }
2759
+ break;
2760
+ }
2761
+ case 'closure': {
2762
+ const root = query.node;
2763
+ if (ts.isFunctionDeclaration(root)) {
2764
+ if ((ts.getCombinedModifierFlags(root) & ts.ModifierFlags.Export) !== 0 && !exportIsUnimported(checker, flow, root))
2765
+ fail('exported-callable');
2766
+ if (ts.isSourceFile(root.parent) && !ts.isExternalModule(root.parent))
2767
+ fail('global-object-callable');
2768
+ refs(root, root);
2769
+ }
2770
+ else if (ts.isMethodDeclaration(root)) {
2771
+ if (ts.isObjectLiteralExpression(root.parent)) {
2772
+ const key = declarationKey(root.name);
2773
+ if (key === null)
2774
+ fail('computed-method');
2775
+ else
2776
+ add(read(publication(root, root.parent, key)));
2777
+ }
2778
+ else
2779
+ refs(root, root);
2780
+ }
2781
+ else if (ts.isExpression(root))
2782
+ add(read(use(root, root)));
2783
+ else
2784
+ fail('unmodelled-root');
2785
+ if (ts.isNewExpression(root)) {
2786
+ const owners = constructionFrames.receiverOwnersOf(root);
2787
+ if (!owners) {
2788
+ fail('opaque-construction');
2789
+ break;
2790
+ }
2791
+ for (const owner of owners) {
2792
+ if (!isClassSpelledSourceClass(owner)) {
2793
+ for (const reference of flow.receiverReferencesToDeclaration(owner))
2794
+ add(read(use(root, reference)));
2795
+ continue;
2796
+ }
2797
+ for (const member of owner.members) {
2798
+ if (ts.isConstructorDeclaration(member) ||
2799
+ (ts.isPropertyDeclaration(member) && (ts.getCombinedModifierFlags(member) & ts.ModifierFlags.Static) === 0))
2800
+ for (const reference of flow.receiverReferencesToDeclaration(member))
2801
+ add(read(use(root, reference)));
2802
+ }
2803
+ }
2804
+ }
2805
+ break;
2806
+ }
2807
+ case 'use':
2808
+ visitUse(query.root, query.node);
2809
+ break;
2810
+ case 'unknown-reads': {
2811
+ // Inverted from a scan of all 968 receivers to a reverse-index
2812
+ // lookup: `holdersOf` hands back the receiver queries that hold
2813
+ // THIS container, so the container asks once instead of every
2814
+ // container asking the same 968-entry list. A holder that is not
2815
+ // one of the unknown-read receivers -- a `slot`, `parameter` or any
2816
+ // other kind of state that also happens to hold this exact node --
2817
+ // is not in `unknownReadsByReceiver` and is simply skipped.
2818
+ for (const holder of holdersOf(query.node))
2819
+ for (const entry of unknownReadsByReceiver.get(holder) ?? NO_READS)
2820
+ facts.add(entry.access);
2821
+ break;
2822
+ }
2823
+ case 'publication': {
2824
+ read(closure(query.node));
2825
+ // A container merged into another by `Object.assign` hands this
2826
+ // key's value to the target as well.
2827
+ for (const stored of read(closure(query.node))) {
2828
+ if (!ts.isCallExpression(stored))
2829
+ continue;
2830
+ const bulk = bulkAssignOf(stored);
2831
+ if (bulk === null || !bulk.sources.some((source) => read(value(source)).has(query.node)))
2832
+ continue;
2833
+ for (const held of read(value(bulk.target)))
2834
+ if (isObjectRoot(held))
2835
+ add(read(publication(query.root, held, query.key)));
2836
+ }
2837
+ for (const stored of read(closure(query.node))) {
2838
+ if (!ts.isCallExpression(stored) || !definitionPlans.has(stored) || query.key !== 'value')
2839
+ continue;
2840
+ const plan = definitionOf(stored);
2841
+ if (plan === null || !read(value(stored.arguments[2])).has(query.node))
2842
+ continue;
2843
+ for (const held of read(value(stored.arguments[0])))
2844
+ if (isObjectRoot(held))
2845
+ for (const key of plan.keys)
2846
+ add(read(publication(query.root, held, key)));
2847
+ }
2848
+ const aliases = ts.isArrayLiteralExpression(query.node)
2849
+ ? query.key === ELEMENT_KEY
2850
+ ? [...readsByKey.keys()].filter((key) => key === ELEMENT_KEY || isCanonicalIndex(key))
2851
+ : isCanonicalIndex(query.key)
2852
+ ? [query.key, ELEMENT_KEY]
2853
+ : [query.key]
2854
+ : [query.key];
2855
+ for (const alias of aliases)
2856
+ for (const entry of readsByKey.get(alias) ?? NO_READS) {
2857
+ if (!observe(entry.receiver).has(query.node))
2858
+ continue;
2859
+ if (keyReaches(query.node, keysOf(entry.access), query.key))
2860
+ add(read(use(query.root, entry.access)));
2861
+ }
2862
+ // Discovery-only, exactly as the receiver test it replaces was: a
2863
+ // publication never required the unknown reads to have settled, it
2864
+ // only had to see the ones that had.
2865
+ for (const access of observe(unknownReadsOf(query.node))) {
2866
+ if (!ts.isPropertyAccessExpression(access) && !ts.isElementAccessExpression(access))
2867
+ continue;
2868
+ if (keyReaches(query.node, keysOf(access), query.key))
2869
+ add(read(use(query.root, access)));
2870
+ }
2871
+ // The value this key holds also reaches every cell a binding element
2872
+ // of this container declares. Enumerating only `propertyAccesses`
2873
+ // left `const { app } = p; sink(app)` out of the inventory, which is
2874
+ // a hole in a closure proof, not a missing capability.
2875
+ for (const element of both(patternReadsByKey.get(query.key), unknownPatternReads)) {
2876
+ const container = bindingContainer(element);
2877
+ if (container === null || !observe(container).has(query.node))
2878
+ continue;
2879
+ if (element.dotDotDotToken || bindingElementKey(element) === null)
2880
+ fail('unmodelled-container-read', element);
2881
+ else
2882
+ refs(query.root, element);
2883
+ }
2884
+ break;
2885
+ }
2886
+ }
2887
+ finalCauses = causes;
2888
+ // Only the seal reads the grounding edges, and the seal is the last
2889
+ // call this query receives; materializing the list on every transfer
2890
+ // allocated one object per carried edge per re-evaluation for nothing.
2891
+ if (sealing)
2892
+ finalGrounding = [...grounding].map((dependency) => ({ domain: VALUE_ORIGIN, dependency }));
2893
+ return facts;
2894
+ };
2895
+ const run = (read, observe, holdersOf, sealing) => {
2896
+ const ledger = deferredIntrinsicProtocolLedgerOf(flow);
2897
+ if (!ledger)
2898
+ return evaluate(read, observe, holdersOf, sealing);
2899
+ const captured = ledger.capture(() => evaluate(read, observe, holdersOf, sealing));
2900
+ // Overwrite, not union -- like `finalCauses`/`finalGrounding` above,
2901
+ // this is safe ONLY because `evaluate` is monotone: `facts` published to
2902
+ // the solver (`component-solver.ts`'s `state.facts`) accumulate forever
2903
+ // regardless of what any one call returns, so the LAST call for this
2904
+ // query (the seal that ends the re-seal loop) is the only one whose
2905
+ // `facts` can differ from that accumulated set, and then only by being
2906
+ // equal to it. `arrayElementKeys`' widen-on-empty was the one place that
2907
+ // invariant broke -- an early pass published every element as a
2908
+ // permanent fact that a later, exact pass never re-derived, so the
2909
+ // ledger requirement that early pass owed was needed forever but this
2910
+ // map would have forgotten it the moment a narrower pass overwrote it.
2911
+ // With that widening now gated on `sealing`, no known transfer in this
2912
+ // file can produce fewer facts on a later call than an earlier one
2913
+ // already published, and a requirement that is raised without being
2914
+ // needed is merely a stricter refusal, while a needed one gone missing
2915
+ // is a wrong answer -- so if this invariant is ever broken again by a
2916
+ // NEW transfer, union (not overwrite) is the direction that cannot lie:
2917
+ // `both(requirements.get(query), captured.requirements)`.
2918
+ requirements.set(query, captured.requirements);
2919
+ return captured.value;
2920
+ };
2921
+ return {
2922
+ transfer: (read, observe, holdersOf) => run(read, observe, holdersOf, false),
2923
+ seal: (read, observe, holdersOf) => {
2924
+ run(read, observe, holdersOf, true);
2925
+ const carriesValue = VALUE_CARRYING_KINDS.has(query.kind);
2926
+ return {
2927
+ locallyComplete: finalCauses.length === 0,
2928
+ causes: finalCauses,
2929
+ groundingRequirements: carriesValue ? [VALUE_ORIGIN] : [],
2930
+ groundingSeeds: seeded ? [VALUE_ORIGIN] : [],
2931
+ groundingDependencies: finalGrounding
2932
+ };
2933
+ }
2934
+ };
2935
+ };
2936
+ const { solve, requiredDependenciesOf, seed } = dependencyFactSolver(define, 'grounding-domains');
2937
+ // `case 'unknown-reads'` now asks `holdersOf` for the receivers that hold a
2938
+ // container, instead of `observe`-ing all 968 of them itself -- but a
2939
+ // reverse index only finds states that already EXIST and have already run.
2940
+ // The `observe` calls it replaces used to materialise every receiver as a
2941
+ // SIDE EFFECT of `factsFrom`'s own `stateOf`; dropping them without this
2942
+ // loop would leave a receiver nothing else in the program asks about never
2943
+ // created; `holdersOf(container)` would then silently return nothing for
2944
+ // it, missing a read that program prints. Seeded once here, for the whole
2945
+ // session, not once per container: 968 scheduling operations total, zero
2946
+ // stored edges, against the 455,769 observe edges this replaces.
2947
+ for (const entry of unknownReads)
2948
+ seed(entry.receiver);
2949
+ // `hasUnnamedWrite` asks the same reverse question of every computed write's receiver.
2950
+ for (const receiver of computedWriteReceiverQueries)
2951
+ seed(receiver);
2952
+ const obligations = (root) => {
2953
+ const found = [];
2954
+ const visited = new Set();
2955
+ const queue = [root];
2956
+ for (let index = 0; index < queue.length; index++) {
2957
+ const query = queue[index];
2958
+ if (visited.has(query))
2959
+ continue;
2960
+ visited.add(query);
2961
+ found.push(...(requirements.get(query) ?? []));
2962
+ for (const dependency of requiredDependenciesOf(query))
2963
+ queue.push(dependency);
2964
+ }
2965
+ return found;
2966
+ };
2967
+ // A literal's function-valued entry (`convert: function ( ... ) { ... }`)
2968
+ // is the same slot as its shorthand method: one literal, one write, no
2969
+ // nominal family. Both spellings occur in three's `ColorManagement`.
2970
+ const isObjectLiteralCallableEntry = (declaration) => ts.isObjectLiteralExpression(declaration.parent) &&
2971
+ !declaration.getSourceFile().isDeclarationFile &&
2972
+ (isSourceInstanceMethod(declaration) ||
2973
+ (ts.isPropertyAssignment(declaration) &&
2974
+ (ts.isFunctionExpression(declaration.initializer) ||
2975
+ ts.isArrowFunction(declaration.initializer) ||
2976
+ // `{ texImage3D: texImage3D }`: the entry names a source function;
2977
+ // the slot's value is that function's binding, which the graph
2978
+ // resolves as it resolves any identifier.
2979
+ (ts.isIdentifier(declaration.initializer) && isBody(flow.targetOf(declaration.initializer)?.declaration ?? declaration)))));
2980
+ const admitted = (query) => {
2981
+ const result = solve(query);
2982
+ if (result.status !== 'complete')
2983
+ return null;
2984
+ const required = obligations(query);
2985
+ if (required.length && deferredIntrinsicProtocolLedgerOf(flow)?.include(required) !== true)
2986
+ return null;
2987
+ return [...result.facts];
2988
+ };
2989
+ const invocationTargetsOf = (call) => {
2990
+ const found = admitted(targets(call));
2991
+ return found !== null && found.every(isCallableValue) ? found : null;
2992
+ };
2993
+ return {
2994
+ ownsInvocation: (call) => {
2995
+ const site = sites.get(call);
2996
+ // Wrapper integrity and lexical-super lookup are separate dispatch
2997
+ // domains still owned by the existing invocation authority. Partition
2998
+ // before solving; failure within the ordinary-member domain is final.
2999
+ if (!site || site.explicitThis || site.operands.dispatch.kind !== 'member')
3000
+ return false;
3001
+ const callee = site.operands.callee;
3002
+ if (!callee || (!ts.isPropertyAccessExpression(callee) && !ts.isElementAccessExpression(callee)))
3003
+ return false;
3004
+ const symbol = flow.targetOf(callee)?.nameSymbol ?? flow.targetOf(callee)?.symbol;
3005
+ const declarations = symbol?.declarations;
3006
+ if (!declarations?.length)
3007
+ return false;
3008
+ // Ordinary source interface-member calls only (§5's cut-over row) --
3009
+ // the graph owns these with no fallback.
3010
+ if (declarations.some((declaration) => !declaration.getSourceFile().isDeclarationFile && (ts.isPropertySignature(declaration) || ts.isMethodSignature(declaration))))
3011
+ return true;
3012
+ // An OBJECT-LITERAL method has no nominal family: no `super`, no
3013
+ // override set to enumerate, no base constructor, no class receiver
3014
+ // forwarded through `new`. None of the four facts listed below applies
3015
+ // to it, and the graph already resolves a literal's slots joint with
3016
+ // the writes that replace them (source-value-session.test.ts). So the
3017
+ // graph owns these now; narrowing the whole `isSourceInstanceMethod`
3018
+ // widening back to the legacy resolver took literal-method-receiver
3019
+ // from 2/3 to 1/3 -- the legacy authority never counted
3020
+ // `ColorManagement.define( ... )` on a literal returned by a factory.
3021
+ if (declarations.every(isObjectLiteralCallableEntry))
3022
+ return true;
3023
+ // Ordinary CLASS methods stay with the legacy authority (§5's
3024
+ // "not migrated" row). Admitting them too, via
3025
+ // `declarations.every(isSourceInstanceMethod)`, was tried and measured
3026
+ // (SEMANTIC-AUTHORITY.md §7 item 5, "the partition, not landed"): it
3027
+ // broke 16 tests across 8 suites plus a new `computed-key-set` failure,
3028
+ // clustering on four still-unbuilt facts --
3029
+ // - lexical `super` beside an ordinary override (invocation-dispatch)
3030
+ // - computed member closure / override-family enumeration for an
3031
+ // EXACT allocation rather than a whole nominal family
3032
+ // (exact-class-allocation-origins, computed-key-set: `this[key] = v`)
3033
+ // - base-constructor setter following (closed-callable-authority)
3034
+ // - frame details: safe `arguments` reads, rest-array element
3035
+ // continuations, TypeScript `this` positions, imported-function
3036
+ // receiver evidence, and a receiver forwarded through a `new`
3037
+ // constructor argument (member-call-forwarding,
3038
+ // source-invocation-layout, array-element-continuation,
3039
+ // class-origin-imports, arguments-frame-member-closure,
3040
+ // mutable-method-parameters)
3041
+ //
3042
+ // Re-measured 2026-09-14 against a later tree (after
3043
+ // `sourceClassCallableMemberPlanOf` and the member-name-is-a-slot-read
3044
+ // fix, commit 83ad7008b and later, §7 item 5 "the missing fact,
3045
+ // built"): widening `ownsInvocation` to
3046
+ // `declarations.every(isSourceInstanceMethod)` now leaves SIX of the
3047
+ // nine files above green -- `invocation-dispatch`,
3048
+ // `exact-class-allocation-origins`, `member-call-forwarding`,
3049
+ // `source-invocation-layout`, `array-element-continuation` and
3050
+ // `class-origin-imports` all pass unmodified. THREE facts remain
3051
+ // unbuilt, each reproduced by exactly one still-failing suite:
3052
+ // - `mutable-method-parameters.test.ts` (3/37 fail): once a class
3053
+ // method's own member calls route through the graph, the legacy
3054
+ // escape walk that `parameter-bindings.ts` still asks
3055
+ // (`hasClosedMemberCallableUses`) cannot read the graph's answer
3056
+ // for those calls and reports the receiver open, so a parameter
3057
+ // bound only through sibling class-method calls loses its type.
3058
+ // - `arguments-frame-member-closure.test.ts` (1/2 fail): a receiver
3059
+ // forwarded through `arguments[ i ]` inside a recursive self-call
3060
+ // (three's `Object3D.add` multi-child form) is not a shape the
3061
+ // graph's `targets`/`value` queries resolve yet, so the whole
3062
+ // family closure opens with
3063
+ // `function-escapes:uncounted-member-reference`. This is the
3064
+ // single largest leaf-refusal shape measured on the three.js app
3065
+ // (`measurements/leaf-refusals.log`, 2026-09-14): a receiver
3066
+ // forwarded through a call argument is not followed -- see §7
3067
+ // item 0's `uncounted-member-reference` breakdown.
3068
+ // - `computed-key-set.test.ts` (1/10 fail, "three's setValues,
3069
+ // reduced"): the refusal reason regresses from the precise
3070
+ // `origin-computed-write` to the earlier, coarser
3071
+ // `object-origin-open-parameter` -- the graph trips a less
3072
+ // specific refusal before it reaches the computed-write site.
3073
+ // - `closed-callable-authority.test.ts` (1/20 fail, "a closed
3074
+ // script realm includes writes and callers from every script"):
3075
+ // the graph's caller closure for a class method shared by two
3076
+ // files under one `ClosedScriptScope` does not yet match the
3077
+ // legacy caller walk it is meant to replace.
3078
+ // Complete those, THEN widen this predicate, then delete the legacy
3079
+ // resolver -- in that order, and never by relaxing a test.
3080
+ return false;
3081
+ },
3082
+ invocationTargetsOf,
3083
+ valuesOf: (expression) => admitted(value(expression)),
3084
+ parameterValuesOf: (parameter) => admitted(nodeQuery('parameter', parameter)),
3085
+ explainParameter: (parameter) => solve(nodeQuery('parameter', parameter)).explain(),
3086
+ explainInvocation: (call) => solve(targets(call)).explain(),
3087
+ explainValue: (expression) => solve(value(expression)).explain()
3088
+ };
3089
+ };