@scriptc/compiler 0.4.5 → 0.4.6

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 (1200) hide show
  1. package/ambient/node-fallback/assert-strict.d.ts +47 -0
  2. package/ambient/node-fallback/assert.d.ts +86 -0
  3. package/ambient/node-fallback/async_hooks.d.ts +41 -0
  4. package/ambient/node-fallback/buffer.d.ts +23 -0
  5. package/ambient/node-fallback/child_process.d.ts +242 -0
  6. package/ambient/node-fallback/cluster.d.ts +17 -0
  7. package/ambient/node-fallback/constants.d.ts +15 -0
  8. package/ambient/node-fallback/crypto.d.ts +837 -0
  9. package/ambient/node-fallback/dgram.d.ts +58 -0
  10. package/ambient/node-fallback/diagnostics_channel.d.ts +87 -0
  11. package/ambient/node-fallback/dns-promises.d.ts +27 -0
  12. package/ambient/node-fallback/dns.d.ts +65 -0
  13. package/ambient/node-fallback/events.d.ts +60 -0
  14. package/ambient/node-fallback/fs-promises.d.ts +225 -0
  15. package/ambient/node-fallback/fs.d.ts +641 -0
  16. package/ambient/node-fallback/graceful-fs.d.ts +9 -0
  17. package/ambient/node-fallback/http.d.ts +326 -0
  18. package/ambient/node-fallback/http2.d.ts +816 -0
  19. package/ambient/node-fallback/https.d.ts +59 -0
  20. package/ambient/node-fallback/module.d.ts +10 -0
  21. package/ambient/node-fallback/net.d.ts +374 -0
  22. package/ambient/node-fallback/os.d.ts +288 -0
  23. package/ambient/node-fallback/path-posix.d.ts +22 -0
  24. package/ambient/node-fallback/path-win32.d.ts +22 -0
  25. package/ambient/node-fallback/path.d.ts +55 -0
  26. package/ambient/node-fallback/process.d.ts +11 -0
  27. package/ambient/node-fallback/punycode.d.ts +18 -0
  28. package/ambient/node-fallback/querystring.d.ts +55 -0
  29. package/ambient/node-fallback/stream-consumers.d.ts +21 -0
  30. package/ambient/node-fallback/stream-promises.d.ts +28 -0
  31. package/ambient/node-fallback/stream-web.d.ts +36 -0
  32. package/ambient/node-fallback/stream.d.ts +644 -0
  33. package/ambient/node-fallback/string_decoder.d.ts +20 -0
  34. package/ambient/node-fallback/test.d.ts +236 -0
  35. package/ambient/node-fallback/timers-promises.d.ts +31 -0
  36. package/ambient/node-fallback/timers.d.ts +28 -0
  37. package/ambient/node-fallback/tls.d.ts +169 -0
  38. package/ambient/node-fallback/url.d.ts +95 -0
  39. package/ambient/node-fallback/util-types.d.ts +50 -0
  40. package/ambient/node-fallback/util.d.ts +416 -0
  41. package/ambient/node-fallback/v8.d.ts +43 -0
  42. package/ambient/node-fallback/worker_threads.d.ts +113 -0
  43. package/ambient/node-fallback/zlib.d.ts +422 -0
  44. package/ambient/scriptc-node-fallback.d.ts +224 -6688
  45. package/dist/backend/cycle-analysis.js +4 -0
  46. package/dist/backend/cycle-analysis.js.map +1 -1
  47. package/dist/backend/executable-features.d.ts +1 -1
  48. package/dist/backend/executable-features.js +15 -2
  49. package/dist/backend/executable-features.js.map +1 -1
  50. package/dist/backend/huge-text.d.ts +16 -0
  51. package/dist/backend/huge-text.js +103 -0
  52. package/dist/backend/huge-text.js.map +1 -0
  53. package/dist/backend/huge-text.test.d.ts +1 -0
  54. package/dist/backend/huge-text.test.js +73 -0
  55. package/dist/backend/huge-text.test.js.map +1 -0
  56. package/dist/backend/library-pack.js +1 -1
  57. package/dist/backend/library-pack.js.map +1 -1
  58. package/dist/backend/link-plan-core.d.ts +10 -0
  59. package/dist/backend/link-plan-core.js +14 -2
  60. package/dist/backend/link-plan-core.js.map +1 -1
  61. package/dist/backend/link-plan-core.test.d.ts +1 -0
  62. package/dist/backend/link-plan-core.test.js +20 -0
  63. package/dist/backend/link-plan-core.test.js.map +1 -0
  64. package/dist/backend/link-plan.d.ts +8 -0
  65. package/dist/backend/link-plan.js +7 -0
  66. package/dist/backend/link-plan.js.map +1 -1
  67. package/dist/backend/linker.js +37 -14
  68. package/dist/backend/linker.js.map +1 -1
  69. package/dist/backend/lld.d.ts +13 -0
  70. package/dist/backend/lld.js +18 -1
  71. package/dist/backend/lld.js.map +1 -1
  72. package/dist/backend/lld.test.js +7 -1
  73. package/dist/backend/lld.test.js.map +1 -1
  74. package/dist/backend/llvm/alloc.d.ts +2 -0
  75. package/dist/backend/llvm/alloc.js +1 -1
  76. package/dist/backend/llvm/alloc.js.map +1 -1
  77. package/dist/backend/llvm/arenas.d.ts +78 -0
  78. package/dist/backend/llvm/arenas.js +313 -0
  79. package/dist/backend/llvm/arenas.js.map +1 -0
  80. package/dist/backend/llvm/arenas.test.d.ts +1 -0
  81. package/dist/backend/llvm/arenas.test.js +140 -0
  82. package/dist/backend/llvm/arenas.test.js.map +1 -0
  83. package/dist/backend/llvm/blocks.d.ts +11 -1
  84. package/dist/backend/llvm/blocks.js +23 -5
  85. package/dist/backend/llvm/blocks.js.map +1 -1
  86. package/dist/backend/llvm/bytes-headers.d.ts +19 -0
  87. package/dist/backend/llvm/bytes-headers.js +55 -0
  88. package/dist/backend/llvm/bytes-headers.js.map +1 -0
  89. package/dist/backend/llvm/bytes-loop-versions.d.ts +4 -3
  90. package/dist/backend/llvm/bytes-loop-versions.js +42 -7
  91. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
  92. package/dist/backend/llvm/bytes-loop-versions.test.js +39 -4
  93. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
  94. package/dist/backend/llvm/call-lifetimes.d.ts +5 -0
  95. package/dist/backend/llvm/call-lifetimes.js +43 -8
  96. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  97. package/dist/backend/llvm/call-lifetimes.test.js +26 -0
  98. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  99. package/dist/backend/llvm/checked-narrows.d.ts +3 -0
  100. package/dist/backend/llvm/checked-narrows.js +8 -1
  101. package/dist/backend/llvm/checked-narrows.js.map +1 -1
  102. package/dist/backend/llvm/class-unions.d.ts +21 -0
  103. package/dist/backend/llvm/class-unions.js +141 -0
  104. package/dist/backend/llvm/class-unions.js.map +1 -0
  105. package/dist/backend/llvm/class-unions.test.d.ts +1 -0
  106. package/dist/backend/llvm/class-unions.test.js +137 -0
  107. package/dist/backend/llvm/class-unions.test.js.map +1 -0
  108. package/dist/backend/llvm/classes.d.ts +46 -8
  109. package/dist/backend/llvm/classes.js +259 -32
  110. package/dist/backend/llvm/classes.js.map +1 -1
  111. package/dist/backend/llvm/classes.test.js +4 -0
  112. package/dist/backend/llvm/classes.test.js.map +1 -1
  113. package/dist/backend/llvm/common.d.ts +23 -0
  114. package/dist/backend/llvm/common.js +34 -0
  115. package/dist/backend/llvm/common.js.map +1 -1
  116. package/dist/backend/llvm/constant-callbacks.test.js +39 -0
  117. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  118. package/dist/backend/llvm/constant-choices.d.ts +32 -0
  119. package/dist/backend/llvm/constant-choices.js +209 -0
  120. package/dist/backend/llvm/constant-choices.js.map +1 -0
  121. package/dist/backend/llvm/constant-choices.test.d.ts +1 -0
  122. package/dist/backend/llvm/constant-choices.test.js +94 -0
  123. package/dist/backend/llvm/constant-choices.test.js.map +1 -0
  124. package/dist/backend/llvm/counted-loops.d.ts +14 -2
  125. package/dist/backend/llvm/counted-loops.js +60 -7
  126. package/dist/backend/llvm/counted-loops.js.map +1 -1
  127. package/dist/backend/llvm/counted-loops.test.d.ts +1 -0
  128. package/dist/backend/llvm/counted-loops.test.js +34 -0
  129. package/dist/backend/llvm/counted-loops.test.js.map +1 -0
  130. package/dist/backend/llvm/cpu-dispatch.d.ts +26 -0
  131. package/dist/backend/llvm/cpu-dispatch.js +279 -0
  132. package/dist/backend/llvm/cpu-dispatch.js.map +1 -0
  133. package/dist/backend/llvm/dense-array-access.d.ts +13 -2
  134. package/dist/backend/llvm/dense-array-access.js +60 -6
  135. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  136. package/dist/backend/llvm/dyn-handle-tags.test.js +40 -14
  137. package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -1
  138. package/dist/backend/llvm/dyn.d.ts +28 -2
  139. package/dist/backend/llvm/dyn.js +176 -27
  140. package/dist/backend/llvm/dyn.js.map +1 -1
  141. package/dist/backend/llvm/emit-function.js +25 -3
  142. package/dist/backend/llvm/emit-function.js.map +1 -1
  143. package/dist/backend/llvm/emit-journal.d.ts +1 -0
  144. package/dist/backend/llvm/emit-journal.js.map +1 -1
  145. package/dist/backend/llvm/emit-module.d.ts +5 -3
  146. package/dist/backend/llvm/emit-module.js +362 -74
  147. package/dist/backend/llvm/emit-module.js.map +1 -1
  148. package/dist/backend/llvm/emit-statements.js +327 -59
  149. package/dist/backend/llvm/emit-statements.js.map +1 -1
  150. package/dist/backend/llvm/emitter.d.ts +223 -33
  151. package/dist/backend/llvm/emitter.js +713 -100
  152. package/dist/backend/llvm/emitter.js.map +1 -1
  153. package/dist/backend/llvm/emitter.test.js +20 -1
  154. package/dist/backend/llvm/emitter.test.js.map +1 -1
  155. package/dist/backend/llvm/expr-async.js +32 -6
  156. package/dist/backend/llvm/expr-async.js.map +1 -1
  157. package/dist/backend/llvm/expr-bytes.d.ts +9 -1
  158. package/dist/backend/llvm/expr-bytes.js +105 -9
  159. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  160. package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
  161. package/dist/backend/llvm/expr-callbacks.js +29 -22
  162. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  163. package/dist/backend/llvm/expr-calls.d.ts +0 -4
  164. package/dist/backend/llvm/expr-calls.js +116 -14
  165. package/dist/backend/llvm/expr-calls.js.map +1 -1
  166. package/dist/backend/llvm/expr-containers.js +77 -12
  167. package/dist/backend/llvm/expr-containers.js.map +1 -1
  168. package/dist/backend/llvm/expr-context.d.ts +22 -0
  169. package/dist/backend/llvm/expr-control.d.ts +4 -0
  170. package/dist/backend/llvm/expr-control.js +485 -426
  171. package/dist/backend/llvm/expr-control.js.map +1 -1
  172. package/dist/backend/llvm/expr-dispatch.js +4 -0
  173. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  174. package/dist/backend/llvm/expr-dynamic.js +3 -3
  175. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  176. package/dist/backend/llvm/expr-primitives.d.ts +6 -0
  177. package/dist/backend/llvm/expr-primitives.js +119 -58
  178. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  179. package/dist/backend/llvm/expr-primitives.test.js +11 -2
  180. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  181. package/dist/backend/llvm/expr-records.d.ts +36 -4
  182. package/dist/backend/llvm/expr-records.js +249 -37
  183. package/dist/backend/llvm/expr-records.js.map +1 -1
  184. package/dist/backend/llvm/expr-stream-bridges.js +124 -7
  185. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  186. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  187. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
  188. package/dist/backend/llvm/expr-stream-callbacks.js +13 -14
  189. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  190. package/dist/backend/llvm/frame-escapes.d.ts +11 -0
  191. package/dist/backend/llvm/frame-escapes.js +219 -0
  192. package/dist/backend/llvm/frame-escapes.js.map +1 -0
  193. package/dist/backend/llvm/function-layout.d.ts +15 -0
  194. package/dist/backend/llvm/function-layout.js +40 -0
  195. package/dist/backend/llvm/function-layout.js.map +1 -0
  196. package/dist/backend/llvm/heap-census.d.ts +34 -0
  197. package/dist/backend/llvm/heap-census.js +163 -0
  198. package/dist/backend/llvm/heap-census.js.map +1 -0
  199. package/dist/backend/llvm/inline-arrays.d.ts +41 -0
  200. package/dist/backend/llvm/inline-arrays.js +195 -0
  201. package/dist/backend/llvm/inline-arrays.js.map +1 -0
  202. package/dist/backend/llvm/int32-kind-loops.js +2 -0
  203. package/dist/backend/llvm/int32-kind-loops.js.map +1 -1
  204. package/dist/backend/llvm/integer-clones.d.ts +32 -5
  205. package/dist/backend/llvm/integer-clones.js +237 -44
  206. package/dist/backend/llvm/integer-clones.js.map +1 -1
  207. package/dist/backend/llvm/integer-clones.test.js +120 -0
  208. package/dist/backend/llvm/integer-clones.test.js.map +1 -1
  209. package/dist/backend/llvm/iterative-teardown.test.d.ts +1 -0
  210. package/dist/backend/llvm/iterative-teardown.test.js +62 -0
  211. package/dist/backend/llvm/iterative-teardown.test.js.map +1 -0
  212. package/dist/backend/llvm/js-ic.js +246 -62
  213. package/dist/backend/llvm/js-ic.js.map +1 -1
  214. package/dist/backend/llvm/lib-connect.js +1 -1
  215. package/dist/backend/llvm/lib-connect.js.map +1 -1
  216. package/dist/backend/llvm/lib-datagram.js +2 -2
  217. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  218. package/dist/backend/llvm/lib-dispatch.js +153 -16
  219. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  220. package/dist/backend/llvm/lib-filesystem.d.ts +8 -0
  221. package/dist/backend/llvm/lib-filesystem.js +48 -4
  222. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  223. package/dist/backend/llvm/lib-http2.js +4 -3
  224. package/dist/backend/llvm/lib-http2.js.map +1 -1
  225. package/dist/backend/llvm/lib-lookup.js +1 -1
  226. package/dist/backend/llvm/lib-lookup.js.map +1 -1
  227. package/dist/backend/llvm/lib-network.js +15 -1
  228. package/dist/backend/llvm/lib-network.js.map +1 -1
  229. package/dist/backend/llvm/lib-process.js +32 -8
  230. package/dist/backend/llvm/lib-process.js.map +1 -1
  231. package/dist/backend/llvm/lib-shared.d.ts +3 -0
  232. package/dist/backend/llvm/lib-shared.js +191 -28
  233. package/dist/backend/llvm/lib-shared.js.map +1 -1
  234. package/dist/backend/llvm/lib-stream.js +1 -1
  235. package/dist/backend/llvm/lib-stream.js.map +1 -1
  236. package/dist/backend/llvm/local-array-reads.js +15 -1
  237. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  238. package/dist/backend/llvm/local-array-reads.test.js +1 -1
  239. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  240. package/dist/backend/llvm/local-extents.d.ts +22 -0
  241. package/dist/backend/llvm/local-extents.js +102 -0
  242. package/dist/backend/llvm/local-extents.js.map +1 -1
  243. package/dist/backend/llvm/local-union-storage.js +15 -2
  244. package/dist/backend/llvm/local-union-storage.js.map +1 -1
  245. package/dist/backend/llvm/local-union-storage.test.js +1 -1
  246. package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
  247. package/dist/backend/llvm/loop-callees.d.ts +21 -0
  248. package/dist/backend/llvm/loop-callees.js +119 -0
  249. package/dist/backend/llvm/loop-callees.js.map +1 -0
  250. package/dist/backend/llvm/loop-callees.test.d.ts +1 -0
  251. package/dist/backend/llvm/loop-callees.test.js +65 -0
  252. package/dist/backend/llvm/loop-callees.test.js.map +1 -0
  253. package/dist/backend/llvm/loop-entry-versions.d.ts +17 -0
  254. package/dist/backend/llvm/loop-entry-versions.js +185 -0
  255. package/dist/backend/llvm/loop-entry-versions.js.map +1 -0
  256. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  257. package/dist/backend/llvm/map-number-lookup.test.js +13 -4
  258. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  259. package/dist/backend/llvm/map-read-lifetimes.d.ts +11 -0
  260. package/dist/backend/llvm/map-read-lifetimes.js +51 -1
  261. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  262. package/dist/backend/llvm/map-read-lifetimes.test.js +6 -3
  263. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
  264. package/dist/backend/llvm/nullable-unions.d.ts +67 -10
  265. package/dist/backend/llvm/nullable-unions.js +218 -22
  266. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  267. package/dist/backend/llvm/nullable-unions.test.js +124 -1
  268. package/dist/backend/llvm/nullable-unions.test.js.map +1 -1
  269. package/dist/backend/llvm/periodic-guards.d.ts +16 -0
  270. package/dist/backend/llvm/periodic-guards.js +91 -0
  271. package/dist/backend/llvm/periodic-guards.js.map +1 -0
  272. package/dist/backend/llvm/periodic-guards.test.d.ts +1 -0
  273. package/dist/backend/llvm/periodic-guards.test.js +64 -0
  274. package/dist/backend/llvm/periodic-guards.test.js.map +1 -0
  275. package/dist/backend/llvm/publish.d.ts +12 -2
  276. package/dist/backend/llvm/publish.js +15 -8
  277. package/dist/backend/llvm/publish.js.map +1 -1
  278. package/dist/backend/llvm/rebound-parameters.d.ts +4 -1
  279. package/dist/backend/llvm/rebound-parameters.js +17 -1
  280. package/dist/backend/llvm/rebound-parameters.js.map +1 -1
  281. package/dist/backend/llvm/receivers.d.ts +7 -0
  282. package/dist/backend/llvm/receivers.js +77 -10
  283. package/dist/backend/llvm/receivers.js.map +1 -1
  284. package/dist/backend/llvm/record-union-keys.test.js +29 -0
  285. package/dist/backend/llvm/record-union-keys.test.js.map +1 -1
  286. package/dist/backend/llvm/record-views.d.ts +29 -0
  287. package/dist/backend/llvm/record-views.js +249 -0
  288. package/dist/backend/llvm/record-views.js.map +1 -0
  289. package/dist/backend/llvm/record-views.test.d.ts +1 -0
  290. package/dist/backend/llvm/record-views.test.js +118 -0
  291. package/dist/backend/llvm/record-views.test.js.map +1 -0
  292. package/dist/backend/llvm/reference-writes.js +21 -0
  293. package/dist/backend/llvm/reference-writes.js.map +1 -1
  294. package/dist/backend/llvm/reference-writes.test.js +42 -0
  295. package/dist/backend/llvm/reference-writes.test.js.map +1 -1
  296. package/dist/backend/llvm/regex-matchers.d.ts +5 -1
  297. package/dist/backend/llvm/regex-matchers.js +173 -21
  298. package/dist/backend/llvm/regex-matchers.js.map +1 -1
  299. package/dist/backend/llvm/regex-matchers.test.js +39 -1
  300. package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
  301. package/dist/backend/llvm/region-groups.d.ts +67 -0
  302. package/dist/backend/llvm/region-groups.js +1719 -0
  303. package/dist/backend/llvm/region-groups.js.map +1 -0
  304. package/dist/backend/llvm/region-groups.test.d.ts +1 -0
  305. package/dist/backend/llvm/region-groups.test.js +197 -0
  306. package/dist/backend/llvm/region-groups.test.js.map +1 -0
  307. package/dist/backend/llvm/region-ir.d.ts +31 -0
  308. package/dist/backend/llvm/region-ir.js +256 -0
  309. package/dist/backend/llvm/region-ir.js.map +1 -0
  310. package/dist/backend/llvm/region-sites.d.ts +20 -0
  311. package/dist/backend/llvm/region-sites.js +327 -0
  312. package/dist/backend/llvm/region-sites.js.map +1 -0
  313. package/dist/backend/llvm/region-sites.test.d.ts +1 -0
  314. package/dist/backend/llvm/region-sites.test.js +216 -0
  315. package/dist/backend/llvm/region-sites.test.js.map +1 -0
  316. package/dist/backend/llvm/repr-report.d.ts +9 -0
  317. package/dist/backend/llvm/repr-report.js +143 -0
  318. package/dist/backend/llvm/repr-report.js.map +1 -0
  319. package/dist/backend/llvm/repr-report.test.d.ts +1 -0
  320. package/dist/backend/llvm/repr-report.test.js +62 -0
  321. package/dist/backend/llvm/repr-report.test.js.map +1 -0
  322. package/dist/backend/llvm/runtime-registries.test.d.ts +1 -0
  323. package/dist/backend/llvm/runtime-registries.test.js +88 -0
  324. package/dist/backend/llvm/runtime-registries.test.js.map +1 -0
  325. package/dist/backend/llvm/serialized-ir-emission.test.js +1 -0
  326. package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -1
  327. package/dist/backend/llvm/shape-union-tags.test.d.ts +1 -0
  328. package/dist/backend/llvm/shape-union-tags.test.js +75 -0
  329. package/dist/backend/llvm/shape-union-tags.test.js.map +1 -0
  330. package/dist/backend/llvm/shapes.d.ts +60 -10
  331. package/dist/backend/llvm/shapes.js +233 -51
  332. package/dist/backend/llvm/shapes.js.map +1 -1
  333. package/dist/backend/llvm/shapes.test.js +37 -18
  334. package/dist/backend/llvm/shapes.test.js.map +1 -1
  335. package/dist/backend/llvm/speculative-integers.d.ts +3 -0
  336. package/dist/backend/llvm/speculative-integers.js +20 -8
  337. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  338. package/dist/backend/llvm/split.js +6 -1
  339. package/dist/backend/llvm/split.js.map +1 -1
  340. package/dist/backend/llvm/split.test.js +23 -0
  341. package/dist/backend/llvm/split.test.js.map +1 -1
  342. package/dist/backend/llvm/stack-callbacks.js +4 -2
  343. package/dist/backend/llvm/stack-callbacks.js.map +1 -1
  344. package/dist/backend/llvm/stack-objects.d.ts +12 -3
  345. package/dist/backend/llvm/stack-objects.js +110 -22
  346. package/dist/backend/llvm/stack-objects.js.map +1 -1
  347. package/dist/backend/llvm/stack-objects.test.js +144 -0
  348. package/dist/backend/llvm/stack-objects.test.js.map +1 -1
  349. package/dist/backend/llvm/stack-unions.test.js +24 -1
  350. package/dist/backend/llvm/stack-unions.test.js.map +1 -1
  351. package/dist/backend/llvm/string-lifetimes.js +2 -1
  352. package/dist/backend/llvm/string-lifetimes.js.map +1 -1
  353. package/dist/backend/llvm/string-lifetimes.test.js +1 -1
  354. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  355. package/dist/backend/llvm/string-reads.d.ts +4 -0
  356. package/dist/backend/llvm/string-reads.js +27 -0
  357. package/dist/backend/llvm/string-reads.js.map +1 -1
  358. package/dist/backend/llvm/test-boxed-unions.d.ts +10 -8
  359. package/dist/backend/llvm/test-boxed-unions.js +20 -25
  360. package/dist/backend/llvm/test-boxed-unions.js.map +1 -1
  361. package/dist/backend/llvm/union-repr.js +9 -8
  362. package/dist/backend/llvm/union-repr.js.map +1 -1
  363. package/dist/backend/llvm/union-retype.test.js +45 -2
  364. package/dist/backend/llvm/union-retype.test.js.map +1 -1
  365. package/dist/backend/llvm/unwind-abi.d.ts +20 -8
  366. package/dist/backend/llvm/unwind-abi.js +177 -70
  367. package/dist/backend/llvm/unwind-abi.js.map +1 -1
  368. package/dist/backend/llvm/unwind-abi.test.js +90 -3
  369. package/dist/backend/llvm/unwind-abi.test.js.map +1 -1
  370. package/dist/backend/llvm/walk-borrows.d.ts +3 -2
  371. package/dist/backend/llvm/walk-borrows.js +2 -2
  372. package/dist/backend/llvm/walk-borrows.js.map +1 -1
  373. package/dist/backend/llvm/walk-borrows.test.js +18 -0
  374. package/dist/backend/llvm/walk-borrows.test.js.map +1 -1
  375. package/dist/backend/llvm/walkers.d.ts +14 -1
  376. package/dist/backend/llvm/walkers.js +103 -11
  377. package/dist/backend/llvm/walkers.js.map +1 -1
  378. package/dist/backend/llvm/wrapping-sums.d.ts +26 -6
  379. package/dist/backend/llvm/wrapping-sums.js +64 -12
  380. package/dist/backend/llvm/wrapping-sums.js.map +1 -1
  381. package/dist/backend/loop-polls.d.ts +4 -2
  382. package/dist/backend/loop-polls.js +11 -2
  383. package/dist/backend/loop-polls.js.map +1 -1
  384. package/dist/backend/mangle.d.ts +0 -5
  385. package/dist/backend/mangle.js +0 -9
  386. package/dist/backend/mangle.js.map +1 -1
  387. package/dist/backend/may-throw.d.ts +10 -9
  388. package/dist/backend/may-throw.js +189 -27
  389. package/dist/backend/may-throw.js.map +1 -1
  390. package/dist/backend/may-throw.test.js +44 -7
  391. package/dist/backend/may-throw.test.js.map +1 -1
  392. package/dist/backend/native/compiler-fingerprint.d.ts +5 -0
  393. package/dist/backend/native/compiler-fingerprint.js +62 -16
  394. package/dist/backend/native/compiler-fingerprint.js.map +1 -1
  395. package/dist/backend/native/contracts.d.ts +31 -8
  396. package/dist/backend/native/executable.js +56 -32
  397. package/dist/backend/native/executable.js.map +1 -1
  398. package/dist/backend/native/library.js +3 -4
  399. package/dist/backend/native/library.js.map +1 -1
  400. package/dist/backend/native/object-merge.d.ts +3 -1
  401. package/dist/backend/native/object-merge.js +24 -11
  402. package/dist/backend/native/object-merge.js.map +1 -1
  403. package/dist/backend/native/program-shards.js +6 -3
  404. package/dist/backend/native/program-shards.js.map +1 -1
  405. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  406. package/dist/backend/native/runtime-inputs.js +3 -0
  407. package/dist/backend/native/runtime-inputs.js.map +1 -1
  408. package/dist/backend/native/vendor.d.ts +1 -1
  409. package/dist/backend/native-codegen-core.d.ts +15 -6
  410. package/dist/backend/native-codegen-core.js +20 -9
  411. package/dist/backend/native-codegen-core.js.map +1 -1
  412. package/dist/backend/native-codegen.js +51 -5
  413. package/dist/backend/native-codegen.js.map +1 -1
  414. package/dist/backend/native-codegen.test.js +82 -8
  415. package/dist/backend/native-codegen.test.js.map +1 -1
  416. package/dist/backend/native-link-info-core.d.ts +30 -0
  417. package/dist/backend/native-link-info-core.js.map +1 -1
  418. package/dist/backend/native-profile.d.ts +68 -4
  419. package/dist/backend/native-profile.js +86 -14
  420. package/dist/backend/native-profile.js.map +1 -1
  421. package/dist/backend/native-profile.test.js +127 -4
  422. package/dist/backend/native-profile.test.js.map +1 -1
  423. package/dist/backend/native-toolchain.d.ts +1 -1
  424. package/dist/backend/native-toolchain.js +1 -1
  425. package/dist/backend/native-toolchain.js.map +1 -1
  426. package/dist/backend/native-toolchain.test.js +58 -4
  427. package/dist/backend/native-toolchain.test.js.map +1 -1
  428. package/dist/backend/native-tools.d.ts +17 -3
  429. package/dist/backend/native-tools.js +12 -4
  430. package/dist/backend/native-tools.js.map +1 -1
  431. package/dist/backend/native-tools.test.d.ts +1 -0
  432. package/dist/backend/native-tools.test.js +76 -0
  433. package/dist/backend/native-tools.test.js.map +1 -0
  434. package/dist/backend/object-localize.js +69 -9
  435. package/dist/backend/object-localize.js.map +1 -1
  436. package/dist/backend/object-localize.test.js +99 -10
  437. package/dist/backend/object-localize.test.js.map +1 -1
  438. package/dist/backend/publication.d.ts +2 -0
  439. package/dist/backend/publication.js +4 -0
  440. package/dist/backend/publication.js.map +1 -1
  441. package/dist/backend/runtime-abi.d.ts +2 -2
  442. package/dist/backend/runtime-abi.js +2 -2
  443. package/dist/backend/runtime-pack-core.d.ts +19 -0
  444. package/dist/backend/runtime-pack-core.js +23 -3
  445. package/dist/backend/runtime-pack-core.js.map +1 -1
  446. package/dist/backend/runtime-pack-targets.test.js +1 -1
  447. package/dist/backend/runtime-pack.test.js +48 -2
  448. package/dist/backend/runtime-pack.test.js.map +1 -1
  449. package/dist/backend/target-cpu.d.ts +2 -0
  450. package/dist/backend/target-cpu.js +4 -0
  451. package/dist/backend/target-cpu.js.map +1 -1
  452. package/dist/backend/target-diagnostics.js +1 -19
  453. package/dist/backend/target-diagnostics.js.map +1 -1
  454. package/dist/backend/target-diagnostics.test.js +1 -1
  455. package/dist/backend/target-diagnostics.test.js.map +1 -1
  456. package/dist/backend/targets.d.ts +28 -0
  457. package/dist/backend/targets.js +70 -0
  458. package/dist/backend/targets.js.map +1 -1
  459. package/dist/backend/targets.test.js +75 -1
  460. package/dist/backend/targets.test.js.map +1 -1
  461. package/dist/backend/vendor-archives.d.ts +1 -1
  462. package/dist/backend/vendor-archives.js +25 -12
  463. package/dist/backend/vendor-archives.js.map +1 -1
  464. package/dist/backend/vendor-inputs.d.ts +15 -2
  465. package/dist/backend/vendor-inputs.js +59 -3
  466. package/dist/backend/vendor-inputs.js.map +1 -1
  467. package/dist/backend/vendor-inputs.test.d.ts +1 -0
  468. package/dist/backend/vendor-inputs.test.js +74 -0
  469. package/dist/backend/vendor-inputs.test.js.map +1 -0
  470. package/dist/cli/command.js +95 -5
  471. package/dist/cli/command.js.map +1 -1
  472. package/dist/cli/host.d.ts +3 -0
  473. package/dist/cli/output-options.d.ts +3 -0
  474. package/dist/cli/output-options.js +8 -2
  475. package/dist/cli/output-options.js.map +1 -1
  476. package/dist/cli/usage.d.ts +28 -1
  477. package/dist/cli/usage.js +56 -6
  478. package/dist/cli/usage.js.map +1 -1
  479. package/dist/compat/fetch-profile.d.ts +3 -0
  480. package/dist/compat/fetch-profile.js +23 -3
  481. package/dist/compat/fetch-profile.js.map +1 -1
  482. package/dist/compile-types.d.ts +45 -0
  483. package/dist/contracts/check.js +70 -2
  484. package/dist/contracts/check.js.map +1 -1
  485. package/dist/contracts/int32-elements.d.ts +2 -1
  486. package/dist/contracts/int32-elements.js.map +1 -1
  487. package/dist/coverage/report.d.ts +5 -1
  488. package/dist/coverage/report.js +83 -2
  489. package/dist/coverage/report.js.map +1 -1
  490. package/dist/coverage/verdict-cache.d.ts +2 -0
  491. package/dist/coverage/verdict-cache.js +5 -10
  492. package/dist/coverage/verdict-cache.js.map +1 -1
  493. package/dist/diagnostics/codes.d.ts +145 -0
  494. package/dist/diagnostics/codes.js +159 -0
  495. package/dist/diagnostics/codes.js.map +1 -0
  496. package/dist/diagnostics/codes.test.d.ts +1 -0
  497. package/dist/diagnostics/codes.test.js +78 -0
  498. package/dist/diagnostics/codes.test.js.map +1 -0
  499. package/dist/diagnostics/diagnostic.d.ts +101 -2
  500. package/dist/diagnostics/diagnostic.js +155 -0
  501. package/dist/diagnostics/diagnostic.js.map +1 -1
  502. package/dist/diagnostics/dynamic-slots.d.ts +23 -0
  503. package/dist/diagnostics/dynamic-slots.js +29 -0
  504. package/dist/diagnostics/dynamic-slots.js.map +1 -0
  505. package/dist/diagnostics/dynamic-tier.d.ts +6 -0
  506. package/dist/diagnostics/dynamic-tier.js +8 -1
  507. package/dist/diagnostics/dynamic-tier.js.map +1 -1
  508. package/dist/diagnostics/envelope.d.ts +43 -1
  509. package/dist/diagnostics/envelope.js +19 -1
  510. package/dist/diagnostics/envelope.js.map +1 -1
  511. package/dist/diagnostics/envelope.test.js.map +1 -1
  512. package/dist/diagnostics/render.d.ts +3 -1
  513. package/dist/diagnostics/render.js +27 -6
  514. package/dist/diagnostics/render.js.map +1 -1
  515. package/dist/executable/executable-cache.d.ts +41 -0
  516. package/dist/executable/executable-cache.js +39 -1
  517. package/dist/executable/executable-cache.js.map +1 -1
  518. package/dist/executable/executable-cache.test.js +4 -1
  519. package/dist/executable/executable-cache.test.js.map +1 -1
  520. package/dist/executable/prepare.d.ts +2 -1
  521. package/dist/executable/prepare.js +421 -10
  522. package/dist/executable/prepare.js.map +1 -1
  523. package/dist/frontend/analysis.js +1 -0
  524. package/dist/frontend/analysis.js.map +1 -1
  525. package/dist/frontend/canon-map.d.ts +17 -0
  526. package/dist/frontend/canon-map.js +177 -0
  527. package/dist/frontend/canon-map.js.map +1 -0
  528. package/dist/frontend/canon.d.ts +122 -0
  529. package/dist/frontend/canon.js +462 -0
  530. package/dist/frontend/canon.js.map +1 -0
  531. package/dist/frontend/contract-types.d.ts +9 -1
  532. package/dist/frontend/contract-types.js +46 -4
  533. package/dist/frontend/contract-types.js.map +1 -1
  534. package/dist/frontend/decl-projection.d.ts +3 -0
  535. package/dist/frontend/decl-projection.js +121 -3
  536. package/dist/frontend/decl-projection.js.map +1 -1
  537. package/dist/frontend/dts-paths.d.ts +17 -4
  538. package/dist/frontend/dts-paths.js +149 -5
  539. package/dist/frontend/dts-paths.js.map +1 -1
  540. package/dist/frontend/fork-target.js +4 -4
  541. package/dist/frontend/fork-target.js.map +1 -1
  542. package/dist/frontend/fork-target.test.js +3 -3
  543. package/dist/frontend/fork-target.test.js.map +1 -1
  544. package/dist/frontend/heritage-elements.d.ts +15 -0
  545. package/dist/frontend/heritage-elements.js +18 -0
  546. package/dist/frontend/heritage-elements.js.map +1 -0
  547. package/dist/frontend/heritage-elements.test.d.ts +1 -0
  548. package/dist/frontend/heritage-elements.test.js +68 -0
  549. package/dist/frontend/heritage-elements.test.js.map +1 -0
  550. package/dist/frontend/input-tracker.d.ts +20 -0
  551. package/dist/frontend/input-tracker.js +74 -4
  552. package/dist/frontend/input-tracker.js.map +1 -1
  553. package/dist/frontend/input-tracker.test.js +66 -0
  554. package/dist/frontend/input-tracker.test.js.map +1 -1
  555. package/dist/frontend/lowering/any-collection-residue.d.ts +9 -0
  556. package/dist/frontend/lowering/any-collection-residue.js +42 -0
  557. package/dist/frontend/lowering/any-collection-residue.js.map +1 -0
  558. package/dist/frontend/lowering/array-values.d.ts +44 -2
  559. package/dist/frontend/lowering/array-values.js +193 -3
  560. package/dist/frontend/lowering/array-values.js.map +1 -1
  561. package/dist/frontend/lowering/builtin-namespaces.d.ts +6 -2
  562. package/dist/frontend/lowering/builtin-namespaces.js +28 -6
  563. package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
  564. package/dist/frontend/lowering/builtins/array-classes.d.ts +69 -0
  565. package/dist/frontend/lowering/builtins/array-classes.js +729 -0
  566. package/dist/frontend/lowering/builtins/array-classes.js.map +1 -0
  567. package/dist/frontend/lowering/builtins/callable-aliases.js +4 -0
  568. package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
  569. package/dist/frontend/lowering/builtins/child-process-methods.js +34 -0
  570. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  571. package/dist/frontend/lowering/builtins/disposable-stack.js +1 -3
  572. package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -1
  573. package/dist/frontend/lowering/builtins/errors.d.ts +13 -9
  574. package/dist/frontend/lowering/builtins/errors.js +136 -56
  575. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  576. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +1 -0
  577. package/dist/frontend/lowering/builtins/filesystem-calls.js +85 -4
  578. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  579. package/dist/frontend/lowering/builtins/filesystem.d.ts +11 -6
  580. package/dist/frontend/lowering/builtins/filesystem.js +270 -24
  581. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  582. package/dist/frontend/lowering/builtins/json.js +7 -1
  583. package/dist/frontend/lowering/builtins/json.js.map +1 -1
  584. package/dist/frontend/lowering/builtins/mime.d.ts +25 -0
  585. package/dist/frontend/lowering/builtins/mime.js +167 -0
  586. package/dist/frontend/lowering/builtins/mime.js.map +1 -0
  587. package/dist/frontend/lowering/builtins/module-bindings.d.ts +3 -0
  588. package/dist/frontend/lowering/builtins/module-bindings.js +6 -0
  589. package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
  590. package/dist/frontend/lowering/builtins/module-calls.js +79 -12
  591. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  592. package/dist/frontend/lowering/builtins/module-resolution.d.ts +7 -4
  593. package/dist/frontend/lowering/builtins/module-resolution.js +115 -13
  594. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
  595. package/dist/frontend/lowering/builtins/navigator.d.ts +3 -1
  596. package/dist/frontend/lowering/builtins/navigator.js +22 -8
  597. package/dist/frontend/lowering/builtins/navigator.js.map +1 -1
  598. package/dist/frontend/lowering/builtins/process.js +49 -9
  599. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  600. package/dist/frontend/lowering/builtins/promises.js +18 -3
  601. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  602. package/dist/frontend/lowering/builtins/promisify-callback.d.ts +6 -2
  603. package/dist/frontend/lowering/builtins/promisify-callback.js +19 -6
  604. package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -1
  605. package/dist/frontend/lowering/builtins/properties.js +23 -5
  606. package/dist/frontend/lowering/builtins/properties.js.map +1 -1
  607. package/dist/frontend/lowering/builtins/web-streams-dyn.d.ts +42 -0
  608. package/dist/frontend/lowering/builtins/web-streams-dyn.js +321 -0
  609. package/dist/frontend/lowering/builtins/web-streams-dyn.js.map +1 -0
  610. package/dist/frontend/lowering/builtins/x509.js +35 -5
  611. package/dist/frontend/lowering/builtins/x509.js.map +1 -1
  612. package/dist/frontend/lowering/call-arguments.d.ts +14 -1
  613. package/dist/frontend/lowering/call-arguments.js +84 -70
  614. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  615. package/dist/frontend/lowering/call-signatures.js +108 -24
  616. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  617. package/dist/frontend/lowering/class-attributes.js +6 -5
  618. package/dist/frontend/lowering/class-attributes.js.map +1 -1
  619. package/dist/frontend/lowering/class-dynamic-dispatch.js +40 -19
  620. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  621. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +1 -0
  622. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  623. package/dist/frontend/lowering/class-protocol-dispatch.js +4 -0
  624. package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
  625. package/dist/frontend/lowering/class-protocols.d.ts +61 -1
  626. package/dist/frontend/lowering/class-protocols.js +297 -21
  627. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  628. package/dist/frontend/lowering/class-to-primitive.d.ts +3 -2
  629. package/dist/frontend/lowering/class-to-primitive.js +15 -5
  630. package/dist/frontend/lowering/class-to-primitive.js.map +1 -1
  631. package/dist/frontend/lowering/coercions/asserted.d.ts +16 -0
  632. package/dist/frontend/lowering/coercions/asserted.js +79 -0
  633. package/dist/frontend/lowering/coercions/asserted.js.map +1 -0
  634. package/dist/frontend/lowering/coercions/function-adapters.d.ts +13 -0
  635. package/dist/frontend/lowering/coercions/function-adapters.js +70 -3
  636. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  637. package/dist/frontend/lowering/coercions/state.d.ts +23 -0
  638. package/dist/frontend/lowering/coercions/state.js +9 -0
  639. package/dist/frontend/lowering/coercions/state.js.map +1 -1
  640. package/dist/frontend/lowering/coercions/structural-plans.js +67 -1
  641. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  642. package/dist/frontend/lowering/coercions/structural.d.ts +10 -0
  643. package/dist/frontend/lowering/coercions/structural.js +134 -4
  644. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  645. package/dist/frontend/lowering/coercions/unions.d.ts +11 -0
  646. package/dist/frontend/lowering/coercions/unions.js +83 -4
  647. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  648. package/dist/frontend/lowering/completion-callbacks.js +3 -2
  649. package/dist/frontend/lowering/completion-callbacks.js.map +1 -1
  650. package/dist/frontend/lowering/containers/array-callbacks.d.ts +10 -0
  651. package/dist/frontend/lowering/containers/array-callbacks.js +224 -81
  652. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  653. package/dist/frontend/lowering/containers/array-concat.d.ts +5 -2
  654. package/dist/frontend/lowering/containers/array-concat.js +76 -7
  655. package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
  656. package/dist/frontend/lowering/containers/array-construction.d.ts +9 -4
  657. package/dist/frontend/lowering/containers/array-construction.js +112 -100
  658. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  659. package/dist/frontend/lowering/containers/array-methods.js +193 -45
  660. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  661. package/dist/frontend/lowering/containers/array-pipelines.d.ts +3 -0
  662. package/dist/frontend/lowering/containers/array-pipelines.js +81 -13
  663. package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
  664. package/dist/frontend/lowering/containers/callback-arguments.d.ts +1 -0
  665. package/dist/frontend/lowering/containers/callback-arguments.js +28 -2
  666. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  667. package/dist/frontend/lowering/containers/collection-methods.js +13 -3
  668. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  669. package/dist/frontend/lowering/containers/filter-predicates.js +34 -3
  670. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
  671. package/dist/frontend/lowering/containers/indexed-objects.d.ts +34 -1
  672. package/dist/frontend/lowering/containers/indexed-objects.js +131 -72
  673. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  674. package/dist/frontend/lowering/cycle-initialization.js +43 -6
  675. package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
  676. package/dist/frontend/lowering/decl-origin.d.ts +49 -0
  677. package/dist/frontend/lowering/decl-origin.js +402 -0
  678. package/dist/frontend/lowering/decl-origin.js.map +1 -0
  679. package/dist/frontend/lowering/deferred-module-initializers.d.ts +2 -0
  680. package/dist/frontend/lowering/deferred-module-initializers.js +7 -0
  681. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
  682. package/dist/frontend/lowering/divergences.js +5 -0
  683. package/dist/frontend/lowering/divergences.js.map +1 -1
  684. package/dist/frontend/lowering/dynamic-tier.d.ts +8 -2
  685. package/dist/frontend/lowering/dynamic-tier.js +111 -3
  686. package/dist/frontend/lowering/dynamic-tier.js.map +1 -1
  687. package/dist/frontend/lowering/expressions/array-literals.d.ts +14 -1
  688. package/dist/frontend/lowering/expressions/array-literals.js +43 -5
  689. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  690. package/dist/frontend/lowering/expressions/asserted-receiver.d.ts +48 -0
  691. package/dist/frontend/lowering/expressions/asserted-receiver.js +233 -0
  692. package/dist/frontend/lowering/expressions/asserted-receiver.js.map +1 -0
  693. package/dist/frontend/lowering/expressions/binary.js +136 -1
  694. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  695. package/dist/frontend/lowering/expressions/element-access.d.ts +7 -0
  696. package/dist/frontend/lowering/expressions/element-access.js +363 -12
  697. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  698. package/dist/frontend/lowering/expressions/identifiers.d.ts +3 -0
  699. package/dist/frontend/lowering/expressions/identifiers.js +78 -62
  700. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  701. package/dist/frontend/lowering/expressions/message-listeners.d.ts +3 -0
  702. package/dist/frontend/lowering/expressions/message-listeners.js +19 -0
  703. package/dist/frontend/lowering/expressions/message-listeners.js.map +1 -0
  704. package/dist/frontend/lowering/expressions/narrowing.js +224 -6
  705. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  706. package/dist/frontend/lowering/expressions/nullish-assignment.js +5 -2
  707. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  708. package/dist/frontend/lowering/expressions/object-literals.d.ts +1 -1
  709. package/dist/frontend/lowering/expressions/object-literals.js +282 -24
  710. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  711. package/dist/frontend/lowering/expressions/property-access.d.ts +15 -3
  712. package/dist/frontend/lowering/expressions/property-access.js +397 -74
  713. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  714. package/dist/frontend/lowering/expressions/relational.js +202 -70
  715. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  716. package/dist/frontend/lowering/expressions/typeof.js +9 -1
  717. package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
  718. package/dist/frontend/lowering/expressions/union-fields.d.ts +28 -8
  719. package/dist/frontend/lowering/expressions/union-fields.js +168 -14
  720. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  721. package/dist/frontend/lowering/frozen-records.d.ts +8 -0
  722. package/dist/frontend/lowering/frozen-records.js +56 -9
  723. package/dist/frontend/lowering/frozen-records.js.map +1 -1
  724. package/dist/frontend/lowering/function-context.d.ts +3 -0
  725. package/dist/frontend/lowering/function-context.js +4 -1
  726. package/dist/frontend/lowering/function-context.js.map +1 -1
  727. package/dist/frontend/lowering/function-returns.d.ts +4 -0
  728. package/dist/frontend/lowering/function-returns.js +231 -2
  729. package/dist/frontend/lowering/function-returns.js.map +1 -1
  730. package/dist/frontend/lowering/generator-delegation.js +3 -2
  731. package/dist/frontend/lowering/generator-delegation.js.map +1 -1
  732. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +26 -0
  733. package/dist/frontend/lowering/generator-dynamic-dispatch.js +294 -2
  734. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  735. package/dist/frontend/lowering/generic-functions.d.ts +10 -0
  736. package/dist/frontend/lowering/generic-functions.js +67 -7
  737. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  738. package/dist/frontend/lowering/global-values.d.ts +37 -0
  739. package/dist/frontend/lowering/global-values.js +395 -0
  740. package/dist/frontend/lowering/global-values.js.map +1 -0
  741. package/dist/frontend/lowering/handle-properties.js +3 -2
  742. package/dist/frontend/lowering/handle-properties.js.map +1 -1
  743. package/dist/frontend/lowering/handle-properties.test.d.ts +1 -0
  744. package/dist/frontend/lowering/handle-properties.test.js +25 -0
  745. package/dist/frontend/lowering/handle-properties.test.js.map +1 -0
  746. package/dist/frontend/lowering/import-meta.d.ts +3 -0
  747. package/dist/frontend/lowering/import-meta.js +8 -3
  748. package/dist/frontend/lowering/import-meta.js.map +1 -1
  749. package/dist/frontend/lowering/iterator-adapters.js +3 -3
  750. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  751. package/dist/frontend/lowering/key-order-witness.d.ts +2 -0
  752. package/dist/frontend/lowering/key-order-witness.js +10 -0
  753. package/dist/frontend/lowering/key-order-witness.js.map +1 -1
  754. package/dist/frontend/lowering/lower-array-sort.d.ts +5 -1
  755. package/dist/frontend/lowering/lower-array-sort.js +16 -2
  756. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  757. package/dist/frontend/lowering/lower-builtin-values.d.ts +7 -0
  758. package/dist/frontend/lowering/lower-builtin-values.js +65 -16
  759. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  760. package/dist/frontend/lowering/lower-calls.js +222 -24
  761. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  762. package/dist/frontend/lowering/lower-classes.d.ts +6 -0
  763. package/dist/frontend/lowering/lower-classes.js +154 -20
  764. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  765. package/dist/frontend/lowering/lower-console.js +25 -2
  766. package/dist/frontend/lowering/lower-console.js.map +1 -1
  767. package/dist/frontend/lowering/lower-exprs.d.ts +29 -0
  768. package/dist/frontend/lowering/lower-exprs.js +544 -24
  769. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  770. package/dist/frontend/lowering/lower-functions.js +93 -18
  771. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  772. package/dist/frontend/lowering/lower-global-value.d.ts +4 -1
  773. package/dist/frontend/lowering/lower-global-value.js +10 -3
  774. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  775. package/dist/frontend/lowering/lower-inspect.d.ts +44 -4
  776. package/dist/frontend/lowering/lower-inspect.js +723 -26
  777. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  778. package/dist/frontend/lowering/lower-modules.d.ts +3 -1
  779. package/dist/frontend/lowering/lower-modules.js +189 -24
  780. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  781. package/dist/frontend/lowering/lower-namespaces.d.ts +7 -0
  782. package/dist/frontend/lowering/lower-namespaces.js +23 -0
  783. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  784. package/dist/frontend/lowering/lower-node-island.d.ts +74 -0
  785. package/dist/frontend/lowering/lower-node-island.js +1931 -0
  786. package/dist/frontend/lowering/lower-node-island.js.map +1 -0
  787. package/dist/frontend/lowering/lower-server.js +44 -0
  788. package/dist/frontend/lowering/lower-server.js.map +1 -1
  789. package/dist/frontend/lowering/lower-shared-modules.d.ts +27 -0
  790. package/dist/frontend/lowering/lower-shared-modules.js +611 -0
  791. package/dist/frontend/lowering/lower-shared-modules.js.map +1 -0
  792. package/dist/frontend/lowering/lower-stdlib.js +85 -9
  793. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  794. package/dist/frontend/lowering/lower-stmts.d.ts +2 -6
  795. package/dist/frontend/lowering/lower-stmts.js +781 -143
  796. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  797. package/dist/frontend/lowering/lower-stream.js +548 -36
  798. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  799. package/dist/frontend/lowering/lower-timers.js +9 -0
  800. package/dist/frontend/lowering/lower-timers.js.map +1 -1
  801. package/dist/frontend/lowering/lowerer.d.ts +514 -10
  802. package/dist/frontend/lowering/lowerer.js +2667 -163
  803. package/dist/frontend/lowering/lowerer.js.map +1 -1
  804. package/dist/frontend/lowering/lowerer.test.js +44 -1
  805. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  806. package/dist/frontend/lowering/maybe-promise.d.ts +6 -0
  807. package/dist/frontend/lowering/maybe-promise.js +13 -0
  808. package/dist/frontend/lowering/maybe-promise.js.map +1 -1
  809. package/dist/frontend/lowering/module-namespace-elements.d.ts +12 -0
  810. package/dist/frontend/lowering/module-namespace-elements.js +114 -18
  811. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  812. package/dist/frontend/lowering/nan-coded-reads.d.ts +11 -0
  813. package/dist/frontend/lowering/nan-coded-reads.js +45 -2
  814. package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
  815. package/dist/frontend/lowering/narrowing-stability.d.ts +4 -0
  816. package/dist/frontend/lowering/narrowing-stability.js +14 -6
  817. package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
  818. package/dist/frontend/lowering/receiver-returns.d.ts +3 -0
  819. package/dist/frontend/lowering/receiver-returns.js +134 -0
  820. package/dist/frontend/lowering/receiver-returns.js.map +1 -0
  821. package/dist/frontend/lowering/record-inherited.d.ts +26 -0
  822. package/dist/frontend/lowering/record-inherited.js +807 -0
  823. package/dist/frontend/lowering/record-inherited.js.map +1 -0
  824. package/dist/frontend/lowering/runtime-optional-elements.d.ts +31 -1
  825. package/dist/frontend/lowering/runtime-optional-elements.js +105 -13
  826. package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
  827. package/dist/frontend/lowering/runtime-optional-guards.d.ts +3 -0
  828. package/dist/frontend/lowering/runtime-optional-guards.js +35 -7
  829. package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
  830. package/dist/frontend/lowering/runtime-optional-guards.test.js +59 -1
  831. package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
  832. package/dist/frontend/lowering/stable-names.d.ts +8 -0
  833. package/dist/frontend/lowering/stable-names.js +22 -0
  834. package/dist/frontend/lowering/stable-names.js.map +1 -1
  835. package/dist/frontend/lowering/stable-names.test.d.ts +1 -0
  836. package/dist/frontend/lowering/stable-names.test.js +16 -0
  837. package/dist/frontend/lowering/stable-names.test.js.map +1 -0
  838. package/dist/frontend/lowering/static-typeof.d.ts +5 -4
  839. package/dist/frontend/lowering/static-typeof.js +10 -4
  840. package/dist/frontend/lowering/static-typeof.js.map +1 -1
  841. package/dist/frontend/lowering/structural-instances.d.ts +22 -0
  842. package/dist/frontend/lowering/structural-instances.js +282 -0
  843. package/dist/frontend/lowering/structural-instances.js.map +1 -0
  844. package/dist/frontend/lowering/surfaces.d.ts +3 -0
  845. package/dist/frontend/lowering/surfaces.js +108 -12
  846. package/dist/frontend/lowering/surfaces.js.map +1 -1
  847. package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
  848. package/dist/frontend/lowering/symbol-fields.js +32 -0
  849. package/dist/frontend/lowering/symbol-fields.js.map +1 -1
  850. package/dist/frontend/lowering/type-failure.d.ts +17 -0
  851. package/dist/frontend/lowering/type-failure.js +163 -0
  852. package/dist/frontend/lowering/type-failure.js.map +1 -0
  853. package/dist/frontend/lowering/typed-arguments.d.ts +5 -6
  854. package/dist/frontend/lowering/typed-arguments.js +10 -2
  855. package/dist/frontend/lowering/typed-arguments.js.map +1 -1
  856. package/dist/frontend/lowering/union-narrow.d.ts +9 -1
  857. package/dist/frontend/lowering/union-narrow.js +31 -2
  858. package/dist/frontend/lowering/union-narrow.js.map +1 -1
  859. package/dist/frontend/lowering/union-retag.test.js +42 -2
  860. package/dist/frontend/lowering/union-retag.test.js.map +1 -1
  861. package/dist/frontend/lowering/unit-journal.d.ts +194 -0
  862. package/dist/frontend/lowering/unit-journal.js +556 -0
  863. package/dist/frontend/lowering/unit-journal.js.map +1 -0
  864. package/dist/frontend/lowering/unit-journal.test.d.ts +1 -0
  865. package/dist/frontend/lowering/unit-journal.test.js +335 -0
  866. package/dist/frontend/lowering/unit-journal.test.js.map +1 -0
  867. package/dist/frontend/lowering/width-lift.d.ts +19 -0
  868. package/dist/frontend/node-api-import.d.ts +21 -0
  869. package/dist/frontend/node-api-import.js +88 -0
  870. package/dist/frontend/node-api-import.js.map +1 -0
  871. package/dist/frontend/npm-static-type-exports-host.js +4 -3
  872. package/dist/frontend/npm-static-type-exports-host.js.map +1 -1
  873. package/dist/frontend/npm-static.js +9 -2
  874. package/dist/frontend/npm-static.js.map +1 -1
  875. package/dist/frontend/package-shims.d.ts +6 -2
  876. package/dist/frontend/package-shims.js +13 -2
  877. package/dist/frontend/package-shims.js.map +1 -1
  878. package/dist/frontend/pipeline.d.ts +11 -4
  879. package/dist/frontend/pipeline.js +249 -26
  880. package/dist/frontend/pipeline.js.map +1 -1
  881. package/dist/frontend/process-fork.d.ts +3 -0
  882. package/dist/frontend/process-fork.js.map +1 -1
  883. package/dist/frontend/program-analysis.d.ts +6 -0
  884. package/dist/frontend/program-analysis.js +4 -0
  885. package/dist/frontend/program-analysis.js.map +1 -1
  886. package/dist/frontend/program.d.ts +12 -1
  887. package/dist/frontend/program.js +256 -36
  888. package/dist/frontend/program.js.map +1 -1
  889. package/dist/frontend/resolve.js +8 -2
  890. package/dist/frontend/resolve.js.map +1 -1
  891. package/dist/frontend/shape-inference/analyze.d.ts +23 -1
  892. package/dist/frontend/shape-inference/analyze.js +982 -97
  893. package/dist/frontend/shape-inference/analyze.js.map +1 -1
  894. package/dist/frontend/shape-inference/constant-graphs.d.ts +2 -0
  895. package/dist/frontend/shape-inference/constant-graphs.js +39 -4
  896. package/dist/frontend/shape-inference/constant-graphs.js.map +1 -1
  897. package/dist/frontend/shape-inference/domain.d.ts +2 -0
  898. package/dist/frontend/shape-inference/domain.js.map +1 -1
  899. package/dist/frontend/shape-inference/fallback.d.ts +17 -0
  900. package/dist/frontend/shape-inference/fallback.js +303 -0
  901. package/dist/frontend/shape-inference/fallback.js.map +1 -0
  902. package/dist/frontend/shape-inference/index.d.ts +75 -1
  903. package/dist/frontend/shape-inference/index.js +531 -2
  904. package/dist/frontend/shape-inference/index.js.map +1 -1
  905. package/dist/frontend/shape-inference/inferred-checks.d.ts +2 -0
  906. package/dist/frontend/shape-inference/inferred-checks.js +90 -0
  907. package/dist/frontend/shape-inference/inferred-checks.js.map +1 -0
  908. package/dist/frontend/shape-inference/memo.d.ts +30 -0
  909. package/dist/frontend/shape-inference/memo.js +99 -0
  910. package/dist/frontend/shape-inference/memo.js.map +1 -0
  911. package/dist/frontend/shape-inference/overlay.d.ts +81 -0
  912. package/dist/frontend/shape-inference/overlay.js +1160 -0
  913. package/dist/frontend/shape-inference/overlay.js.map +1 -0
  914. package/dist/frontend/shape-inference/registry.test.d.ts +1 -0
  915. package/dist/frontend/shape-inference/registry.test.js +34 -0
  916. package/dist/frontend/shape-inference/registry.test.js.map +1 -0
  917. package/dist/frontend/shape-inference/report.js +42 -8
  918. package/dist/frontend/shape-inference/report.js.map +1 -1
  919. package/dist/frontend/shape-inference/static-objects.d.ts +29 -0
  920. package/dist/frontend/shape-inference/static-objects.js +1951 -0
  921. package/dist/frontend/shape-inference/static-objects.js.map +1 -0
  922. package/dist/frontend/tier-analysis.d.ts +53 -1
  923. package/dist/frontend/tier-analysis.js +133 -0
  924. package/dist/frontend/tier-analysis.js.map +1 -1
  925. package/dist/frontend/ts7/api.js +4 -2
  926. package/dist/frontend/ts7/api.js.map +1 -1
  927. package/dist/frontend/ts7/ast-node.d.ts +9 -0
  928. package/dist/frontend/ts7/ast-node.js +42 -10
  929. package/dist/frontend/ts7/ast-node.js.map +1 -1
  930. package/dist/frontend/ts7/ast-node.test.js +23 -0
  931. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  932. package/dist/frontend/ts7/ast-wire-protocols.test.d.ts +1 -0
  933. package/dist/frontend/ts7/ast-wire-protocols.test.js +93 -0
  934. package/dist/frontend/ts7/ast-wire-protocols.test.js.map +1 -0
  935. package/dist/frontend/ts7/ast-wire.d.ts +18 -0
  936. package/dist/frontend/ts7/ast-wire.js +66 -4
  937. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  938. package/dist/frontend/ts7/checker-server.d.ts +12 -11
  939. package/dist/frontend/ts7/checker-server.js +28 -12
  940. package/dist/frontend/ts7/checker-server.js.map +1 -1
  941. package/dist/frontend/ts7/checker-server.test.js +8 -3
  942. package/dist/frontend/ts7/checker-server.test.js.map +1 -1
  943. package/dist/frontend/ts7/checker.d.ts +4 -0
  944. package/dist/frontend/ts7/checker.js +9 -0
  945. package/dist/frontend/ts7/checker.js.map +1 -1
  946. package/dist/frontend/ts7/checker.test.js +216 -205
  947. package/dist/frontend/ts7/checker.test.js.map +1 -1
  948. package/dist/frontend/ts7/lib-diagnostics.d.ts +71 -4
  949. package/dist/frontend/ts7/lib-diagnostics.js +337 -20
  950. package/dist/frontend/ts7/lib-diagnostics.js.map +1 -1
  951. package/dist/frontend/ts7/lib-diagnostics.test.js +268 -5
  952. package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -1
  953. package/dist/frontend/ts7/native-api.d.ts +4 -0
  954. package/dist/frontend/ts7/native-api.js +36 -1
  955. package/dist/frontend/ts7/native-api.js.map +1 -1
  956. package/dist/frontend/ts7/program-host.d.ts +19 -2
  957. package/dist/frontend/ts7/program-host.js +69 -9
  958. package/dist/frontend/ts7/program-host.js.map +1 -1
  959. package/dist/frontend/ts7/program-host.test.js +42 -1
  960. package/dist/frontend/ts7/program-host.test.js.map +1 -1
  961. package/dist/frontend/ts7/rpc-filesystem.d.ts +4 -2
  962. package/dist/frontend/ts7/rpc-filesystem.js +23 -2
  963. package/dist/frontend/ts7/rpc-filesystem.js.map +1 -1
  964. package/dist/frontend/ts7/rpc-filesystem.test.js +28 -2
  965. package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -1
  966. package/dist/frontend/ts7/semantic-checker.js +73 -5
  967. package/dist/frontend/ts7/semantic-checker.js.map +1 -1
  968. package/dist/frontend/ts7/semantic-checker.test.js +106 -74
  969. package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
  970. package/dist/frontend/ts7/semantic-json.d.ts +2 -6
  971. package/dist/frontend/ts7/semantic-model-71.test.d.ts +1 -0
  972. package/dist/frontend/ts7/semantic-model-71.test.js +131 -0
  973. package/dist/frontend/ts7/semantic-model-71.test.js.map +1 -0
  974. package/dist/frontend/ts7/semantic-model.d.ts +121 -3
  975. package/dist/frontend/ts7/semantic-model.js +245 -8
  976. package/dist/frontend/ts7/semantic-model.js.map +1 -1
  977. package/dist/frontend/ts7/session.d.ts +19 -1
  978. package/dist/frontend/ts7/session.js +111 -11
  979. package/dist/frontend/ts7/session.js.map +1 -1
  980. package/dist/frontend/ts7/session.test.js +259 -239
  981. package/dist/frontend/ts7/session.test.js.map +1 -1
  982. package/dist/frontend/ts7/test-servers.d.ts +12 -0
  983. package/dist/frontend/ts7/test-servers.js +16 -0
  984. package/dist/frontend/ts7/test-servers.js.map +1 -0
  985. package/dist/frontend/tsc-codes.js +6 -3
  986. package/dist/frontend/tsc-codes.js.map +1 -1
  987. package/dist/frontend/type-mapper.d.ts +61 -1
  988. package/dist/frontend/type-mapper.js +577 -28
  989. package/dist/frontend/type-mapper.js.map +1 -1
  990. package/dist/frontend/type-patches/command.d.ts +19 -0
  991. package/dist/frontend/type-patches/command.js +352 -0
  992. package/dist/frontend/type-patches/command.js.map +1 -0
  993. package/dist/frontend/type-patches/layer.d.ts +45 -0
  994. package/dist/frontend/type-patches/layer.js +409 -0
  995. package/dist/frontend/type-patches/layer.js.map +1 -0
  996. package/dist/frontend/type-patches/locate.d.ts +41 -0
  997. package/dist/frontend/type-patches/locate.js +914 -0
  998. package/dist/frontend/type-patches/locate.js.map +1 -0
  999. package/dist/frontend/type-patches/locate.test.d.ts +1 -0
  1000. package/dist/frontend/type-patches/locate.test.js +179 -0
  1001. package/dist/frontend/type-patches/locate.test.js.map +1 -0
  1002. package/dist/frontend/type-patches/selector.d.ts +43 -0
  1003. package/dist/frontend/type-patches/selector.js +126 -0
  1004. package/dist/frontend/type-patches/selector.js.map +1 -0
  1005. package/dist/frontend/type-patches/selector.test.d.ts +1 -0
  1006. package/dist/frontend/type-patches/selector.test.js +56 -0
  1007. package/dist/frontend/type-patches/selector.test.js.map +1 -0
  1008. package/dist/frontend/type-patches/semver.d.ts +19 -0
  1009. package/dist/frontend/type-patches/semver.js +221 -0
  1010. package/dist/frontend/type-patches/semver.js.map +1 -0
  1011. package/dist/frontend/type-patches/semver.test.d.ts +1 -0
  1012. package/dist/frontend/type-patches/semver.test.js +47 -0
  1013. package/dist/frontend/type-patches/semver.test.js.map +1 -0
  1014. package/dist/frontend/worker-target.test.js +2 -2
  1015. package/dist/frontend/worker-target.test.js.map +1 -1
  1016. package/dist/index.d.ts +4 -1
  1017. package/dist/index.js +292 -27
  1018. package/dist/index.js.map +1 -1
  1019. package/dist/ir/builtin-effects.js +51 -5
  1020. package/dist/ir/builtin-effects.js.map +1 -1
  1021. package/dist/ir/builtin-signatures.d.ts +4 -3
  1022. package/dist/ir/builtin-signatures.js +277 -12
  1023. package/dist/ir/builtin-signatures.js.map +1 -1
  1024. package/dist/ir/callback-specialization.js +108 -67
  1025. package/dist/ir/callback-specialization.js.map +1 -1
  1026. package/dist/ir/capture-values.d.ts +7 -1
  1027. package/dist/ir/capture-values.js +28 -5
  1028. package/dist/ir/capture-values.js.map +1 -1
  1029. package/dist/ir/char-unit-locals.js +38 -42
  1030. package/dist/ir/char-unit-locals.js.map +1 -1
  1031. package/dist/ir/expression-inlining.js +12 -6
  1032. package/dist/ir/expression-inlining.js.map +1 -1
  1033. package/dist/ir/fields.generated.d.ts +751 -0
  1034. package/dist/ir/fields.generated.js +2071 -0
  1035. package/dist/ir/fields.generated.js.map +1 -0
  1036. package/dist/ir/fields.test.d.ts +1 -0
  1037. package/dist/ir/fields.test.js +113 -0
  1038. package/dist/ir/fields.test.js.map +1 -0
  1039. package/dist/ir/function-references.js +4 -0
  1040. package/dist/ir/function-references.js.map +1 -1
  1041. package/dist/ir/function-references.test.js +25 -0
  1042. package/dist/ir/function-references.test.js.map +1 -1
  1043. package/dist/ir/inline-array-sources.d.ts +15 -0
  1044. package/dist/ir/inline-array-sources.js +1825 -0
  1045. package/dist/ir/inline-array-sources.js.map +1 -0
  1046. package/dist/ir/inline-arrays.d.ts +41 -0
  1047. package/dist/ir/inline-arrays.js +533 -0
  1048. package/dist/ir/inline-arrays.js.map +1 -0
  1049. package/dist/ir/inline-arrays.test.d.ts +1 -0
  1050. package/dist/ir/inline-arrays.test.js +225 -0
  1051. package/dist/ir/inline-arrays.test.js.map +1 -0
  1052. package/dist/ir/int32-slots.d.ts +6 -0
  1053. package/dist/ir/int32-slots.js +154 -16
  1054. package/dist/ir/int32-slots.js.map +1 -1
  1055. package/dist/ir/int32-slots.test.js +48 -0
  1056. package/dist/ir/int32-slots.test.js.map +1 -1
  1057. package/dist/ir/integer-loops.d.ts +12 -0
  1058. package/dist/ir/integer-loops.js +23 -0
  1059. package/dist/ir/integer-loops.js.map +1 -1
  1060. package/dist/ir/integer-ranges.d.ts +7 -1
  1061. package/dist/ir/integer-ranges.js +29 -2
  1062. package/dist/ir/integer-ranges.js.map +1 -1
  1063. package/dist/ir/intrinsic-signatures.js +2 -1
  1064. package/dist/ir/intrinsic-signatures.js.map +1 -1
  1065. package/dist/ir/ir.d.ts +103 -5
  1066. package/dist/ir/ir.js +38 -4
  1067. package/dist/ir/ir.js.map +1 -1
  1068. package/dist/ir/ir.test.js +134 -1
  1069. package/dist/ir/ir.test.js.map +1 -1
  1070. package/dist/ir/jsval.js +211 -29
  1071. package/dist/ir/jsval.js.map +1 -1
  1072. package/dist/ir/jsval.test.js +120 -0
  1073. package/dist/ir/jsval.test.js.map +1 -1
  1074. package/dist/ir/loop-entry-ranges.d.ts +38 -0
  1075. package/dist/ir/loop-entry-ranges.js +259 -0
  1076. package/dist/ir/loop-entry-ranges.js.map +1 -0
  1077. package/dist/ir/loop-entry-ranges.test.d.ts +1 -0
  1078. package/dist/ir/loop-entry-ranges.test.js +191 -0
  1079. package/dist/ir/loop-entry-ranges.test.js.map +1 -0
  1080. package/dist/ir/node-index.d.ts +3 -0
  1081. package/dist/ir/node-index.js +6 -0
  1082. package/dist/ir/node-index.js.map +1 -1
  1083. package/dist/ir/numeric-call-specialization.d.ts +9 -6
  1084. package/dist/ir/numeric-call-specialization.js +164 -34
  1085. package/dist/ir/numeric-call-specialization.js.map +1 -1
  1086. package/dist/ir/paired-while-loops.js +23 -19
  1087. package/dist/ir/paired-while-loops.js.map +1 -1
  1088. package/dist/ir/parameter-versions.js +6 -3
  1089. package/dist/ir/parameter-versions.js.map +1 -1
  1090. package/dist/ir/receiver-readers.d.ts +10 -0
  1091. package/dist/ir/receiver-readers.js +65 -28
  1092. package/dist/ir/receiver-readers.js.map +1 -1
  1093. package/dist/ir/row-pairs.d.ts +9 -1
  1094. package/dist/ir/row-pairs.js +136 -43
  1095. package/dist/ir/row-pairs.js.map +1 -1
  1096. package/dist/ir/row-pairs.test.js +25 -5
  1097. package/dist/ir/row-pairs.test.js.map +1 -1
  1098. package/dist/ir/runtime-features.d.ts +33 -1
  1099. package/dist/ir/runtime-features.js +104 -6
  1100. package/dist/ir/runtime-features.js.map +1 -1
  1101. package/dist/ir/runtime-features.test.js +13 -0
  1102. package/dist/ir/runtime-features.test.js.map +1 -1
  1103. package/dist/ir/saturating-loop-jams.d.ts +24 -0
  1104. package/dist/ir/saturating-loop-jams.js +420 -0
  1105. package/dist/ir/saturating-loop-jams.js.map +1 -0
  1106. package/dist/ir/saturating-loop-jams.test.d.ts +1 -0
  1107. package/dist/ir/saturating-loop-jams.test.js +196 -0
  1108. package/dist/ir/saturating-loop-jams.test.js.map +1 -0
  1109. package/dist/ir/scalar-records.js +9 -3
  1110. package/dist/ir/scalar-records.js.map +1 -1
  1111. package/dist/ir/self-captures.js +2 -1
  1112. package/dist/ir/self-captures.js.map +1 -1
  1113. package/dist/ir/serialize.d.ts +5 -1
  1114. package/dist/ir/serialize.js +7 -1
  1115. package/dist/ir/serialize.js.map +1 -1
  1116. package/dist/ir/traverse.js +3 -0
  1117. package/dist/ir/traverse.js.map +1 -1
  1118. package/dist/ir/validate.js +91 -9
  1119. package/dist/ir/validate.js.map +1 -1
  1120. package/dist/library/ir-policy.js +1 -0
  1121. package/dist/library/ir-policy.js.map +1 -1
  1122. package/dist/native/cache.js +2 -0
  1123. package/dist/native/cache.js.map +1 -1
  1124. package/dist/native/cli.js +54 -7
  1125. package/dist/native/cli.js.map +1 -1
  1126. package/dist/native/compiler.d.ts +3 -0
  1127. package/dist/native/compiler.js +173 -36
  1128. package/dist/native/compiler.js.map +1 -1
  1129. package/dist/native/compiler.test.js +86 -3
  1130. package/dist/native/compiler.test.js.map +1 -1
  1131. package/dist/native/executable-cache.d.ts +20 -2
  1132. package/dist/native/executable-cache.js +17 -10
  1133. package/dist/native/executable-cache.js.map +1 -1
  1134. package/dist/native/executable-cache.test.js +38 -1
  1135. package/dist/native/executable-cache.test.js.map +1 -1
  1136. package/dist/native/linker-job.d.ts +71 -0
  1137. package/dist/native/linker-job.js +242 -0
  1138. package/dist/native/linker-job.js.map +1 -0
  1139. package/dist/native/linker-job.test.d.ts +1 -0
  1140. package/dist/native/linker-job.test.js +349 -0
  1141. package/dist/native/linker-job.test.js.map +1 -0
  1142. package/dist/native/prepare.js +15 -2
  1143. package/dist/native/prepare.js.map +1 -1
  1144. package/dist/native/sanitizer.js +10 -15
  1145. package/dist/native/sanitizer.js.map +1 -1
  1146. package/dist/native/sanitizer.test.js +152 -66
  1147. package/dist/native/sanitizer.test.js.map +1 -1
  1148. package/dist/native/toolchain.d.ts +11 -2
  1149. package/dist/native/toolchain.js +43 -17
  1150. package/dist/native/toolchain.js.map +1 -1
  1151. package/dist/native/toolchain.test.js +75 -0
  1152. package/dist/native/toolchain.test.js.map +1 -1
  1153. package/dist/node-islands/boundary.d.ts +37 -0
  1154. package/dist/node-islands/boundary.js +135 -0
  1155. package/dist/node-islands/boundary.js.map +1 -0
  1156. package/dist/node-islands/classify.js +1 -1
  1157. package/dist/node-islands/classify.js.map +1 -1
  1158. package/dist/node-islands/effect-gate.d.ts +11 -0
  1159. package/dist/node-islands/effect-gate.js +746 -0
  1160. package/dist/node-islands/effect-gate.js.map +1 -0
  1161. package/dist/node-islands/effect-gate.test.d.ts +1 -0
  1162. package/dist/node-islands/effect-gate.test.js +152 -0
  1163. package/dist/node-islands/effect-gate.test.js.map +1 -0
  1164. package/dist/node-islands/libnode-pack.d.ts +68 -0
  1165. package/dist/node-islands/libnode-pack.js +199 -0
  1166. package/dist/node-islands/libnode-pack.js.map +1 -0
  1167. package/dist/node-islands/libnode-pack.test.d.ts +1 -0
  1168. package/dist/node-islands/libnode-pack.test.js +258 -0
  1169. package/dist/node-islands/libnode-pack.test.js.map +1 -0
  1170. package/dist/node-islands/libnode.d.ts +32 -0
  1171. package/dist/node-islands/libnode.js +212 -0
  1172. package/dist/node-islands/libnode.js.map +1 -0
  1173. package/dist/node-islands/libnode.test.d.ts +1 -0
  1174. package/dist/node-islands/libnode.test.js +170 -0
  1175. package/dist/node-islands/libnode.test.js.map +1 -0
  1176. package/dist/node-islands/modules.d.ts +96 -0
  1177. package/dist/node-islands/modules.js +803 -0
  1178. package/dist/node-islands/modules.js.map +1 -0
  1179. package/dist/node-islands/modules.test.d.ts +1 -0
  1180. package/dist/node-islands/modules.test.js +276 -0
  1181. package/dist/node-islands/modules.test.js.map +1 -0
  1182. package/dist/node-islands/resolve.d.ts +8 -0
  1183. package/dist/node-islands/resolve.js +10 -0
  1184. package/dist/node-islands/resolve.js.map +1 -0
  1185. package/dist/node-islands/snapshot.d.ts +16 -0
  1186. package/dist/node-islands/snapshot.js +486 -0
  1187. package/dist/node-islands/snapshot.js.map +1 -0
  1188. package/dist/node-islands/snapshot.test.d.ts +1 -0
  1189. package/dist/node-islands/snapshot.test.js +56 -0
  1190. package/dist/node-islands/snapshot.test.js.map +1 -0
  1191. package/dist/project-config.d.ts +37 -1
  1192. package/dist/project-config.js +159 -7
  1193. package/dist/project-config.js.map +1 -1
  1194. package/dist/project-config.test.js +153 -0
  1195. package/dist/project-config.test.js.map +1 -1
  1196. package/dist/startup-cache.d.ts +1 -0
  1197. package/dist/startup-cache.js +1 -0
  1198. package/dist/startup-cache.js.map +1 -1
  1199. package/package.json +24 -21
  1200. package/surface-manifest.json +47 -7
@@ -24,7 +24,7 @@
24
24
  import * as ts from "../ts7/adapter.js";
25
25
  import { isJsSourceFile } from "../program.js";
26
26
  import { npmStaticPackageOfPath } from "../npm-static.js";
27
- import { AtomTable, MODELED_GLOBALS, STRING_METHOD_RESULTS } from "./domain.js";
27
+ import { AtomTable, MODELED_GLOBALS, OBJECT_PROTOTYPE_MEMBERS, STRING_METHOD_RESULTS, } from "./domain.js";
28
28
  /** Array.prototype members: other names on an array are own properties. */
29
29
  const ARRAY_METHODS = new Set([
30
30
  "at",
@@ -67,6 +67,109 @@ const ARRAY_METHODS = new Set([
67
67
  "with",
68
68
  ]);
69
69
  const MAX_STEPS = 20_000_000;
70
+ /** The well-known symbols, static members of `Symbol` (Node 24). */
71
+ const WELL_KNOWN_SYMBOLS = new Set([
72
+ "asyncDispose",
73
+ "asyncIterator",
74
+ "dispose",
75
+ "hasInstance",
76
+ "isConcatSpreadable",
77
+ "iterator",
78
+ "match",
79
+ "matchAll",
80
+ "replace",
81
+ "search",
82
+ "species",
83
+ "split",
84
+ "toPrimitive",
85
+ "toStringTag",
86
+ "unscopables",
87
+ ]);
88
+ /** The members String.prototype, Number.prototype and Boolean.prototype
89
+ * define (Node 24); Object.prototype's come from OBJECT_PROTOTYPE_MEMBERS. */
90
+ const PRIMITIVE_MEMBERS = {
91
+ string: new Set([
92
+ "at",
93
+ "charAt",
94
+ "charCodeAt",
95
+ "codePointAt",
96
+ "concat",
97
+ "endsWith",
98
+ "includes",
99
+ "indexOf",
100
+ "isWellFormed",
101
+ "lastIndexOf",
102
+ "localeCompare",
103
+ "match",
104
+ "matchAll",
105
+ "normalize",
106
+ "padEnd",
107
+ "padStart",
108
+ "repeat",
109
+ "replace",
110
+ "replaceAll",
111
+ "search",
112
+ "slice",
113
+ "split",
114
+ "startsWith",
115
+ "substr",
116
+ "substring",
117
+ "toLocaleLowerCase",
118
+ "toLocaleUpperCase",
119
+ "toLowerCase",
120
+ "toString",
121
+ "toUpperCase",
122
+ "toWellFormed",
123
+ "trim",
124
+ "trimEnd",
125
+ "trimStart",
126
+ "trimLeft",
127
+ "trimRight",
128
+ "valueOf",
129
+ "anchor",
130
+ "big",
131
+ "blink",
132
+ "bold",
133
+ "fixed",
134
+ "fontcolor",
135
+ "fontsize",
136
+ "italics",
137
+ "link",
138
+ "small",
139
+ "strike",
140
+ "sub",
141
+ "sup",
142
+ "length",
143
+ "constructor",
144
+ ]),
145
+ number: new Set([
146
+ "toExponential",
147
+ "toFixed",
148
+ "toLocaleString",
149
+ "toPrecision",
150
+ "toString",
151
+ "valueOf",
152
+ "constructor",
153
+ ]),
154
+ boolean: new Set(["toString", "valueOf", "constructor"]),
155
+ };
156
+ /** Per-call-site clones of an init factory, at most (SCRIPTC_SHAPE_SITE_CLONES;
157
+ * 0 turns them off), and the deepest chain of nested clones. */
158
+ const SITE_CLONES = Number(process.env["SCRIPTC_SHAPE_SITE_CLONES"] ?? 64);
159
+ const SITE_CLONE_DEPTH = 4;
160
+ /** The prototypes a string, number or boolean member read reaches. */
161
+ const PRIMITIVE_PROTOTYPES = new Set([
162
+ "String.prototype",
163
+ "Number.prototype",
164
+ "Boolean.prototype",
165
+ "Object.prototype",
166
+ ]);
167
+ function isPrimitivePrototype(a) {
168
+ return a.kind === "builtin" && a.receiver === undefined && PRIMITIVE_PROTOTYPES.has(a.path ?? "");
169
+ }
170
+ /** The most atoms a value node tracks before it widens to ⊤
171
+ * (SCRIPTC_SHAPE_WIDEN overrides). */
172
+ const WIDEN_AT = Number(process.env["SCRIPTC_SHAPE_WIDEN"] ?? 32);
70
173
  function list(arr) {
71
174
  return arr?.nodes ?? [];
72
175
  }
@@ -103,7 +206,14 @@ function propertyNameText(name) {
103
206
  }
104
207
  return null;
105
208
  }
209
+ const shortFiles = new Map();
106
210
  function shortFile(fileName) {
211
+ let short = shortFiles.get(fileName);
212
+ if (short === undefined)
213
+ shortFiles.set(fileName, (short = shortFileOf(fileName)));
214
+ return short;
215
+ }
216
+ function shortFileOf(fileName) {
107
217
  const norm = fileName.split("\\").join("/");
108
218
  const nm = norm.lastIndexOf("/node_modules/");
109
219
  if (nm >= 0) {
@@ -130,6 +240,38 @@ function isLoop(node) {
130
240
  ts.isWhileStatement(node) ||
131
241
  ts.isDoStatement(node));
132
242
  }
243
+ /** Whether control can reach the end of `stmts`. False only when every
244
+ * path ends in a return or throw, or in a `while (true)`, `do … while
245
+ * (true)` or `for (;;)` loop with no break inside; anything else is
246
+ * assumed to complete. */
247
+ function canComplete(stmts) {
248
+ return stmts.every(canCompleteStatement);
249
+ }
250
+ function canCompleteStatement(s) {
251
+ if (ts.isReturnStatement(s) || ts.isThrowStatement(s))
252
+ return false;
253
+ if (ts.isBlock(s))
254
+ return canComplete(list(s.statements));
255
+ if (ts.isIfStatement(s))
256
+ return (s.elseStatement === undefined ||
257
+ canCompleteStatement(s.thenStatement) ||
258
+ canCompleteStatement(s.elseStatement));
259
+ if (ts.isTryStatement(s)) {
260
+ if (s.finallyBlock !== undefined && !canCompleteStatement(s.finallyBlock))
261
+ return false;
262
+ return (canCompleteStatement(s.tryBlock) ||
263
+ (s.catchClause !== undefined && canCompleteStatement(s.catchClause.block)));
264
+ }
265
+ const endless = ((ts.isWhileStatement(s) || ts.isDoStatement(s)) &&
266
+ s.expression.kind === ts.SyntaxKind.TrueKeyword) ||
267
+ (ts.isForStatement(s) && s.condition === undefined);
268
+ return !endless || containsBreak(s);
269
+ }
270
+ /** Whether a break statement occurs in `node`'s body, outside nested
271
+ * functions. */
272
+ function containsBreak(node) {
273
+ return (ts.forEachChild(node, (c) => ts.isBreakStatement(c) || (!ts.isFunctionLike(c) && containsBreak(c)) ? true : undefined) === true);
274
+ }
133
275
  const LOOP_CALLBACK_METHODS = new Set([
134
276
  "map",
135
277
  "forEach",
@@ -149,12 +291,22 @@ const LOOP_CALLBACK_METHODS = new Set([
149
291
  "replace",
150
292
  "replaceAll",
151
293
  ]);
152
- export function analyzeShapes(program, checker) {
153
- return new Analyzer(program, checker).run();
294
+ export function analyzeShapes(program, checker, options = {}) {
295
+ return new Analyzer(program, checker, options.siteClones ?? SITE_CLONES).run();
154
296
  }
155
297
  class Analyzer {
156
298
  program;
157
299
  checker;
300
+ siteCloneLimit;
301
+ /** locLabel per node: sink reasons and atom labels name the same sites
302
+ * over and over, and each label reads the file's text for its line. */
303
+ locLabels = new Map();
304
+ loc(node) {
305
+ let label = this.locLabels.get(node);
306
+ if (label === undefined)
307
+ this.locLabels.set(node, (label = locLabel(node)));
308
+ return label;
309
+ }
158
310
  atoms = new AtomTable();
159
311
  nodes = [];
160
312
  functions = new Map();
@@ -165,6 +317,14 @@ class Analyzer {
165
317
  escaped = new Map();
166
318
  topWriteNames = new Map();
167
319
  topComputedWrites = [];
320
+ /** Names a write may add to a primitive's prototype chain, or every name
321
+ * (`primitiveExtensionsAll`). A read of a name the chain lacks reads ⊤
322
+ * for them as well as undefined. */
323
+ primitiveExtensions = new Set();
324
+ primitiveExtensionsAll = false;
325
+ /** Reads of names a primitive's prototype chain lacks, by name; each
326
+ * takes ⊤ once a write may add the name. */
327
+ primitiveReads = new Map();
168
328
  fields = new Map();
169
329
  elements = new Map();
170
330
  top;
@@ -196,8 +356,8 @@ class Analyzer {
196
356
  * (JSON.parse revivers, JSON.stringify replacers and toJSON methods),
197
357
  * which may run after the call's own handling. */
198
358
  repeatingSites = new Set();
199
- edgeFor(site, callee) {
200
- const ctx = this.siteCtx.get(site);
359
+ edgeFor(site, callee, args) {
360
+ const ctx = (args !== undefined ? this.argsFrom.get(args) : undefined) ?? this.siteCtx.get(site);
201
361
  this.calls.push({
202
362
  caller: ctx?.caller ?? null,
203
363
  callee,
@@ -205,11 +365,52 @@ class Analyzer {
205
365
  site,
206
366
  });
207
367
  }
208
- constructor(program, checker) {
368
+ constructor(program, checker, siteCloneLimit) {
209
369
  this.program = program;
210
370
  this.checker = checker;
371
+ this.siteCloneLimit = siteCloneLimit;
211
372
  this.top = this.atoms.intern("top", () => ({ kind: "top", label: "⊤" }));
212
373
  }
374
+ /** SCRIPTC_DEBUG_SHAPES_PROFILE: where the solver's steps go. */
375
+ profileReport() {
376
+ const byNodeLabel = new Map();
377
+ let atomsTotal = 0;
378
+ let maxAtoms = 0;
379
+ let onAtoms = 0;
380
+ let succ = 0;
381
+ for (const n of this.nodes) {
382
+ atomsTotal += n.atoms.size;
383
+ maxAtoms = Math.max(maxAtoms, n.atoms.size);
384
+ onAtoms += n.onAtom.length;
385
+ succ += n.succ.size;
386
+ }
387
+ const kinds = new Map();
388
+ for (const a of this.atoms.atoms)
389
+ kinds.set(a.kind, (kinds.get(a.kind) ?? 0) + 1);
390
+ const ctxPerFn = new Map();
391
+ for (const info of this.functions.values())
392
+ ctxPerFn.set(info.node, (ctxPerFn.get(info.node) ?? 0) + 1);
393
+ const topFns = [...ctxPerFn.entries()].sort((a, b) => b[1] - a[1]).slice(0, 15);
394
+ const lines = [
395
+ `nodes ${this.nodes.length} atoms ${this.atoms.atoms.length} (${[...kinds].map(([k, v]) => `${k} ${v}`).join(", ")})`,
396
+ `solve ${this.solveMs.toFixed(0)} ms (nested walks included) checker ${this.checkerMs.toFixed(0)} ms in ${this.checkerCalls} calls`,
397
+ `node-atom pairs ${atomsTotal} max ${maxAtoms} edges ${succ} listeners ${onAtoms} functions ${this.functions.size} steps ${this.steps}`,
398
+ ...topFns.map(([n, c]) => ` ${c} contexts: ${locLabel(n)}`),
399
+ ...[...this.popsByAtom.entries()]
400
+ .sort((a, b) => b[1] - a[1])
401
+ .slice(0, 15)
402
+ .map(([a, c]) => ` ${c} pops: atom ${a.kind} ${a.label}`),
403
+ ...[...this.popsByNode.entries()]
404
+ .sort((a, b) => b[1] - a[1])
405
+ .slice(0, 10)
406
+ .map(([id, c]) => ` ${c} pops: node ${id} ${this.nodeLabel.get(id) ?? ""} atoms ${this.nodes[id].atoms.size} succ ${this.nodes[id].succ.size} listeners ${this.nodes[id].onAtom.length}`),
407
+ ];
408
+ void byNodeLabel;
409
+ process.stderr.write(lines.map((l) => `[shapes-profile] ${l}\n`).join(""));
410
+ }
411
+ profiling = process.env["SCRIPTC_DEBUG_SHAPES_PROFILE"] !== undefined;
412
+ popsByAtom = new Map();
413
+ popsByNode = new Map();
213
414
  run() {
214
415
  for (const sf of this.program.getImplementationSourceFiles()) {
215
416
  const name = sf.fileName.split("\\").join("/");
@@ -220,11 +421,15 @@ class Analyzer {
220
421
  if (inPackage)
221
422
  this.packageFiles++;
222
423
  }
424
+ // Analysis resolves names and never asks for types: the program it
425
+ // runs on is usually replaced by the overlay's before lowering.
223
426
  for (const sf of this.files)
224
- this.checker.prefetchSourceFile(sf);
427
+ this.checker.prefetchSourceFileSymbols(sf);
225
428
  for (const sf of this.files)
226
429
  this.moduleBody(sf);
227
430
  this.finish();
431
+ if (this.profiling)
432
+ this.profileReport();
228
433
  return {
229
434
  atoms: this.atoms,
230
435
  nodes: this.nodes,
@@ -247,6 +452,11 @@ class Analyzer {
247
452
  nodeLabel: this.nodeLabel,
248
453
  escapedFunctions: this.escapedFunctionCalls,
249
454
  protoOf: this.protoOf,
455
+ fnOfInstance: this.fnOfInstance,
456
+ declValues: (decl) => this.declValues(decl),
457
+ classChain: (decl) => this.classChain(decl),
458
+ branchIfs: this.branchIfs,
459
+ walkedBranches: this.walkedBranches,
250
460
  };
251
461
  }
252
462
  // ---- value nodes -------------------------------------------------------
@@ -264,7 +474,23 @@ class Analyzer {
264
474
  const n = this.nodes[node];
265
475
  if (n.atoms.has(atom))
266
476
  return;
477
+ if (n.wide === true) {
478
+ this.escape(atom, "a value set too large to track");
479
+ return;
480
+ }
267
481
  n.atoms.add(atom);
482
+ // Widening: a value set this large is merged code (a utility every
483
+ // value flows through). It becomes ⊤: its values escape, so the facts
484
+ // stay sound, and the solver stops multiplying constraints per atom.
485
+ if (n.atoms.size > WIDEN_AT) {
486
+ n.wide = true;
487
+ for (const a of n.atoms)
488
+ this.escape(a, "a value set too large to track");
489
+ if (!n.atoms.has(this.top)) {
490
+ n.atoms.add(this.top);
491
+ this.worklist.push([node, this.top]);
492
+ }
493
+ }
268
494
  if (this.traceTop && atom === this.top && !this.topCause.has(node))
269
495
  this.topCause.set(node, this.cause ??
270
496
  (new Error().stack ?? "")
@@ -318,6 +544,27 @@ class Analyzer {
318
544
  * and which function each `new F()` instance atom belongs to. */
319
545
  protoOf = new Map();
320
546
  fnOfInstance = new Map();
547
+ /** Per dictionary atom, the prototypes it was created with (Object.create). */
548
+ dictProtos = new Map();
549
+ /** Per object literal atom, the keys it has from its creation: another
550
+ * key may be absent when read (flow-insensitively, before its write). */
551
+ literalOwnKeys = new Map();
552
+ protoReads = new Set();
553
+ /** Arrays whose elements an index read inside its bounds may still miss:
554
+ * shrunk (pop, shift, splice, a length write), holey (`new Array(n)`, a
555
+ * delete, a store at an index that is not proven in bounds or the end). */
556
+ unsafeArrays = new Set();
557
+ /** Index reads proven in bounds by their loop (`for (let i = 0; i <
558
+ * a.length; i++) a[i]`): undefined joins them only if the array turns
559
+ * out unsafe (finish). */
560
+ guardedIndexReads = [];
561
+ boundsMemo = new Map();
562
+ dictProto(d) {
563
+ let id = this.dictProtos.get(d);
564
+ if (id === undefined)
565
+ this.dictProtos.set(d, (id = this.newNode()));
566
+ return id;
567
+ }
321
568
  protoAtom(fn) {
322
569
  let p = this.protoOf.get(fn);
323
570
  if (p === undefined) {
@@ -333,11 +580,93 @@ class Analyzer {
333
580
  }
334
581
  return p;
335
582
  }
583
+ /** A boolean literal: labeled `boolean` like any boolean, but its
584
+ * truthiness is known, so `if` statements on it walk one branch. */
585
+ boolLiteral(value) {
586
+ return this.atoms.intern(`prim:boolean:${value}`, () => ({
587
+ kind: "prim",
588
+ label: "boolean",
589
+ literal: value,
590
+ }));
591
+ }
592
+ /** The analysis environment a deferred walk restores. */
593
+ env() {
594
+ return {
595
+ ctx: this.ctx,
596
+ ctxRoot: this.ctxRoot,
597
+ currentFn: this.currentFn,
598
+ loopDepth: this.loopDepth,
599
+ };
600
+ }
601
+ inEnv(env, walk) {
602
+ const saved = this.env();
603
+ this.ctx = env.ctx;
604
+ this.ctxRoot = env.ctxRoot;
605
+ this.currentFn = env.currentFn;
606
+ this.loopDepth = env.loopDepth;
607
+ try {
608
+ walk();
609
+ }
610
+ finally {
611
+ this.ctx = saved.ctx;
612
+ this.ctxRoot = saved.ctxRoot;
613
+ this.currentFn = saved.currentFn;
614
+ this.loopDepth = saved.loopDepth;
615
+ }
616
+ }
617
+ branchIfs = new Set();
618
+ walkedBranches = new Set();
619
+ /** Ifs whose branches wait for condition values; at the fixpoint, an
620
+ * `if` whose condition node stayed empty walks every waiting branch. */
621
+ pendingIfs = [];
622
+ /** An `if` walks a branch once a condition value allows it: the then
623
+ * branch on a value that may be truthy, the else branch on one that may
624
+ * be falsy. A branch no value allows is never walked, so its effects
625
+ * (returns, calls, writes) stay out of the facts; the overlay turns it
626
+ * into a checked internal error. */
627
+ ifStatement(s) {
628
+ const cond = this.expr(s.expression);
629
+ this.branchIfs.add(s);
630
+ const pending = {
631
+ s,
632
+ cond,
633
+ env: this.env(),
634
+ thenDone: false,
635
+ elseDone: s.elseStatement === undefined,
636
+ };
637
+ this.pendingIfs.push(pending);
638
+ this.on(cond, (a) => {
639
+ if (!pending.thenDone && mayBeTruthy(a))
640
+ this.walkBranch(pending, "then");
641
+ if (!pending.elseDone && mayBeFalsy(a))
642
+ this.walkBranch(pending, "else");
643
+ });
644
+ }
645
+ walkBranch(pending, which) {
646
+ const branch = which === "then" ? pending.s.thenStatement : pending.s.elseStatement;
647
+ if (which === "then")
648
+ pending.thenDone = true;
649
+ else
650
+ pending.elseDone = true;
651
+ this.walkedBranches.add(branch);
652
+ this.inEnv(pending.env, () => this.stmt(branch));
653
+ }
336
654
  builtin(path, receiver) {
337
655
  const key = receiver === undefined ? `builtin:${path}` : `builtin:${path}@${receiver.id}`;
338
656
  return this.atoms.intern(key, () => ({ kind: "builtin", label: path, path, receiver }));
339
657
  }
658
+ solveMs = 0;
340
659
  solve() {
660
+ const started = this.profiling ? performance.now() : 0;
661
+ try {
662
+ this.solveLoop();
663
+ }
664
+ finally {
665
+ if (this.profiling)
666
+ this.solveMs += performance.now() - started;
667
+ }
668
+ }
669
+ solveLoop() {
341
670
  while (this.worklist.length > 0) {
342
671
  if (++this.steps > MAX_STEPS) {
343
672
  this.budgetExceeded = true;
@@ -345,6 +674,10 @@ class Analyzer {
345
674
  }
346
675
  const [id, atom] = this.worklist.pop();
347
676
  const n = this.nodes[id];
677
+ if (this.profiling) {
678
+ this.popsByAtom.set(atom, (this.popsByAtom.get(atom) ?? 0) + 1);
679
+ this.popsByNode.set(id, (this.popsByNode.get(id) ?? 0) + 1);
680
+ }
348
681
  this.cause = id;
349
682
  for (const s of n.succ)
350
683
  this.add(s, atom);
@@ -401,6 +734,9 @@ class Analyzer {
401
734
  escape(atom, reason) {
402
735
  if (atom.kind === "prim" || atom.kind === "top")
403
736
  return;
737
+ // Unknown code may add any member to a primitive's prototype.
738
+ if (isPrimitivePrototype(atom))
739
+ this.extendPrimitives(null);
404
740
  if (atom.kind === "builtin" && atom.receiver === undefined)
405
741
  return;
406
742
  if (this.escaped.has(atom))
@@ -459,6 +795,8 @@ class Analyzer {
459
795
  }
460
796
  /** Property names that untyped code writes on receivers that may be ⊤ (census). */
461
797
  noteTopWrite(name, node) {
798
+ // ⊤ may be a primitive's prototype.
799
+ this.extendPrimitives(name);
462
800
  if (name === null) {
463
801
  const first = this.topComputedWrites.length === 0;
464
802
  this.topComputedWrites.push(node);
@@ -482,6 +820,47 @@ class Analyzer {
482
820
  this.add(id, this.top);
483
821
  }
484
822
  }
823
+ /** A read of a name a primitive's prototype chain lacks: ⊤ as well, now
824
+ * or once a write may add the name there. */
825
+ primitiveRead(name, dst) {
826
+ if (this.primitiveExtensionsAll || this.primitiveExtensions.has(name)) {
827
+ this.add(dst, this.top);
828
+ return;
829
+ }
830
+ const reads = this.primitiveReads.get(name);
831
+ if (reads === undefined)
832
+ this.primitiveReads.set(name, [dst]);
833
+ else
834
+ reads.push(dst);
835
+ }
836
+ /** A write that may add `name` (any name when null) to String.prototype,
837
+ * Number.prototype, Boolean.prototype or Object.prototype. */
838
+ extendPrimitives(name) {
839
+ if (this.primitiveExtensionsAll)
840
+ return;
841
+ if (name === null || name === "__proto__") {
842
+ this.primitiveExtensionsAll = true;
843
+ for (const reads of this.primitiveReads.values())
844
+ for (const dst of reads)
845
+ this.add(dst, this.top);
846
+ this.primitiveReads.clear();
847
+ return;
848
+ }
849
+ if (this.primitiveExtensions.has(name))
850
+ return;
851
+ this.primitiveExtensions.add(name);
852
+ for (const dst of this.primitiveReads.get(name) ?? [])
853
+ this.add(dst, this.top);
854
+ this.primitiveReads.delete(name);
855
+ }
856
+ /** An operation that may add, replace or remove `name` (any name when
857
+ * null) on its receiver: a primitive's prototype, or ⊤, which may be one. */
858
+ prototypeWrite(recv, name) {
859
+ this.on(recv, (t) => {
860
+ if (t.kind === "top" || isPrimitivePrototype(t))
861
+ this.extendPrimitives(name);
862
+ });
863
+ }
485
864
  // ---- classes ---------------------------------------------------------------
486
865
  /** The base class declaration of `decl`, via the checker; null at a
487
866
  * builtin base or none; undefined when unresolved. */
@@ -563,7 +942,22 @@ class Analyzer {
563
942
  return null;
564
943
  }
565
944
  // ---- symbols -----------------------------------------------------------------
945
+ checkerMs = 0;
946
+ checkerCalls = 0;
947
+ resolved = new Map();
566
948
  resolve(id) {
949
+ if (this.resolved.has(id))
950
+ return this.resolved.get(id);
951
+ const started = this.profiling ? performance.now() : 0;
952
+ const out = this.resolveUncached(id);
953
+ if (this.profiling) {
954
+ this.checkerMs += performance.now() - started;
955
+ this.checkerCalls++;
956
+ }
957
+ this.resolved.set(id, out);
958
+ return out;
959
+ }
960
+ resolveUncached(id) {
567
961
  let sym = this.checker.getSymbolAtLocation(id);
568
962
  if (sym === undefined)
569
963
  return undefined;
@@ -584,7 +978,7 @@ class Analyzer {
584
978
  id = this.newNode();
585
979
  this.bindings.set(key, id);
586
980
  if (this.traceTop)
587
- this.nodeLabel.set(id, `binding ${decl.name?.text ?? "?"}@${locLabel(decl)}${this.ctx !== "" ? ` [${this.ctx}]` : ""}`);
981
+ this.nodeLabel.set(id, `binding ${decl.name?.text ?? "?"}@${this.loc(decl)}${this.ctx !== "" ? ` [${this.ctx}]` : ""}`);
588
982
  }
589
983
  return id;
590
984
  }
@@ -598,6 +992,27 @@ class Analyzer {
598
992
  node.end <= root.end;
599
993
  return `${inside ? this.ctx : ""}|${this.nodeKey(node)}`;
600
994
  }
995
+ declIndex = null;
996
+ declValues(decl) {
997
+ if (this.declIndex === null) {
998
+ this.declIndex = new Map();
999
+ for (const [key, id] of this.bindings) {
1000
+ const k = Number(key.slice(key.lastIndexOf("|") + 1));
1001
+ let l = this.declIndex.get(k);
1002
+ if (l === undefined)
1003
+ this.declIndex.set(k, (l = []));
1004
+ l.push(id);
1005
+ }
1006
+ }
1007
+ const out = new Set();
1008
+ const k = this.nodeKeys.get(decl);
1009
+ if (k === undefined)
1010
+ return out;
1011
+ for (const id of this.declIndex.get(k) ?? [])
1012
+ for (const a of this.nodes[id].atoms)
1013
+ out.add(a);
1014
+ return out;
1015
+ }
601
1016
  receiverCtx(atom) {
602
1017
  return atom.kind === "instance" || atom.kind === "class" ? `C${atom.id}` : "";
603
1018
  }
@@ -607,7 +1022,9 @@ class Analyzer {
607
1022
  return this.functions.get(`${atom.ctx ?? ""}|${this.nodeKey(atom.node)}`);
608
1023
  }
609
1024
  // ---- functions ---------------------------------------------------------------
610
- functionInfo(node, ownerClass, ctxArg = "") {
1025
+ /** `lexicalThis`: an arrow's receiver node, for a clone walked away from
1026
+ * the function that encloses the arrow. */
1027
+ functionInfo(node, ownerClass, ctxArg = "", lexicalThis = null) {
611
1028
  // A nested closure walked inside a clone shares the clone's context.
612
1029
  const inherit = ctxArg === "" &&
613
1030
  this.ctxRoot !== null &&
@@ -639,7 +1056,7 @@ class Analyzer {
639
1056
  const nameNode = fn.name;
640
1057
  const name = nameNode !== undefined ? (propertyNameText(nameNode) ?? "<computed>") : null;
641
1058
  const owner = ownerClass !== null ? this.className(ownerClass) : null;
642
- const label = `${owner !== null ? `${owner}.` : ""}${name ?? (ts.isConstructorDeclaration(node) ? "constructor" : "<fn>")}@${locLabel(node)}`;
1059
+ const label = `${owner !== null ? `${owner}.` : ""}${name ?? (ts.isConstructorDeclaration(node) ? "constructor" : "<fn>")}@${this.loc(node)}`;
643
1060
  const info = {
644
1061
  node,
645
1062
  ctx,
@@ -648,7 +1065,11 @@ class Analyzer {
648
1065
  label: ctx === "" ? label : `${label} [${this.ctxLabel(ctx)}]`,
649
1066
  params,
650
1067
  rest,
651
- thisNode: isArrow && this.currentFn !== null ? this.currentFn.thisNode : this.newNode(),
1068
+ thisNode: isArrow && lexicalThis !== null
1069
+ ? lexicalThis
1070
+ : isArrow && this.currentFn !== null
1071
+ ? this.currentFn.thisNode
1072
+ : this.newNode(),
652
1073
  ret: this.newNode(),
653
1074
  isArrow,
654
1075
  isAsync: mods.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword),
@@ -685,7 +1106,7 @@ class Analyzer {
685
1106
  if (p.dotDotDotToken !== undefined) {
686
1107
  const arr = this.atoms.intern(`rest:${this.nodes.length}`, () => ({
687
1108
  kind: "array",
688
- label: `rest@${locLabel(p)}`,
1109
+ label: `rest@${this.loc(p)}`,
689
1110
  node: p,
690
1111
  }));
691
1112
  this.add(this.binding(p), arr);
@@ -694,8 +1115,12 @@ class Analyzer {
694
1115
  }
695
1116
  const body = fn.body;
696
1117
  if (body !== undefined) {
697
- if (ts.isBlock(body))
1118
+ if (ts.isBlock(body)) {
698
1119
  this.stmts(list(body.statements));
1120
+ // A call that runs off the end of the body returns undefined.
1121
+ if (canComplete(list(body.statements)))
1122
+ this.add(info.ret, this.prim("undefined"));
1123
+ }
699
1124
  else
700
1125
  this.edge(this.expr(body), info.ret);
701
1126
  }
@@ -730,7 +1155,7 @@ class Analyzer {
730
1155
  const p = decl.parent;
731
1156
  if (p !== undefined && ts.isVariableDeclaration(p) && ts.isIdentifier(p.name))
732
1157
  return p.name.text;
733
- return `<class@${locLabel(decl)}>`;
1158
+ return `<class@${this.loc(decl)}>`;
734
1159
  }
735
1160
  classAtoms(decl) {
736
1161
  const name = this.className(decl);
@@ -769,7 +1194,7 @@ class Analyzer {
769
1194
  ctx: "",
770
1195
  root: null,
771
1196
  walked: true,
772
- label: `${label}.${suffix}@${locLabel(decl)}`,
1197
+ label: `${label}.${suffix}@${this.loc(decl)}`,
773
1198
  params: [],
774
1199
  rest: -1,
775
1200
  thisNode: this.newNode(),
@@ -838,7 +1263,9 @@ class Analyzer {
838
1263
  this.callConstructorChain(decl, instance, args, spread, site);
839
1264
  }
840
1265
  callConstructorChain(decl, instance, args, spread, site) {
841
- const key = `ctor:${this.nodeKey(decl)}:${instance.id}:${this.nodeKey(site)}`;
1266
+ // The arguments' nodes too: one `new` site walked in several contexts
1267
+ // (receiver classes, per-site clones) passes each context's values.
1268
+ const key = `ctor:${this.nodeKey(decl)}:${instance.id}:${this.nodeKey(site)}:${args.join(",")}`;
842
1269
  if (this.boundCalls.has(key))
843
1270
  return;
844
1271
  this.boundCalls.add(key);
@@ -850,7 +1277,7 @@ class Analyzer {
850
1277
  this.activate(info);
851
1278
  this.add(info.thisNode, instance);
852
1279
  this.bindArgs(info, args, spread);
853
- this.edgeFor(site, info);
1280
+ this.edgeFor(site, info, args);
854
1281
  return;
855
1282
  }
856
1283
  const base = this.baseClass(decl);
@@ -894,18 +1321,19 @@ class Analyzer {
894
1321
  }
895
1322
  }
896
1323
  /** Call of a function atom with a receiver node. */
897
- callFunction(info, thisNode, args, spread, dst, site) {
1324
+ callFunction(callee, thisNode, args, spread, dst, site) {
898
1325
  // `() => Object.create(null)` helpers: each call site gets its own
899
1326
  // dictionary, as if the helper were inlined.
900
- if (this.isFactory(info.node)) {
1327
+ if (this.isFactory(callee.node)) {
901
1328
  const d = this.atoms.intern(`dict:${this.nodeKey(site)}`, () => ({
902
1329
  kind: "dictionary",
903
- label: `Object.create@${locLabel(site)}`,
1330
+ label: `Object.create@${this.loc(site)}`,
904
1331
  node: site,
905
1332
  }));
906
1333
  this.add(dst, d);
907
1334
  return;
908
1335
  }
1336
+ const info = this.siteClone(callee, site, args) ?? callee;
909
1337
  this.activate(info);
910
1338
  const fnNode = info.node;
911
1339
  const key = `call:${info.ctx}|${this.nodeKey(fnNode)}:${this.nodeKey(site)}:${thisNode ?? -1}:${dst}`;
@@ -925,7 +1353,88 @@ class Analyzer {
925
1353
  }
926
1354
  else
927
1355
  this.edge(info.ret, dst);
928
- this.edgeFor(site, info);
1356
+ this.edgeFor(site, info, args);
1357
+ }
1358
+ /** The prototype object of a class declaration (`C.prototype`). */
1359
+ classProto(decl) {
1360
+ return this.atoms.intern(`cproto:${this.nodeKey(decl)}`, () => ({
1361
+ kind: "object",
1362
+ label: `${this.className(decl)}.prototype`,
1363
+ node: decl,
1364
+ }));
1365
+ }
1366
+ /** Per-call-site clones of init factories: a function called from
1367
+ * module initialization (top-level code outside loops, or another such
1368
+ * clone) is analyzed once per call site, so the objects it creates are
1369
+ * one allocation per site (`z.string()` and `z.object(…)` schemas,
1370
+ * valibot's schema literals) instead of one per function. Clones run
1371
+ * at most once, which makes their objects singletons. */
1372
+ siteClones = new Map();
1373
+ /** The site-clone context a literal at `node` is allocated in, or "". */
1374
+ siteCloneCtx(node) {
1375
+ const root = this.ctxRoot;
1376
+ if (!this.ctx.includes("@S") || root === null)
1377
+ return "";
1378
+ const inside = node.getSourceFile() === root.getSourceFile() && node.pos >= root.pos && node.end <= root.end;
1379
+ return inside ? this.ctx : "";
1380
+ }
1381
+ siteClone(info, site, args) {
1382
+ if (this.siteCloneLimit === 0 || info.isGenerator || ts.isSourceFile(info.node))
1383
+ return null;
1384
+ if (ts.isClassLikeDeclaration(info.node))
1385
+ return null;
1386
+ // A function walked in an enclosing clone's or receiver's context reads
1387
+ // and writes that context's bindings of the variables it captures. A
1388
+ // clone is its own context root, so it would resolve them in the
1389
+ // default context instead, and their writes would be lost.
1390
+ if (info.root !== null && info.root !== info.node)
1391
+ return null;
1392
+ // A class's constructor and methods run in receiver contexts of their
1393
+ // own, rooted at each member: inside a clone they too would resolve the
1394
+ // function's bindings in the default context.
1395
+ if (this.declaresClass(info.node))
1396
+ return null;
1397
+ const sc = this.argsFrom.get(args);
1398
+ if (sc === undefined || sc.inLoop || this.forceLoop || this.repeatingSites.has(site))
1399
+ return null;
1400
+ const caller = sc.caller;
1401
+ if (caller === null)
1402
+ return null;
1403
+ // The clone itself, not a closure created inside it (which inherits
1404
+ // its context but may run any number of times).
1405
+ const callerInit = ts.isSourceFile(caller.node) || (caller.ctx.includes("@S") && caller.root === caller.node);
1406
+ if (!callerInit)
1407
+ return null;
1408
+ // A clone inside a clone keys on the whole chain of sites.
1409
+ const chain = caller.ctx.includes("@S") ? caller.ctx.slice(caller.ctx.indexOf("@S")) : "";
1410
+ if (chain.split("@S").length > SITE_CLONE_DEPTH)
1411
+ return null;
1412
+ const ctx = `${info.ctx}${chain}@S${this.nodeKey(site)}`;
1413
+ const existing = this.functions.get(`${ctx}|${this.nodeKey(info.node)}`);
1414
+ if (existing !== undefined)
1415
+ return existing;
1416
+ const count = this.siteClones.get(info.node) ?? 0;
1417
+ if (count >= this.siteCloneLimit)
1418
+ return null;
1419
+ this.siteClones.set(info.node, count + 1);
1420
+ // The clone keeps the function's receiver: an arrow's lexical `this`,
1421
+ // and whatever reaches a function's own `this`, such as the receiver
1422
+ // `bind` supplies.
1423
+ const clone = this.functionInfo(info.node, info.ownerClass, ctx, info.thisNode);
1424
+ if (!clone.isArrow)
1425
+ this.edge(info.thisNode, clone.thisNode);
1426
+ return clone;
1427
+ }
1428
+ classDeclarers = new Map();
1429
+ /** Whether a class declaration or expression is anywhere inside `node`. */
1430
+ declaresClass(node) {
1431
+ let r = this.classDeclarers.get(node);
1432
+ if (r === undefined) {
1433
+ const visit = (n) => ts.isClassLikeDeclaration(n) ? true : ts.forEachChild(n, visit);
1434
+ r = ts.forEachChild(node, visit) === true;
1435
+ this.classDeclarers.set(node, r);
1436
+ }
1437
+ return r;
929
1438
  }
930
1439
  factories = new Map();
931
1440
  isFactory(node) {
@@ -969,7 +1478,7 @@ class Analyzer {
969
1478
  syntheticArray(site, tag) {
970
1479
  return this.atoms.intern(`arr:${tag}:${this.nodeKey(site)}`, () => ({
971
1480
  kind: "array",
972
- label: `${tag}[]@${locLabel(site)}`,
1481
+ label: `${tag}[]@${this.loc(site)}`,
973
1482
  node: site,
974
1483
  }));
975
1484
  }
@@ -1013,8 +1522,12 @@ class Analyzer {
1013
1522
  return;
1014
1523
  }
1015
1524
  if (ts.isReturnStatement(s)) {
1016
- if (s.expression !== undefined && this.currentFn !== null)
1525
+ if (this.currentFn === null)
1526
+ return;
1527
+ if (s.expression !== undefined)
1017
1528
  this.edge(this.expr(s.expression), this.currentFn.ret);
1529
+ else
1530
+ this.add(this.currentFn.ret, this.prim("undefined"));
1018
1531
  return;
1019
1532
  }
1020
1533
  if (ts.isFunctionDeclaration(s)) {
@@ -1085,7 +1598,7 @@ class Analyzer {
1085
1598
  return;
1086
1599
  }
1087
1600
  if (ts.isThrowStatement(s)) {
1088
- this.sink(this.expr(s.expression), `thrown at ${locLabel(s)}`);
1601
+ this.sink(this.expr(s.expression), `thrown at ${this.loc(s)}`);
1089
1602
  return;
1090
1603
  }
1091
1604
  if (ts.isImportDeclaration(s) ||
@@ -1097,6 +1610,10 @@ class Analyzer {
1097
1610
  this.expr(s.expression);
1098
1611
  return;
1099
1612
  }
1613
+ if (ts.isIfStatement(s) && this.currentFn !== null) {
1614
+ this.ifStatement(s);
1615
+ return;
1616
+ }
1100
1617
  // Blocks, ifs, switches, labels: walk children, evaluating expressions.
1101
1618
  ts.forEachChild(s, (child) => {
1102
1619
  if (ts.isExpression(child))
@@ -1110,6 +1627,13 @@ class Analyzer {
1110
1627
  const b = this.binding(d);
1111
1628
  if (d.initializer !== undefined)
1112
1629
  this.edge(this.expr(d.initializer), b);
1630
+ else {
1631
+ // `let x;` holds undefined until it is assigned (a for-in/for-of
1632
+ // binding gets its values from the loop).
1633
+ const loop = d.parent?.parent;
1634
+ if (loop === undefined || !(ts.isForOfStatement(loop) || ts.isForInStatement(loop)))
1635
+ this.add(b, this.prim("undefined"));
1636
+ }
1113
1637
  this.bindPattern(d.name, b);
1114
1638
  }
1115
1639
  /** Destructuring: binding elements read from the source node. */
@@ -1168,7 +1692,7 @@ class Analyzer {
1168
1692
  else {
1169
1693
  this.add(dst, this.top);
1170
1694
  if (a.kind !== "top")
1171
- this.escape(a, `iterated at ${locLabel(site)}`);
1695
+ this.escape(a, `iterated at ${this.loc(site)}`);
1172
1696
  }
1173
1697
  });
1174
1698
  }
@@ -1178,10 +1702,18 @@ class Analyzer {
1178
1702
  const memo = this.exprMemo.get(key);
1179
1703
  if (memo !== undefined)
1180
1704
  return memo;
1181
- const id = this.exprUncached(e);
1705
+ let id = this.exprUncached(e);
1706
+ // A member of an optional chain (`a?.b.c`, `f?.()`) is undefined when
1707
+ // the chain short-circuits.
1708
+ if ((e.flags & ts.NodeFlags.OptionalChain) !== 0) {
1709
+ const out = this.newNode();
1710
+ this.edge(id, out);
1711
+ this.add(out, this.prim("undefined"));
1712
+ id = out;
1713
+ }
1182
1714
  this.exprMemo.set(key, id);
1183
1715
  if (this.traceTop && !this.nodeLabel.has(id))
1184
- this.nodeLabel.set(id, `expr ${e.getText().slice(0, 40).replace(/\s+/g, " ")}@${locLabel(e)}`);
1716
+ this.nodeLabel.set(id, `expr ${e.getText().slice(0, 40).replace(/\s+/g, " ")}@${this.loc(e)}`);
1185
1717
  return id;
1186
1718
  }
1187
1719
  exprUncached(e) {
@@ -1201,8 +1733,9 @@ class Analyzer {
1201
1733
  case ts.SyntaxKind.BigIntLiteral:
1202
1734
  return this.constNode(this.prim("bigint"));
1203
1735
  case ts.SyntaxKind.TrueKeyword:
1736
+ return this.constNode(this.boolLiteral(true));
1204
1737
  case ts.SyntaxKind.FalseKeyword:
1205
- return this.constNode(this.prim("boolean"));
1738
+ return this.constNode(this.boolLiteral(false));
1206
1739
  case ts.SyntaxKind.NullKeyword:
1207
1740
  return this.constNode(this.prim("null"));
1208
1741
  case ts.SyntaxKind.RegularExpressionLiteral:
@@ -1298,18 +1831,23 @@ class Analyzer {
1298
1831
  const recv = this.expr(target.expression);
1299
1832
  const name = ts.isPropertyAccessExpression(target) ? target.name.text : null;
1300
1833
  this.ops.push({ kind: "delete", recv, name, node: e });
1834
+ this.prototypeWrite(recv, name);
1301
1835
  }
1302
1836
  return this.constNode(this.prim("boolean"));
1303
1837
  }
1304
1838
  if (ts.isPrefixUnaryExpression(e) || ts.isPostfixUnaryExpression(e)) {
1305
1839
  const operand = e.operand;
1306
- this.expr(operand);
1307
- if (e.operator === ts.SyntaxKind.PlusPlusToken ||
1308
- e.operator === ts.SyntaxKind.MinusMinusToken)
1309
- this.assignTo(operand, this.constNode(this.prim("number")));
1840
+ const value = this.expr(operand);
1310
1841
  if (ts.isPrefixUnaryExpression(e) && e.operator === ts.SyntaxKind.ExclamationToken)
1311
1842
  return this.constNode(this.prim("boolean"));
1312
- return this.constNode(this.prim("number"));
1843
+ // `+x` is a number (a bigint throws); `-x`, `~x`, `++`/`--` keep a bigint.
1844
+ if (ts.isPrefixUnaryExpression(e) && e.operator === ts.SyntaxKind.PlusToken)
1845
+ return this.constNode(this.prim("number"));
1846
+ const result = this.numericResult([value]);
1847
+ if (e.operator === ts.SyntaxKind.PlusPlusToken ||
1848
+ e.operator === ts.SyntaxKind.MinusMinusToken)
1849
+ this.assignTo(operand, result);
1850
+ return result;
1313
1851
  }
1314
1852
  if (ts.isSpreadElement(e))
1315
1853
  return this.expr(e.expression);
@@ -1317,7 +1855,7 @@ class Analyzer {
1317
1855
  return this.taggedTemplate(e);
1318
1856
  if (ts.isYieldExpression(e)) {
1319
1857
  if (e.expression !== undefined)
1320
- this.sink(this.expr(e.expression), `yielded at ${locLabel(e)}`);
1858
+ this.sink(this.expr(e.expression), `yielded at ${this.loc(e)}`);
1321
1859
  return this.constNode(this.top);
1322
1860
  }
1323
1861
  if (ts.isMetaProperty(e))
@@ -1343,6 +1881,8 @@ class Analyzer {
1343
1881
  const arr = this.syntheticArray(id, "arguments");
1344
1882
  for (const p of fn.params)
1345
1883
  this.edge(p, this.element(arr));
1884
+ // Arguments past the declared parameters are not tracked.
1885
+ this.add(this.element(arr), this.top);
1346
1886
  return this.constNode(arr);
1347
1887
  }
1348
1888
  }
@@ -1581,7 +2121,7 @@ class Analyzer {
1581
2121
  let hasComputedKey = false;
1582
2122
  const spreads = [];
1583
2123
  const inPackage = isPackageJsFile(e.getSourceFile());
1584
- const label = () => `{${keys.slice(0, 6).join(",")}${keys.length > 6 ? ",…" : ""}${keysKnown ? "" : ",…"}}@${locLabel(e)}`;
2124
+ const label = () => `{${keys.slice(0, 6).join(",")}${keys.length > 6 ? ",…" : ""}${keysKnown ? "" : ",…"}}@${this.loc(e)}`;
1585
2125
  // keys first, so the label is complete
1586
2126
  for (const p of list(e.properties)) {
1587
2127
  if (ts.isSpreadAssignment(p)) {
@@ -1600,11 +2140,8 @@ class Analyzer {
1600
2140
  if (!keys.includes(key))
1601
2141
  keys.push(key);
1602
2142
  }
1603
- const atom = this.atoms.intern(`obj:${this.nodeKey(e)}`, () => ({
1604
- kind: "object",
1605
- label: label(),
1606
- node: e,
1607
- }));
2143
+ const sctx = this.siteCloneCtx(e);
2144
+ const atom = this.atoms.intern(sctx === "" ? `obj:${this.nodeKey(e)}` : `obj:${sctx}|${this.nodeKey(e)}`, () => ({ kind: "object", label: label(), node: e, ...(sctx === "" ? {} : { ctx: sctx }) }));
1608
2145
  const n = this.newNode();
1609
2146
  this.add(n, atom);
1610
2147
  for (const p of list(e.properties)) {
@@ -1649,17 +2186,21 @@ class Analyzer {
1649
2186
  else
1650
2187
  this.edge(value, this.anyField(atom));
1651
2188
  }
2189
+ if (!this.literalOwnKeys.has(atom))
2190
+ this.literalOwnKeys.set(atom, new Set(keys));
1652
2191
  if (!this.siteAtoms.has(atom) && this.siteAtoms.add(atom))
1653
2192
  this.sites.push({
1654
2193
  atom,
1655
2194
  node: e,
1656
2195
  kind: "object",
1657
2196
  keys: keysKnown ? keys : null,
2197
+ ownKeys: keys,
1658
2198
  hasAccessor,
1659
2199
  hasProto,
1660
2200
  hasComputedKey,
1661
2201
  spreads,
1662
2202
  inPackage,
2203
+ ctx: sctx,
1663
2204
  });
1664
2205
  return n;
1665
2206
  }
@@ -1786,10 +2327,12 @@ class Analyzer {
1786
2327
  this.lateCopies.push(call);
1787
2328
  }
1788
2329
  arrayLiteral(e) {
1789
- const atom = this.atoms.intern(`arr:${this.nodeKey(e)}`, () => ({
2330
+ const sctx = this.siteCloneCtx(e);
2331
+ const atom = this.atoms.intern(sctx === "" ? `arr:${this.nodeKey(e)}` : `arr:${sctx}|${this.nodeKey(e)}`, () => ({
1790
2332
  kind: "array",
1791
- label: `[]@${locLabel(e)}`,
2333
+ label: `[]@${this.loc(e)}`,
1792
2334
  node: e,
2335
+ ...(sctx === "" ? {} : { ctx: sctx }),
1793
2336
  }));
1794
2337
  const n = this.newNode();
1795
2338
  this.add(n, atom);
@@ -1811,11 +2354,13 @@ class Analyzer {
1811
2354
  node: e,
1812
2355
  kind: "array",
1813
2356
  keys: null,
2357
+ ownKeys: [],
1814
2358
  hasAccessor: false,
1815
2359
  hasProto: hasHole,
1816
2360
  hasComputedKey: false,
1817
2361
  spreads: [],
1818
2362
  inPackage: isPackageJsFile(e.getSourceFile()),
2363
+ ctx: sctx,
1819
2364
  });
1820
2365
  return n;
1821
2366
  }
@@ -1837,14 +2382,12 @@ class Analyzer {
1837
2382
  return n;
1838
2383
  }
1839
2384
  if (op >= ts.SyntaxKind.FirstCompoundAssignment && op <= ts.SyntaxKind.LastCompoundAssignment) {
1840
- this.expr(e.left);
1841
- this.expr(e.right);
1842
- const result = this.constNode(op === ts.SyntaxKind.PlusEqualsToken ? this.top : this.prim("number"));
1843
- if (op === ts.SyntaxKind.PlusEqualsToken) {
1844
- this.nodes[result].atoms.clear();
2385
+ const lv = this.expr(e.left);
2386
+ const rv = this.expr(e.right);
2387
+ // Arithmetic on bigints answers bigints; `+=` may also concatenate.
2388
+ const result = this.numericResult([lv, rv]);
2389
+ if (op === ts.SyntaxKind.PlusEqualsToken)
1845
2390
  this.add(result, this.prim("string"));
1846
- this.add(result, this.prim("number"));
1847
- }
1848
2391
  this.assignTo(e.left, result);
1849
2392
  return result;
1850
2393
  }
@@ -1885,13 +2428,15 @@ class Analyzer {
1885
2428
  this.add(n, this.prim("number"));
1886
2429
  if (a.kind === "top")
1887
2430
  this.add(n, this.prim("number"));
2431
+ if (a.kind === "top" || (a.kind === "prim" && a.label === "bigint"))
2432
+ this.add(n, this.prim("bigint"));
1888
2433
  };
1889
2434
  this.on(l, strOrNum);
1890
2435
  this.on(r, strOrNum);
1891
2436
  return n;
1892
2437
  }
1893
2438
  default:
1894
- return this.constNode(this.prim("number"));
2439
+ return this.numericResult([l, r]);
1895
2440
  }
1896
2441
  }
1897
2442
  assignTo(target, value) {
@@ -1899,7 +2444,7 @@ class Analyzer {
1899
2444
  if (ts.isIdentifier(t)) {
1900
2445
  const decl = this.resolve(t);
1901
2446
  if (decl === undefined || decl.getSourceFile().isDeclarationFile) {
1902
- this.sink(value, `global write at ${locLabel(t)}`);
2447
+ this.sink(value, `global write at ${this.loc(t)}`);
1903
2448
  return;
1904
2449
  }
1905
2450
  this.edge(value, this.binding(decl));
@@ -1972,8 +2517,22 @@ class Analyzer {
1972
2517
  case "prim":
1973
2518
  if (name === "length" && a.label === "string")
1974
2519
  this.add(dst, this.prim("number"));
1975
- else if (a.label === "string" || a.label === "number" || a.label === "boolean")
1976
- this.add(dst, this.builtin(`${a.label}.${name}`, a));
2520
+ else if (a.label === "string" && /^\d+$/.test(name)) {
2521
+ // An index past the end reads the prototype chain.
2522
+ this.add(dst, this.prim("string"));
2523
+ this.add(dst, this.prim("undefined"));
2524
+ this.primitiveRead(name, dst);
2525
+ }
2526
+ else if (a.label === "string" || a.label === "number" || a.label === "boolean") {
2527
+ // A name the primitive's prototype chain lacks reads undefined,
2528
+ // unless the program may add it there.
2529
+ if (PRIMITIVE_MEMBERS[a.label].has(name) || OBJECT_PROTOTYPE_MEMBERS.has(name))
2530
+ this.add(dst, this.builtin(`${a.label}.${name}`, a));
2531
+ else {
2532
+ this.add(dst, this.prim("undefined"));
2533
+ this.primitiveRead(name, dst);
2534
+ }
2535
+ }
1977
2536
  return;
1978
2537
  case "instance": {
1979
2538
  const decl = a.node;
@@ -1984,6 +2543,9 @@ class Analyzer {
1984
2543
  this.unknownKeysInto(a, dst);
1985
2544
  return;
1986
2545
  }
2546
+ // Members stored on a class's prototype object after the fact.
2547
+ for (const c of this.classChain(decl))
2548
+ this.edge(this.field(this.classProto(c), name), dst);
1987
2549
  const member = this.lookupMember(decl, name, false);
1988
2550
  if (member?.kind === "method")
1989
2551
  this.add(dst, this.fnAtom(member.method, this.ownerOf(member.method), this.receiverCtx(a)));
@@ -2004,7 +2566,9 @@ class Analyzer {
2004
2566
  case "class": {
2005
2567
  const decl = a.node;
2006
2568
  if (name === "prototype" || name === "name") {
2007
- this.add(dst, name === "prototype" ? this.top : this.prim("string"));
2569
+ // A class's prototype object: members stored on it later
2570
+ // (`C.prototype.isVector3 = true`) are members of its instances.
2571
+ this.add(dst, name === "prototype" ? this.classProto(decl) : this.prim("string"));
2008
2572
  this.fieldInto(a, name, dst);
2009
2573
  this.unknownKeysInto(a, dst);
2010
2574
  return;
@@ -2051,8 +2615,10 @@ class Analyzer {
2051
2615
  case "array":
2052
2616
  if (name === "length")
2053
2617
  this.add(dst, this.prim("number"));
2054
- else if (/^\d+$/.test(name))
2618
+ else if (/^\d+$/.test(name)) {
2055
2619
  this.edge(this.element(a), dst);
2620
+ this.add(dst, this.prim("undefined"));
2621
+ }
2056
2622
  else {
2057
2623
  // A named property, written by name or under an unknown key; an own field shadows a method.
2058
2624
  if (ARRAY_METHODS.has(name)) {
@@ -2065,8 +2631,17 @@ class Analyzer {
2065
2631
  }
2066
2632
  return;
2067
2633
  case "object": {
2634
+ // A read through a class's prototype object (`C.prototype.m`) may
2635
+ // be any member: unknown, as before prototype objects were tracked.
2636
+ if (a.label.endsWith(".prototype") &&
2637
+ a.node !== undefined &&
2638
+ ts.isClassLikeDeclaration(a.node))
2639
+ this.add(dst, this.top);
2068
2640
  this.edge(this.field(a, name), dst);
2069
2641
  this.edge(this.anyField(a), dst);
2642
+ const own = this.literalOwnKeys.get(a);
2643
+ if (own !== undefined && !own.has(name) && !OBJECT_PROTOTYPE_MEMBERS.has(name))
2644
+ this.add(dst, this.prim("undefined"));
2070
2645
  if (this.namespaceAtoms.has(a) && name !== "exports") {
2071
2646
  this.loadConstraint(this.field(a, "exports"), name, dst, site);
2072
2647
  }
@@ -2092,10 +2667,24 @@ class Analyzer {
2092
2667
  this.add(dst, this.builtin(`object.${name}`, a));
2093
2668
  return;
2094
2669
  }
2095
- case "dictionary":
2670
+ case "dictionary": {
2096
2671
  this.edge(this.anyField(a), dst);
2097
2672
  this.edge(this.field(a, name), dst);
2673
+ // An absent key reads undefined, or what the prototype has.
2674
+ this.add(dst, this.prim("undefined"));
2675
+ const proto = this.dictProtos.get(a);
2676
+ // Once per dictionary, name and destination: prototype chains can
2677
+ // be cyclic in the analysis (`Object.create(this)`).
2678
+ const key = `${a.id}:${name}:${dst}`;
2679
+ if (proto !== undefined && !this.protoReads.has(key)) {
2680
+ this.protoReads.add(key);
2681
+ this.on(proto, (p) => {
2682
+ if (p.kind !== "prim")
2683
+ this.loadAtom(p, name, dst, site);
2684
+ });
2685
+ }
2098
2686
  return;
2687
+ }
2099
2688
  case "promise":
2100
2689
  if (name === "then" || name === "catch" || name === "finally")
2101
2690
  this.add(dst, this.builtin(`promise.${name}`, a));
@@ -2130,8 +2719,16 @@ class Analyzer {
2130
2719
  this.add(dst, this.prim("number"));
2131
2720
  else if (path === "Math" && /^[A-Z0-9_]+$/.test(name))
2132
2721
  this.add(dst, this.prim("number"));
2133
- else if (path === "Symbol")
2134
- this.add(dst, this.prim("symbol"));
2722
+ else if (path === "Symbol") {
2723
+ // The well-known symbols are symbols; `Symbol.for` and `Symbol.keyFor`
2724
+ // are functions (a call of a symbol would answer nothing).
2725
+ if (WELL_KNOWN_SYMBOLS.has(name))
2726
+ this.add(dst, this.prim("symbol"));
2727
+ else if (name === "for" || name === "keyFor")
2728
+ this.add(dst, this.builtin(`Symbol.${name}`));
2729
+ else
2730
+ this.add(dst, this.top);
2731
+ }
2135
2732
  else if (path === "Error.instance" || path === "error") {
2136
2733
  if (name === "message" || name === "stack" || name === "name")
2137
2734
  this.add(dst, this.prim("string"));
@@ -2140,6 +2737,7 @@ class Analyzer {
2140
2737
  }
2141
2738
  else if (a.receiver === undefined &&
2142
2739
  MODELED_GLOBALS.has(path.split(".")[0]) &&
2740
+ !path.endsWith(".instance") &&
2143
2741
  path.split(".").length < 4)
2144
2742
  this.add(dst, this.builtin(`${path}.${name}`));
2145
2743
  else if (path === "RegExp.instance")
@@ -2152,7 +2750,7 @@ class Analyzer {
2152
2750
  switch (a.kind) {
2153
2751
  case "top":
2154
2752
  this.noteTopWrite(name, site);
2155
- this.sink(value, `stored into ⊤.${name} at ${locLabel(site)}`);
2753
+ this.sink(value, `stored into ⊤.${name} at ${this.loc(site)}`);
2156
2754
  return;
2157
2755
  case "instance": {
2158
2756
  const member = this.lookupMember(a.node, name, false);
@@ -2174,6 +2772,8 @@ class Analyzer {
2174
2772
  this.edge(value, this.field(a, name));
2175
2773
  return;
2176
2774
  case "array":
2775
+ if (/^\d+$/.test(name) || name === "length")
2776
+ this.unsafeArrays.add(a);
2177
2777
  if (/^\d+$/.test(name))
2178
2778
  this.edge(value, this.element(a));
2179
2779
  else if (name !== "length")
@@ -2182,7 +2782,9 @@ class Analyzer {
2182
2782
  case "prim":
2183
2783
  return;
2184
2784
  default:
2185
- this.sink(value, `stored into ${a.label} at ${locLabel(site)}`);
2785
+ if (isPrimitivePrototype(a))
2786
+ this.extendPrimitives(name);
2787
+ this.sink(value, `stored into ${a.label} at ${this.loc(site)}`);
2186
2788
  }
2187
2789
  });
2188
2790
  }
@@ -2193,12 +2795,23 @@ class Analyzer {
2193
2795
  this.add(dst, this.top);
2194
2796
  return;
2195
2797
  case "array":
2798
+ // An index past the end (or a hole) reads undefined, unless the
2799
+ // loop proves the index in bounds of an array without holes.
2800
+ this.edge(this.element(a), dst);
2801
+ if (this.indexInBounds(site))
2802
+ this.guardedIndexReads.push({ recv: a, dst, done: false });
2803
+ else
2804
+ this.add(dst, this.prim("undefined"));
2805
+ return;
2196
2806
  case "collection":
2197
2807
  this.edge(this.element(a), dst);
2198
2808
  return;
2199
2809
  case "prim":
2200
- if (a.label === "string")
2810
+ if (a.label === "string") {
2201
2811
  this.add(dst, this.prim("string"));
2812
+ if (!this.indexInBounds(site))
2813
+ this.add(dst, this.prim("undefined"));
2814
+ }
2202
2815
  return;
2203
2816
  case "object":
2204
2817
  case "dictionary":
@@ -2219,6 +2832,9 @@ class Analyzer {
2219
2832
  this.lateCopies.push(copy);
2220
2833
  if (a.kind === "instance" || a.kind === "class")
2221
2834
  this.add(dst, this.top);
2835
+ // A key the object does not have reads undefined.
2836
+ else
2837
+ this.add(dst, this.prim("undefined"));
2222
2838
  return;
2223
2839
  }
2224
2840
  default:
@@ -2232,12 +2848,14 @@ class Analyzer {
2232
2848
  switch (a.kind) {
2233
2849
  case "top":
2234
2850
  this.noteTopWrite(null, site);
2235
- this.sink(value, `stored into ⊤[k] at ${locLabel(site)}`);
2851
+ this.sink(value, `stored into ⊤[k] at ${this.loc(site)}`);
2236
2852
  return;
2237
2853
  case "array":
2238
2854
  // An index, or a named property under an unknown key.
2239
2855
  this.edge(value, this.element(a));
2240
2856
  this.edge(value, this.anyField(a));
2857
+ if (!this.indexInBounds(site) && !isAppendIndex(site))
2858
+ this.unsafeArrays.add(a);
2241
2859
  return;
2242
2860
  case "prim":
2243
2861
  return;
@@ -2250,7 +2868,9 @@ class Analyzer {
2250
2868
  return;
2251
2869
  default:
2252
2870
  // As a store under a name: a builtin, promise or collection keeps it where it isn't tracked.
2253
- this.sink(value, `stored into ${a.label}[k] at ${locLabel(site)}`);
2871
+ if (isPrimitivePrototype(a))
2872
+ this.extendPrimitives(null);
2873
+ this.sink(value, `stored into ${a.label}[k] at ${this.loc(site)}`);
2254
2874
  }
2255
2875
  });
2256
2876
  }
@@ -2309,8 +2929,19 @@ class Analyzer {
2309
2929
  }
2310
2930
  out.push(this.expr(a));
2311
2931
  }
2932
+ // The walk context of this call (one argument list per call site and
2933
+ // context): calls fire during solving, after the walk moved on.
2934
+ this.argsFrom.set(out, {
2935
+ caller: this.currentFn,
2936
+ inLoop: this.loopDepth > 0 || this.forceLoop,
2937
+ });
2312
2938
  return { args: out, spread };
2313
2939
  }
2940
+ /** Per argument list (args()), the calling function and whether the call
2941
+ * is in a loop, in the context the call was walked in. siteCtx keeps
2942
+ * the first context per syntax node, which a site walked in several
2943
+ * contexts (receiver classes, per-site clones) does not determine. */
2944
+ argsFrom = new Map();
2314
2945
  call(e) {
2315
2946
  this.noteSite(e);
2316
2947
  const callee = unparen(e.expression);
@@ -2328,7 +2959,7 @@ class Analyzer {
2328
2959
  }
2329
2960
  else if (base === undefined)
2330
2961
  for (const a of args)
2331
- this.sink(a, `super(...) at ${locLabel(e)}`);
2962
+ this.sink(a, `super(...) at ${this.loc(e)}`);
2332
2963
  return dst;
2333
2964
  }
2334
2965
  // CommonJS `require("<spec>")` of an analyzed module: its exports (the
@@ -2382,6 +3013,8 @@ class Analyzer {
2382
3013
  }
2383
3014
  if (name !== null)
2384
3015
  this.ops.push({ kind: "read", recv, name, node: callee });
3016
+ else
3017
+ this.ops.push({ kind: "computedRead", recv, name: null, node: callee });
2385
3018
  // Per receiver atom: the member it resolves to runs with that atom as `this`.
2386
3019
  const member = name;
2387
3020
  this.on(recv, (a) => {
@@ -2416,9 +3049,9 @@ class Analyzer {
2416
3049
  return;
2417
3050
  default:
2418
3051
  for (const x of args)
2419
- this.sink(x, `argument of ⊤ call at ${locLabel(site)}`);
3052
+ this.sink(x, `argument of ⊤ call at ${this.loc(site)}`);
2420
3053
  if (recv !== null && a.kind === "top")
2421
- this.sink(recv, `receiver of ⊤ call at ${locLabel(site)}`);
3054
+ this.sink(recv, `receiver of ⊤ call at ${this.loc(site)}`);
2422
3055
  this.add(dst, this.top);
2423
3056
  }
2424
3057
  });
@@ -2447,17 +3080,24 @@ class Analyzer {
2447
3080
  this.activate(info);
2448
3081
  this.add(info.thisNode, inst);
2449
3082
  this.bindArgs(info, args, spread);
2450
- this.edge(info.ret, dst);
2451
- this.edgeFor(e, info);
3083
+ // `new` ignores a primitive result (and the undefined of a
3084
+ // body that runs off its end) and yields the instance.
3085
+ this.on(info.ret, (r) => {
3086
+ if (r.kind !== "prim")
3087
+ this.add(dst, r);
3088
+ });
3089
+ this.edgeFor(e, info, args);
2452
3090
  }
2453
3091
  return;
2454
3092
  }
2455
3093
  case "builtin":
2456
3094
  this.constructBuiltin(a.path ?? "", args, dst, e);
2457
3095
  return;
3096
+ case "prim":
3097
+ return; // `new` of a primitive throws
2458
3098
  default:
2459
3099
  for (const x of args)
2460
- this.sink(x, `argument of ⊤ constructor at ${locLabel(e)}`);
3100
+ this.sink(x, `argument of ⊤ constructor at ${this.loc(e)}`);
2461
3101
  this.add(dst, this.top);
2462
3102
  }
2463
3103
  });
@@ -2471,7 +3111,7 @@ class Analyzer {
2471
3111
  case "WeakSet": {
2472
3112
  const c = this.atoms.intern(`coll:${this.nodeKey(site)}`, () => ({
2473
3113
  kind: "collection",
2474
- label: `${path}@${locLabel(site)}`,
3114
+ label: `${path}@${this.loc(site)}`,
2475
3115
  node: site,
2476
3116
  }));
2477
3117
  this.add(dst, c);
@@ -2486,7 +3126,7 @@ class Analyzer {
2486
3126
  this.add(dst, this.builtin("Error.instance"));
2487
3127
  return;
2488
3128
  case "Promise": {
2489
- const p = this.promiseAtom(site, locLabel(site));
3129
+ const p = this.promiseAtom(site, this.loc(site));
2490
3130
  this.add(this.field(p, "value"), this.top);
2491
3131
  this.add(dst, p);
2492
3132
  if (args[0] !== undefined) {
@@ -2505,7 +3145,10 @@ class Analyzer {
2505
3145
  this.add(dst, this.builtin("RegExp.instance"));
2506
3146
  return;
2507
3147
  case "Array": {
2508
- this.add(dst, this.syntheticArray(site, "Array"));
3148
+ const arr = this.syntheticArray(site, "Array");
3149
+ // `new Array(n)` has holes.
3150
+ this.unsafeArrays.add(arr);
3151
+ this.add(dst, arr);
2509
3152
  return;
2510
3153
  }
2511
3154
  case "Proxy":
@@ -2513,12 +3156,12 @@ class Analyzer {
2513
3156
  if (args[0] !== undefined)
2514
3157
  this.ops.push({ kind: "proxy", recv: args[0], name: null, node: site });
2515
3158
  for (const x of args)
2516
- this.sink(x, `argument of new Proxy at ${locLabel(site)}`);
3159
+ this.sink(x, `argument of new Proxy at ${this.loc(site)}`);
2517
3160
  this.add(dst, this.top);
2518
3161
  return;
2519
3162
  default:
2520
3163
  for (const x of args)
2521
- this.sink(x, `argument of new ${path} at ${locLabel(site)}`);
3164
+ this.sink(x, `argument of new ${path} at ${this.loc(site)}`);
2522
3165
  this.add(dst, this.top);
2523
3166
  }
2524
3167
  }
@@ -2540,7 +3183,7 @@ class Analyzer {
2540
3183
  }
2541
3184
  else if (f.kind === "top" || f.kind === "builtin") {
2542
3185
  for (const x of cbArgs)
2543
- this.sink(x, `argument of ⊤ callback at ${locLabel(site)}`);
3186
+ this.sink(x, `argument of ⊤ callback at ${this.loc(site)}`);
2544
3187
  if (ret !== null)
2545
3188
  this.add(ret, this.top);
2546
3189
  }
@@ -2548,7 +3191,7 @@ class Analyzer {
2548
3191
  };
2549
3192
  const escapeAll = () => {
2550
3193
  for (const x of args)
2551
- this.sink(x, `argument of ${path} at ${locLabel(site)}`);
3194
+ this.sink(x, `argument of ${path} at ${this.loc(site)}`);
2552
3195
  this.add(dst, this.top);
2553
3196
  };
2554
3197
  // Methods of builtin receivers.
@@ -2572,6 +3215,8 @@ class Analyzer {
2572
3215
  case "pop":
2573
3216
  case "shift":
2574
3217
  case "at":
3218
+ if (method !== "at")
3219
+ this.unsafeArrays.add(recv);
2575
3220
  this.edge(el, dst);
2576
3221
  this.add(dst, this.prim("undefined"));
2577
3222
  return;
@@ -2625,6 +3270,8 @@ class Analyzer {
2625
3270
  case "toSorted":
2626
3271
  case "toReversed":
2627
3272
  case "flat": {
3273
+ if (method === "splice")
3274
+ this.unsafeArrays.add(recv);
2628
3275
  if (method === "filter")
2629
3276
  callback(0, [el, num, recvN], null);
2630
3277
  if (method === "sort" || method === "toSorted")
@@ -2679,7 +3326,7 @@ class Analyzer {
2679
3326
  return;
2680
3327
  }
2681
3328
  escapeAll();
2682
- this.escape(recv, `array.${method} at ${locLabel(site)}`);
3329
+ this.escape(recv, `array.${method} at ${this.loc(site)}`);
2683
3330
  return;
2684
3331
  }
2685
3332
  if (path.startsWith("string.") || path.startsWith("number.") || path.startsWith("boolean.")) {
@@ -2705,8 +3352,10 @@ class Analyzer {
2705
3352
  if (method === "test")
2706
3353
  prim("boolean");
2707
3354
  else if (method === "exec") {
3355
+ // The match and its capture groups; a group that did not take part is undefined.
2708
3356
  const out = this.syntheticArray(site, "exec");
2709
3357
  this.add(this.element(out), this.prim("string"));
3358
+ this.add(this.element(out), this.prim("undefined"));
2710
3359
  this.add(dst, out);
2711
3360
  prim("null");
2712
3361
  }
@@ -2715,7 +3364,7 @@ class Analyzer {
2715
3364
  return;
2716
3365
  }
2717
3366
  if (path.startsWith("promise.")) {
2718
- const out = this.promiseAtom(site, locLabel(site));
3367
+ const out = this.promiseAtom(site, this.loc(site));
2719
3368
  const value = this.field(recv, "value");
2720
3369
  const ret = this.newNode();
2721
3370
  if (method === "then") {
@@ -2790,7 +3439,7 @@ class Analyzer {
2790
3439
  for (const p of info.params)
2791
3440
  this.add(p, this.top);
2792
3441
  for (const x of args.slice(1))
2793
- this.sink(x, `bound argument at ${locLabel(site)}`);
3442
+ this.sink(x, `bound argument at ${this.loc(site)}`);
2794
3443
  }
2795
3444
  this.add(dst, recv);
2796
3445
  return;
@@ -2886,12 +3535,13 @@ class Analyzer {
2886
3535
  return;
2887
3536
  case "Object.assign": {
2888
3537
  this.ops.push({ kind: "assign", recv: arg(0), name: null, node: site });
3538
+ this.prototypeWrite(arg(0), null);
2889
3539
  this.on(arg(0), (t) => {
2890
3540
  for (const s of args.slice(1))
2891
3541
  this.copyFields(s, t, site);
2892
3542
  if (t.kind === "top")
2893
3543
  for (const s of args.slice(1))
2894
- this.sink(s, `Object.assign into ⊤ at ${locLabel(site)}`);
3544
+ this.sink(s, `Object.assign into ⊤ at ${this.loc(site)}`);
2895
3545
  });
2896
3546
  this.edge(arg(0), dst);
2897
3547
  return;
@@ -2900,29 +3550,35 @@ class Analyzer {
2900
3550
  case "Object.defineProperties":
2901
3551
  case "Reflect.defineProperty":
2902
3552
  this.ops.push({ kind: "defineProperty", recv: arg(0), name: null, node: site });
2903
- this.sink(arg(2), `property descriptor at ${locLabel(site)}`);
2904
- this.sink(arg(1), `property descriptor at ${locLabel(site)}`);
3553
+ this.prototypeWrite(arg(0), path === "Object.defineProperties" ? null : literalKey(site, 1));
3554
+ this.sink(arg(2), `property descriptor at ${this.loc(site)}`);
3555
+ this.sink(arg(1), `property descriptor at ${this.loc(site)}`);
2905
3556
  this.edge(arg(0), dst);
2906
3557
  return;
2907
3558
  case "Object.setPrototypeOf":
2908
3559
  case "Reflect.setPrototypeOf":
2909
3560
  this.ops.push({ kind: "setPrototypeOf", recv: arg(0), name: null, node: site });
2910
- this.sink(arg(1), `prototype at ${locLabel(site)}`);
3561
+ this.prototypeWrite(arg(0), null);
3562
+ this.sink(arg(1), `prototype at ${this.loc(site)}`);
2911
3563
  this.edge(arg(0), dst);
2912
3564
  return;
2913
3565
  case "Object.create": {
2914
3566
  const d = this.atoms.intern(`dict:${this.nodeKey(site)}`, () => ({
2915
3567
  kind: "dictionary",
2916
- label: `Object.create@${locLabel(site)}`,
3568
+ label: `Object.create@${this.loc(site)}`,
2917
3569
  node: site,
2918
3570
  }));
3571
+ // Its members are inherited from the prototype argument.
3572
+ this.edge(arg(0), this.dictProto(d));
3573
+ if (args[1] !== undefined)
3574
+ this.sink(args[1], `property descriptors at ${locLabel(site)}`);
2919
3575
  this.add(dst, d);
2920
3576
  return;
2921
3577
  }
2922
3578
  case "Object.fromEntries": {
2923
3579
  const d = this.atoms.intern(`dict:${this.nodeKey(site)}`, () => ({
2924
3580
  kind: "dictionary",
2925
- label: `fromEntries@${locLabel(site)}`,
3581
+ label: `fromEntries@${this.loc(site)}`,
2926
3582
  node: site,
2927
3583
  }));
2928
3584
  const pairs = this.newNode();
@@ -2970,7 +3626,7 @@ class Analyzer {
2970
3626
  if (f.kind === "function")
2971
3627
  this.callFunction(this.infoOfAtom(f), revived, [this.constNode(this.prim("string")), revived], false, revived, site);
2972
3628
  else if (f.kind === "top")
2973
- this.sink(revived, `JSON.parse reviver at ${locLabel(site)}`);
3629
+ this.sink(revived, `JSON.parse reviver at ${this.loc(site)}`);
2974
3630
  });
2975
3631
  this.edge(revived, dst);
2976
3632
  return;
@@ -2990,18 +3646,16 @@ class Analyzer {
2990
3646
  if (f.kind === "function")
2991
3647
  this.callFunction(this.infoOfAtom(f), serialized, [key, serialized], false, serialized, site);
2992
3648
  else if (f.kind === "top")
2993
- this.sink(serialized, `JSON.stringify replacer at ${locLabel(site)}`);
3649
+ this.sink(serialized, `JSON.stringify replacer at ${this.loc(site)}`);
2994
3650
  });
2995
3651
  prim("string");
2996
3652
  prim("undefined");
2997
3653
  return;
2998
3654
  }
2999
3655
  case "Reflect.deleteProperty": {
3000
- const key = ts.isCallExpression(site) ? unparen(list(site.arguments)[1]) : undefined;
3001
- const name = key !== undefined && (ts.isStringLiteral(key) || ts.isNoSubstitutionTemplateLiteral(key))
3002
- ? key.text
3003
- : null;
3656
+ const name = literalKey(site, 1);
3004
3657
  this.ops.push({ kind: "delete", recv: arg(0), name, node: site });
3658
+ this.prototypeWrite(arg(0), name);
3005
3659
  prim("boolean");
3006
3660
  return;
3007
3661
  }
@@ -3019,7 +3673,7 @@ class Analyzer {
3019
3673
  if (c.kind === "builtin" && c.path === "Proxy")
3020
3674
  this.ops.push({ kind: "proxy", recv: listed, name: null, node: site });
3021
3675
  });
3022
- this.sink(listed, `argument of ${path} at ${locLabel(site)}`);
3676
+ this.sink(listed, `argument of ${path} at ${this.loc(site)}`);
3023
3677
  escapeAll();
3024
3678
  return;
3025
3679
  }
@@ -3048,7 +3702,7 @@ class Analyzer {
3048
3702
  prim("bigint");
3049
3703
  return;
3050
3704
  case "Promise.resolve": {
3051
- const p = this.promiseAtom(site, locLabel(site));
3705
+ const p = this.promiseAtom(site, this.loc(site));
3052
3706
  if (args[0] !== undefined)
3053
3707
  this.awaitInto(args[0], this.field(p, "value"));
3054
3708
  else
@@ -3057,17 +3711,17 @@ class Analyzer {
3057
3711
  return;
3058
3712
  }
3059
3713
  case "Promise.reject": {
3060
- const p = this.promiseAtom(site, locLabel(site));
3714
+ const p = this.promiseAtom(site, this.loc(site));
3061
3715
  this.add(dst, p);
3062
3716
  if (args[0] !== undefined)
3063
- this.sink(args[0], `rejection at ${locLabel(site)}`);
3717
+ this.sink(args[0], `rejection at ${this.loc(site)}`);
3064
3718
  return;
3065
3719
  }
3066
3720
  case "Promise.all":
3067
3721
  case "Promise.allSettled":
3068
3722
  case "Promise.race":
3069
3723
  case "Promise.any": {
3070
- const p = this.promiseAtom(site, locLabel(site));
3724
+ const p = this.promiseAtom(site, this.loc(site));
3071
3725
  const items = this.newNode();
3072
3726
  if (args[0] !== undefined)
3073
3727
  this.iterateInto(args[0], items, site);
@@ -3085,7 +3739,7 @@ class Analyzer {
3085
3739
  }
3086
3740
  case "promise.resolver":
3087
3741
  for (const x of args)
3088
- this.sink(x, `promise resolution at ${locLabel(site)}`);
3742
+ this.sink(x, `promise resolution at ${this.loc(site)}`);
3089
3743
  return;
3090
3744
  }
3091
3745
  if (path.startsWith("console.")) {
@@ -3107,6 +3761,163 @@ class Analyzer {
3107
3761
  void recvNode;
3108
3762
  escapeAll();
3109
3763
  }
3764
+ /** Whether an index access `x[i]` reads inside the bounds of `x` on
3765
+ * every evaluation: an enclosing `for (let i = <n ≥ 0>; i < x.length;
3766
+ * i++ | ++i | i += <n > 0>)` whose body assigns neither `i` nor `x`.
3767
+ * (The array's own length may still shrink or have holes: unsafeArrays.) */
3768
+ indexInBounds(site) {
3769
+ if (!ts.isElementAccessExpression(site) || site.questionDotToken !== undefined)
3770
+ return false;
3771
+ const memo = this.boundsMemo.get(site);
3772
+ if (memo !== undefined)
3773
+ return memo;
3774
+ const out = this.indexInBoundsUncached(site);
3775
+ this.boundsMemo.set(site, out);
3776
+ return out;
3777
+ }
3778
+ indexInBoundsUncached(site) {
3779
+ const obj = unparen(site.expression);
3780
+ const key = unparen(site.argumentExpression);
3781
+ if (!ts.isIdentifier(obj) || !ts.isIdentifier(key))
3782
+ return false;
3783
+ const objDecl = this.resolve(obj);
3784
+ const keyDecl = this.resolve(key);
3785
+ if (objDecl === undefined || keyDecl === undefined)
3786
+ return false;
3787
+ const names = (id, decl) => ts.isIdentifier(id) && this.resolve(id) === decl;
3788
+ for (let n = site.parent; n !== undefined; n = n.parent) {
3789
+ if (ts.isFunctionLike(n) || ts.isSourceFile(n))
3790
+ return false;
3791
+ if (!ts.isForStatement(n) || n.statement === undefined)
3792
+ continue;
3793
+ if (!(site.pos >= n.statement.pos && site.end <= n.statement.end))
3794
+ continue;
3795
+ const cond = n.condition !== undefined ? unparen(n.condition) : undefined;
3796
+ if (cond === undefined ||
3797
+ !ts.isBinaryExpression(cond) ||
3798
+ cond.operatorToken.kind !== ts.SyntaxKind.LessThanToken ||
3799
+ !names(unparen(cond.left), keyDecl))
3800
+ continue;
3801
+ const bound = unparen(cond.right);
3802
+ if (!ts.isPropertyAccessExpression(bound) ||
3803
+ bound.name.text !== "length" ||
3804
+ !names(unparen(bound.expression), objDecl))
3805
+ continue;
3806
+ // The index starts at a non-negative integer literal ...
3807
+ const init = n.initializer;
3808
+ let start;
3809
+ // (declared by the loop, so only the loop's own code can write it)
3810
+ if (init !== undefined &&
3811
+ ts.isVariableDeclarationList(init) &&
3812
+ (init.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0) {
3813
+ const d = init.declarations.nodes.find((x) => x === keyDecl);
3814
+ start = d !== undefined ? d.initializer : undefined;
3815
+ }
3816
+ if (start === undefined || !nonNegativeIntegerLiteral(start))
3817
+ continue;
3818
+ if (!this.neverReassigned(objDecl))
3819
+ continue;
3820
+ // ... and only grows by integers,
3821
+ const inc = n.incrementor !== undefined ? unparen(n.incrementor) : undefined;
3822
+ const grows = inc !== undefined &&
3823
+ (((ts.isPostfixUnaryExpression(inc) || ts.isPrefixUnaryExpression(inc)) &&
3824
+ inc.operator === ts.SyntaxKind.PlusPlusToken &&
3825
+ names(unparen(inc.operand), keyDecl)) ||
3826
+ (ts.isBinaryExpression(inc) &&
3827
+ inc.operatorToken.kind === ts.SyntaxKind.PlusEqualsToken &&
3828
+ names(unparen(inc.left), keyDecl) &&
3829
+ positiveIntegerLiteral(inc.right)));
3830
+ if (!grows)
3831
+ continue;
3832
+ // ... and the body writes neither the index nor the array binding.
3833
+ let written = false;
3834
+ const visit = (m) => {
3835
+ if (written)
3836
+ return;
3837
+ if (ts.isBinaryExpression(m) &&
3838
+ m.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
3839
+ m.operatorToken.kind <= ts.SyntaxKind.LastAssignment &&
3840
+ (names(unparen(m.left), keyDecl) || names(unparen(m.left), objDecl)))
3841
+ written = true;
3842
+ else if ((ts.isPostfixUnaryExpression(m) || ts.isPrefixUnaryExpression(m)) &&
3843
+ (m.operator === ts.SyntaxKind.PlusPlusToken ||
3844
+ m.operator === ts.SyntaxKind.MinusMinusToken) &&
3845
+ (names(unparen(m.operand), keyDecl) || names(unparen(m.operand), objDecl)))
3846
+ written = true;
3847
+ ts.forEachChild(m, (c) => {
3848
+ visit(c);
3849
+ return undefined;
3850
+ });
3851
+ };
3852
+ visit(n.statement);
3853
+ if (!written)
3854
+ return true;
3855
+ }
3856
+ return false;
3857
+ }
3858
+ reassignMemo = new Map();
3859
+ /** Whether a binding keeps the value it is declared with: a `const`, or a
3860
+ * parameter or variable that no code in its scope assigns. */
3861
+ neverReassigned(decl) {
3862
+ const memo = this.reassignMemo.get(decl);
3863
+ if (memo !== undefined)
3864
+ return memo;
3865
+ let out = false;
3866
+ if (ts.isVariableDeclaration(decl) || ts.isParameter(decl)) {
3867
+ const list = decl.parent;
3868
+ if (ts.isVariableDeclaration(decl) &&
3869
+ list !== undefined &&
3870
+ ts.isVariableDeclarationList(list) &&
3871
+ (list.flags & ts.NodeFlags.Const) !== 0)
3872
+ out = true;
3873
+ else {
3874
+ let scope = decl.parent;
3875
+ while (scope !== undefined && !ts.isFunctionLike(scope) && !ts.isSourceFile(scope))
3876
+ scope = scope.parent;
3877
+ if (scope !== undefined && ts.isIdentifier(decl.name)) {
3878
+ const text = decl.name.text;
3879
+ let written = false;
3880
+ const target = (e) => {
3881
+ const u = unparen(e);
3882
+ return ts.isIdentifier(u) && u.text === text && this.resolve(u) === decl;
3883
+ };
3884
+ const visit = (m) => {
3885
+ if (written)
3886
+ return;
3887
+ if ((ts.isBinaryExpression(m) &&
3888
+ m.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
3889
+ m.operatorToken.kind <= ts.SyntaxKind.LastAssignment &&
3890
+ target(m.left)) ||
3891
+ ((ts.isPostfixUnaryExpression(m) || ts.isPrefixUnaryExpression(m)) &&
3892
+ (m.operator === ts.SyntaxKind.PlusPlusToken ||
3893
+ m.operator === ts.SyntaxKind.MinusMinusToken) &&
3894
+ target(m.operand)))
3895
+ written = true;
3896
+ ts.forEachChild(m, (c) => {
3897
+ visit(c);
3898
+ return undefined;
3899
+ });
3900
+ };
3901
+ visit(scope);
3902
+ out = !written;
3903
+ }
3904
+ }
3905
+ }
3906
+ this.reassignMemo.set(decl, out);
3907
+ return out;
3908
+ }
3909
+ /** The result of arithmetic over the operands: a number, or a bigint
3910
+ * where an operand may be one. */
3911
+ numericResult(operands) {
3912
+ const n = this.newNode();
3913
+ this.add(n, this.prim("number"));
3914
+ for (const o of operands)
3915
+ this.on(o, (a) => {
3916
+ if (a.kind === "top" || (a.kind === "prim" && a.label === "bigint"))
3917
+ this.add(n, this.prim("bigint"));
3918
+ });
3919
+ return n;
3920
+ }
3110
3921
  /** Re-run deferred field copies until nothing new flows. */
3111
3922
  finish() {
3112
3923
  for (;;) {
@@ -3114,11 +3925,59 @@ class Analyzer {
3114
3925
  for (const c of this.lateCopies)
3115
3926
  c();
3116
3927
  this.solve();
3928
+ for (const o of this.ops)
3929
+ if (o.kind === "delete" || o.kind === "lengthWrite")
3930
+ for (const a of this.nodes[o.recv].atoms)
3931
+ if (a.kind === "array")
3932
+ this.unsafeArrays.add(a);
3933
+ for (const g of this.guardedIndexReads)
3934
+ if (!g.done && this.unsafeArrays.has(g.recv)) {
3935
+ g.done = true;
3936
+ this.add(g.dst, this.prim("undefined"));
3937
+ }
3938
+ this.solve();
3939
+ // A condition with no values at the fixpoint is one the analysis
3940
+ // could not evaluate: walk both of its branches.
3941
+ let walked = false;
3942
+ for (const p of this.pendingIfs) {
3943
+ if (this.nodes[p.cond].atoms.size > 0)
3944
+ continue;
3945
+ if (!p.thenDone) {
3946
+ this.walkBranch(p, "then");
3947
+ walked = true;
3948
+ }
3949
+ if (!p.elseDone) {
3950
+ this.walkBranch(p, "else");
3951
+ walked = true;
3952
+ }
3953
+ }
3954
+ if (walked)
3955
+ continue;
3117
3956
  if (this.steps === before || this.budgetExceeded)
3118
3957
  return;
3119
3958
  }
3120
3959
  }
3121
3960
  }
3961
+ function nonNegativeIntegerLiteral(e) {
3962
+ const u = unparen(e);
3963
+ return ts.isNumericLiteral(u) && Number.isInteger(Number(u.text)) && Number(u.text) >= 0;
3964
+ }
3965
+ function positiveIntegerLiteral(e) {
3966
+ const u = unparen(e);
3967
+ return ts.isNumericLiteral(u) && Number.isInteger(Number(u.text)) && Number(u.text) > 0;
3968
+ }
3969
+ /** `x[x.length] = v`: a store at the end, which appends without a hole. */
3970
+ function isAppendIndex(site) {
3971
+ if (!ts.isElementAccessExpression(site))
3972
+ return false;
3973
+ const obj = unparen(site.expression);
3974
+ const key = unparen(site.argumentExpression);
3975
+ return (ts.isIdentifier(obj) &&
3976
+ ts.isPropertyAccessExpression(key) &&
3977
+ key.name.text === "length" &&
3978
+ ts.isIdentifier(unparen(key.expression)) &&
3979
+ unparen(key.expression).text === obj.text);
3980
+ }
3122
3981
  /** The export name of a CommonJS export declaration the checker resolves
3123
3982
  * bindings to: a member of the `module.exports` literal, or the target of
3124
3983
  * `exports.name =` / `module.exports.name =`. */
@@ -3135,4 +3994,30 @@ function cjsExportName(decl) {
3135
3994
  return decl.left.name.text;
3136
3995
  return null;
3137
3996
  }
3997
+ /** The string literal a call passes as argument `i`, or null. */
3998
+ function literalKey(site, i) {
3999
+ const key = ts.isCallExpression(site) ? list(site.arguments)[i] : undefined;
4000
+ if (key === undefined)
4001
+ return null;
4002
+ const k = unparen(key);
4003
+ return ts.isStringLiteral(k) || ts.isNoSubstitutionTemplateLiteral(k) ? k.text : null;
4004
+ }
4005
+ /** Whether a value of the atom may be truthy (only `null`, `undefined` and
4006
+ * the literal `false` never are; ⊤ may be anything). */
4007
+ function mayBeTruthy(a) {
4008
+ if (a.kind !== "prim")
4009
+ return true;
4010
+ if (a.label === "null" || a.label === "undefined")
4011
+ return false;
4012
+ return a.literal !== false;
4013
+ }
4014
+ /** Whether a value of the atom may be falsy (objects, arrays, functions,
4015
+ * classes, promises and collections never are). */
4016
+ function mayBeFalsy(a) {
4017
+ if (a.kind === "top")
4018
+ return true;
4019
+ if (a.kind !== "prim")
4020
+ return false;
4021
+ return a.literal !== true;
4022
+ }
3138
4023
  //# sourceMappingURL=analyze.js.map