@scriptc/compiler 0.3.6 → 0.4.1

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 (1358) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +717 -55
  2. package/ambient/scriptc.d.ts +134 -0
  3. package/dist/backend/cycle-analysis.d.ts +1 -1
  4. package/dist/backend/cycle-analysis.js +1 -0
  5. package/dist/backend/cycle-analysis.js.map +1 -1
  6. package/dist/backend/cycle-analysis.test.js +13 -1
  7. package/dist/backend/cycle-analysis.test.js.map +1 -1
  8. package/dist/backend/cycle-mutability.js +16 -5
  9. package/dist/backend/cycle-mutability.js.map +1 -1
  10. package/dist/backend/executable-features.js +20 -0
  11. package/dist/backend/executable-features.js.map +1 -1
  12. package/dist/backend/immutability.test.js +1 -1
  13. package/dist/backend/library-pack.js +9 -0
  14. package/dist/backend/library-pack.js.map +1 -1
  15. package/dist/backend/link-plan-core.d.ts +2 -0
  16. package/dist/backend/link-plan-core.js +2 -0
  17. package/dist/backend/link-plan-core.js.map +1 -1
  18. package/dist/backend/link-plan.d.ts +1 -0
  19. package/dist/backend/link-plan.js +1 -0
  20. package/dist/backend/link-plan.js.map +1 -1
  21. package/dist/backend/llvm/alloc.d.ts +41 -4
  22. package/dist/backend/llvm/alloc.js +138 -7
  23. package/dist/backend/llvm/alloc.js.map +1 -1
  24. package/dist/backend/llvm/alloc.test.js +30 -1
  25. package/dist/backend/llvm/alloc.test.js.map +1 -1
  26. package/dist/backend/llvm/appended-array-literals.test.js +1 -1
  27. package/dist/backend/llvm/array-search.js +3 -1
  28. package/dist/backend/llvm/array-search.js.map +1 -1
  29. package/dist/backend/llvm/array-search.test.js +1 -1
  30. package/dist/backend/llvm/blocks.d.ts +8 -0
  31. package/dist/backend/llvm/blocks.js +43 -1
  32. package/dist/backend/llvm/blocks.js.map +1 -1
  33. package/dist/backend/llvm/blocks.test.js +22 -1
  34. package/dist/backend/llvm/blocks.test.js.map +1 -1
  35. package/dist/backend/llvm/byte-numbers.js +15 -5
  36. package/dist/backend/llvm/byte-numbers.js.map +1 -1
  37. package/dist/backend/llvm/bytes-alias.d.ts +14 -0
  38. package/dist/backend/llvm/bytes-alias.js +20 -0
  39. package/dist/backend/llvm/bytes-alias.js.map +1 -0
  40. package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
  41. package/dist/backend/llvm/bytes-loop-versions.js +506 -0
  42. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
  43. package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
  44. package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
  45. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
  46. package/dist/backend/llvm/call-lifetimes.js +50 -1
  47. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  48. package/dist/backend/llvm/call-lifetimes.test.js +34 -0
  49. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  50. package/dist/backend/llvm/checked-narrows.test.js +1 -1
  51. package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
  52. package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
  53. package/dist/backend/llvm/classes.d.ts +38 -1
  54. package/dist/backend/llvm/classes.js +185 -35
  55. package/dist/backend/llvm/classes.js.map +1 -1
  56. package/dist/backend/llvm/classes.test.js +79 -17
  57. package/dist/backend/llvm/classes.test.js.map +1 -1
  58. package/dist/backend/llvm/common.d.ts +21 -3
  59. package/dist/backend/llvm/common.js +51 -3
  60. package/dist/backend/llvm/common.js.map +1 -1
  61. package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
  62. package/dist/backend/llvm/constant-callbacks.js +55 -12
  63. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  64. package/dist/backend/llvm/constant-callbacks.test.js +88 -1
  65. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  66. package/dist/backend/llvm/counted-loops.d.ts +4 -0
  67. package/dist/backend/llvm/counted-loops.js +37 -0
  68. package/dist/backend/llvm/counted-loops.js.map +1 -1
  69. package/dist/backend/llvm/dense-array-access.d.ts +15 -4
  70. package/dist/backend/llvm/dense-array-access.js +125 -44
  71. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  72. package/dist/backend/llvm/dense-array-access.test.js +63 -3
  73. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  74. package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
  75. package/dist/backend/llvm/dense-array-loops.js +162 -0
  76. package/dist/backend/llvm/dense-array-loops.js.map +1 -0
  77. package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
  78. package/dist/backend/llvm/dense-array-loops.test.js +128 -0
  79. package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
  80. package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
  81. package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
  82. package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
  83. package/dist/backend/llvm/dyn.d.ts +37 -4
  84. package/dist/backend/llvm/dyn.js +354 -183
  85. package/dist/backend/llvm/dyn.js.map +1 -1
  86. package/dist/backend/llvm/emit-function.d.ts +64 -0
  87. package/dist/backend/llvm/emit-function.js +1193 -0
  88. package/dist/backend/llvm/emit-function.js.map +1 -0
  89. package/dist/backend/llvm/emit-module.d.ts +24 -0
  90. package/dist/backend/llvm/emit-module.js +1557 -0
  91. package/dist/backend/llvm/emit-module.js.map +1 -0
  92. package/dist/backend/llvm/emit-statements.d.ts +59 -0
  93. package/dist/backend/llvm/emit-statements.js +2041 -0
  94. package/dist/backend/llvm/emit-statements.js.map +1 -0
  95. package/dist/backend/llvm/emitter.d.ts +566 -291
  96. package/dist/backend/llvm/emitter.js +728 -4671
  97. package/dist/backend/llvm/emitter.js.map +1 -1
  98. package/dist/backend/llvm/emitter.test.js +57 -3
  99. package/dist/backend/llvm/emitter.test.js.map +1 -1
  100. package/dist/backend/llvm/expr-async.js +73 -46
  101. package/dist/backend/llvm/expr-async.js.map +1 -1
  102. package/dist/backend/llvm/expr-async.test.js +1 -1
  103. package/dist/backend/llvm/expr-bytes.d.ts +2 -0
  104. package/dist/backend/llvm/expr-bytes.js +76 -29
  105. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  106. package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
  107. package/dist/backend/llvm/expr-callbacks.js +48 -11
  108. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  109. package/dist/backend/llvm/expr-calls.d.ts +1 -1
  110. package/dist/backend/llvm/expr-calls.js +87 -56
  111. package/dist/backend/llvm/expr-calls.js.map +1 -1
  112. package/dist/backend/llvm/expr-calls.test.js +1 -1
  113. package/dist/backend/llvm/expr-containers.js +45 -24
  114. package/dist/backend/llvm/expr-containers.js.map +1 -1
  115. package/dist/backend/llvm/expr-control.js +16 -16
  116. package/dist/backend/llvm/expr-control.js.map +1 -1
  117. package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
  118. package/dist/backend/llvm/expr-dynamic.js +113 -66
  119. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  120. package/dist/backend/llvm/expr-primitives.js +124 -28
  121. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  122. package/dist/backend/llvm/expr-primitives.test.js +57 -2
  123. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  124. package/dist/backend/llvm/expr-records.d.ts +1 -1
  125. package/dist/backend/llvm/expr-records.js +32 -11
  126. package/dist/backend/llvm/expr-records.js.map +1 -1
  127. package/dist/backend/llvm/expr-stream-bridges.js +65 -27
  128. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  129. package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
  130. package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
  131. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  132. package/dist/backend/llvm/int32-abi.test.js +2 -2
  133. package/dist/backend/llvm/integer-clones.js +3 -3
  134. package/dist/backend/llvm/integer-clones.js.map +1 -1
  135. package/dist/backend/llvm/integer-clones.test.js +3 -3
  136. package/dist/backend/llvm/integer-remainder.d.ts +34 -13
  137. package/dist/backend/llvm/integer-remainder.js +156 -22
  138. package/dist/backend/llvm/integer-remainder.js.map +1 -1
  139. package/dist/backend/llvm/intern-tables.test.js +1 -1
  140. package/dist/backend/llvm/js-ic.d.ts +18 -0
  141. package/dist/backend/llvm/js-ic.js +712 -0
  142. package/dist/backend/llvm/js-ic.js.map +1 -0
  143. package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
  144. package/dist/backend/llvm/jsval-encoding.js +20 -0
  145. package/dist/backend/llvm/jsval-encoding.js.map +1 -0
  146. package/dist/backend/llvm/jsval.d.ts +12 -0
  147. package/dist/backend/llvm/jsval.js +616 -0
  148. package/dist/backend/llvm/jsval.js.map +1 -0
  149. package/dist/backend/llvm/lazy-captures.d.ts +12 -2
  150. package/dist/backend/llvm/lazy-captures.js +39 -17
  151. package/dist/backend/llvm/lazy-captures.js.map +1 -1
  152. package/dist/backend/llvm/lib-abi.js +1 -1
  153. package/dist/backend/llvm/lib-abi.js.map +1 -1
  154. package/dist/backend/llvm/lib-connect.js +1 -1
  155. package/dist/backend/llvm/lib-connect.js.map +1 -1
  156. package/dist/backend/llvm/lib-datagram.js +14 -8
  157. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  158. package/dist/backend/llvm/lib-dispatch.js +189 -23
  159. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  160. package/dist/backend/llvm/lib-filesystem.js +42 -13
  161. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  162. package/dist/backend/llvm/lib-http2.js +3 -3
  163. package/dist/backend/llvm/lib-http2.js.map +1 -1
  164. package/dist/backend/llvm/lib-lookup.js +2 -2
  165. package/dist/backend/llvm/lib-lookup.js.map +1 -1
  166. package/dist/backend/llvm/lib-network.js +56 -22
  167. package/dist/backend/llvm/lib-network.js.map +1 -1
  168. package/dist/backend/llvm/lib-process.js +94 -53
  169. package/dist/backend/llvm/lib-process.js.map +1 -1
  170. package/dist/backend/llvm/lib-shared.d.ts +12 -0
  171. package/dist/backend/llvm/lib-shared.js +209 -6
  172. package/dist/backend/llvm/lib-shared.js.map +1 -1
  173. package/dist/backend/llvm/lib-stream.js +46 -16
  174. package/dist/backend/llvm/lib-stream.js.map +1 -1
  175. package/dist/backend/llvm/lib-test.js +43 -7
  176. package/dist/backend/llvm/lib-test.js.map +1 -1
  177. package/dist/backend/llvm/lib-tls.js +4 -9
  178. package/dist/backend/llvm/lib-tls.js.map +1 -1
  179. package/dist/backend/llvm/local-array-reads.js +42 -33
  180. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  181. package/dist/backend/llvm/local-array-reads.test.js +1 -1
  182. package/dist/backend/llvm/local-extents.d.ts +19 -0
  183. package/dist/backend/llvm/local-extents.js +169 -0
  184. package/dist/backend/llvm/local-extents.js.map +1 -0
  185. package/dist/backend/llvm/local-extents.test.d.ts +1 -0
  186. package/dist/backend/llvm/local-extents.test.js +92 -0
  187. package/dist/backend/llvm/local-extents.test.js.map +1 -0
  188. package/dist/backend/llvm/local-union-storage.js +7 -7
  189. package/dist/backend/llvm/local-union-storage.js.map +1 -1
  190. package/dist/backend/llvm/local-union-storage.test.js +2 -2
  191. package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
  192. package/dist/backend/llvm/map-number-lookup.d.ts +20 -4
  193. package/dist/backend/llvm/map-number-lookup.js +45 -9
  194. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  195. package/dist/backend/llvm/map-number-lookup.test.js +2 -2
  196. package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
  197. package/dist/backend/llvm/narrow-guards.d.ts +38 -0
  198. package/dist/backend/llvm/narrow-guards.js +215 -0
  199. package/dist/backend/llvm/narrow-guards.js.map +1 -0
  200. package/dist/backend/llvm/nullable-unions.d.ts +64 -6
  201. package/dist/backend/llvm/nullable-unions.js +103 -6
  202. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  203. package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
  204. package/dist/backend/llvm/nullable-unions.test.js +65 -0
  205. package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
  206. package/dist/backend/llvm/publish.d.ts +7 -0
  207. package/dist/backend/llvm/publish.js +50 -19
  208. package/dist/backend/llvm/publish.js.map +1 -1
  209. package/dist/backend/llvm/publish.test.js +1 -1
  210. package/dist/backend/llvm/receivers.d.ts +31 -0
  211. package/dist/backend/llvm/receivers.js +395 -0
  212. package/dist/backend/llvm/receivers.js.map +1 -0
  213. package/dist/backend/llvm/record-results.d.ts +12 -1
  214. package/dist/backend/llvm/record-results.js +64 -4
  215. package/dist/backend/llvm/record-results.js.map +1 -1
  216. package/dist/backend/llvm/reference-effects.js +9 -0
  217. package/dist/backend/llvm/reference-effects.js.map +1 -1
  218. package/dist/backend/llvm/reference-writes.d.ts +4 -0
  219. package/dist/backend/llvm/reference-writes.js +142 -6
  220. package/dist/backend/llvm/reference-writes.js.map +1 -1
  221. package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
  222. package/dist/backend/llvm/reference-writes.test.js +88 -0
  223. package/dist/backend/llvm/reference-writes.test.js.map +1 -0
  224. package/dist/backend/llvm/regex-matchers.d.ts +8 -0
  225. package/dist/backend/llvm/regex-matchers.js +33 -0
  226. package/dist/backend/llvm/regex-matchers.js.map +1 -1
  227. package/dist/backend/llvm/regex-matchers.test.js +23 -1
  228. package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
  229. package/dist/backend/llvm/regions.d.ts +1 -1
  230. package/dist/backend/llvm/regions.js +10 -7
  231. package/dist/backend/llvm/regions.js.map +1 -1
  232. package/dist/backend/llvm/regions.test.js +8 -2
  233. package/dist/backend/llvm/regions.test.js.map +1 -1
  234. package/dist/backend/llvm/shapes.d.ts +74 -45
  235. package/dist/backend/llvm/shapes.js +289 -28
  236. package/dist/backend/llvm/shapes.js.map +1 -1
  237. package/dist/backend/llvm/shapes.test.js +37 -3
  238. package/dist/backend/llvm/shapes.test.js.map +1 -1
  239. package/dist/backend/llvm/speculative-integers.d.ts +20 -1
  240. package/dist/backend/llvm/speculative-integers.js +94 -6
  241. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  242. package/dist/backend/llvm/speculative-integers.test.js +55 -1
  243. package/dist/backend/llvm/speculative-integers.test.js.map +1 -1
  244. package/dist/backend/llvm/split-loops.js +2 -2
  245. package/dist/backend/llvm/split-loops.js.map +1 -1
  246. package/dist/backend/llvm/stack-objects.d.ts +26 -6
  247. package/dist/backend/llvm/stack-objects.js +133 -10
  248. package/dist/backend/llvm/stack-objects.js.map +1 -1
  249. package/dist/backend/llvm/stack-objects.test.js +55 -1
  250. package/dist/backend/llvm/stack-objects.test.js.map +1 -1
  251. package/dist/backend/llvm/stack-unions.test.js +1 -1
  252. package/dist/backend/llvm/string-construction.test.js +1 -1
  253. package/dist/backend/llvm/string-lifetimes.test.js +15 -14
  254. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  255. package/dist/backend/llvm/string-reads.d.ts +1 -1
  256. package/dist/backend/llvm/string-reads.js +4 -4
  257. package/dist/backend/llvm/string-reads.js.map +1 -1
  258. package/dist/backend/llvm/string-slices.d.ts +25 -0
  259. package/dist/backend/llvm/string-slices.js +207 -1
  260. package/dist/backend/llvm/string-slices.js.map +1 -1
  261. package/dist/backend/llvm/string-slices.test.js +139 -2
  262. package/dist/backend/llvm/string-slices.test.js.map +1 -1
  263. package/dist/backend/llvm/switch-dispatch.test.js +2 -2
  264. package/dist/backend/llvm/thread-slots.d.ts +5 -0
  265. package/dist/backend/llvm/thread-slots.js +142 -0
  266. package/dist/backend/llvm/thread-slots.js.map +1 -0
  267. package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
  268. package/dist/backend/llvm/thread-slots.test.js +111 -0
  269. package/dist/backend/llvm/thread-slots.test.js.map +1 -0
  270. package/dist/backend/llvm/union-repr.d.ts +7 -7
  271. package/dist/backend/llvm/union-repr.js +18 -2
  272. package/dist/backend/llvm/union-repr.js.map +1 -1
  273. package/dist/backend/llvm/union-retype.test.js +17 -3
  274. package/dist/backend/llvm/union-retype.test.js.map +1 -1
  275. package/dist/backend/llvm/walkers.d.ts +2 -2
  276. package/dist/backend/llvm/walkers.js +51 -26
  277. package/dist/backend/llvm/walkers.js.map +1 -1
  278. package/dist/backend/llvm/wasm-modules.d.ts +16 -0
  279. package/dist/backend/llvm/wasm-modules.js +66 -0
  280. package/dist/backend/llvm/wasm-modules.js.map +1 -0
  281. package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
  282. package/dist/backend/llvm/wrapping-sums.js +11 -3
  283. package/dist/backend/llvm/wrapping-sums.js.map +1 -1
  284. package/dist/backend/mangle.d.ts +12 -0
  285. package/dist/backend/mangle.js +18 -0
  286. package/dist/backend/mangle.js.map +1 -1
  287. package/dist/backend/may-throw.d.ts +3 -0
  288. package/dist/backend/may-throw.js +4 -2
  289. package/dist/backend/may-throw.js.map +1 -1
  290. package/dist/backend/may-throw.test.js +1 -1
  291. package/dist/backend/native/contracts.d.ts +57 -0
  292. package/dist/backend/native/executable.js +211 -139
  293. package/dist/backend/native/executable.js.map +1 -1
  294. package/dist/backend/native/library.js +2 -0
  295. package/dist/backend/native/library.js.map +1 -1
  296. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  297. package/dist/backend/native/runtime-inputs.js +1 -0
  298. package/dist/backend/native/runtime-inputs.js.map +1 -1
  299. package/dist/backend/native-codegen.d.ts +6 -0
  300. package/dist/backend/native-codegen.js +19 -0
  301. package/dist/backend/native-codegen.js.map +1 -1
  302. package/dist/backend/native-codegen.test.js +27 -0
  303. package/dist/backend/native-codegen.test.js.map +1 -1
  304. package/dist/backend/native-link-info-core.d.ts +48 -0
  305. package/dist/backend/native-link-info-core.js.map +1 -1
  306. package/dist/backend/native-profile.d.ts +32 -0
  307. package/dist/backend/native-profile.js +39 -0
  308. package/dist/backend/native-profile.js.map +1 -0
  309. package/dist/backend/native-profile.test.d.ts +1 -0
  310. package/dist/backend/native-profile.test.js +58 -0
  311. package/dist/backend/native-profile.test.js.map +1 -0
  312. package/dist/backend/native-tools.d.ts +14 -0
  313. package/dist/backend/native-tools.js +13 -0
  314. package/dist/backend/native-tools.js.map +1 -1
  315. package/dist/backend/publication.test.js +1 -1
  316. package/dist/backend/runtime-abi.d.ts +2 -2
  317. package/dist/backend/runtime-abi.js +2 -2
  318. package/dist/backend/runtime-pack-core.d.ts +13 -1
  319. package/dist/backend/runtime-pack-core.js +14 -1
  320. package/dist/backend/runtime-pack-core.js.map +1 -1
  321. package/dist/backend/runtime-pack-native.js +1 -1
  322. package/dist/backend/runtime-pack-native.js.map +1 -1
  323. package/dist/backend/runtime-pack-native.test.d.ts +1 -0
  324. package/dist/backend/runtime-pack-native.test.js +31 -0
  325. package/dist/backend/runtime-pack-native.test.js.map +1 -0
  326. package/dist/backend/runtime-pack-targets.test.js +9 -1
  327. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  328. package/dist/backend/runtime-pack.test.js +9 -1
  329. package/dist/backend/runtime-pack.test.js.map +1 -1
  330. package/dist/backend/stack-observations.d.ts +22 -0
  331. package/dist/backend/stack-observations.js +382 -0
  332. package/dist/backend/stack-observations.js.map +1 -0
  333. package/dist/backend/stack-observations.test.d.ts +1 -0
  334. package/dist/backend/stack-observations.test.js +233 -0
  335. package/dist/backend/stack-observations.test.js.map +1 -0
  336. package/dist/backend/target-diagnostics.js +15 -0
  337. package/dist/backend/target-diagnostics.js.map +1 -1
  338. package/dist/backend/target-diagnostics.test.js +1 -1
  339. package/dist/backend/warm-cache.js +8 -0
  340. package/dist/backend/warm-cache.js.map +1 -1
  341. package/dist/backend/young-nursery.d.ts +7 -0
  342. package/dist/backend/young-nursery.js +10 -0
  343. package/dist/backend/young-nursery.js.map +1 -0
  344. package/dist/cli/command.js +106 -4
  345. package/dist/cli/command.js.map +1 -1
  346. package/dist/cli/host.d.ts +3 -0
  347. package/dist/cli/output-options.d.ts +2 -0
  348. package/dist/cli/output-options.js +9 -0
  349. package/dist/cli/output-options.js.map +1 -1
  350. package/dist/cli/usage.d.ts +21 -1
  351. package/dist/cli/usage.js +43 -1
  352. package/dist/cli/usage.js.map +1 -1
  353. package/dist/compat/fetch-profile.js +10 -1
  354. package/dist/compat/fetch-profile.js.map +1 -1
  355. package/dist/compile-types.d.ts +22 -0
  356. package/dist/contracts/check.js +25 -8
  357. package/dist/contracts/check.js.map +1 -1
  358. package/dist/contracts/int32-elements.d.ts +115 -0
  359. package/dist/contracts/int32-elements.js +1179 -0
  360. package/dist/contracts/int32-elements.js.map +1 -0
  361. package/dist/coverage/report.d.ts +16 -0
  362. package/dist/coverage/report.js +182 -1
  363. package/dist/coverage/report.js.map +1 -1
  364. package/dist/coverage/surface-manifest.js +16 -3
  365. package/dist/coverage/surface-manifest.js.map +1 -1
  366. package/dist/coverage/verdict-cache.d.ts +2 -0
  367. package/dist/coverage/verdict-cache.js +12 -0
  368. package/dist/coverage/verdict-cache.js.map +1 -1
  369. package/dist/coverage/verdict-cache.test.js +2 -1
  370. package/dist/coverage/verdict-cache.test.js.map +1 -1
  371. package/dist/diagnostics/diagnostic.d.ts +10 -6
  372. package/dist/diagnostics/diagnostic.js +29 -21
  373. package/dist/diagnostics/diagnostic.js.map +1 -1
  374. package/dist/diagnostics/envelope.d.ts +39 -2
  375. package/dist/diagnostics/envelope.js.map +1 -1
  376. package/dist/diagnostics/render.d.ts +7 -0
  377. package/dist/diagnostics/render.js +50 -13
  378. package/dist/diagnostics/render.js.map +1 -1
  379. package/dist/diagnostics/render.test.d.ts +1 -0
  380. package/dist/diagnostics/render.test.js +49 -0
  381. package/dist/diagnostics/render.test.js.map +1 -0
  382. package/dist/executable/executable-cache.d.ts +27 -0
  383. package/dist/executable/executable-cache.js +19 -1
  384. package/dist/executable/executable-cache.js.map +1 -1
  385. package/dist/executable/executable-cache.test.js +12 -1
  386. package/dist/executable/executable-cache.test.js.map +1 -1
  387. package/dist/executable/prepare.js +2 -1
  388. package/dist/executable/prepare.js.map +1 -1
  389. package/dist/frontend/analysis.js +6 -1
  390. package/dist/frontend/analysis.js.map +1 -1
  391. package/dist/frontend/arguments-usage.d.ts +8 -0
  392. package/dist/frontend/arguments-usage.js +98 -0
  393. package/dist/frontend/arguments-usage.js.map +1 -1
  394. package/dist/frontend/arguments-usage.test.d.ts +1 -0
  395. package/dist/frontend/arguments-usage.test.js +32 -0
  396. package/dist/frontend/arguments-usage.test.js.map +1 -0
  397. package/dist/frontend/builtin-modules.d.ts +16 -2
  398. package/dist/frontend/builtin-modules.js +40 -7
  399. package/dist/frontend/builtin-modules.js.map +1 -1
  400. package/dist/frontend/builtin-package-aliases.d.ts +24 -0
  401. package/dist/frontend/builtin-package-aliases.js +133 -0
  402. package/dist/frontend/builtin-package-aliases.js.map +1 -0
  403. package/dist/frontend/builtin-package-aliases.test.d.ts +1 -0
  404. package/dist/frontend/builtin-package-aliases.test.js +48 -0
  405. package/dist/frontend/builtin-package-aliases.test.js.map +1 -0
  406. package/dist/frontend/cjs-syntax.js +52 -51
  407. package/dist/frontend/cjs-syntax.js.map +1 -1
  408. package/dist/frontend/contract-types.d.ts +3 -0
  409. package/dist/frontend/contract-types.js +36 -7
  410. package/dist/frontend/contract-types.js.map +1 -1
  411. package/dist/frontend/dts-paths.d.ts +4 -0
  412. package/dist/frontend/dts-paths.js +9 -1
  413. package/dist/frontend/dts-paths.js.map +1 -1
  414. package/dist/frontend/experimental-import.d.ts +5 -1
  415. package/dist/frontend/experimental-import.js +26 -7
  416. package/dist/frontend/experimental-import.js.map +1 -1
  417. package/dist/frontend/fork-target.js +20 -22
  418. package/dist/frontend/fork-target.js.map +1 -1
  419. package/dist/frontend/fork-target.test.js +2 -1
  420. package/dist/frontend/fork-target.test.js.map +1 -1
  421. package/dist/frontend/function-completion.js +6 -6
  422. package/dist/frontend/function-completion.js.map +1 -1
  423. package/dist/frontend/helper-tokens.js +15 -3
  424. package/dist/frontend/helper-tokens.js.map +1 -1
  425. package/dist/frontend/helper-tokens.test.js +7 -1
  426. package/dist/frontend/helper-tokens.test.js.map +1 -1
  427. package/dist/frontend/inferred-js-diagnostics.js +14 -17
  428. package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
  429. package/dist/frontend/input-tracker.d.ts +3 -0
  430. package/dist/frontend/input-tracker.js +32 -3
  431. package/dist/frontend/input-tracker.js.map +1 -1
  432. package/dist/frontend/lib-contract.js +36 -32
  433. package/dist/frontend/lib-contract.js.map +1 -1
  434. package/dist/frontend/lib-exports.js +3 -3
  435. package/dist/frontend/lib-exports.js.map +1 -1
  436. package/dist/frontend/lowering/array-values.d.ts +8 -3
  437. package/dist/frontend/lowering/array-values.js +60 -11
  438. package/dist/frontend/lowering/array-values.js.map +1 -1
  439. package/dist/frontend/lowering/assert-instances.js +4 -4
  440. package/dist/frontend/lowering/assert-instances.js.map +1 -1
  441. package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
  442. package/dist/frontend/lowering/assertion-identity.js +70 -0
  443. package/dist/frontend/lowering/assertion-identity.js.map +1 -0
  444. package/dist/frontend/lowering/assertion-members.d.ts +28 -0
  445. package/dist/frontend/lowering/assertion-members.js +185 -0
  446. package/dist/frontend/lowering/assertion-members.js.map +1 -0
  447. package/dist/frontend/lowering/binding-analysis.js +27 -20
  448. package/dist/frontend/lowering/binding-analysis.js.map +1 -1
  449. package/dist/frontend/lowering/builtin-calls.js +63 -5
  450. package/dist/frontend/lowering/builtin-calls.js.map +1 -1
  451. package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
  452. package/dist/frontend/lowering/builtin-function-fences.js +42 -0
  453. package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
  454. package/dist/frontend/lowering/builtins/arguments.js +1 -1
  455. package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
  456. package/dist/frontend/lowering/builtins/async-context.js +53 -52
  457. package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
  458. package/dist/frontend/lowering/builtins/atomics.js +6 -6
  459. package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
  460. package/dist/frontend/lowering/builtins/blob.js +8 -6
  461. package/dist/frontend/lowering/builtins/blob.js.map +1 -1
  462. package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +31 -0
  463. package/dist/frontend/lowering/builtins/builtin-class-dyn.js +205 -0
  464. package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
  465. package/dist/frontend/lowering/builtins/callable-aliases.js +17 -5
  466. package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
  467. package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
  468. package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
  469. package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
  470. package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
  471. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  472. package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
  473. package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
  474. package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
  475. package/dist/frontend/lowering/builtins/child-process.js +85 -61
  476. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  477. package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
  478. package/dist/frontend/lowering/builtins/class-values.js +226 -0
  479. package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
  480. package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
  481. package/dist/frontend/lowering/builtins/compression.js +107 -44
  482. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  483. package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
  484. package/dist/frontend/lowering/builtins/constants.js +28 -7
  485. package/dist/frontend/lowering/builtins/constants.js.map +1 -1
  486. package/dist/frontend/lowering/builtins/crypto.d.ts +22 -0
  487. package/dist/frontend/lowering/builtins/crypto.js +215 -38
  488. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  489. package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
  490. package/dist/frontend/lowering/builtins/dates.js +92 -16
  491. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  492. package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
  493. package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
  494. package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
  495. package/dist/frontend/lowering/builtins/ecdh.d.ts +10 -0
  496. package/dist/frontend/lowering/builtins/ecdh.js +208 -0
  497. package/dist/frontend/lowering/builtins/ecdh.js.map +1 -0
  498. package/dist/frontend/lowering/builtins/environment.js +3 -3
  499. package/dist/frontend/lowering/builtins/environment.js.map +1 -1
  500. package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
  501. package/dist/frontend/lowering/builtins/errors.js +169 -3
  502. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  503. package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
  504. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  505. package/dist/frontend/lowering/builtins/filesystem.js +77 -77
  506. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  507. package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
  508. package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
  509. package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
  510. package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
  511. package/dist/frontend/lowering/builtins/ipc.js +45 -8
  512. package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
  513. package/dist/frontend/lowering/builtins/json.js +284 -24
  514. package/dist/frontend/lowering/builtins/json.js.map +1 -1
  515. package/dist/frontend/lowering/builtins/key-object.js +4 -4
  516. package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
  517. package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
  518. package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
  519. package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
  520. package/dist/frontend/lowering/builtins/module-calls.js +55 -44
  521. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  522. package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
  523. package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
  524. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
  525. package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
  526. package/dist/frontend/lowering/builtins/navigator.js +40 -0
  527. package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
  528. package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
  529. package/dist/frontend/lowering/builtins/net-address.js +156 -0
  530. package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
  531. package/dist/frontend/lowering/builtins/numbers.js +25 -9
  532. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  533. package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
  534. package/dist/frontend/lowering/builtins/operating-system.js +25 -12
  535. package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
  536. package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
  537. package/dist/frontend/lowering/builtins/performance.js +259 -8
  538. package/dist/frontend/lowering/builtins/performance.js.map +1 -1
  539. package/dist/frontend/lowering/builtins/process.d.ts +41 -1
  540. package/dist/frontend/lowering/builtins/process.js +505 -99
  541. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  542. package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
  543. package/dist/frontend/lowering/builtins/promises.js +326 -43
  544. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  545. package/dist/frontend/lowering/builtins/promisify-callback.d.ts +40 -0
  546. package/dist/frontend/lowering/builtins/promisify-callback.js +338 -0
  547. package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
  548. package/dist/frontend/lowering/builtins/properties.js +37 -1
  549. package/dist/frontend/lowering/builtins/properties.js.map +1 -1
  550. package/dist/frontend/lowering/builtins/querystring.js +14 -14
  551. package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
  552. package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
  553. package/dist/frontend/lowering/builtins/readline.js +136 -39
  554. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  555. package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
  556. package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
  557. package/dist/frontend/lowering/builtins/reflection.js +42 -14
  558. package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
  559. package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
  560. package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
  561. package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
  562. package/dist/frontend/lowering/builtins/strings.js +101 -12
  563. package/dist/frontend/lowering/builtins/strings.js.map +1 -1
  564. package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
  565. package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
  566. package/dist/frontend/lowering/builtins/timers.js +79 -30
  567. package/dist/frontend/lowering/builtins/timers.js.map +1 -1
  568. package/dist/frontend/lowering/builtins/typed-array-members.d.ts +7 -0
  569. package/dist/frontend/lowering/builtins/typed-array-members.js +160 -0
  570. package/dist/frontend/lowering/builtins/typed-array-members.js.map +1 -0
  571. package/dist/frontend/lowering/builtins/url.d.ts +3 -0
  572. package/dist/frontend/lowering/builtins/url.js +120 -17
  573. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  574. package/dist/frontend/lowering/builtins/util-types.js +20 -4
  575. package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
  576. package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
  577. package/dist/frontend/lowering/builtins/v8.js +105 -0
  578. package/dist/frontend/lowering/builtins/v8.js.map +1 -0
  579. package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
  580. package/dist/frontend/lowering/builtins/webassembly.js +388 -0
  581. package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
  582. package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
  583. package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
  584. package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
  585. package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
  586. package/dist/frontend/lowering/builtins/workers.js +193 -8
  587. package/dist/frontend/lowering/builtins/workers.js.map +1 -1
  588. package/dist/frontend/lowering/call-arguments.js +69 -14
  589. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  590. package/dist/frontend/lowering/call-signatures.d.ts +23 -1
  591. package/dist/frontend/lowering/call-signatures.js +379 -55
  592. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  593. package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
  594. package/dist/frontend/lowering/checked-promise-all.js +1 -1
  595. package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
  596. package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
  597. package/dist/frontend/lowering/cjs-exports-object.js +561 -0
  598. package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
  599. package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
  600. package/dist/frontend/lowering/cjs-inline-require.js +314 -0
  601. package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
  602. package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
  603. package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
  604. package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
  605. package/dist/frontend/lowering/class-attributes.d.ts +19 -0
  606. package/dist/frontend/lowering/class-attributes.js +378 -0
  607. package/dist/frontend/lowering/class-attributes.js.map +1 -0
  608. package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
  609. package/dist/frontend/lowering/class-callbacks.js +21 -10
  610. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  611. package/dist/frontend/lowering/class-construction.js +49 -4
  612. package/dist/frontend/lowering/class-construction.js.map +1 -1
  613. package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
  614. package/dist/frontend/lowering/class-descriptors.js +8 -8
  615. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  616. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
  617. package/dist/frontend/lowering/class-dynamic-dispatch.js +1124 -90
  618. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  619. package/dist/frontend/lowering/class-instance-constructor.js +1 -1
  620. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  621. package/dist/frontend/lowering/class-iterables.d.ts +11 -0
  622. package/dist/frontend/lowering/class-iterables.js +31 -0
  623. package/dist/frontend/lowering/class-iterables.js.map +1 -0
  624. package/dist/frontend/lowering/class-method-mutations.js +73 -35
  625. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  626. package/dist/frontend/lowering/class-method-values.js +56 -10
  627. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  628. package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
  629. package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
  630. package/dist/frontend/lowering/class-protocols.d.ts +10 -0
  631. package/dist/frontend/lowering/class-protocols.js +76 -45
  632. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  633. package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
  634. package/dist/frontend/lowering/class-prototypes.js +86 -19
  635. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  636. package/dist/frontend/lowering/class-runtime-statics.js +1 -1
  637. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  638. package/dist/frontend/lowering/class-static-data.js +2 -2
  639. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  640. package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
  641. package/dist/frontend/lowering/class-to-primitive.js +264 -0
  642. package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
  643. package/dist/frontend/lowering/class-unions.d.ts +25 -0
  644. package/dist/frontend/lowering/class-unions.js +102 -1
  645. package/dist/frontend/lowering/class-unions.js.map +1 -1
  646. package/dist/frontend/lowering/code-generation.d.ts +14 -0
  647. package/dist/frontend/lowering/code-generation.js +127 -0
  648. package/dist/frontend/lowering/code-generation.js.map +1 -0
  649. package/dist/frontend/lowering/coercions/fresh-spread.d.ts +13 -0
  650. package/dist/frontend/lowering/coercions/fresh-spread.js +95 -0
  651. package/dist/frontend/lowering/coercions/fresh-spread.js.map +1 -0
  652. package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
  653. package/dist/frontend/lowering/coercions/function-adapters.js +239 -68
  654. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  655. package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
  656. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  657. package/dist/frontend/lowering/coercions/structural.js +35 -3
  658. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  659. package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
  660. package/dist/frontend/lowering/coercions/unions.js +57 -1
  661. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  662. package/dist/frontend/lowering/collection-ingestion.js +2 -2
  663. package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
  664. package/dist/frontend/lowering/collection-narrowing.js +2 -4
  665. package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
  666. package/dist/frontend/lowering/construction-escapes.js +8 -8
  667. package/dist/frontend/lowering/construction-escapes.js.map +1 -1
  668. package/dist/frontend/lowering/construction-escapes.test.js +4 -4
  669. package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
  670. package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
  671. package/dist/frontend/lowering/constructor-returns.js +477 -0
  672. package/dist/frontend/lowering/constructor-returns.js.map +1 -0
  673. package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
  674. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
  675. package/dist/frontend/lowering/containers/array-callbacks.d.ts +17 -0
  676. package/dist/frontend/lowering/containers/array-callbacks.js +287 -118
  677. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  678. package/dist/frontend/lowering/containers/array-concat.js +1 -1
  679. package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
  680. package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
  681. package/dist/frontend/lowering/containers/array-construction.js +58 -13
  682. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  683. package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
  684. package/dist/frontend/lowering/containers/array-from-async.js +159 -14
  685. package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
  686. package/dist/frontend/lowering/containers/array-methods.js +94 -77
  687. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  688. package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
  689. package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
  690. package/dist/frontend/lowering/containers/bytes.d.ts +9 -0
  691. package/dist/frontend/lowering/containers/bytes.js +649 -113
  692. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  693. package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
  694. package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
  695. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  696. package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
  697. package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
  698. package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
  699. package/dist/frontend/lowering/containers/collection-methods.js +126 -28
  700. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  701. package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
  702. package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
  703. package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
  704. package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
  705. package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
  706. package/dist/frontend/lowering/containers/for-of.js +19 -19
  707. package/dist/frontend/lowering/containers/for-of.js.map +1 -1
  708. package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
  709. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  710. package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
  711. package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
  712. package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
  713. package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
  714. package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
  715. package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
  716. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
  717. package/dist/frontend/lowering/containers/string-and-regexp.js +455 -30
  718. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  719. package/dist/frontend/lowering/containers/string-replacement.js +1 -1
  720. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
  721. package/dist/frontend/lowering/cycle-initialization.d.ts +30 -10
  722. package/dist/frontend/lowering/cycle-initialization.js +191 -35
  723. package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
  724. package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
  725. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
  726. package/dist/frontend/lowering/devirtualize.d.ts +1 -1
  727. package/dist/frontend/lowering/devirtualize.js +27 -7
  728. package/dist/frontend/lowering/devirtualize.js.map +1 -1
  729. package/dist/frontend/lowering/divergences.d.ts +0 -5
  730. package/dist/frontend/lowering/divergences.js +62 -125
  731. package/dist/frontend/lowering/divergences.js.map +1 -1
  732. package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
  733. package/dist/frontend/lowering/dyn-streams.js +257 -0
  734. package/dist/frontend/lowering/dyn-streams.js.map +1 -0
  735. package/dist/frontend/lowering/error-methods.js +4 -1
  736. package/dist/frontend/lowering/error-methods.js.map +1 -1
  737. package/dist/frontend/lowering/error-name-order.d.ts +19 -0
  738. package/dist/frontend/lowering/error-name-order.js +93 -0
  739. package/dist/frontend/lowering/error-name-order.js.map +1 -0
  740. package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
  741. package/dist/frontend/lowering/expressions/array-literals.js +723 -0
  742. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
  743. package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
  744. package/dist/frontend/lowering/expressions/binary.js +2557 -0
  745. package/dist/frontend/lowering/expressions/binary.js.map +1 -0
  746. package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
  747. package/dist/frontend/lowering/expressions/element-access.js +1804 -0
  748. package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
  749. package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
  750. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
  751. package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
  752. package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
  753. package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
  754. package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
  755. package/dist/frontend/lowering/expressions/identifiers.js +830 -0
  756. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
  757. package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +52 -0
  758. package/dist/frontend/lowering/expressions/keyed-field-targets.js +307 -0
  759. package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
  760. package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
  761. package/dist/frontend/lowering/expressions/narrowing.js +1337 -0
  762. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
  763. package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
  764. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
  765. package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
  766. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  767. package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
  768. package/dist/frontend/lowering/expressions/object-literals.js +301 -86
  769. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  770. package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -2
  771. package/dist/frontend/lowering/expressions/optional-chains.js +103 -17
  772. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  773. package/dist/frontend/lowering/expressions/property-access.d.ts +115 -0
  774. package/dist/frontend/lowering/expressions/property-access.js +3787 -0
  775. package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
  776. package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
  777. package/dist/frontend/lowering/expressions/relational.js +1724 -0
  778. package/dist/frontend/lowering/expressions/relational.js.map +1 -0
  779. package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
  780. package/dist/frontend/lowering/expressions/typeof.js +551 -0
  781. package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
  782. package/dist/frontend/lowering/expressions/union-fields.js +1 -1
  783. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  784. package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
  785. package/dist/frontend/lowering/expressions/updates.js +780 -0
  786. package/dist/frontend/lowering/expressions/updates.js.map +1 -0
  787. package/dist/frontend/lowering/function-context.d.ts +10 -0
  788. package/dist/frontend/lowering/function-context.js +11 -1
  789. package/dist/frontend/lowering/function-context.js.map +1 -1
  790. package/dist/frontend/lowering/function-returns.js +52 -28
  791. package/dist/frontend/lowering/function-returns.js.map +1 -1
  792. package/dist/frontend/lowering/general-streams.d.ts +25 -0
  793. package/dist/frontend/lowering/general-streams.js +108 -0
  794. package/dist/frontend/lowering/general-streams.js.map +1 -0
  795. package/dist/frontend/lowering/generator-delegation.d.ts +8 -0
  796. package/dist/frontend/lowering/generator-delegation.js +191 -1
  797. package/dist/frontend/lowering/generator-delegation.js.map +1 -1
  798. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
  799. package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
  800. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  801. package/dist/frontend/lowering/generic-functions.d.ts +43 -0
  802. package/dist/frontend/lowering/generic-functions.js +593 -118
  803. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  804. package/dist/frontend/lowering/handle-properties.d.ts +24 -0
  805. package/dist/frontend/lowering/handle-properties.js +281 -0
  806. package/dist/frontend/lowering/handle-properties.js.map +1 -0
  807. package/dist/frontend/lowering/import-meta.js +2 -2
  808. package/dist/frontend/lowering/import-meta.js.map +1 -1
  809. package/dist/frontend/lowering/intern-tables.js +10 -9
  810. package/dist/frontend/lowering/intern-tables.js.map +1 -1
  811. package/dist/frontend/lowering/iterable-spelling.d.ts +7 -0
  812. package/dist/frontend/lowering/iterable-spelling.js +38 -0
  813. package/dist/frontend/lowering/iterable-spelling.js.map +1 -0
  814. package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
  815. package/dist/frontend/lowering/iterator-adapters.js +331 -3
  816. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  817. package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
  818. package/dist/frontend/lowering/js-class-fields.js +170 -0
  819. package/dist/frontend/lowering/js-class-fields.js.map +1 -0
  820. package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
  821. package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
  822. package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
  823. package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
  824. package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
  825. package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
  826. package/dist/frontend/lowering/json-require.d.ts +22 -0
  827. package/dist/frontend/lowering/json-require.js +131 -0
  828. package/dist/frontend/lowering/json-require.js.map +1 -0
  829. package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
  830. package/dist/frontend/lowering/key-order-witness.js +641 -0
  831. package/dist/frontend/lowering/key-order-witness.js.map +1 -0
  832. package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
  833. package/dist/frontend/lowering/key-order-witness.test.js +239 -0
  834. package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
  835. package/dist/frontend/lowering/lifetime-regions.js +7 -7
  836. package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
  837. package/dist/frontend/lowering/lower-array-sort.d.ts +33 -15
  838. package/dist/frontend/lowering/lower-array-sort.js +117 -21
  839. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  840. package/dist/frontend/lowering/lower-array-sort.test.js +93 -14
  841. package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
  842. package/dist/frontend/lowering/lower-assert.js +61 -60
  843. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  844. package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
  845. package/dist/frontend/lowering/lower-async-iteration.js +34 -6
  846. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  847. package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
  848. package/dist/frontend/lowering/lower-builtin-values.js +33 -3
  849. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  850. package/dist/frontend/lowering/lower-calls.js +1404 -448
  851. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  852. package/dist/frontend/lowering/lower-classes.d.ts +54 -3
  853. package/dist/frontend/lowering/lower-classes.js +1529 -472
  854. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  855. package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
  856. package/dist/frontend/lowering/lower-comptime.js +111 -13
  857. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  858. package/dist/frontend/lowering/lower-console.js +13 -11
  859. package/dist/frontend/lowering/lower-console.js.map +1 -1
  860. package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
  861. package/dist/frontend/lowering/lower-dgram.js +241 -21
  862. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  863. package/dist/frontend/lowering/lower-enums.js +113 -14
  864. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  865. package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
  866. package/dist/frontend/lowering/lower-event-emitter.js +258 -70
  867. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  868. package/dist/frontend/lowering/lower-event-target.js +2 -2
  869. package/dist/frontend/lowering/lower-event-target.js.map +1 -1
  870. package/dist/frontend/lowering/lower-expando.js +17 -13
  871. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  872. package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
  873. package/dist/frontend/lowering/lower-exprs.js +1509 -12486
  874. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  875. package/dist/frontend/lowering/lower-functions.js +72 -22
  876. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  877. package/dist/frontend/lowering/lower-generators.d.ts +6 -0
  878. package/dist/frontend/lowering/lower-generators.js +39 -20
  879. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  880. package/dist/frontend/lowering/lower-global-value.js +5 -1
  881. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  882. package/dist/frontend/lowering/lower-inspect.js +900 -107
  883. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  884. package/dist/frontend/lowering/lower-mixins.js +23 -20
  885. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  886. package/dist/frontend/lowering/lower-mock.d.ts +8 -1
  887. package/dist/frontend/lowering/lower-mock.js +185 -18
  888. package/dist/frontend/lowering/lower-mock.js.map +1 -1
  889. package/dist/frontend/lowering/lower-modules.d.ts +11 -3
  890. package/dist/frontend/lowering/lower-modules.js +445 -94
  891. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  892. package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
  893. package/dist/frontend/lowering/lower-namespaces.js +65 -33
  894. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  895. package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
  896. package/dist/frontend/lowering/lower-node-module.js +147 -14
  897. package/dist/frontend/lowering/lower-node-module.js.map +1 -1
  898. package/dist/frontend/lowering/lower-server.d.ts +6 -6
  899. package/dist/frontend/lowering/lower-server.js +514 -101
  900. package/dist/frontend/lowering/lower-server.js.map +1 -1
  901. package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
  902. package/dist/frontend/lowering/lower-stdlib.js +179 -118
  903. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  904. package/dist/frontend/lowering/lower-stmts.d.ts +30 -7
  905. package/dist/frontend/lowering/lower-stmts.js +1950 -433
  906. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  907. package/dist/frontend/lowering/lower-stream.d.ts +3 -0
  908. package/dist/frontend/lowering/lower-stream.js +398 -56
  909. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  910. package/dist/frontend/lowering/lower-test.d.ts +3 -0
  911. package/dist/frontend/lowering/lower-test.js +437 -62
  912. package/dist/frontend/lowering/lower-test.js.map +1 -1
  913. package/dist/frontend/lowering/lower-timers.js +96 -32
  914. package/dist/frontend/lowering/lower-timers.js.map +1 -1
  915. package/dist/frontend/lowering/lower-url.js +1 -1
  916. package/dist/frontend/lowering/lower-url.js.map +1 -1
  917. package/dist/frontend/lowering/lowerer.d.ts +424 -27
  918. package/dist/frontend/lowering/lowerer.js +2062 -310
  919. package/dist/frontend/lowering/lowerer.js.map +1 -1
  920. package/dist/frontend/lowering/lowerer.test.js +10 -4
  921. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  922. package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
  923. package/dist/frontend/lowering/maybe-promise.js +249 -0
  924. package/dist/frontend/lowering/maybe-promise.js.map +1 -0
  925. package/dist/frontend/lowering/module-member-this.d.ts +3 -0
  926. package/dist/frontend/lowering/module-member-this.js +262 -0
  927. package/dist/frontend/lowering/module-member-this.js.map +1 -0
  928. package/dist/frontend/lowering/module-namespace-elements.js +1 -1
  929. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  930. package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
  931. package/dist/frontend/lowering/nan-coded-reads.js +45 -32
  932. package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
  933. package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
  934. package/dist/frontend/lowering/narrowing-stability.js +104 -32
  935. package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
  936. package/dist/frontend/lowering/native-ffi.js +11 -11
  937. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  938. package/dist/frontend/lowering/object-factory-new.js +6 -8
  939. package/dist/frontend/lowering/object-factory-new.js.map +1 -1
  940. package/dist/frontend/lowering/private-brands.d.ts +46 -0
  941. package/dist/frontend/lowering/private-brands.js +265 -0
  942. package/dist/frontend/lowering/private-brands.js.map +1 -0
  943. package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
  944. package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
  945. package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
  946. package/dist/frontend/lowering/rebindable-functions.d.ts +8 -0
  947. package/dist/frontend/lowering/rebindable-functions.js +54 -0
  948. package/dist/frontend/lowering/rebindable-functions.js.map +1 -0
  949. package/dist/frontend/lowering/require-initialization.d.ts +32 -0
  950. package/dist/frontend/lowering/require-initialization.js +246 -0
  951. package/dist/frontend/lowering/require-initialization.js.map +1 -0
  952. package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
  953. package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
  954. package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
  955. package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
  956. package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
  957. package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
  958. package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
  959. package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
  960. package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
  961. package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
  962. package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
  963. package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
  964. package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
  965. package/dist/frontend/lowering/runtime-optional-records.js +205 -32
  966. package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
  967. package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
  968. package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
  969. package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
  970. package/dist/frontend/lowering/split-consumers.js +4 -4
  971. package/dist/frontend/lowering/split-consumers.js.map +1 -1
  972. package/dist/frontend/lowering/static-function-names.d.ts +28 -0
  973. package/dist/frontend/lowering/static-function-names.js +212 -0
  974. package/dist/frontend/lowering/static-function-names.js.map +1 -0
  975. package/dist/frontend/lowering/static-this.js +6 -6
  976. package/dist/frontend/lowering/static-this.js.map +1 -1
  977. package/dist/frontend/lowering/static-typeof.d.ts +26 -0
  978. package/dist/frontend/lowering/static-typeof.js +133 -0
  979. package/dist/frontend/lowering/static-typeof.js.map +1 -0
  980. package/dist/frontend/lowering/strict-mode.d.ts +5 -0
  981. package/dist/frontend/lowering/strict-mode.js +31 -0
  982. package/dist/frontend/lowering/strict-mode.js.map +1 -0
  983. package/dist/frontend/lowering/string-index-bounds.js +13 -12
  984. package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
  985. package/dist/frontend/lowering/string-index.d.ts +12 -0
  986. package/dist/frontend/lowering/string-index.js +72 -1
  987. package/dist/frontend/lowering/string-index.js.map +1 -1
  988. package/dist/frontend/lowering/surfaces.d.ts +12 -3
  989. package/dist/frontend/lowering/surfaces.js +282 -45
  990. package/dist/frontend/lowering/surfaces.js.map +1 -1
  991. package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
  992. package/dist/frontend/lowering/symbol-fields.js +204 -36
  993. package/dist/frontend/lowering/symbol-fields.js.map +1 -1
  994. package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
  995. package/dist/frontend/lowering/symbol-methods.js +24 -6
  996. package/dist/frontend/lowering/symbol-methods.js.map +1 -1
  997. package/dist/frontend/lowering/thenables.d.ts +16 -0
  998. package/dist/frontend/lowering/thenables.js +124 -0
  999. package/dist/frontend/lowering/thenables.js.map +1 -0
  1000. package/dist/frontend/lowering/thread-slots.d.ts +13 -0
  1001. package/dist/frontend/lowering/thread-slots.js +208 -0
  1002. package/dist/frontend/lowering/thread-slots.js.map +1 -0
  1003. package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
  1004. package/dist/frontend/lowering/typed-arguments.js +472 -0
  1005. package/dist/frontend/lowering/typed-arguments.js.map +1 -0
  1006. package/dist/frontend/lowering/union-retag.d.ts +8 -0
  1007. package/dist/frontend/lowering/union-retag.js +27 -0
  1008. package/dist/frontend/lowering/union-retag.js.map +1 -1
  1009. package/dist/frontend/lowering/union-retag.test.js +24 -1
  1010. package/dist/frontend/lowering/union-retag.test.js.map +1 -1
  1011. package/dist/frontend/lowering/var-hoisting.js +6 -6
  1012. package/dist/frontend/lowering/var-hoisting.js.map +1 -1
  1013. package/dist/frontend/lowering/width-lift.d.ts +4 -0
  1014. package/dist/frontend/mock-shapes.js +13 -6
  1015. package/dist/frontend/mock-shapes.js.map +1 -1
  1016. package/dist/frontend/module-source-candidates.js +1 -1
  1017. package/dist/frontend/module-source-candidates.js.map +1 -1
  1018. package/dist/frontend/module-source-candidates.test.js +2 -1
  1019. package/dist/frontend/module-source-candidates.test.js.map +1 -1
  1020. package/dist/frontend/module-syntax.js +8 -8
  1021. package/dist/frontend/module-syntax.js.map +1 -1
  1022. package/dist/frontend/npm-static-builtin-aliases.d.ts +8 -0
  1023. package/dist/frontend/npm-static-builtin-aliases.js +65 -0
  1024. package/dist/frontend/npm-static-builtin-aliases.js.map +1 -0
  1025. package/dist/frontend/npm-static-bundled-chunks.d.ts +58 -0
  1026. package/dist/frontend/npm-static-bundled-chunks.js +981 -0
  1027. package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
  1028. package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
  1029. package/dist/frontend/npm-static-bundled-chunks.test.js +399 -0
  1030. package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
  1031. package/dist/frontend/npm-static-bundled-cjs.js +24 -23
  1032. package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
  1033. package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
  1034. package/dist/frontend/npm-static-bundled-esm.js +988 -0
  1035. package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
  1036. package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
  1037. package/dist/frontend/npm-static-bundled-esm.test.js +336 -0
  1038. package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
  1039. package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
  1040. package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
  1041. package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
  1042. package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
  1043. package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
  1044. package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
  1045. package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
  1046. package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
  1047. package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
  1048. package/dist/frontend/npm-static-declaration-syntax.js +102 -101
  1049. package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
  1050. package/dist/frontend/npm-static-enum-iife.d.ts +6 -0
  1051. package/dist/frontend/npm-static-enum-iife.js +280 -0
  1052. package/dist/frontend/npm-static-enum-iife.js.map +1 -0
  1053. package/dist/frontend/npm-static-enum-iife.test.d.ts +1 -0
  1054. package/dist/frontend/npm-static-enum-iife.test.js +116 -0
  1055. package/dist/frontend/npm-static-enum-iife.test.js.map +1 -0
  1056. package/dist/frontend/npm-static-prune.js +36 -24
  1057. package/dist/frontend/npm-static-prune.js.map +1 -1
  1058. package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
  1059. package/dist/frontend/npm-static-rewrite-host.js +14 -3
  1060. package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
  1061. package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
  1062. package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
  1063. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  1064. package/dist/frontend/npm-static-subtyping.js +7 -9
  1065. package/dist/frontend/npm-static-subtyping.js.map +1 -1
  1066. package/dist/frontend/npm-static.d.ts +25 -1
  1067. package/dist/frontend/npm-static.js +212 -16
  1068. package/dist/frontend/npm-static.js.map +1 -1
  1069. package/dist/frontend/npm-static.test.js +22 -1
  1070. package/dist/frontend/npm-static.test.js.map +1 -1
  1071. package/dist/frontend/npm.js +13 -0
  1072. package/dist/frontend/npm.js.map +1 -1
  1073. package/dist/frontend/package-shims.d.ts +47 -0
  1074. package/dist/frontend/package-shims.js +300 -0
  1075. package/dist/frontend/package-shims.js.map +1 -0
  1076. package/dist/frontend/pipeline.js +230 -26
  1077. package/dist/frontend/pipeline.js.map +1 -1
  1078. package/dist/frontend/pipeline.test.js +22 -1
  1079. package/dist/frontend/pipeline.test.js.map +1 -1
  1080. package/dist/frontend/program-analysis.d.ts +6 -1
  1081. package/dist/frontend/program-analysis.js +7 -0
  1082. package/dist/frontend/program-analysis.js.map +1 -1
  1083. package/dist/frontend/program.d.ts +100 -2
  1084. package/dist/frontend/program.js +1627 -262
  1085. package/dist/frontend/program.js.map +1 -1
  1086. package/dist/frontend/program.test.js +76 -6
  1087. package/dist/frontend/program.test.js.map +1 -1
  1088. package/dist/frontend/resolve.js +49 -2
  1089. package/dist/frontend/resolve.js.map +1 -1
  1090. package/dist/frontend/resolve.test.js +49 -0
  1091. package/dist/frontend/resolve.test.js.map +1 -1
  1092. package/dist/frontend/services.d.ts +26 -1
  1093. package/dist/frontend/services.js +59 -3
  1094. package/dist/frontend/services.js.map +1 -1
  1095. package/dist/frontend/services.test.js +2 -1
  1096. package/dist/frontend/services.test.js.map +1 -1
  1097. package/dist/frontend/threads-import.js +1 -1
  1098. package/dist/frontend/threads-import.js.map +1 -1
  1099. package/dist/frontend/tier-analysis.d.ts +71 -0
  1100. package/dist/frontend/tier-analysis.js +522 -0
  1101. package/dist/frontend/tier-analysis.js.map +1 -0
  1102. package/dist/frontend/ts7/api-conformance.d.ts +234 -0
  1103. package/dist/frontend/ts7/api-conformance.js +7 -0
  1104. package/dist/frontend/ts7/api-conformance.js.map +1 -0
  1105. package/dist/frontend/ts7/ast-guards.generated.js +2 -1
  1106. package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
  1107. package/dist/frontend/ts7/ast-node.d.ts +47 -25
  1108. package/dist/frontend/ts7/ast-node.js +64 -18
  1109. package/dist/frontend/ts7/ast-node.js.map +1 -1
  1110. package/dist/frontend/ts7/ast-node.test.js +36 -12
  1111. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  1112. package/dist/frontend/ts7/ast-types.d.ts +10 -3
  1113. package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
  1114. package/dist/frontend/ts7/ast.d.ts +1 -0
  1115. package/dist/frontend/ts7/ast.js +3 -2
  1116. package/dist/frontend/ts7/ast.js.map +1 -1
  1117. package/dist/frontend/ts7/checker-backend.d.ts +23 -0
  1118. package/dist/frontend/ts7/checker-backend.js +88 -0
  1119. package/dist/frontend/ts7/checker-backend.js.map +1 -0
  1120. package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
  1121. package/dist/frontend/ts7/checker-backend.test.js +63 -0
  1122. package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
  1123. package/dist/frontend/ts7/checker-cache.d.ts +0 -3
  1124. package/dist/frontend/ts7/checker-cache.js +0 -6
  1125. package/dist/frontend/ts7/checker-cache.js.map +1 -1
  1126. package/dist/frontend/ts7/checker.d.ts +18 -11
  1127. package/dist/frontend/ts7/checker.js +42 -55
  1128. package/dist/frontend/ts7/checker.js.map +1 -1
  1129. package/dist/frontend/ts7/checker.test.js +10 -7
  1130. package/dist/frontend/ts7/checker.test.js.map +1 -1
  1131. package/dist/frontend/ts7/diagnostic.d.ts +19 -0
  1132. package/dist/frontend/ts7/diagnostic.js +22 -0
  1133. package/dist/frontend/ts7/diagnostic.js.map +1 -0
  1134. package/dist/frontend/ts7/node-functions.d.ts +8 -0
  1135. package/dist/frontend/ts7/node-functions.js +18 -0
  1136. package/dist/frontend/ts7/node-functions.js.map +1 -0
  1137. package/dist/frontend/ts7/program-host.d.ts +10 -5
  1138. package/dist/frontend/ts7/program-host.js +19 -0
  1139. package/dist/frontend/ts7/program-host.js.map +1 -1
  1140. package/dist/frontend/ts7/rpc-api.d.ts +5 -1
  1141. package/dist/frontend/ts7/rpc-api.js +8 -1
  1142. package/dist/frontend/ts7/rpc-api.js.map +1 -1
  1143. package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
  1144. package/dist/frontend/ts7/semantic-checker.js +26 -8
  1145. package/dist/frontend/ts7/semantic-checker.js.map +1 -1
  1146. package/dist/frontend/ts7/semantic-checker.test.js +12 -9
  1147. package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
  1148. package/dist/frontend/ts7/semantic-model.d.ts +57 -24
  1149. package/dist/frontend/ts7/semantic-model.js +114 -16
  1150. package/dist/frontend/ts7/semantic-model.js.map +1 -1
  1151. package/dist/frontend/ts7/semantic-model.test.js +4 -4
  1152. package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
  1153. package/dist/frontend/ts7/semantic-types.d.ts +7 -3
  1154. package/dist/frontend/ts7/semantic-types.js +1 -1
  1155. package/dist/frontend/ts7/semantic-types.js.map +1 -1
  1156. package/dist/frontend/ts7/session.d.ts +30 -15
  1157. package/dist/frontend/ts7/session.js +8 -5
  1158. package/dist/frontend/ts7/session.js.map +1 -1
  1159. package/dist/frontend/ts7/session.test.js +9 -5
  1160. package/dist/frontend/ts7/session.test.js.map +1 -1
  1161. package/dist/frontend/ts7/source-parser.d.ts +6 -2
  1162. package/dist/frontend/ts7/source-parser.js +24 -3
  1163. package/dist/frontend/ts7/source-parser.js.map +1 -1
  1164. package/dist/frontend/ts7/source-parser.test.js +38 -17
  1165. package/dist/frontend/ts7/source-parser.test.js.map +1 -1
  1166. package/dist/frontend/type-mapper.d.ts +122 -2
  1167. package/dist/frontend/type-mapper.js +2735 -723
  1168. package/dist/frontend/type-mapper.js.map +1 -1
  1169. package/dist/frontend/type-only-imports.d.ts +28 -0
  1170. package/dist/frontend/type-only-imports.js +122 -0
  1171. package/dist/frontend/type-only-imports.js.map +1 -0
  1172. package/dist/frontend/worker-target.js +8 -8
  1173. package/dist/frontend/worker-target.js.map +1 -1
  1174. package/dist/index.d.ts +4 -1
  1175. package/dist/index.js +87 -8
  1176. package/dist/index.js.map +1 -1
  1177. package/dist/ir/analysis.js +4 -2
  1178. package/dist/ir/analysis.js.map +1 -1
  1179. package/dist/ir/api.d.ts +1 -1
  1180. package/dist/ir/api.js +1 -1
  1181. package/dist/ir/api.js.map +1 -1
  1182. package/dist/ir/array-length-stability.d.ts +31 -0
  1183. package/dist/ir/array-length-stability.js +249 -0
  1184. package/dist/ir/array-length-stability.js.map +1 -0
  1185. package/dist/ir/array-length-stability.test.d.ts +1 -0
  1186. package/dist/ir/array-length-stability.test.js +134 -0
  1187. package/dist/ir/array-length-stability.test.js.map +1 -0
  1188. package/dist/ir/build.d.ts +2 -2
  1189. package/dist/ir/build.js +1 -1
  1190. package/dist/ir/build.js.map +1 -1
  1191. package/dist/ir/builtin-effects.js +116 -0
  1192. package/dist/ir/builtin-effects.js.map +1 -1
  1193. package/dist/ir/builtin-signatures.d.ts +1 -1
  1194. package/dist/ir/builtin-signatures.js +540 -29
  1195. package/dist/ir/builtin-signatures.js.map +1 -1
  1196. package/dist/ir/byte-numbers.js +3 -0
  1197. package/dist/ir/byte-numbers.js.map +1 -1
  1198. package/dist/ir/callback-specialization.d.ts +37 -0
  1199. package/dist/ir/callback-specialization.js +459 -0
  1200. package/dist/ir/callback-specialization.js.map +1 -0
  1201. package/dist/ir/callback-specialization.test.d.ts +1 -0
  1202. package/dist/ir/callback-specialization.test.js +208 -0
  1203. package/dist/ir/callback-specialization.test.js.map +1 -0
  1204. package/dist/ir/capture-values.d.ts +0 -1
  1205. package/dist/ir/capture-values.js +51 -40
  1206. package/dist/ir/capture-values.js.map +1 -1
  1207. package/dist/ir/constant-globals.test.js +1 -1
  1208. package/dist/ir/constant-tables.test.js +1 -1
  1209. package/dist/ir/field-values.test.js +1 -1
  1210. package/dist/ir/final-fields.test.js +1 -1
  1211. package/dist/ir/function-references.test.js +9 -1
  1212. package/dist/ir/function-references.test.js.map +1 -1
  1213. package/dist/ir/init-only-globals.test.js +1 -1
  1214. package/dist/ir/initializer-bindings.test.js +1 -1
  1215. package/dist/ir/int32-slots.d.ts +14 -0
  1216. package/dist/ir/int32-slots.js +97 -14
  1217. package/dist/ir/int32-slots.js.map +1 -1
  1218. package/dist/ir/int32-slots.test.js +1 -1
  1219. package/dist/ir/integer-loop-facts.d.ts +7 -0
  1220. package/dist/ir/integer-loop-facts.js +103 -17
  1221. package/dist/ir/integer-loop-facts.js.map +1 -1
  1222. package/dist/ir/integer-loops.d.ts +1 -1
  1223. package/dist/ir/integer-loops.js +39 -9
  1224. package/dist/ir/integer-loops.js.map +1 -1
  1225. package/dist/ir/integer-loops.test.js +104 -0
  1226. package/dist/ir/integer-loops.test.js.map +1 -1
  1227. package/dist/ir/integer-ranges.d.ts +13 -1
  1228. package/dist/ir/integer-ranges.js +125 -26
  1229. package/dist/ir/integer-ranges.js.map +1 -1
  1230. package/dist/ir/integer-ranges.test.js +273 -2
  1231. package/dist/ir/integer-ranges.test.js.map +1 -1
  1232. package/dist/ir/intrinsic-signatures.js +6 -0
  1233. package/dist/ir/intrinsic-signatures.js.map +1 -1
  1234. package/dist/ir/ir.d.ts +221 -58
  1235. package/dist/ir/ir.js +127 -12
  1236. package/dist/ir/ir.js.map +1 -1
  1237. package/dist/ir/ir.test.js +10 -0
  1238. package/dist/ir/ir.test.js.map +1 -1
  1239. package/dist/ir/js-ic.d.ts +52 -0
  1240. package/dist/ir/js-ic.js +199 -0
  1241. package/dist/ir/js-ic.js.map +1 -0
  1242. package/dist/ir/js-ic.test.d.ts +1 -0
  1243. package/dist/ir/js-ic.test.js +148 -0
  1244. package/dist/ir/js-ic.test.js.map +1 -0
  1245. package/dist/ir/jsval.d.ts +8 -0
  1246. package/dist/ir/jsval.js +399 -0
  1247. package/dist/ir/jsval.js.map +1 -0
  1248. package/dist/ir/jsval.test.d.ts +1 -0
  1249. package/dist/ir/jsval.test.js +239 -0
  1250. package/dist/ir/jsval.test.js.map +1 -0
  1251. package/dist/ir/runtime-features.d.ts +183 -33
  1252. package/dist/ir/runtime-features.js +795 -422
  1253. package/dist/ir/runtime-features.js.map +1 -1
  1254. package/dist/ir/scalar-records.test.js +1 -1
  1255. package/dist/ir/self-captures.d.ts +33 -0
  1256. package/dist/ir/self-captures.js +245 -0
  1257. package/dist/ir/self-captures.js.map +1 -0
  1258. package/dist/ir/self-captures.test.d.ts +1 -0
  1259. package/dist/ir/self-captures.test.js +135 -0
  1260. package/dist/ir/self-captures.test.js.map +1 -0
  1261. package/dist/ir/serialize.d.ts +1 -1
  1262. package/dist/ir/serialize.js +7 -4
  1263. package/dist/ir/serialize.js.map +1 -1
  1264. package/dist/ir/tiers.d.ts +26 -0
  1265. package/dist/ir/tiers.js +101 -0
  1266. package/dist/ir/tiers.js.map +1 -0
  1267. package/dist/ir/tiers.test.d.ts +1 -0
  1268. package/dist/ir/tiers.test.js +140 -0
  1269. package/dist/ir/tiers.test.js.map +1 -0
  1270. package/dist/ir/traverse.js +201 -150
  1271. package/dist/ir/traverse.js.map +1 -1
  1272. package/dist/ir/traverse.test.js +33 -30
  1273. package/dist/ir/traverse.test.js.map +1 -1
  1274. package/dist/ir/unshare.js +65 -3
  1275. package/dist/ir/unshare.js.map +1 -1
  1276. package/dist/ir/unshare.test.js +1 -1
  1277. package/dist/ir/validate.js +196 -76
  1278. package/dist/ir/validate.js.map +1 -1
  1279. package/dist/ir/validate.test.js +41 -11
  1280. package/dist/ir/validate.test.js.map +1 -1
  1281. package/dist/library/fence-eval.test.js +1 -1
  1282. package/dist/library/int-infer.test.js +4 -4
  1283. package/dist/library/ir-policy.js +14 -0
  1284. package/dist/library/ir-policy.js.map +1 -1
  1285. package/dist/library/library-cache.d.ts +1 -0
  1286. package/dist/library/library-cache.js.map +1 -1
  1287. package/dist/library/library-cache.test.js +5 -5
  1288. package/dist/library/library-profile.d.ts +4 -4
  1289. package/dist/library/library-profile.js +35 -7
  1290. package/dist/library/library-profile.js.map +1 -1
  1291. package/dist/library/prepare.js +13 -1
  1292. package/dist/library/prepare.js.map +1 -1
  1293. package/dist/native/cli.js +22 -0
  1294. package/dist/native/cli.js.map +1 -1
  1295. package/dist/native/compiler.js +35 -6
  1296. package/dist/native/compiler.js.map +1 -1
  1297. package/dist/native/compiler.test.js +2 -2
  1298. package/dist/native/executable-cache.js +3 -0
  1299. package/dist/native/executable-cache.js.map +1 -1
  1300. package/dist/native/prepare.js +10 -0
  1301. package/dist/native/prepare.js.map +1 -1
  1302. package/dist/native/sanitizer.test.js +19 -0
  1303. package/dist/native/sanitizer.test.js.map +1 -1
  1304. package/dist/native/toolchain.d.ts +2 -0
  1305. package/dist/native/toolchain.js +10 -1
  1306. package/dist/native/toolchain.js.map +1 -1
  1307. package/dist/native/toolchain.test.js +39 -1
  1308. package/dist/native/toolchain.test.js.map +1 -1
  1309. package/dist/startup-cache.d.ts +1 -0
  1310. package/dist/startup-cache.js +1 -0
  1311. package/dist/startup-cache.js.map +1 -1
  1312. package/dist/wasm/base64.d.ts +5 -0
  1313. package/dist/wasm/base64.js +62 -0
  1314. package/dist/wasm/base64.js.map +1 -0
  1315. package/dist/wasm/binary.d.ts +36 -0
  1316. package/dist/wasm/binary.js +1976 -0
  1317. package/dist/wasm/binary.js.map +1 -0
  1318. package/dist/wasm/binary.test.d.ts +1 -0
  1319. package/dist/wasm/binary.test.js +190 -0
  1320. package/dist/wasm/binary.test.js.map +1 -0
  1321. package/dist/wasm/discover.d.ts +38 -0
  1322. package/dist/wasm/discover.js +377 -0
  1323. package/dist/wasm/discover.js.map +1 -0
  1324. package/dist/wasm/discover.test.d.ts +1 -0
  1325. package/dist/wasm/discover.test.js +24 -0
  1326. package/dist/wasm/discover.test.js.map +1 -0
  1327. package/dist/wasm/module.d.ts +151 -0
  1328. package/dist/wasm/module.js +575 -0
  1329. package/dist/wasm/module.js.map +1 -0
  1330. package/dist/wasm/translate.d.ts +48 -0
  1331. package/dist/wasm/translate.js +2129 -0
  1332. package/dist/wasm/translate.js.map +1 -0
  1333. package/dist/wasm/translate.test.d.ts +1 -0
  1334. package/dist/wasm/translate.test.js +207 -0
  1335. package/dist/wasm/translate.test.js.map +1 -0
  1336. package/package.json +22 -20
  1337. package/shims/fs-extra/core/api.ts +1192 -0
  1338. package/shims/fs-extra/index.ts +9 -0
  1339. package/shims/undici/core/agent.ts +163 -0
  1340. package/shims/undici/core/api.ts +93 -0
  1341. package/shims/undici/core/client.ts +1304 -0
  1342. package/shims/undici/core/connector.ts +157 -0
  1343. package/shims/undici/core/diagnostics-types.ts +68 -0
  1344. package/shims/undici/core/diagnostics.ts +16 -0
  1345. package/shims/undici/core/dispatcher.ts +574 -0
  1346. package/shims/undici/core/errors-v5.ts +22 -0
  1347. package/shims/undici/core/errors-v7.ts +25 -0
  1348. package/shims/undici/core/errors.ts +255 -0
  1349. package/shims/undici/core/fetch.ts +635 -0
  1350. package/shims/undici/core/pool.ts +280 -0
  1351. package/shims/undici/core/readable.ts +268 -0
  1352. package/shims/undici/core/request.ts +313 -0
  1353. package/shims/undici/core/timers.ts +80 -0
  1354. package/shims/undici/core/types.ts +167 -0
  1355. package/shims/undici/core/util.ts +67 -0
  1356. package/shims/undici/v5.ts +119 -0
  1357. package/shims/undici/v7.ts +119 -0
  1358. package/surface-manifest.json +304 -22
@@ -0,0 +1,2557 @@
1
+ /* Binary operators: arithmetic, comparisons and equality, logical and nullish pairs, and string conversion for concatenation. */
2
+ import * as ts from "../../ts7/adapter.js";
3
+ import { cleanFuncAdaptable } from "../coercions/function-adapters.js";
4
+ import { jsFuncNameOf } from "../lowerer.js";
5
+ import { BIGINT_T, BOOL, DYN, DYN_HANDLE_KINDS, F64, REF_TRUTHY_KINDS, STRING, UNDEFINED_T, VOID, canBoxFuncIntoDyn, isUnitType, typeEquals, typeKey, } from "../../../ir/ir.js";
6
+ import { isSafeToDiscard, isSafeToRepeat } from "./evaluation-safety.js";
7
+ import { bigintCompoundValue, compoundUnsupported, concatOperand, constructorGlobalTypeof, deferredSlotOr, dynCompoundValue, lowerAbsenceProbe, lowerDynMemberAssignment, lowerOptionalNumber, lowerPresenceOperand, nullishBranches, operandPairs, operatorUnsupported, runtimeOptionalStorageOperand, symbolFieldInfo, typeofAnswer, } from "../lower-exprs.js";
8
+ import { COMPOUND_ASSIGN_OPS, NARROW_FIRST } from "../surfaces.js";
9
+ import { lowerElementCompoundParts } from "./element-access.js";
10
+ import { InternalCompilerError } from "../../../errors.js";
11
+ import { isJsSourceFile, locOf } from "../../program.js";
12
+ import { storedClassValueType } from "../lower-classes.js";
13
+ import { builtinClassKind } from "../builtins/builtin-class-dyn.js";
14
+ import { hasRuntimeStatics } from "../class-runtime-statics.js";
15
+ import { tryLowerExpression } from "./try-lower-expression.js";
16
+ import { fenceNodeModuleMutation, lowerRequireCacheHas } from "../lower-node-module.js";
17
+ import { errorToStringCall } from "../error-methods.js";
18
+ import { classToStringConversion, classUnionToString } from "../class-to-primitive.js";
19
+ import { isPerfEntryType, perfEntryTag } from "../builtins/performance.js";
20
+ import { guardNullProto, nullProtoRecordShape } from "../null-prototype.js";
21
+ import { numLit, varRef } from "../../../ir/build.js";
22
+ import { lowerUrlAssignment } from "../builtins/url.js";
23
+ import { lowerClassPrototypeComputedAssignment } from "../class-prototypes.js";
24
+ import { lowerShortCircuitAssignment } from "./nullish-assignment.js";
25
+ import { lowerEventObjectPropertyWrite } from "../lower-event-target.js";
26
+ import { lowerFieldCompoundValue } from "./updates.js";
27
+ import { expandoWritableTarget } from "../lower-expando.js";
28
+ import { nsWritableTarget } from "../lower-namespaces.js";
29
+ import { arrayValueStore, tryLowerBytesReadNumberEquality } from "../array-values.js";
30
+ import { cjsExportMemberWriteGlobalOf, cjsInFileExportGlobalOf } from "../cjs-exports-object.js";
31
+ import { lowerUnionFieldWrite } from "./union-fields.js";
32
+ import { lowerAbstractEquality } from "../abstract-equality.js";
33
+ import { lowerInExpression } from "./relational.js";
34
+ import { lowerDynTypeofTest, lowerErrorCodeTypeofTest } from "./typeof.js";
35
+ import { builtinClassRefOf, sameBuiltinClass } from "../builtins/class-values.js";
36
+ import { lowerRuntimeConstructorIs, runtimeConstructorReceiver, } from "../builtins/runtime-constructor.js";
37
+ import { tryLowerIndexedComparison } from "../indexed-comparison.js";
38
+ import { lowerUnionEquality, tagEqualityMayMissAlias } from "../strict-equality.js";
39
+ import { withUnitArm } from "../../type-mapper.js";
40
+ import { npmStaticPackageOfPath } from "../../npm-static.js";
41
+ import { lowerWebAssemblyTypeof } from "../builtins/webassembly.js";
42
+ /** `v === undefined` / `v !== null` — the narrowing tests for unit-armed
43
+ * unions. A union operand compared with a unit literal lowers to a
44
+ * runtime TAG test (unionIsTag); afterwards tsc's control-flow narrowing
45
+ * types the branches and reads bridge through maybeNarrow as usual. When
46
+ * the checker already narrowed the non-literal side PAST the union
47
+ * (`w = 5; if (w !== null)`), the comparison is statically decided and
48
+ * folds to a bool literal — that drops only a side-effect-free read
49
+ * (flow narrowing applies to references, never to calls), and soundness
50
+ * rests on the same narrowing proof unionNarrow relies on. Null when
51
+ * neither side is a unit literal (not a unit comparison). */
52
+ export function lowerUnitComparison(lowerer, left, right, negated, loc) {
53
+ const unit = left.kind === "unitLit" ? left : right.kind === "unitLit" ? right : null;
54
+ if (!unit)
55
+ return null;
56
+ const other = unit === left ? right : left;
57
+ if (other.kind === "unitLit") {
58
+ // Two unit literals (`undefined === undefined`): statically decided.
59
+ return { kind: "boolLit", value: (other.unit === unit.unit) !== negated, type: BOOL, loc };
60
+ }
61
+ const slot = lowerer.deferredFieldSlot(other);
62
+ if (slot)
63
+ return lowerUnitComparison(lowerer, slot, unit, negated, loc);
64
+ // A binding the checker narrowed past the unit can still hold it at
65
+ // runtime when its value came from an unassigned deferred-init field;
66
+ // the stored tag answers either way.
67
+ if (other.kind === "unionNarrow" &&
68
+ other.value.kind === "varRef" &&
69
+ other.value.type.kind === "union" &&
70
+ lowerer.armTag(other.value.type.unionId, unit.type) >= 0)
71
+ return lowerUnitComparison(lowerer, other.value, unit, negated, loc);
72
+ if (other.type.kind === "union") {
73
+ const tag = lowerer.armTag(other.type.unionId, unit.type);
74
+ if (tag < 0) {
75
+ // A union WITHOUT that unit arm: legal TS (`miss === null` on a
76
+ // `number | undefined` — null/undefined guard comparisons are
77
+ // permitted against nullable-adjacent types), and === never
78
+ // coerces, so the answer is the constant `negated`. The literal
79
+ // must NOT flow into the union representation (the unionEq
80
+ // fallback would coerce it through the stranded-arm trap and
81
+ // throw where Node answers false). JS still evaluates the
82
+ // operand, so a non-droppable one (`xs.find(f) === null` — the
83
+ // callback's effects are observable) rides one throwaway tag
84
+ // test; droppable reads fold to the bare literal.
85
+ const answer = { kind: "boolLit", value: negated, type: BOOL, loc };
86
+ if (isSafeToDiscard(other))
87
+ return answer;
88
+ const evalOnce = {
89
+ kind: "unionIsTag",
90
+ unionId: other.type.unionId,
91
+ tag: 0,
92
+ negated: false,
93
+ value: other,
94
+ type: BOOL,
95
+ loc,
96
+ };
97
+ return {
98
+ kind: "logical",
99
+ op: negated ? "||" : "&&",
100
+ left: evalOnce,
101
+ right: answer,
102
+ type: BOOL,
103
+ loc,
104
+ };
105
+ }
106
+ return {
107
+ kind: "unionIsTag",
108
+ unionId: other.type.unionId,
109
+ tag,
110
+ negated,
111
+ value: other,
112
+ type: BOOL,
113
+ loc,
114
+ };
115
+ }
116
+ // A process.env read tsc narrowed past its union (an earlier write to
117
+ // the same key): the environment is VOLATILE — `delete process.env.K`
118
+ // undoes the write the narrowing rode on — so folding would bake a
119
+ // stale answer. Compare the fresh read's union tag instead.
120
+ const envRead = volatileEnvRead(other);
121
+ if (envRead && envRead.type.kind === "union") {
122
+ const tag = lowerer.armTag(envRead.type.unionId, unit.type);
123
+ if (tag >= 0) {
124
+ return {
125
+ kind: "unionIsTag",
126
+ unionId: envRead.type.unionId,
127
+ tag,
128
+ negated,
129
+ value: envRead,
130
+ type: BOOL,
131
+ loc,
132
+ };
133
+ }
134
+ }
135
+ // A VOID-typed operand (`foo() === undefined` where foo's declared
136
+ // return is undefined/void — the mapping folds both to void): JS
137
+ // yields undefined from such a call, so the compare is TRUE-when-equal
138
+ // — the opposite of the never-holds-units fold below — and the IR has
139
+ // no value (nor a sequence form to keep the call's effects). Fall
140
+ // through to the caller's comparison fence instead of folding a lie.
141
+ if (other.type.kind === "void")
142
+ return null;
143
+ // Non-union operand: it can never hold undefined/null at runtime (the
144
+ // checker narrowed it to a concrete arm), so `=== unit` is false and
145
+ // `!== unit` is true.
146
+ return { kind: "boolLit", value: negated, type: BOOL, loc };
147
+ }
148
+ /** The union-typed process.envGet read inside a checker-narrowed operand,
149
+ * or null — the volatility escape above (and lowerLooseNullCompare's). */
150
+ function volatileEnvRead(e) {
151
+ if (e.kind === "libCall" && e.fn === "process.envGet")
152
+ return e;
153
+ if (e.kind === "unionNarrow" && e.value.kind === "libCall" && e.value.fn === "process.envGet") {
154
+ return e.value;
155
+ }
156
+ return null;
157
+ }
158
+ function lowerLooseNullCompare(lowerer, expr, loc) {
159
+ const negated = expr.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken;
160
+ const unwrap = (e) => ts.isParenthesizedExpression(e) ? unwrap(e.expression) : e;
161
+ const left = unwrap(expr.left);
162
+ const right = unwrap(expr.right);
163
+ const leftIsNull = left.kind === ts.SyntaxKind.NullKeyword;
164
+ if (!leftIsNull && right.kind !== ts.SyntaxKind.NullKeyword)
165
+ return null;
166
+ const otherNode = leftIsNull ? right : left;
167
+ const other = lowerPresenceOperand(lowerer, otherNode);
168
+ if (isUnitType(other.type)) {
169
+ // `null == null`, `undefined == null`: units are mutually loose-equal.
170
+ return { kind: "boolLit", value: !negated, type: BOOL, loc };
171
+ }
172
+ if (other.type.kind === "dyn") {
173
+ // `v != null` on unknown: one dyn kind test covers both units.
174
+ return {
175
+ kind: "dynTest",
176
+ test: "nullish",
177
+ ...(negated ? { negated: true } : {}),
178
+ value: other,
179
+ type: BOOL,
180
+ loc,
181
+ };
182
+ }
183
+ if (other.type.kind === "union") {
184
+ const ut = other.type;
185
+ const def = lowerer.unions.get(ut.unionId);
186
+ if (!def)
187
+ lowerer.badType(otherNode, lowerer.typeOf(otherNode));
188
+ const tags = def.arms.flatMap((a, i) => (isUnitType(a) ? [i] : []));
189
+ if (tags.length === 0) {
190
+ // No unit arms: never null-ish (defensive — the fold below).
191
+ return { kind: "boolLit", value: negated, type: BOOL, loc };
192
+ }
193
+ const isTag = (tag) => ({
194
+ kind: "unionIsTag",
195
+ unionId: ut.unionId,
196
+ tag,
197
+ negated,
198
+ value: other,
199
+ type: BOOL,
200
+ loc,
201
+ });
202
+ if (tags.length === 1)
203
+ return isTag(tags[0]);
204
+ // Both null AND undefined arms: tag-in-set as a short-circuit pair
205
+ // (De Morgan for `!=`). The operand IrExpr rides both tests, so the
206
+ // backend emits it per test — restricted to re-emittable pure reads;
207
+ // anything effectful gets its own actionable fence (the generic
208
+ // SC1040 hint would wrongly suggest `== null` as the fix).
209
+ if (!isSafeToRepeat(other)) {
210
+ lowerer.unsupported("SC1090", expr, `'== null' / '!= null' on a '${lowerer.fmt(ut)}' value that isn't a plain read ` +
211
+ `(both unit arms need the operand twice — bind it to a const first)`);
212
+ }
213
+ return {
214
+ kind: "logical",
215
+ op: negated ? "&&" : "||",
216
+ left: isTag(tags[0]),
217
+ right: isTag(tags[1]),
218
+ type: BOOL,
219
+ loc,
220
+ };
221
+ }
222
+ if (other.type.kind === "void") {
223
+ return null; // no static tag to test — keep the fence
224
+ }
225
+ // The env-volatility escape (see lowerUnitComparison): a narrowed
226
+ // process.env read compares its FRESH union tag instead of folding.
227
+ const envRead = volatileEnvRead(other);
228
+ if (envRead && envRead.type.kind === "union") {
229
+ const def = lowerer.unions.get(envRead.type.unionId);
230
+ const tag = def ? def.arms.findIndex((a) => isUnitType(a)) : -1;
231
+ if (tag >= 0) {
232
+ return {
233
+ kind: "unionIsTag",
234
+ unionId: envRead.type.unionId,
235
+ tag,
236
+ negated,
237
+ value: envRead,
238
+ type: BOOL,
239
+ loc,
240
+ };
241
+ }
242
+ }
243
+ // A non-nullable operand (tsc allows the comparison as a guard):
244
+ // `== null` is statically false, `!= null` statically true.
245
+ return { kind: "boolLit", value: negated, type: BOOL, loc };
246
+ }
247
+ /** A plain value read that may be runtime-optional: an unchecked element
248
+ * read, or a binding, member or call that carries one. Lowering these
249
+ * without a destination type is the same as lowering them into one. */
250
+ function isPlainValueRead(node) {
251
+ while (ts.isParenthesizedExpression(node))
252
+ node = node.expression;
253
+ return (ts.isElementAccessExpression(node) ||
254
+ ts.isIdentifier(node) ||
255
+ ts.isPropertyAccessExpression(node) ||
256
+ ts.isCallExpression(node));
257
+ }
258
+ /** A member access or call receiver needs the present value itself (JS
259
+ * throws a TypeError reading a member of undefined). */
260
+ function isMemberReceiver(node) {
261
+ let child = node;
262
+ let parent = node.parent;
263
+ while (ts.isParenthesizedExpression(parent)) {
264
+ child = parent;
265
+ parent = parent.parent;
266
+ }
267
+ return (((ts.isPropertyAccessExpression(parent) ||
268
+ ts.isElementAccessExpression(parent) ||
269
+ ts.isCallExpression(parent)) &&
270
+ parent.expression === child) ||
271
+ (ts.isTaggedTemplateExpression(parent) && parent.tag === child));
272
+ }
273
+ export function lowerNullishPair(lowerer, expr, loc, left) {
274
+ if (left.type.kind === "dyn") {
275
+ // `a ?? b` on a CHECKED-DYNAMIC left: the deciding test is the
276
+ // runtime kind (scr_dyn_is_nullish — UNDEF/NULL take the default).
277
+ // Both sides live in the checked-dynamic tree — the right converts through
278
+ // the usual boundary and evaluates lazily in its branch; a default
279
+ // with no dyn representation keeps the fence.
280
+ const right = lowerer.coerceToExpected(lowerer.lowerExpr(expr.right), DYN);
281
+ if (right.type.kind !== "dyn") {
282
+ lowerer.unsupported("SC1100", expr, "nullish coalescing on 'unknown' values against defaults with no dynamic representation");
283
+ }
284
+ return { kind: "nullish", left, right, type: DYN, loc };
285
+ }
286
+ if (left.type.kind !== "union")
287
+ return left;
288
+ const def = lowerer.unions.get(left.type.unionId);
289
+ if (!def)
290
+ lowerer.badType(expr.left, lowerer.typeOf(expr.left));
291
+ if (!def.arms.some(isUnitType))
292
+ return left;
293
+ const rest = def.arms.filter((a) => !isUnitType(a));
294
+ // `optionalMap ?? new Map()` carries its element contract on the left;
295
+ // the empty fallback may use it without constructing a Map<any, any>
296
+ // arm that has no first-class union representation.
297
+ const fresh = rest.length === 1 ? lowerer.emptyCollectionFor(expr.right, rest[0]) : null;
298
+ if (fresh)
299
+ return { kind: "nullish", left, right: fresh, type: fresh.type, loc };
300
+ let type = lowerer.irTypeOf(expr);
301
+ // A runtime-optional read can reach the default even when declarations
302
+ // call the left side present. Preserve a differently typed primitive
303
+ // fallback rather than checking it against that incomplete result type.
304
+ const rightType = lowerer.mapTypeOf(lowerer.typeOf(expr.right));
305
+ const primitive = (t) => t.kind === "f64" || t.kind === "string" || t.kind === "bool";
306
+ if (rightType &&
307
+ primitive(type) &&
308
+ primitive(rightType) &&
309
+ !typeEquals(type, rightType) &&
310
+ rest.every(primitive)) {
311
+ const arms = [...rest];
312
+ if (!arms.some((arm) => typeEquals(arm, rightType)))
313
+ arms.push(rightType);
314
+ arms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
315
+ type = { kind: "union", unionId: lowerer.unions.intern(arms) };
316
+ lowerer.runtimeOptionalArithmeticTypes.set(expr, type);
317
+ }
318
+ if (type.kind === "dyn" && lowerer.dynConvertible(left.type)) {
319
+ return {
320
+ kind: "nullish",
321
+ left: lowerer.coerceToExpected(left, DYN),
322
+ right: lowerer.lowerExprExpecting(expr.right, DYN),
323
+ type: DYN,
324
+ loc,
325
+ };
326
+ }
327
+ // A runtime-optional default (`name ?? names[0]`): the checker types an
328
+ // unchecked element read as the bare element type, but an out-of-range
329
+ // read is undefined at runtime. When the default shares the left's
330
+ // optional union, that union is the result, so the undefined state
331
+ // reaches the consumer (an optional return or parameter takes it as its
332
+ // undefined arm; a plain slot still extracts the element with its
333
+ // checked narrow).
334
+ if (rest.length === 1 &&
335
+ typeEquals(type, rest[0]) &&
336
+ isPlainValueRead(expr.right) &&
337
+ !isMemberReceiver(expr)) {
338
+ const raw = lowerer.lowerExpr(expr.right);
339
+ if (typeEquals(raw.type, left.type))
340
+ return { kind: "nullish", left, right: raw, type: left.type, loc };
341
+ // `names[0] ?? undefined`: an explicit unit default stays the left's arm.
342
+ if (isUnitType(raw.type) && lowerer.armTag(left.type.unionId, raw.type) >= 0) {
343
+ const right = lowerer.coerceInto(expr.right, raw, left.type);
344
+ return { kind: "nullish", left, right, type: left.type, loc };
345
+ }
346
+ return { kind: "nullish", left, right: lowerer.coerceInto(expr.right, raw, type), type, loc };
347
+ }
348
+ if (typeEquals(type, left.type) || (rest.length === 1 && typeEquals(type, rest[0]))) {
349
+ const right = lowerer.lowerExprExpecting(expr.right, type);
350
+ return { kind: "nullish", left, right, type, loc };
351
+ }
352
+ if (type.kind !== "union" && rest.length > 1 && rest.some((arm) => typeEquals(arm, type))) {
353
+ const helper = lowerer.narrowedArmHelper(left.type.unionId, type, loc);
354
+ if (helper !== null) {
355
+ return nullishBranches(lowerer, left, left.type, def.arms, type, loc, () => lowerer.lowerExprExpecting(expr.right, type), (stable) => ({ kind: "call", callee: helper, args: [stable], type, loc }));
356
+ }
357
+ }
358
+ // A subclass value defaulted to a base-class value (`circle ?? shape`):
359
+ // the present arm upcasts after the original nullish test, and the
360
+ // default lowers lazily into the base-class result.
361
+ const present = rest.length === 1 ? rest[0] : null;
362
+ if (present?.kind === "object" &&
363
+ type.kind === "object" &&
364
+ present.className !== type.className &&
365
+ lowerer.isSubclassOf(present.className, type.className)) {
366
+ const helper = lowerer.narrowedArmHelper(left.type.unionId, present, loc);
367
+ if (helper !== null) {
368
+ return nullishBranches(lowerer, left, left.type, def.arms, type, loc, () => lowerer.lowerExprExpecting(expr.right, type), (stable) => ({
369
+ kind: "upcast",
370
+ value: { kind: "call", callee: helper, args: [stable], type: present, loc },
371
+ type,
372
+ loc,
373
+ }));
374
+ }
375
+ }
376
+ // A default may change the union or widen its records. Test the
377
+ // original tag before coercing: converting the whole left first can
378
+ // lose nullish arms, and evaluating the default eagerly loses laziness.
379
+ if (type.kind === "union") {
380
+ const retag = lowerer.unionRetagHelper(left.type.unionId, type.unionId, loc) ??
381
+ lowerer.narrowedRetagHelper(expr.left, left.type.unionId, type.unionId, loc);
382
+ if (retag !== null) {
383
+ // Narrowing may exclude a record/class arm while storage retains
384
+ // it. The checked retag traps that impossible arm, but only AFTER
385
+ // the original nullish test: null/undefined must reach the lazy
386
+ // default even when neither is representable in the result.
387
+ return nullishBranches(lowerer, left, left.type, def.arms, type, loc, () => lowerer.lowerExprExpecting(expr.right, type), (stable) => ({ kind: "call", callee: retag, args: [stable], type, loc }));
388
+ }
389
+ }
390
+ // An optional callback defaulted to a function of another signature
391
+ // (`o.tags ?? (() => ({}))`, fewer parameters or a narrower result): the
392
+ // result is the callback's own function type, and the default adapts into
393
+ // it (JavaScript ignores surplus arguments). The checker's merged union
394
+ // signature would lose the callback's result shape.
395
+ if (present?.kind === "func" && present.rest !== true) {
396
+ const raw = lowerer.lowerExpr(expr.right);
397
+ if (raw.type.kind === "func" &&
398
+ (typeEquals(raw.type, present) || cleanFuncAdaptable(lowerer, raw.type, present))) {
399
+ const right = lowerer.coerceInto(expr.right, raw, present);
400
+ lowerer.nullishFuncResults.add(expr);
401
+ return { kind: "nullish", left, right, type: present, loc };
402
+ }
403
+ }
404
+ lowerer.unsupported("SC1090", expr, rest.length !== 1
405
+ ? `'??' on '${lowerer.fmt(left.type)}' (the non-nullish result is a sub-union; check a discriminant field first)`
406
+ : `'??' where the default changes the result type (left is '${lowerer.fmt(left.type)}' but the whole expression is '${lowerer.fmt(type)}' — give both sides one type)`);
407
+ }
408
+ /** `a[i] op= rhs` over native arrays and byte views. A compound assignment
409
+ * evaluates the receiver and index, reads the old element, evaluates rhs,
410
+ * then writes. Capture each stage so a call in the index or rhs cannot
411
+ * change the target or the value used by the operator. The expression yields
412
+ * the computed value before a typed array or Buffer coerces it for storage. */
413
+ export function lowerElementCompound(lowerer, expr, op) {
414
+ const lowered = lowerElementCompoundParts(lowerer, expr, op, false);
415
+ if (!lowered.expr)
416
+ throw new InternalCompilerError("a compound element value lowered to statements");
417
+ return lowered.expr;
418
+ }
419
+ /** JavaScript callable members live on the closure, so aliases and chained
420
+ * writes share the same storage as Object.defineProperties. */
421
+ export function lowerNativeFunctionAssignment(lowerer, expr) {
422
+ const target = expr.left;
423
+ if (!isJsSourceFile(ts.getSourceFileOfNode(expr)) ||
424
+ (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) ||
425
+ target.questionDotToken)
426
+ return null;
427
+ // Checked constructors share the callable's live property descriptors.
428
+ const classType = storedClassValueType(lowerer, target.expression);
429
+ const staticClass = classType?.kind === "classval" ? lowerer.classes.get(classType.className) : undefined;
430
+ if (staticClass && hasRuntimeStatics(staticClass)) {
431
+ return lowerDynMemberAssignment(lowerer, expr, lowerer.lowerExprExpecting(target.expression, DYN));
432
+ }
433
+ // Other class statics and prototype tables have their own paths.
434
+ // Probing them as ordinary functions could materialize unused methods.
435
+ if (lowerer.exactClassOfReceiver(target.expression) ||
436
+ (ts.isPropertyAccessExpression(target.expression) &&
437
+ target.expression.name.text === "prototype" &&
438
+ lowerer.exactClassOfReceiver(target.expression.expression)))
439
+ return null;
440
+ const receiver = tryLowerExpression(lowerer, target.expression);
441
+ if (receiver?.type.kind !== "func" ||
442
+ !canBoxFuncIntoDyn(receiver.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id)))
443
+ return null;
444
+ fenceNodeModuleMutation(lowerer, target, "assignment");
445
+ const fnName = jsFuncNameOf(target.expression);
446
+ const boxed = {
447
+ kind: "dynFrom",
448
+ value: receiver,
449
+ type: DYN,
450
+ loc: locOf(target.expression),
451
+ ...(fnName !== null ? { fnName } : {}),
452
+ };
453
+ return lowerDynMemberAssignment(lowerer, expr, boxed);
454
+ }
455
+ /** `typeof globalThis.AbortSignal.any === "function"`: the comparison
456
+ * folds with constructorGlobalTypeof's answer. */
457
+ function lowerConstructorGlobalTypeofTest(lowerer, expr, loc) {
458
+ const negated = expr.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken;
459
+ for (const [a, b] of operandPairs(expr)) {
460
+ if (!ts.isTypeOfExpression(a) || !ts.isStringLiteral(b))
461
+ continue;
462
+ const answer = constructorGlobalTypeof(lowerer, a.expression);
463
+ if (answer !== null)
464
+ return { kind: "boolLit", value: (answer === b.text) !== negated, type: BOOL, loc };
465
+ }
466
+ return null;
467
+ }
468
+ export function ensureString(lowerer, e, node) {
469
+ if (e.type.kind === "string")
470
+ return e;
471
+ if (e.type.kind === "url")
472
+ return { kind: "libCall", fn: "url.href", args: [e], type: STRING, loc: e.loc };
473
+ // String(date) / `${date}` / "" + date: Date's ToPrimitive prefers
474
+ // toString().
475
+ if (e.type.kind === "date")
476
+ return { kind: "libCall", fn: "date.toString", args: [e], type: STRING, loc: e.loc };
477
+ if (e.type.kind === "regex") {
478
+ return {
479
+ kind: "regexIntrinsic",
480
+ method: "toString",
481
+ receiver: e,
482
+ args: [],
483
+ type: STRING,
484
+ loc: e.loc,
485
+ };
486
+ }
487
+ if (e.type.kind === "bigint") {
488
+ return {
489
+ kind: "libCall",
490
+ fn: "bigint.toString",
491
+ args: [e, { kind: "numLit", value: 10, type: F64, loc: e.loc }],
492
+ type: STRING,
493
+ loc: e.loc,
494
+ };
495
+ }
496
+ if (e.type.kind === "dyn") {
497
+ // String(u) / `${u}`: a runtime dispatch over the dyn kind — Node's
498
+ // String() exactly (undefined/null texts, JS number formatting,
499
+ // strings verbatim, arrays via join, objects as "[object Object]").
500
+ return { kind: "toString", operand: e, type: STRING, loc: e.loc };
501
+ }
502
+ if (e.type.kind === "bytes") {
503
+ // Preserve the runtime brand: typed arrays join numeric elements,
504
+ // while a Buffer stored in a Uint8Array slot decodes its bytes.
505
+ const boxed = { kind: "dynFrom", value: e, type: DYN, loc: e.loc };
506
+ return { kind: "toString", operand: boxed, type: STRING, loc: e.loc };
507
+ }
508
+ if (e.type.kind === "object") {
509
+ // String(err) / `${err}` uses the same dispatch as err.toString().
510
+ for (let c = lowerer.classes.get(e.type.className) ?? null; c; c = c.base) {
511
+ if (c.builtinError) {
512
+ return errorToStringCall(lowerer, e);
513
+ }
514
+ }
515
+ // A program class instance converts through its own methods.
516
+ const converted = classToStringConversion(lowerer, e, "string", node);
517
+ if (converted)
518
+ return converted;
519
+ }
520
+ if (e.type.kind === "union") {
521
+ // `${u}` — the arm's ToString via a per-union interned helper
522
+ // (sc_us_*), Node-exact per arm kind: unit arms are the known texts
523
+ // "undefined"/"null", string arms pass through, f64/bool arms use the
524
+ // JS-exact formatters. Ref arms (records, arrays, ...) stay fenced:
525
+ // JS would print "[object Object]" and friends — narrow first.
526
+ const def = lowerer.unions.get(e.type.unionId);
527
+ const stringable = def?.arms.every((a) => a.kind === "undefinedT" ||
528
+ a.kind === "nullT" ||
529
+ a.kind === "string" ||
530
+ a.kind === "f64" ||
531
+ a.kind === "bigint" ||
532
+ a.kind === "bool");
533
+ if (stringable) {
534
+ return { kind: "toString", operand: e, type: STRING, loc: e.loc };
535
+ }
536
+ // Runtime-optional locals can retain their stored union after the
537
+ // checker has narrowed this use to a primitive arm. Validate that
538
+ // arm before converting it; an unguarded object arm stays fenced.
539
+ const narrowed = lowerer.mapTypeOf(lowerer.typeOf(node));
540
+ if (narrowed &&
541
+ (narrowed.kind === "string" ||
542
+ narrowed.kind === "f64" ||
543
+ narrowed.kind === "bool" ||
544
+ narrowed.kind === "bigint")) {
545
+ const helper = lowerer.narrowedArmHelper(e.type.unionId, narrowed, e.loc);
546
+ if (helper) {
547
+ return ensureString(lowerer, lowerer.checkedNarrowCall(helper, e, narrowed, e.loc), node);
548
+ }
549
+ }
550
+ if (narrowed?.kind === "union" &&
551
+ !typeEquals(narrowed, e.type) &&
552
+ lowerer.unions
553
+ .get(narrowed.unionId)
554
+ ?.arms.every((arm) => isUnitType(arm) ||
555
+ arm.kind === "string" ||
556
+ arm.kind === "f64" ||
557
+ arm.kind === "bool" ||
558
+ arm.kind === "bigint")) {
559
+ const helper = lowerer.narrowedRetagHelper(node, e.type.unionId, narrowed.unionId, e.loc);
560
+ if (helper)
561
+ return ensureString(lowerer, { kind: "call", callee: helper, args: [e], type: narrowed, loc: e.loc }, node);
562
+ }
563
+ const viaClasses = classUnionToString(lowerer, e, "string", node);
564
+ if (viaClasses)
565
+ return viaClasses;
566
+ lowerer.unsupported("SC1090", node, `string conversions of unions with object arms (${NARROW_FIRST})`);
567
+ }
568
+ if (e.type.kind === "symbol") {
569
+ // JS splits here: `${sym}` and concatenation THROW a TypeError,
570
+ // String(sym) answers "Symbol(desc)". One shared lowering cannot
571
+ // honor both — fence with the sanctioned spelling instead of
572
+ // guessing the context.
573
+ lowerer.unsupported("SC1090", node, "string conversions of symbol values (template literals throw in JS — call .toString() explicitly)");
574
+ }
575
+ if (isUnitType(e.type)) {
576
+ if (e.kind === "unitLit") {
577
+ return { kind: "strLit", value: e.unit, type: STRING, loc: e.loc };
578
+ }
579
+ // Keep sequencing and branch effects even though the final unit's
580
+ // spelling is constant. Never turn an unknown producer into a literal.
581
+ if (e.kind === "seqExpr") {
582
+ return { ...e, result: lowerer.ensureString(e.result, node), type: STRING };
583
+ }
584
+ if (e.kind === "ternary") {
585
+ return {
586
+ ...e,
587
+ then: lowerer.ensureString(e.then, node),
588
+ else_: lowerer.ensureString(e.else_, node),
589
+ type: STRING,
590
+ };
591
+ }
592
+ lowerer.unsupported("SC1090", node, `string conversions of '${e.type.kind === "undefinedT" ? "undefined" : "null"}' values`);
593
+ }
594
+ if (e.type.kind === "array") {
595
+ // `${[1,2,3]}` / String(arr): Array.prototype.toString IS join(",")
596
+ // — the SAME intrinsic the .join() lowering emits, fenced to the
597
+ // same element kinds (f64/string/bool, unions of those with unit
598
+ // arms printing empty). Nested arrays would need JS's recursive
599
+ // dispatch — the join fence already tells that story.
600
+ const elem = e.type.elem;
601
+ const joinableUnion = elem.kind === "union" &&
602
+ (lowerer.unions
603
+ .get(elem.unionId)
604
+ ?.arms.every((a) => a.kind === "f64" || a.kind === "string" || a.kind === "bool" || isUnitType(a)) ??
605
+ false);
606
+ if (elem.kind === "f64" || elem.kind === "string" || elem.kind === "bool" || joinableUnion) {
607
+ const sep = { kind: "strLit", value: ",", type: STRING, loc: e.loc };
608
+ return {
609
+ kind: "arrIntrinsic",
610
+ method: "join",
611
+ receiver: e,
612
+ args: [sep],
613
+ type: STRING,
614
+ loc: e.loc,
615
+ };
616
+ }
617
+ }
618
+ if (e.type.kind === "record") {
619
+ // `${obj}` / String(obj): a plain data record has no toString of its
620
+ // own (a func-typed `toString` FIELD would shadow the prototype's —
621
+ // JS would call it, so that shape keeps the fence), and a TUPLE
622
+ // prints its elements like an array (not lowered — fenced) — every
623
+ // other record is Object.prototype.toString's constant.
624
+ const shape = lowerer.shapes.get(e.type.shapeId);
625
+ if (isPerfEntryType(lowerer, e.type))
626
+ return perfEntryTag(lowerer, e, e.type, e.loc);
627
+ if (shape && !shape.tuple && !shape.fields.some((f) => f.name === "toString")) {
628
+ // A null-prototype record (Object.groupBy) has no toString or
629
+ // valueOf: ToPrimitive throws Node's TypeError.
630
+ const nullProtoT = nullProtoRecordShape(lowerer, e.type);
631
+ if (nullProtoT)
632
+ return nullProtoToString(lowerer, e, nullProtoT);
633
+ return { kind: "toString", operand: e, type: STRING, loc: e.loc };
634
+ }
635
+ }
636
+ if (e.type.kind !== "f64" && e.type.kind !== "bool")
637
+ lowerer.badType(node, lowerer.typeOf(node));
638
+ return { kind: "toString", operand: e, type: STRING, loc: e.loc };
639
+ }
640
+ /** String(r) over a record that may have a null prototype: an interned
641
+ * helper that throws Node's TypeError for a null-prototype record and
642
+ * answers "[object Object]" otherwise. */
643
+ function nullProtoToString(lowerer, e, t) {
644
+ const loc = e.loc;
645
+ const key = `nullProtoToString:${t.shapeId}`;
646
+ let helper = lowerer.valueHelpers.get(key);
647
+ if (!helper) {
648
+ helper = `%rec.tostr.${lowerer.valueHelpers.size}`;
649
+ lowerer.valueHelpers.set(key, helper);
650
+ const r = varRef("r.0", t, loc);
651
+ lowerer.liftedFns.push({
652
+ name: helper,
653
+ params: [{ localId: "r.0", name: "r", type: t }],
654
+ returnType: STRING,
655
+ locals: [{ id: "r.0", name: "r", type: t, mutable: false }],
656
+ body: [
657
+ {
658
+ kind: "return",
659
+ value: guardNullProto(r, t.shapeId, "Cannot convert object to primitive value", { kind: "toString", operand: r, type: STRING, loc }, loc),
660
+ loc,
661
+ },
662
+ ],
663
+ loc,
664
+ });
665
+ }
666
+ return { kind: "call", callee: helper, args: [e], type: STRING, loc };
667
+ }
668
+ /** Whether a lowered statement can live inside a seqExpr. These statements
669
+ * do not leave the expression through a jump; the native emitters can place
670
+ * their writes and local state branches before evaluating the final result.
671
+ * Blocks check their bodies recursively. */
672
+ function seqExprSafeStmt(s) {
673
+ switch (s.kind) {
674
+ case "varDecl":
675
+ case "assign":
676
+ case "exprStmt":
677
+ case "fieldSet":
678
+ case "recordSet":
679
+ case "recordKeySet":
680
+ case "arraySet":
681
+ case "arraySetLength":
682
+ case "bytesSet":
683
+ case "arraySetUndefined":
684
+ case "arrayDelete":
685
+ return true;
686
+ case "if":
687
+ return s.then.every(seqExprSafeStmt) && (s.else_?.every(seqExprSafeStmt) ?? true);
688
+ case "block":
689
+ return s.body.every(seqExprSafeStmt);
690
+ default:
691
+ return false;
692
+ }
693
+ }
694
+ export function lowerCompoundValueToTarget(lowerer, expr, compound, target) {
695
+ const loc = locOf(expr);
696
+ const read = {
697
+ kind: "varRef",
698
+ localId: target.id,
699
+ type: target.type,
700
+ loc: locOf(expr.left),
701
+ };
702
+ const rhs = lowerer.lowerExpr(expr.right);
703
+ const numericRead = lowerOptionalNumber(lowerer, read, loc);
704
+ const numericRhs = lowerOptionalNumber(lowerer, rhs, loc);
705
+ if (compound === "+" &&
706
+ (target.type.kind === "string" ||
707
+ (target.type.kind === "union" &&
708
+ lowerer.stripUndefinedArm(target.type).kind === "string" &&
709
+ rhs.type.kind === "string"))) {
710
+ return lowerer.coerceInto(expr, {
711
+ kind: "strConcat",
712
+ left: lowerer.ensureString(read, expr.left),
713
+ right: concatOperand(lowerer, rhs, expr.right),
714
+ type: STRING,
715
+ loc,
716
+ }, target.type);
717
+ }
718
+ if (numericRead.type.kind === "f64" && numericRhs.type.kind === "f64") {
719
+ return lowerer.coerceInto(expr, { kind: "bin", op: compound, left: numericRead, right: numericRhs, type: F64, loc }, target.type);
720
+ }
721
+ // An untyped operand: exactly the expanded `x = x op rhs` — the runtime
722
+ // operator on both values, then the checked conversion into the
723
+ // target's declared type (a string result for a number target throws the
724
+ // catchable TypeError, as the expanded assignment does).
725
+ if ((target.type.kind === "dyn" || rhs.type.kind === "dyn") &&
726
+ (isJsSourceFile(ts.getSourceFileOfNode(expr)) ||
727
+ (lowerer.dynConvertible(read.type) && lowerer.dynConvertible(rhs.type)))) {
728
+ const left = lowerer.coerceInto(expr.left, read, DYN);
729
+ const right = lowerer.coerceInto(expr.right, rhs, DYN);
730
+ return lowerer.coerceInto(expr, dynCompoundValue(compound, left, right, loc), target.type);
731
+ }
732
+ const bigint = bigintCompoundValue(compound, read, rhs, loc);
733
+ if (bigint)
734
+ return bigint;
735
+ compoundUnsupported(lowerer, expr, compound, read.type, rhs.type);
736
+ }
737
+ /** Equality of two NaN-coded values (nan-coded-reads.ts), each of which may
738
+ * stand for undefined and never holds a genuine NaN: Node's undefined equals
739
+ * undefined, so two NaNs compare equal here. Operands evaluate once, in
740
+ * order. */
741
+ function lowerNanCodedEquality(lowerer, expr) {
742
+ const loc = locOf(expr);
743
+ const left = lowerer.lowerExpr(expr.left);
744
+ const right = lowerer.lowerExpr(expr.right);
745
+ if (left.type.kind !== "f64" || right.type.kind !== "f64") {
746
+ throw new InternalCompilerError("NaN-coded equality operand is not a plain number");
747
+ }
748
+ const stmts = [];
749
+ const stable = (value, name) => {
750
+ if (value.kind === "varRef" || value.kind === "numLit")
751
+ return value;
752
+ const tmp = lowerer.declareHiddenLocal(name, F64);
753
+ stmts.push({ kind: "varDecl", localId: tmp.id, init: value, loc });
754
+ return varRef(tmp.id, F64, loc);
755
+ };
756
+ const a = stable(left, "%eqLeft");
757
+ const b = stable(right, "%eqRight");
758
+ const isNaN = (value) => ({
759
+ kind: "libCall",
760
+ fn: "num.isNaN",
761
+ args: [value],
762
+ type: BOOL,
763
+ loc,
764
+ });
765
+ const bothUndefined = {
766
+ kind: "logical",
767
+ op: "&&",
768
+ left: isNaN(a),
769
+ right: isNaN(b),
770
+ type: BOOL,
771
+ loc,
772
+ };
773
+ const op = expr.operatorToken.kind;
774
+ const negated = op === ts.SyntaxKind.ExclamationEqualsEqualsToken ||
775
+ op === ts.SyntaxKind.ExclamationEqualsToken;
776
+ const result = negated
777
+ ? {
778
+ kind: "logical",
779
+ op: "&&",
780
+ left: { kind: "bin", op: "!==", left: a, right: b, type: BOOL, loc },
781
+ right: { kind: "unary", op: "!", operand: bothUndefined, type: BOOL, loc },
782
+ type: BOOL,
783
+ loc,
784
+ }
785
+ : {
786
+ kind: "logical",
787
+ op: "||",
788
+ left: { kind: "bin", op: "===", left: a, right: b, type: BOOL, loc },
789
+ right: bothUndefined,
790
+ type: BOOL,
791
+ loc,
792
+ };
793
+ return stmts.length === 0 ? result : { kind: "seqExpr", stmts, result, type: BOOL, loc };
794
+ }
795
+ export function lowerBinary(lowerer, expr) {
796
+ const loc = locOf(expr);
797
+ const op = expr.operatorToken.kind;
798
+ const cacheHas = lowerRequireCacheHas(lowerer, expr);
799
+ if (cacheHas)
800
+ return cacheHas;
801
+ if (lowerer.nanCodedReads?.needsUndefinedEquality(expr)) {
802
+ const undefinedEquality = lowerNanCodedEquality(lowerer, expr);
803
+ if (undefinedEquality)
804
+ return undefinedEquality;
805
+ }
806
+ if (op === ts.SyntaxKind.EqualsToken ||
807
+ (op >= ts.SyntaxKind.FirstCompoundAssignment && op <= ts.SyntaxKind.LastCompoundAssignment)) {
808
+ const urlWrite = lowerUrlAssignment(lowerer, expr);
809
+ if (urlWrite)
810
+ return urlWrite;
811
+ if (op === ts.SyntaxKind.EqualsToken) {
812
+ const prototypeWrite = lowerClassPrototypeComputedAssignment(lowerer, expr);
813
+ if (prototypeWrite)
814
+ return prototypeWrite;
815
+ const callableWrite = lowerNativeFunctionAssignment(lowerer, expr);
816
+ if (callableWrite)
817
+ return callableWrite;
818
+ }
819
+ if (op === ts.SyntaxKind.QuestionQuestionEqualsToken ||
820
+ op === ts.SyntaxKind.AmpersandAmpersandEqualsToken ||
821
+ op === ts.SyntaxKind.BarBarEqualsToken) {
822
+ return lowerShortCircuitAssignment(lowerer, expr);
823
+ }
824
+ if (ts.isPropertyAccessExpression(expr.left) || ts.isElementAccessExpression(expr.left)) {
825
+ fenceNodeModuleMutation(lowerer, expr.left, "assignment");
826
+ }
827
+ // The writable Event accessors on Event subclass instances, in value
828
+ // position (`const r = (event.returnValue = false)`).
829
+ if (op === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(expr.left)) {
830
+ const eventWrite = lowerEventObjectPropertyWrite(lowerer, expr.left, expr.right);
831
+ if (eventWrite)
832
+ return eventWrite;
833
+ }
834
+ // `x = e` in EXPRESSION position (`while ((idx = s.indexOf("\n")) !== -1)`,
835
+ // `f(x = v)`): evaluate e once, write the binding, yield the assigned
836
+ // value — JS evaluation order. Variable targets only (locals and module
837
+ // globals, captured/boxed included); the RHS coerces into the binding's
838
+ // type exactly like statement position, and the expression's value is
839
+ // the coerced binding-typed value (representation change only — never
840
+ // observably different from JS's raw-RHS yield). Indexed compounds
841
+ // use a sequenced read/modify/write; other member targets and
842
+ // destructuring targets stay fenced.
843
+ if (op === ts.SyntaxKind.EqualsToken && ts.isIdentifier(expr.left)) {
844
+ const target = lowerer.resolveWritable(expr.left);
845
+ if (!target) {
846
+ lowerer.rejectUnresolved(expr.left, `assignment to '${expr.left.text}' (not a writable local or module global)`);
847
+ }
848
+ const value = lowerer.lowerExprExpecting(expr.right, target.type);
849
+ const runtimeOptionalRoot = lowerer.runtimeOptionalRootOf(target);
850
+ if (lowerer.runtimeOptionalStorageLocals.has(runtimeOptionalRoot))
851
+ lowerer.runtimeOptionalLocals.add(runtimeOptionalRoot);
852
+ return { kind: "assignExpr", localId: target.id, value, type: target.type, loc };
853
+ }
854
+ const indexedCompound = COMPOUND_ASSIGN_OPS[op];
855
+ if (indexedCompound !== undefined && ts.isElementAccessExpression(expr.left)) {
856
+ if (symbolFieldInfo(lowerer, expr.left))
857
+ return lowerFieldCompoundValue(lowerer, expr.left, indexedCompound, expr.right, loc);
858
+ return lowerElementCompound(lowerer, expr, indexedCompound);
859
+ }
860
+ if (indexedCompound !== undefined && ts.isIdentifier(expr.left)) {
861
+ const target = lowerer.resolveWritable(expr.left);
862
+ if (!target) {
863
+ lowerer.rejectUnresolved(expr.left, "assignment to an unresolved variable");
864
+ }
865
+ const value = lowerCompoundValueToTarget(lowerer, expr, indexedCompound, target);
866
+ return { kind: "assignExpr", localId: target.id, value, type: target.type, loc };
867
+ }
868
+ if (indexedCompound !== undefined &&
869
+ (ts.isPropertyAccessExpression(expr.left) || ts.isElementAccessExpression(expr.left)) &&
870
+ !(ts.isPropertyAccessExpression(expr.left) && expr.left.questionDotToken)) {
871
+ const target = expandoWritableTarget(lowerer, expr.left) ??
872
+ (ts.isPropertyAccessExpression(expr.left) ? nsWritableTarget(lowerer, expr.left) : null);
873
+ if (target) {
874
+ const value = lowerCompoundValueToTarget(lowerer, expr, indexedCompound, target);
875
+ return { kind: "assignExpr", localId: target.id, value, type: target.type, loc };
876
+ }
877
+ return lowerFieldCompoundValue(lowerer, expr.left, indexedCompound, expr.right, loc);
878
+ }
879
+ // `events.defaultMaxListeners = v` — the module-property write
880
+ // Node validates (validateNumber(n, 'defaultMaxListeners', 0)):
881
+ // the value crosses into the checked-dynamic tree and the runtime ladder throws
882
+ // ERR_INVALID_ARG_TYPE / ERR_OUT_OF_RANGE with Node's exact slot
883
+ // name; valid numbers apply. The expression's value is the RHS
884
+ // (JS's assignment yield).
885
+ if (op === ts.SyntaxKind.EqualsToken &&
886
+ ts.isPropertyAccessExpression(expr.left) &&
887
+ !expr.left.questionDotToken &&
888
+ expr.left.name.text === "defaultMaxListeners") {
889
+ const bi = lowerer.builtinMemberOf(expr.left);
890
+ if (bi && bi.module === "events" && bi.member === "defaultMaxListeners") {
891
+ const rhs = lowerer.lowerExpr(expr.right);
892
+ if (rhs.type.kind === "dyn" || rhs.kind === "unitLit" || lowerer.dynConvertible(rhs.type)) {
893
+ const valTmp = lowerer.declareHiddenLocal("%setVal", rhs.type);
894
+ const valRef = () => ({
895
+ kind: "varRef",
896
+ localId: valTmp.id,
897
+ type: rhs.type,
898
+ loc,
899
+ });
900
+ const dynVal = rhs.type.kind === "dyn"
901
+ ? valRef()
902
+ : { kind: "dynFrom", value: valRef(), type: DYN, loc };
903
+ return {
904
+ kind: "seqExpr",
905
+ stmts: [
906
+ { kind: "varDecl", localId: valTmp.id, init: rhs, loc },
907
+ {
908
+ kind: "exprStmt",
909
+ expr: {
910
+ kind: "libCall",
911
+ fn: "emitter.setDefaultMaxChk",
912
+ args: [
913
+ dynVal,
914
+ { kind: "strLit", value: "defaultMaxListeners", type: STRING, loc },
915
+ ],
916
+ type: VOID,
917
+ loc,
918
+ },
919
+ loc,
920
+ },
921
+ ],
922
+ result: valRef(),
923
+ type: rhs.type,
924
+ loc,
925
+ };
926
+ }
927
+ }
928
+ }
929
+ // Member targets whose storage IS a module global — namespace
930
+ // members (`N.x`) and expando function members (`Foo.baz`): the
931
+ // same assignExpr, since the "member" is a variable.
932
+ if (op === ts.SyntaxKind.EqualsToken &&
933
+ (ts.isPropertyAccessExpression(expr.left) || ts.isElementAccessExpression(expr.left)) &&
934
+ !(ts.isPropertyAccessExpression(expr.left) && expr.left.questionDotToken)) {
935
+ const target = expandoWritableTarget(lowerer, expr.left) ??
936
+ (ts.isPropertyAccessExpression(expr.left) ? nsWritableTarget(lowerer, expr.left) : null);
937
+ if (target) {
938
+ const value = lowerer.lowerExprExpecting(expr.right, target.type);
939
+ return { kind: "assignExpr", localId: target.id, value, type: target.type, loc };
940
+ }
941
+ // Bundled numeric enums use e[e["name"] = value] = "name".
942
+ // Capture the receiver and key before the RHS. PutValue coerces the
943
+ // key afterward, then yields the RHS without rereading the property.
944
+ if (ts.isElementAccessExpression(expr.left) && !expr.left.questionDotToken) {
945
+ const recv = tryLowerExpression(lowerer, expr.left.expression);
946
+ if (recv &&
947
+ (recv.type.kind === "dyn" ||
948
+ (recv.type.kind === "array" &&
949
+ isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
950
+ lowerer.dynConvertible(recv.type)))) {
951
+ return lowerDynMemberAssignment(lowerer, expr, lowerer.coerceInto(expr.left.expression, recv, DYN));
952
+ }
953
+ if (recv?.type.kind === "array" || recv?.type.kind === "bytes") {
954
+ const receiver = lowerer.declareHiddenLocal("%setArray", recv.type);
955
+ const index = lowerOptionalNumber(lowerer, lowerer.lowerExpr(expr.left.argumentExpression), locOf(expr.left.argumentExpression), expr.left.argumentExpression);
956
+ if (index.type.kind !== "f64")
957
+ lowerer.unsupported("SC1090", expr.left.argumentExpression, "indexing with non-number keys");
958
+ const key = lowerer.declareHiddenLocal("%setIndex", F64);
959
+ const raw = lowerer.lowerExpr(expr.right);
960
+ const value = lowerer.declareHiddenLocal("%setValue", raw.type);
961
+ const result = varRef(value.id, raw.type, loc);
962
+ const arr = varRef(receiver.id, recv.type, loc);
963
+ const idx = varRef(key.id, F64, loc);
964
+ const write = recv.type.kind === "array"
965
+ ? arrayValueStore(lowerer, arr, idx, result, recv.type.elem, loc)
966
+ : {
967
+ kind: "bytesSet",
968
+ arr,
969
+ index: idx,
970
+ value: lowerer.coerceInto(expr.right, result, F64),
971
+ loc,
972
+ };
973
+ return {
974
+ kind: "seqExpr",
975
+ stmts: [
976
+ { kind: "varDecl", localId: receiver.id, init: recv, loc },
977
+ { kind: "varDecl", localId: key.id, init: index, loc },
978
+ { kind: "varDecl", localId: value.id, init: raw, loc },
979
+ write,
980
+ ],
981
+ result,
982
+ type: result.type,
983
+ loc,
984
+ };
985
+ }
986
+ }
987
+ // `h.k = v` on a CHECKED-DYNAMIC receiver in VALUE position
988
+ // (`var _ = module.exports = foo`): receiver first, then RHS
989
+ // (JS's reference-before-value order), the keyed write, and the
990
+ // RHS value is the expression's value — its OWN type, so the
991
+ // consumer sees exactly what the checker typed.
992
+ if (ts.isPropertyAccessExpression(expr.left) && !expr.left.questionDotToken) {
993
+ // `const src = exports.src = []`: an export member assigned in
994
+ // value position writes its export global and yields the value.
995
+ {
996
+ let inFunction = false;
997
+ for (let p = expr.parent; p !== undefined; p = p.parent) {
998
+ if (ts.isFunctionLike(p) || ts.isClassDeclaration(p) || ts.isClassExpression(p)) {
999
+ inFunction = true;
1000
+ break;
1001
+ }
1002
+ }
1003
+ const g = inFunction
1004
+ ? cjsExportMemberWriteGlobalOf(lowerer, expr.left)
1005
+ : cjsInFileExportGlobalOf(lowerer, expr.left);
1006
+ if (g) {
1007
+ const value = lowerer.lowerExprExpecting(expr.right, g.type);
1008
+ const tmp = lowerer.declareHiddenLocal("%exportValue", value.type);
1009
+ const result = varRef(tmp.id, value.type, loc);
1010
+ return {
1011
+ kind: "seqExpr",
1012
+ stmts: [
1013
+ { kind: "varDecl", localId: tmp.id, init: value, loc },
1014
+ { kind: "assign", localId: g.id, value: result, loc },
1015
+ ],
1016
+ result,
1017
+ type: value.type,
1018
+ loc,
1019
+ };
1020
+ }
1021
+ }
1022
+ const recv = tryLowerExpression(lowerer, expr.left.expression);
1023
+ if (recv && recv.type.kind === "dyn")
1024
+ return lowerDynMemberAssignment(lowerer, expr, recv);
1025
+ const unionWrite = lowerUnionFieldWrite(lowerer, expr.left, expr.right);
1026
+ if (unionWrite)
1027
+ return unionWrite;
1028
+ const field = lowerer.fieldTarget(expr.left);
1029
+ if (field) {
1030
+ const recvTmp = lowerer.declareHiddenLocal("%setReceiver", field.obj.type);
1031
+ const receiver = field.obj;
1032
+ field.obj = varRef(recvTmp.id, receiver.type, loc);
1033
+ const value = lowerer.lowerExprExpecting(expr.right, field.fieldType);
1034
+ const valTmp = lowerer.declareHiddenLocal("%setValue", value.type);
1035
+ const result = varRef(valTmp.id, value.type, loc);
1036
+ return {
1037
+ kind: "seqExpr",
1038
+ stmts: [
1039
+ { kind: "varDecl", localId: recvTmp.id, init: receiver, loc },
1040
+ { kind: "varDecl", localId: valTmp.id, init: value, loc },
1041
+ lowerer.fieldSetStmt(field, result, loc, expr.left),
1042
+ ],
1043
+ result,
1044
+ type: result.type,
1045
+ loc,
1046
+ };
1047
+ }
1048
+ }
1049
+ }
1050
+ // Destructuring assignment in VALUE position (`(() => [i] = [i+1])()`,
1051
+ // `({} = {x} = a)`, `var d = ([] = src)`): the statement machinery's
1052
+ // parts under a seqExpr — the expression's value is the RHS value
1053
+ // (JS's GetValue of the right reference), which is exactly the
1054
+ // parts' hidden temp.
1055
+ if (op === ts.SyntaxKind.EqualsToken &&
1056
+ (ts.isObjectLiteralExpression(expr.left) || ts.isArrayLiteralExpression(expr.left))) {
1057
+ const parts = lowerer.lowerDestructuringAssignParts(expr.left, expr.right, loc);
1058
+ return {
1059
+ kind: "seqExpr",
1060
+ stmts: parts.stmts,
1061
+ result: parts.value,
1062
+ type: parts.value.type,
1063
+ loc,
1064
+ };
1065
+ }
1066
+ lowerer.unsupported("SC1090", expr, op === ts.SyntaxKind.EqualsToken
1067
+ ? "assignment to non-variables as an expression (only `x = e` over a variable yields a value; write property/destructuring assignments as statements)"
1068
+ : "compound assignment as an expression (write `x op= e` as a statement, or spell out `x = x op e`)");
1069
+ }
1070
+ if (op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken) {
1071
+ const nullTest = lowerLooseNullCompare(lowerer, expr, loc);
1072
+ if (nullTest)
1073
+ return nullTest;
1074
+ const loose = lowerAbstractEquality(lowerer, deferredSlotOr(lowerer, lowerer.lowerExpr(expr.left)), deferredSlotOr(lowerer, lowerer.lowerExpr(expr.right)), op === ts.SyntaxKind.ExclamationEqualsToken, loc);
1075
+ if (loose)
1076
+ return loose;
1077
+ lowerer.unsupported("SC1040", expr, undefined, "object-to-primitive loose equality can call user-defined valueOf/toString methods — compare explicit primitive conversions instead");
1078
+ }
1079
+ if (op === ts.SyntaxKind.AmpersandAmpersandToken || op === ts.SyntaxKind.BarBarToken) {
1080
+ return lowerLogicalChain(lowerer, expr);
1081
+ }
1082
+ if (op === ts.SyntaxKind.QuestionQuestionToken) {
1083
+ return lowerer.lowerNullishCoalesce(expr, loc);
1084
+ }
1085
+ if (op === ts.SyntaxKind.CommaToken) {
1086
+ // Comma expression in VALUE position (`r = ({} = a, [] = a)` — the
1087
+ // conformance corpus's paired-destructuring idiom): the left operand
1088
+ // runs for EFFECT exactly as its statement lowering (JS discards its
1089
+ // value), the right operand is the expression's value — a seqExpr.
1090
+ // The validator restricts seqExpr statements to straight-line writes
1091
+ // (the lowering point is mid-expression), so a left operand whose
1092
+ // statement lowering needs real control flow keeps a pointed fence
1093
+ // instead of tripping the validator downstream.
1094
+ const effect = lowerer.lowerExprStatement(expr.left);
1095
+ if (!seqExprSafeStmt(effect)) {
1096
+ lowerer.unsupported("SC1090", expr.left, "comma expressions whose left operand needs control flow (run it as its own statement first)");
1097
+ }
1098
+ const result = lowerer.lowerExpr(expr.right);
1099
+ return { kind: "seqExpr", stmts: [effect], result, type: result.type, loc };
1100
+ }
1101
+ if (op === ts.SyntaxKind.InstanceOfKeyword)
1102
+ return lowerer.lowerInstanceOf(expr, loc);
1103
+ if (op === ts.SyntaxKind.InKeyword) {
1104
+ return lowerInExpression(lowerer, expr, loc);
1105
+ }
1106
+ // `typeof e === "string"` on a catch binding or an `unknown` value: a
1107
+ // runtime kind test — intercepted BEFORE the operands lower (a raw
1108
+ // read of the binding is the narrowness fence, and bare `typeof e`
1109
+ // has no lowering).
1110
+ if (op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
1111
+ op === ts.SyntaxKind.ExclamationEqualsEqualsToken) {
1112
+ const test = lowerConstructorGlobalTypeofTest(lowerer, expr, loc) ??
1113
+ lowerWebAssemblyTypeofTest(lowerer, expr, loc) ??
1114
+ lowerErrorCodeTypeofTest(lowerer, expr, loc) ??
1115
+ lowerer.lowerCaughtTypeofTest(expr, loc) ??
1116
+ lowerDynTypeofTest(lowerer, expr, loc) ??
1117
+ lowerUnionTypeofTest(lowerer, expr, loc);
1118
+ if (test)
1119
+ return test;
1120
+ }
1121
+ // `x.constructor === Readable` for an instance of EventEmitter or a
1122
+ // stream class: the instance's own class, compared without a class value.
1123
+ if (op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
1124
+ op === ts.SyntaxKind.ExclamationEqualsEqualsToken) {
1125
+ for (const [side, other] of [
1126
+ [expr.left, expr.right],
1127
+ [expr.right, expr.left],
1128
+ ]) {
1129
+ const ctor = runtimeConstructorReceiver(lowerer, side);
1130
+ const target = ctor ? builtinClassRefOf(lowerer, other) : null;
1131
+ if (ctor && (target?.kind === "emitter" || target?.kind === "stream")) {
1132
+ const negated = op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
1133
+ return lowerRuntimeConstructorIs(lowerer, ctor.receiver, target.info, negated, loc);
1134
+ }
1135
+ }
1136
+ }
1137
+ // `C === EventEmitter` between two builtin class references: the
1138
+ // classes are compile-time values, so the answer folds.
1139
+ if (op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
1140
+ op === ts.SyntaxKind.ExclamationEqualsEqualsToken) {
1141
+ const leftClass = builtinClassRefOf(lowerer, expr.left);
1142
+ const rightClass = leftClass === null ? null : builtinClassRefOf(lowerer, expr.right);
1143
+ if (leftClass !== null && rightClass !== null) {
1144
+ const negated = op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
1145
+ const same = sameBuiltinClass(leftClass, rightClass);
1146
+ return { kind: "boolLit", value: same !== negated, type: BOOL, loc };
1147
+ }
1148
+ }
1149
+ const strictEquality = op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
1150
+ op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
1151
+ // An identifier whose storage is runtime-optional is compared by its
1152
+ // stored value: the checker's narrowing to the present arm is not a
1153
+ // runtime proof. Identifier reads are pure, so taking the stored value
1154
+ // after both operands lowered keeps the evaluation order. A union on
1155
+ // the other side keeps the narrowed read (union-to-union comparison
1156
+ // has no lowering).
1157
+ let left = strictEquality
1158
+ ? (lowerAbsenceProbe(lowerer, expr.left) ?? lowerer.lowerExpr(expr.left))
1159
+ : lowerer.lowerExpr(expr.left);
1160
+ let right = strictEquality
1161
+ ? (lowerAbsenceProbe(lowerer, expr.right) ?? lowerer.lowerExpr(expr.right))
1162
+ : lowerer.lowerExpr(expr.right);
1163
+ if (strictEquality) {
1164
+ const storedLeft = runtimeOptionalStorageOperand(lowerer, expr.left);
1165
+ const storedRight = runtimeOptionalStorageOperand(lowerer, expr.right);
1166
+ if (storedLeft !== null && right.type.kind !== "union")
1167
+ left = storedLeft;
1168
+ if (storedRight !== null && left.type.kind !== "union")
1169
+ right = storedRight;
1170
+ // A typed-array read compared with a plain number needs no
1171
+ // `number | undefined` box.
1172
+ const fusedLeft = tryLowerBytesReadNumberEquality(lowerer, left, right, expr.right);
1173
+ if (fusedLeft)
1174
+ left = fusedLeft;
1175
+ else {
1176
+ const fusedRight = tryLowerBytesReadNumberEquality(lowerer, right, left, expr.left);
1177
+ if (fusedRight)
1178
+ right = fusedRight;
1179
+ }
1180
+ }
1181
+ if (strictEquality && (left.type.kind === "caught" || right.type.kind === "caught")) {
1182
+ if (left.type.kind === "caught")
1183
+ left = { kind: "caughtToDyn", value: left, type: DYN, loc: left.loc };
1184
+ if (right.type.kind === "caught")
1185
+ right = { kind: "caughtToDyn", value: right, type: DYN, loc: right.loc };
1186
+ }
1187
+ if (left.type.kind === "dyn" || right.type.kind === "dyn") {
1188
+ // The narrowing unit comparisons ARE answerable on unknown: `v ===
1189
+ // undefined` / `v !== null` test the dyn node's kind directly, and
1190
+ // tsc's control flow narrows the branches (reads then bridge through
1191
+ // maybeNarrow's validated extraction).
1192
+ if (op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
1193
+ op === ts.SyntaxKind.ExclamationEqualsEqualsToken) {
1194
+ const negated = op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
1195
+ const unit = left.kind === "unitLit" ? left : right.kind === "unitLit" ? right : null;
1196
+ const other = left.kind === "unitLit" ? right : left;
1197
+ if (unit && other.type.kind === "dyn") {
1198
+ return {
1199
+ kind: "dynTest",
1200
+ test: unit.unit,
1201
+ ...(negated ? { negated: true } : {}),
1202
+ value: other,
1203
+ type: BOOL,
1204
+ loc,
1205
+ };
1206
+ }
1207
+ // dyn vs SCALAR strict equality (`value !== ""`, `u === 5` — the
1208
+ // normalizePricing filter): a guarded kind test + payload compare,
1209
+ // JS-exact (strict equality never coerces; a non-matching dyn kind
1210
+ // answers false). dyn vs dyn keeps the fence below.
1211
+ const dynSide = left.type.kind === "dyn" ? left : right;
1212
+ const scalarSide = dynSide === left ? right : left;
1213
+ const reference = scalarSide.type;
1214
+ if ((reference.kind === "object" ||
1215
+ reference.kind === "record" ||
1216
+ reference.kind === "array" ||
1217
+ reference.kind === "bytes" ||
1218
+ reference.kind === "func" ||
1219
+ reference.kind === "classval" ||
1220
+ reference.kind === "regex" ||
1221
+ reference.kind === "url" ||
1222
+ reference.kind === "bigint" ||
1223
+ reference.kind === "symbol" ||
1224
+ reference.kind === "map" ||
1225
+ reference.kind === "set" ||
1226
+ reference.kind === "union" ||
1227
+ DYN_HANDLE_KINDS.has(reference.kind)) &&
1228
+ lowerer.dynConvertible(reference)) {
1229
+ // Records, arrays and byte views compare by the capsule identity
1230
+ // their dyn reads produce, including when they arrive through a
1231
+ // union (an optional array field read from a typed record).
1232
+ const liveArm = (type) => {
1233
+ if (type.kind === "array" || type.kind === "bytes")
1234
+ return true;
1235
+ const shape = type.kind === "record" ? lowerer.shapes.get(type.shapeId) : undefined;
1236
+ return !!shape && (shape.fields.length > 0 || shape.indexValue !== undefined);
1237
+ };
1238
+ const boxed = {
1239
+ kind: "dynFrom",
1240
+ value: scalarSide,
1241
+ type: DYN,
1242
+ loc: scalarSide.loc,
1243
+ ...(reference.kind === "record" ||
1244
+ liveArm(reference) ||
1245
+ (reference.kind === "union" &&
1246
+ (lowerer.unions.get(reference.unionId)?.arms.some(liveArm) ?? false))
1247
+ ? { liveRef: true }
1248
+ : {}),
1249
+ };
1250
+ return {
1251
+ kind: "dynScalarEq",
1252
+ left: scalarSide === left ? boxed : left,
1253
+ right: scalarSide === right ? boxed : right,
1254
+ ...(negated ? { negated: true } : {}),
1255
+ type: BOOL,
1256
+ loc,
1257
+ };
1258
+ }
1259
+ // EventEmitter or a stream class against an untyped value in
1260
+ // JavaScript: the untyped value can hold the class's untyped
1261
+ // constructor (coerceToExpected), which compares by identity.
1262
+ if (dynSide.type.kind === "dyn" &&
1263
+ isJsSourceFile(expr.getSourceFile()) &&
1264
+ ((scalarSide.type.kind === "moduleNs" && scalarSide.type.moduleId === "builtin:events") ||
1265
+ (scalarSide.kind === "classRef" && builtinClassKind(scalarSide.className) !== null))) {
1266
+ const boxed = lowerer.coerceToExpected(scalarSide, DYN);
1267
+ return {
1268
+ kind: "dynScalarEq",
1269
+ left: scalarSide === left ? boxed : left,
1270
+ right: scalarSide === right ? boxed : right,
1271
+ ...(negated ? { negated: true } : {}),
1272
+ type: BOOL,
1273
+ loc,
1274
+ };
1275
+ }
1276
+ if (dynSide.type.kind === "dyn" &&
1277
+ (scalarSide.type.kind === "f64" ||
1278
+ scalarSide.type.kind === "string" ||
1279
+ scalarSide.type.kind === "bool" ||
1280
+ // dyn vs dyn (`context.actual !== context.exact` —
1281
+ // test/common's exit accounting): the runtime's whole-dyn
1282
+ // strict equality — scalars by value, units by kind,
1283
+ // reference kinds by identity (scr_dyn_strict_eq).
1284
+ scalarSide.type.kind === "dyn")) {
1285
+ return {
1286
+ kind: "dynScalarEq",
1287
+ left,
1288
+ right,
1289
+ ...(negated ? { negated: true } : {}),
1290
+ type: BOOL,
1291
+ loc,
1292
+ };
1293
+ }
1294
+ }
1295
+ const bitwise = {
1296
+ [ts.SyntaxKind.AmpersandToken]: "&",
1297
+ [ts.SyntaxKind.BarToken]: "|",
1298
+ [ts.SyntaxKind.CaretToken]: "^",
1299
+ [ts.SyntaxKind.LessThanLessThanToken]: "<<",
1300
+ [ts.SyntaxKind.GreaterThanGreaterThanToken]: ">>",
1301
+ [ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken]: ">>>",
1302
+ };
1303
+ if (bitwise[op]) {
1304
+ const l = lowerer.coerceToExpected(left, DYN);
1305
+ const r = lowerer.coerceToExpected(right, DYN);
1306
+ if (l.type.kind === "dyn" && r.type.kind === "dyn") {
1307
+ const value = {
1308
+ kind: "libCall",
1309
+ fn: "dyn.bitwise",
1310
+ args: [l, r, { kind: "strLit", value: bitwise[op], type: STRING, loc }],
1311
+ type: DYN,
1312
+ loc,
1313
+ };
1314
+ return left.type.kind === "f64" || right.type.kind === "f64"
1315
+ ? { kind: "dynCheck", value, type: F64, loc }
1316
+ : value;
1317
+ }
1318
+ }
1319
+ // Numeric operators dispatch on ToNumeric's actual Number/BigInt
1320
+ // result, including values flowing through native callable properties.
1321
+ if (isJsSourceFile(ts.getSourceFileOfNode(expr)) ||
1322
+ op === ts.SyntaxKind.PlusToken ||
1323
+ [
1324
+ ts.SyntaxKind.LessThanToken,
1325
+ ts.SyntaxKind.LessThanEqualsToken,
1326
+ ts.SyntaxKind.GreaterThanToken,
1327
+ ts.SyntaxKind.GreaterThanEqualsToken,
1328
+ ].includes(op) ||
1329
+ [
1330
+ ts.SyntaxKind.MinusToken,
1331
+ ts.SyntaxKind.AsteriskToken,
1332
+ ts.SyntaxKind.SlashToken,
1333
+ ts.SyntaxKind.PercentToken,
1334
+ ts.SyntaxKind.AsteriskAsteriskToken,
1335
+ ].includes(op)) {
1336
+ const other = left.type.kind === "dyn" ? right : left;
1337
+ const NUM_BIN = {
1338
+ [ts.SyntaxKind.MinusToken]: "-",
1339
+ [ts.SyntaxKind.AsteriskToken]: "*",
1340
+ [ts.SyntaxKind.SlashToken]: "/",
1341
+ [ts.SyntaxKind.PercentToken]: "%",
1342
+ [ts.SyntaxKind.AsteriskAsteriskToken]: "**",
1343
+ };
1344
+ const NUM_CMP = {
1345
+ [ts.SyntaxKind.LessThanToken]: "<",
1346
+ [ts.SyntaxKind.LessThanEqualsToken]: "<=",
1347
+ [ts.SyntaxKind.GreaterThanToken]: ">",
1348
+ [ts.SyntaxKind.GreaterThanEqualsToken]: ">=",
1349
+ };
1350
+ const arith = NUM_BIN[op];
1351
+ const cmp = NUM_CMP[op];
1352
+ if (arith) {
1353
+ const l = lowerer.coerceToExpected(left, DYN);
1354
+ const r = lowerer.coerceToExpected(right, DYN);
1355
+ if (l.type.kind === "dyn" && r.type.kind === "dyn") {
1356
+ const value = {
1357
+ kind: "libCall",
1358
+ fn: "dyn.arithmetic",
1359
+ args: [l, r, { kind: "strLit", value: arith, type: STRING, loc }],
1360
+ type: DYN,
1361
+ loc,
1362
+ };
1363
+ const numeric = left.type.kind === "bigint" || right.type.kind === "bigint"
1364
+ ? BIGINT_T
1365
+ : left.type.kind === "f64" || right.type.kind === "f64"
1366
+ ? F64
1367
+ : null;
1368
+ return numeric ? { kind: "dynCheck", value, type: numeric, loc } : value;
1369
+ }
1370
+ }
1371
+ if (cmp && lowerer.dynConvertible(left.type) && lowerer.dynConvertible(right.type)) {
1372
+ return {
1373
+ kind: "libCall",
1374
+ fn: "dyn.compare",
1375
+ args: [
1376
+ lowerer.coerceToExpected(left, DYN),
1377
+ lowerer.coerceToExpected(right, DYN),
1378
+ { kind: "strLit", value: cmp, type: STRING, loc },
1379
+ ],
1380
+ type: BOOL,
1381
+ loc,
1382
+ };
1383
+ }
1384
+ // Untyped addition chooses concatenation or numeric addition only
1385
+ // after both operands have undergone ToPrimitive at runtime.
1386
+ if (op === ts.SyntaxKind.PlusToken) {
1387
+ const l = lowerer.coerceToExpected(left, DYN);
1388
+ const r = lowerer.coerceToExpected(right, DYN);
1389
+ if (l.type.kind === "dyn" && r.type.kind === "dyn") {
1390
+ const value = { kind: "libCall", fn: "dyn.add", args: [l, r], type: DYN, loc };
1391
+ // A statically known string operand guarantees a string result.
1392
+ return other.type.kind === "string"
1393
+ ? { kind: "dynCheck", value, type: STRING, loc }
1394
+ : value;
1395
+ }
1396
+ }
1397
+ }
1398
+ // Unsupported `any`-origin operations get their specific diagnostic;
1399
+ // unknown retains the narrowing diagnostic below.
1400
+ if ((left.type.kind === "dyn" && lowerer.anyOrigin(expr.left)) ||
1401
+ (right.type.kind === "dyn" && lowerer.anyOrigin(expr.right))) {
1402
+ // `JSON.parse` and other checked-dynamic producers deliberately
1403
+ // remain dyn when assigned to an `any` local: eagerly converting
1404
+ // the binding would deep-copy its data and sever aliases. At an
1405
+ // unsupported operator, require an explicit represented type.
1406
+ lowerer.anyOpFence(`the '${ts.tokenToString(op) ?? ts.syntaxKindName(op)}' operator`, expr);
1407
+ }
1408
+ // tsc allows ===/!== on unknown (arithmetic/comparisons it rejects
1409
+ // itself); a dynamic equality would need a dyn walk — validate first.
1410
+ lowerer.unsupported("SC1100", expr, "operators on 'unknown' values");
1411
+ }
1412
+ if (left.type.kind === "bigint" && right.type.kind === "bigint") {
1413
+ const binary = {
1414
+ [ts.SyntaxKind.PlusToken]: "bigint.add",
1415
+ [ts.SyntaxKind.MinusToken]: "bigint.sub",
1416
+ [ts.SyntaxKind.AsteriskToken]: "bigint.mul",
1417
+ [ts.SyntaxKind.SlashToken]: "bigint.div",
1418
+ [ts.SyntaxKind.PercentToken]: "bigint.mod",
1419
+ [ts.SyntaxKind.AsteriskAsteriskToken]: "bigint.pow",
1420
+ [ts.SyntaxKind.AmpersandToken]: "bigint.and",
1421
+ [ts.SyntaxKind.BarToken]: "bigint.or",
1422
+ [ts.SyntaxKind.CaretToken]: "bigint.xor",
1423
+ [ts.SyntaxKind.LessThanLessThanToken]: "bigint.shl",
1424
+ [ts.SyntaxKind.GreaterThanGreaterThanToken]: "bigint.shr",
1425
+ };
1426
+ const fn = binary[op];
1427
+ if (fn)
1428
+ return { kind: "libCall", fn, args: [left, right], type: BIGINT_T, loc };
1429
+ if (op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
1430
+ op === ts.SyntaxKind.ExclamationEqualsEqualsToken) {
1431
+ const equal = {
1432
+ kind: "libCall",
1433
+ fn: "bigint.eq",
1434
+ args: [left, right],
1435
+ type: BOOL,
1436
+ loc,
1437
+ };
1438
+ return op === ts.SyntaxKind.ExclamationEqualsEqualsToken
1439
+ ? { kind: "unary", op: "!", operand: equal, type: BOOL, loc }
1440
+ : equal;
1441
+ }
1442
+ if (op === ts.SyntaxKind.LessThanToken ||
1443
+ op === ts.SyntaxKind.LessThanEqualsToken ||
1444
+ op === ts.SyntaxKind.GreaterThanToken ||
1445
+ op === ts.SyntaxKind.GreaterThanEqualsToken) {
1446
+ const cmp = {
1447
+ kind: "libCall",
1448
+ fn: "bigint.cmp",
1449
+ args: [left, right],
1450
+ type: F64,
1451
+ loc,
1452
+ };
1453
+ const zero = { kind: "numLit", value: 0, type: F64, loc };
1454
+ const cmpOp = op === ts.SyntaxKind.LessThanToken
1455
+ ? "<"
1456
+ : op === ts.SyntaxKind.LessThanEqualsToken
1457
+ ? "<="
1458
+ : op === ts.SyntaxKind.GreaterThanToken
1459
+ ? ">"
1460
+ : ">=";
1461
+ return { kind: "bin", op: cmpOp, left: cmp, right: zero, type: BOOL, loc };
1462
+ }
1463
+ }
1464
+ if ((left.type.kind === "bigint" && right.type.kind === "f64") ||
1465
+ (left.type.kind === "f64" && right.type.kind === "bigint")) {
1466
+ if (op === ts.SyntaxKind.LessThanToken ||
1467
+ op === ts.SyntaxKind.LessThanEqualsToken ||
1468
+ op === ts.SyntaxKind.GreaterThanToken ||
1469
+ op === ts.SyntaxKind.GreaterThanEqualsToken) {
1470
+ const big = left.type.kind === "bigint" ? left : right;
1471
+ const num = left.type.kind === "f64" ? left : right;
1472
+ const cmp = {
1473
+ kind: "libCall",
1474
+ fn: "bigint.cmpNumber",
1475
+ args: [big, num],
1476
+ type: F64,
1477
+ loc,
1478
+ };
1479
+ const cmpLocal = lowerer.declareHiddenLocal("%bigcmp", F64);
1480
+ const cmpRef = { kind: "varRef", localId: cmpLocal.id, type: F64, loc };
1481
+ const unordered = {
1482
+ kind: "bin",
1483
+ op: "===",
1484
+ left: cmpRef,
1485
+ right: { kind: "numLit", value: 2, type: F64, loc },
1486
+ type: BOOL,
1487
+ loc,
1488
+ };
1489
+ const zero = { kind: "numLit", value: 0, type: F64, loc };
1490
+ const leftBig = left.type.kind === "bigint";
1491
+ const cmpOp = leftBig
1492
+ ? op === ts.SyntaxKind.LessThanToken
1493
+ ? "<"
1494
+ : op === ts.SyntaxKind.LessThanEqualsToken
1495
+ ? "<="
1496
+ : op === ts.SyntaxKind.GreaterThanToken
1497
+ ? ">"
1498
+ : ">="
1499
+ : op === ts.SyntaxKind.LessThanToken
1500
+ ? ">"
1501
+ : op === ts.SyntaxKind.LessThanEqualsToken
1502
+ ? ">="
1503
+ : op === ts.SyntaxKind.GreaterThanToken
1504
+ ? "<"
1505
+ : "<=";
1506
+ const result = {
1507
+ kind: "logical",
1508
+ op: "&&",
1509
+ left: { kind: "unary", op: "!", operand: unordered, type: BOOL, loc },
1510
+ right: { kind: "bin", op: cmpOp, left: cmpRef, right: zero, type: BOOL, loc },
1511
+ type: BOOL,
1512
+ loc,
1513
+ };
1514
+ return {
1515
+ kind: "seqExpr",
1516
+ stmts: [{ kind: "varDecl", localId: cmpLocal.id, init: cmp, loc }],
1517
+ result,
1518
+ type: BOOL,
1519
+ loc,
1520
+ };
1521
+ }
1522
+ }
1523
+ // An unchecked array read keeps its undefined arm in the IR even when
1524
+ // the checker typed the binding as `string`. An optional string is not
1525
+ // itself a string operand for `+`: `undefined + 1` and
1526
+ // `undefined + undefined` are NaN, while a present string concatenates.
1527
+ // Keep this predicate exact so a nullable string does not take the
1528
+ // string path either.
1529
+ const optionalStringType = (type) => {
1530
+ if (type.kind !== "union")
1531
+ return false;
1532
+ const arms = lowerer.unions.get(type.unionId)?.arms;
1533
+ return (!!arms &&
1534
+ arms.length === 2 &&
1535
+ arms.some((arm) => arm.kind === "string") &&
1536
+ arms.some((arm) => arm.kind === "undefinedT"));
1537
+ };
1538
+ const arithmeticNumber = (operand, node) => lowerOptionalNumber(lowerer, operand, loc, node);
1539
+ const arithmeticLeft = strictEquality ? left : arithmeticNumber(left, expr.left);
1540
+ const arithmeticRight = strictEquality ? right : arithmeticNumber(right, expr.right);
1541
+ const bothNum = arithmeticLeft.type.kind === "f64" && arithmeticRight.type.kind === "f64";
1542
+ const bothStr = left.type.kind === "string" && right.type.kind === "string";
1543
+ const lowerOptionalStringPlus = () => {
1544
+ const leftOptional = optionalStringType(left.type);
1545
+ const rightOptional = optionalStringType(right.type);
1546
+ if (!leftOptional && !rightOptional)
1547
+ return null;
1548
+ const allowed = (type) => type.kind === "f64" || type.kind === "string" || optionalStringType(type);
1549
+ if (!allowed(left.type) || !allowed(right.type))
1550
+ return null;
1551
+ // The tag tests and the chosen concatenation branch must see the same
1552
+ // operand values. This matters for `take()[0] + 1` and for two reads
1553
+ // with observable getters/calls.
1554
+ const prefix = [];
1555
+ const stable = (operand) => {
1556
+ if (isSafeToRepeat(operand) || isSafeToDiscard(operand))
1557
+ return operand;
1558
+ const tmp = lowerer.declareHiddenLocal("%plus", operand.type);
1559
+ prefix.push({ kind: "varDecl", localId: tmp.id, init: operand, loc });
1560
+ return varRef(tmp.id, operand.type, loc);
1561
+ };
1562
+ const stableLeft = stable(left);
1563
+ const stableRight = stable(right);
1564
+ const leftString = lowerer.ensureString(stableLeft, expr.left);
1565
+ const rightString = lowerer.ensureString(stableRight, expr.right);
1566
+ const concat = {
1567
+ kind: "strConcat",
1568
+ left: leftString,
1569
+ right: rightString,
1570
+ type: STRING,
1571
+ loc,
1572
+ };
1573
+ const nan = {
1574
+ kind: "bin",
1575
+ op: "/",
1576
+ left: numLit(0, loc),
1577
+ right: numLit(0, loc),
1578
+ type: F64,
1579
+ loc,
1580
+ };
1581
+ const resultT = { kind: "union", unionId: lowerer.unions.intern([F64, STRING]) };
1582
+ lowerer.runtimeOptionalArithmeticTypes.set(expr, resultT);
1583
+ const numberTag = lowerer.armTag(resultT.unionId, F64);
1584
+ const stringTag = lowerer.armTag(resultT.unionId, STRING);
1585
+ if (numberTag < 0 || stringTag < 0)
1586
+ throw new InternalCompilerError("lowerer bug: optional string plus result union");
1587
+ const number = () => ({
1588
+ kind: "unionWrap",
1589
+ unionId: resultT.unionId,
1590
+ tag: numberTag,
1591
+ value: nan,
1592
+ type: resultT,
1593
+ loc,
1594
+ });
1595
+ const string = () => ({
1596
+ kind: "unionWrap",
1597
+ unionId: resultT.unionId,
1598
+ tag: stringTag,
1599
+ value: concat,
1600
+ type: resultT,
1601
+ loc,
1602
+ });
1603
+ const undefinedTest = (operand) => ({
1604
+ kind: "unionIsTag",
1605
+ unionId: operand.type.kind === "union" ? operand.type.unionId : "",
1606
+ tag: operand.type.kind === "union" ? lowerer.armTag(operand.type.unionId, UNDEFINED_T) : -1,
1607
+ negated: false,
1608
+ value: operand,
1609
+ type: BOOL,
1610
+ loc,
1611
+ });
1612
+ let result;
1613
+ if (leftOptional && rightOptional) {
1614
+ const rightMissing = undefinedTest(stableRight);
1615
+ const bothMissing = {
1616
+ kind: "ternary",
1617
+ cond: rightMissing,
1618
+ then: number(),
1619
+ else_: string(),
1620
+ type: resultT,
1621
+ loc,
1622
+ };
1623
+ result = {
1624
+ kind: "ternary",
1625
+ cond: undefinedTest(stableLeft),
1626
+ then: bothMissing,
1627
+ else_: string(),
1628
+ type: resultT,
1629
+ loc,
1630
+ };
1631
+ }
1632
+ else if (leftOptional) {
1633
+ result = {
1634
+ kind: "ternary",
1635
+ cond: undefinedTest(stableLeft),
1636
+ then: number(),
1637
+ else_: string(),
1638
+ type: resultT,
1639
+ loc,
1640
+ };
1641
+ }
1642
+ else {
1643
+ result = {
1644
+ kind: "ternary",
1645
+ cond: undefinedTest(stableRight),
1646
+ then: number(),
1647
+ else_: string(),
1648
+ type: resultT,
1649
+ loc,
1650
+ };
1651
+ }
1652
+ return prefix.length === 0
1653
+ ? result
1654
+ : { kind: "seqExpr", stmts: prefix, result, type: resultT, loc };
1655
+ };
1656
+ switch (op) {
1657
+ case ts.SyntaxKind.PlusToken:
1658
+ if (bothNum)
1659
+ return {
1660
+ kind: "bin",
1661
+ op: "+",
1662
+ left: arithmeticLeft,
1663
+ right: arithmeticRight,
1664
+ type: F64,
1665
+ loc,
1666
+ };
1667
+ if (left.type.kind === "string" || right.type.kind === "string") {
1668
+ return {
1669
+ kind: "strConcat",
1670
+ left: concatOperand(lowerer, left, expr.left),
1671
+ right: concatOperand(lowerer, right, expr.right),
1672
+ type: STRING,
1673
+ loc,
1674
+ };
1675
+ }
1676
+ const optionalStringPlus = lowerOptionalStringPlus();
1677
+ if (optionalStringPlus)
1678
+ return optionalStringPlus;
1679
+ {
1680
+ const primitive = (type) => type.kind === "f64" ||
1681
+ type.kind === "string" ||
1682
+ type.kind === "bool" ||
1683
+ isUnitType(type) ||
1684
+ (type.kind === "union" &&
1685
+ (lowerer.unions.get(type.unionId)?.arms.every(primitive) ?? false));
1686
+ if ((left.type.kind === "union" || right.type.kind === "union") &&
1687
+ primitive(left.type) &&
1688
+ primitive(right.type)) {
1689
+ lowerer.runtimeOptionalArithmeticTypes.set(expr, DYN);
1690
+ return {
1691
+ kind: "libCall",
1692
+ fn: "dyn.add",
1693
+ args: [lowerer.coerceToExpected(left, DYN), lowerer.coerceToExpected(right, DYN)],
1694
+ type: DYN,
1695
+ loc,
1696
+ };
1697
+ }
1698
+ }
1699
+ operatorUnsupported(lowerer, expr, "+", [left.type, right.type]);
1700
+ break;
1701
+ case ts.SyntaxKind.MinusToken:
1702
+ case ts.SyntaxKind.AsteriskToken:
1703
+ case ts.SyntaxKind.SlashToken:
1704
+ case ts.SyntaxKind.PercentToken:
1705
+ case ts.SyntaxKind.AsteriskAsteriskToken: {
1706
+ if (!bothNum)
1707
+ operatorUnsupported(lowerer, expr, ts.tokenToString(op) ?? "?", [left.type, right.type]);
1708
+ const binOp = op === ts.SyntaxKind.MinusToken
1709
+ ? "-"
1710
+ : op === ts.SyntaxKind.AsteriskToken
1711
+ ? "*"
1712
+ : op === ts.SyntaxKind.SlashToken
1713
+ ? "/"
1714
+ : op === ts.SyntaxKind.PercentToken
1715
+ ? "%"
1716
+ : "**";
1717
+ return {
1718
+ kind: "bin",
1719
+ op: binOp,
1720
+ left: arithmeticLeft,
1721
+ right: arithmeticRight,
1722
+ type: F64,
1723
+ loc,
1724
+ };
1725
+ }
1726
+ // The bitwise six, JS-exact: operands through ToInt32/ToUint32
1727
+ // (NaN/±Infinity → 0, truncate, wrap mod 2^32), the operation in
1728
+ // 32-bit space (shift counts masked to 5 bits), the result back to
1729
+ // f64 — `>>>` as Uint32, the rest as Int32 (runtime scr_bit_*).
1730
+ case ts.SyntaxKind.AmpersandToken:
1731
+ case ts.SyntaxKind.BarToken:
1732
+ case ts.SyntaxKind.CaretToken:
1733
+ case ts.SyntaxKind.LessThanLessThanToken:
1734
+ case ts.SyntaxKind.GreaterThanGreaterThanToken:
1735
+ case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: {
1736
+ // Booleans take part as ToNumber converts them, true to 1 and false
1737
+ // to 0: JavaScript code writes `isFn(a) ^ isFn(b)` and `flags | ok`.
1738
+ // A hoisted JavaScript `var` can also hold undefined, and ToInt32
1739
+ // maps ToNumber(undefined) (NaN) and ToNumber(null) to 0.
1740
+ const optionalBoolTag = (e) => {
1741
+ if (e.type.kind !== "union")
1742
+ return -1;
1743
+ const arms = lowerer.unions.get(e.type.unionId)?.arms ?? [];
1744
+ const ok = arms.every((a) => a.kind === "bool" || a.kind === "undefinedT" || a.kind === "nullT");
1745
+ return ok ? arms.findIndex((a) => a.kind === "bool") : -1;
1746
+ };
1747
+ const numeric = (e) => e.type.kind === "f64" || e.type.kind === "bool" || optionalBoolTag(e) >= 0;
1748
+ const boolBits = !bothNum && numeric(arithmeticLeft) && numeric(arithmeticRight);
1749
+ if (!bothNum && !boolBits)
1750
+ operatorUnsupported(lowerer, expr, ts.tokenToString(op) ?? "?", [left.type, right.type]);
1751
+ const bitPrefix = [];
1752
+ const oneOrZero = (cond) => ({
1753
+ kind: "ternary",
1754
+ cond,
1755
+ then: numLit(1, loc),
1756
+ else_: numLit(0, loc),
1757
+ type: F64,
1758
+ loc,
1759
+ });
1760
+ // The tag test reads an operand twice: when either side needs it,
1761
+ // both sides evaluate once into temporaries, in source order. A left
1762
+ // operand that is safe to repeat still takes a temporary when the
1763
+ // right one does: the right operand runs first in the prefix, and it
1764
+ // can assign what the left operand reads.
1765
+ const stash = optionalBoolTag(arithmeticLeft) >= 0 || optionalBoolTag(arithmeticRight) >= 0;
1766
+ const rightTemp = stash && !isSafeToRepeat(arithmeticRight);
1767
+ const stable = (e, beforeTemp) => {
1768
+ if (!stash || (isSafeToRepeat(e) && !beforeTemp))
1769
+ return e;
1770
+ const tmp = lowerer.declareHiddenLocal("%bits", e.type);
1771
+ bitPrefix.push({ kind: "varDecl", localId: tmp.id, init: e, loc });
1772
+ return varRef(tmp.id, e.type, loc);
1773
+ };
1774
+ const bitOperand = (operand, beforeTemp) => {
1775
+ const e = stable(operand, beforeTemp);
1776
+ if (e.type.kind === "bool")
1777
+ return oneOrZero(e);
1778
+ const tag = optionalBoolTag(e);
1779
+ if (tag < 0 || e.type.kind !== "union")
1780
+ return e;
1781
+ const unionId = e.type.unionId;
1782
+ return {
1783
+ kind: "ternary",
1784
+ cond: { kind: "unionIsTag", unionId, tag, negated: false, value: e, type: BOOL, loc },
1785
+ then: oneOrZero({ kind: "unionNarrow", unionId, tag, value: e, type: BOOL, loc }),
1786
+ else_: numLit(0, loc),
1787
+ type: F64,
1788
+ loc,
1789
+ };
1790
+ };
1791
+ const bitOp = op === ts.SyntaxKind.AmpersandToken
1792
+ ? "&"
1793
+ : op === ts.SyntaxKind.BarToken
1794
+ ? "|"
1795
+ : op === ts.SyntaxKind.CaretToken
1796
+ ? "^"
1797
+ : op === ts.SyntaxKind.LessThanLessThanToken
1798
+ ? "<<"
1799
+ : op === ts.SyntaxKind.GreaterThanGreaterThanToken
1800
+ ? ">>"
1801
+ : ">>>";
1802
+ const bits = {
1803
+ kind: "bin",
1804
+ op: bitOp,
1805
+ left: bitOperand(arithmeticLeft, rightTemp),
1806
+ right: bitOperand(arithmeticRight, false),
1807
+ type: F64,
1808
+ loc,
1809
+ };
1810
+ return bitPrefix.length === 0
1811
+ ? bits
1812
+ : { kind: "seqExpr", stmts: bitPrefix, result: bits, type: F64, loc };
1813
+ }
1814
+ case ts.SyntaxKind.EqualsEqualsEqualsToken:
1815
+ case ts.SyntaxKind.ExclamationEqualsEqualsToken:
1816
+ return lowerStrictEquality(lowerer, expr, expr.left, expr.right, left, right, op === ts.SyntaxKind.ExclamationEqualsEqualsToken, loc);
1817
+ case ts.SyntaxKind.LessThanToken:
1818
+ case ts.SyntaxKind.LessThanEqualsToken:
1819
+ case ts.SyntaxKind.GreaterThanToken:
1820
+ case ts.SyntaxKind.GreaterThanEqualsToken: {
1821
+ const cmpOp = op === ts.SyntaxKind.LessThanToken
1822
+ ? "<"
1823
+ : op === ts.SyntaxKind.LessThanEqualsToken
1824
+ ? "<="
1825
+ : op === ts.SyntaxKind.GreaterThanToken
1826
+ ? ">"
1827
+ : ">=";
1828
+ if (bothNum)
1829
+ return {
1830
+ kind: "bin",
1831
+ op: cmpOp,
1832
+ left: arithmeticLeft,
1833
+ right: arithmeticRight,
1834
+ type: BOOL,
1835
+ loc,
1836
+ };
1837
+ if (bothStr)
1838
+ return { kind: "strCmp", op: cmpOp, left, right, type: BOOL, loc };
1839
+ // A Date converts to a new checked-dynamic Date on each crossing, so
1840
+ // comparisons keep their Date fence instead of comparing copies.
1841
+ if (left.type.kind !== "date" &&
1842
+ right.type.kind !== "date" &&
1843
+ lowerer.dynConvertible(left.type) &&
1844
+ lowerer.dynConvertible(right.type)) {
1845
+ return {
1846
+ kind: "libCall",
1847
+ fn: "dyn.compare",
1848
+ args: [
1849
+ lowerer.coerceToExpected(left, DYN),
1850
+ lowerer.coerceToExpected(right, DYN),
1851
+ { kind: "strLit", value: cmpOp, type: STRING, loc },
1852
+ ],
1853
+ type: BOOL,
1854
+ loc,
1855
+ };
1856
+ }
1857
+ lowerer.unsupported("SC1043", expr);
1858
+ break;
1859
+ }
1860
+ default:
1861
+ break;
1862
+ }
1863
+ lowerer.unsupported("SC1090", expr, `operator '${ts.tokenToString(op) ?? ts.syntaxKindName(op)}'`);
1864
+ }
1865
+ /** `left === right` (`!==` when negated) over lowered operands: JS strict
1866
+ * equality for every pair of static kinds the program can compare.
1867
+ * `node` anchors diagnostics, and `leftNode`/`rightNode` the coercions. */
1868
+ export function lowerStrictEquality(lowerer, node, leftNode, rightNode, left, right, negated, loc) {
1869
+ const plainBothNum = left.type.kind === "f64" && right.type.kind === "f64";
1870
+ const bothStr = left.type.kind === "string" && right.type.kind === "string";
1871
+ const indexed = tryLowerIndexedComparison(lowerer, left, right, negated, loc);
1872
+ if (indexed)
1873
+ return indexed;
1874
+ if (plainBothNum)
1875
+ return { kind: "bin", op: negated ? "!==" : "===", left, right, type: BOOL, loc };
1876
+ if (bothStr) {
1877
+ if (left.kind === "strLit" && right.kind === "strLit")
1878
+ return {
1879
+ kind: "boolLit",
1880
+ value: (left.value === right.value) !== negated,
1881
+ type: BOOL,
1882
+ loc,
1883
+ };
1884
+ return { kind: "strEq", negated, left, right, type: BOOL, loc };
1885
+ }
1886
+ // bool === bool: a plain value compare (the config-drift checks'
1887
+ // `desired.lanMode !== actual.lanMode` shape).
1888
+ if (left.type.kind === "bool" && right.type.kind === "bool") {
1889
+ return { kind: "bin", op: negated ? "!==" : "===", left, right, type: BOOL, loc };
1890
+ }
1891
+ const unitTest = lowerer.lowerUnitComparison(left, right, negated, loc);
1892
+ if (unitTest)
1893
+ return unitTest;
1894
+ if (left.type.kind === "union" || right.type.kind === "union") {
1895
+ const compared = lowerUnionEquality(lowerer, left, right, negated, false, loc);
1896
+ if (compared)
1897
+ return compared;
1898
+ const aliasRefusal = (type) => {
1899
+ if (tagEqualityMayMissAlias(lowerer, type))
1900
+ lowerer.unsupported("SC1090", node, `comparisons of related class values beside structural union members (${NARROW_FIRST})`);
1901
+ };
1902
+ // JS strict equality of the ARM values, per union tag (a
1903
+ // per-union helper): equal tags compare payloads (f64 ==, string
1904
+ // bytes, bool ==, ref-arm POINTER identity), different tags are
1905
+ // never equal. Two shapes lower: same union on both sides, and
1906
+ // union vs plain arm value (`u === "text"` where the checker
1907
+ // didn't narrow) — the plain side wraps into the union, which
1908
+ // preserves payload identity. Different unions (tsc admits
1909
+ // partially-overlapping ones) still need narrowing first.
1910
+ const ut = left.type.kind === "union" ? left.type : right.type;
1911
+ const bothUnion = left.type.kind === "union" && right.type.kind === "union";
1912
+ const sameUnion = bothUnion && typeEquals(left.type, right.type);
1913
+ const plainFunc = left.type.kind === "func" ? left : right.type.kind === "func" ? right : null;
1914
+ const unionArms = lowerer.unions.get(ut.unionId)?.arms ?? [];
1915
+ const funcArm = unionArms.find((arm) => arm.kind === "func");
1916
+ // `listeners()` reports original prefix callbacks, but the
1917
+ // checker views an indexed result as function | undefined. For
1918
+ // identity comparison, retain the original closure pointer rather
1919
+ // than adapting it to the tuple signature.
1920
+ if (!bothUnion &&
1921
+ plainFunc !== null &&
1922
+ funcArm?.kind === "func" &&
1923
+ unionArms.filter((arm) => arm.kind === "func").length === 1 &&
1924
+ unionArms.some(isUnitType)) {
1925
+ return {
1926
+ kind: "unionFuncEq",
1927
+ unionId: ut.unionId,
1928
+ tag: lowerer.armTag(ut.unionId, funcArm),
1929
+ union: left.type.kind === "union" ? left : right,
1930
+ func: plainFunc,
1931
+ negated,
1932
+ type: BOOL,
1933
+ loc,
1934
+ };
1935
+ }
1936
+ if ((sameUnion || !bothUnion) && lowerer.eqComparableUnion(ut.unionId)) {
1937
+ aliasRefusal(ut);
1938
+ return {
1939
+ kind: "unionEq",
1940
+ unionId: ut.unionId,
1941
+ negated,
1942
+ sameValue: false,
1943
+ left: lowerer.coerceInto(leftNode, left, ut),
1944
+ right: lowerer.coerceInto(rightNode, right, ut),
1945
+ type: BOOL,
1946
+ loc,
1947
+ };
1948
+ }
1949
+ if (left.type.kind === "union" && right.type.kind === "union") {
1950
+ const leftDef = lowerer.unions.get(left.type.unionId);
1951
+ const rightDef = lowerer.unions.get(right.type.unionId);
1952
+ if (leftDef && rightDef) {
1953
+ const leftValues = leftDef.arms.filter((arm) => !isUnitType(arm));
1954
+ const rightValues = rightDef.arms.filter((arm) => !isUnitType(arm));
1955
+ const sameValueArms = leftValues.length === rightValues.length &&
1956
+ leftValues.every((arm) => rightValues.some((candidate) => typeEquals(candidate, arm)));
1957
+ if (sameValueArms) {
1958
+ const arms = [...leftDef.arms];
1959
+ for (const arm of rightDef.arms) {
1960
+ if (!arms.some((candidate) => typeEquals(candidate, arm)))
1961
+ arms.push(arm);
1962
+ }
1963
+ arms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
1964
+ const common = {
1965
+ kind: "union",
1966
+ unionId: lowerer.unions.intern(arms),
1967
+ };
1968
+ aliasRefusal(common);
1969
+ return {
1970
+ kind: "unionEq",
1971
+ unionId: common.unionId,
1972
+ negated,
1973
+ sameValue: false,
1974
+ left: lowerer.coerceInto(leftNode, left, common),
1975
+ right: lowerer.coerceInto(rightNode, right, common),
1976
+ type: BOOL,
1977
+ loc,
1978
+ };
1979
+ }
1980
+ }
1981
+ }
1982
+ lowerer.unsupported("SC1090", node, `comparisons of union-typed values (${NARROW_FIRST})`);
1983
+ }
1984
+ // Arrays, maps, functions, class instances and records compare by
1985
+ // reference identity (pointer compare) — JS-exact object equality.
1986
+ // Hierarchy-related classes compare after widening the derived side
1987
+ // (same pointer either way — prefix layout).
1988
+ let idLeft = left;
1989
+ let idRight = right;
1990
+ if (left.type.kind === "object" && right.type.kind === "object") {
1991
+ if (lowerer.isSubclassOf(left.type.className, right.type.className)) {
1992
+ idLeft = lowerer.upcastTo(left, right.type.className);
1993
+ }
1994
+ else if (lowerer.isSubclassOf(right.type.className, left.type.className)) {
1995
+ idRight = lowerer.upcastTo(right, left.type.className);
1996
+ }
1997
+ }
1998
+ // Two function values compare by identity whatever their STATIC
1999
+ // signatures (tsc admits the comparison when one side is
2000
+ // assignable to the other — a tuple-typed listeners() element
2001
+ // against a prefix-declared handler): the pointer answers it.
2002
+ if (idLeft.type.kind === "func" && idRight.type.kind === "func") {
2003
+ return {
2004
+ kind: "bin",
2005
+ op: negated ? "!==" : "===",
2006
+ left: idLeft,
2007
+ right: idRight,
2008
+ type: BOOL,
2009
+ loc,
2010
+ };
2011
+ }
2012
+ // Two CLASS values compare by identity whatever their static
2013
+ // classes — one immortal object per class, one pointer compare
2014
+ // (the function-identity rule verbatim; `X === D` through a
2015
+ // base-typed slot answers exactly JS).
2016
+ if (idLeft.type.kind === "classval" && idRight.type.kind === "classval") {
2017
+ return {
2018
+ kind: "bin",
2019
+ op: negated ? "!==" : "===",
2020
+ left: idLeft,
2021
+ right: idRight,
2022
+ type: BOOL,
2023
+ loc,
2024
+ };
2025
+ }
2026
+ if (idLeft.type.kind === "moduleNs" && idRight.type.kind === "moduleNs") {
2027
+ return {
2028
+ kind: "bin",
2029
+ op: negated ? "!==" : "===",
2030
+ left: idLeft,
2031
+ right: idRight,
2032
+ type: BOOL,
2033
+ loc,
2034
+ };
2035
+ }
2036
+ if ((idLeft.type.kind === "array" ||
2037
+ idLeft.type.kind === "map" ||
2038
+ idLeft.type.kind === "set" ||
2039
+ idLeft.type.kind === "regex" ||
2040
+ idLeft.type.kind === "url" ||
2041
+ idLeft.type.kind === "object" ||
2042
+ idLeft.type.kind === "record" ||
2043
+ // Symbols ARE identity: `Symbol('a') === Symbol('a')` is false,
2044
+ // a symbol equals exactly itself, and Symbol.for's interned
2045
+ // values compare equal across call sites — all one pointer
2046
+ // compare, JS's spec without approximation.
2047
+ idLeft.type.kind === "symbol" ||
2048
+ // Typed arrays / Buffers ARE objects to ===: pointer identity
2049
+ // (buf === buf.swap16() — the in-place mutators return this).
2050
+ idLeft.type.kind === "bytes" ||
2051
+ idLeft.type.kind === "promise") &&
2052
+ typeEquals(idLeft.type, idRight.type)) {
2053
+ return {
2054
+ kind: "bin",
2055
+ op: negated ? "!==" : "===",
2056
+ left: idLeft,
2057
+ right: idRight,
2058
+ type: BOOL,
2059
+ loc,
2060
+ };
2061
+ }
2062
+ // Runtime HANDLES are objects to === too: one handle per socket/
2063
+ // request/response, so pointer identity IS JS's object equality
2064
+ // (`c.pause() === c` — Node's chaining assertions). */
2065
+ if (DYN_HANDLE_KINDS.has(idLeft.type.kind) && typeEquals(idLeft.type, idRight.type)) {
2066
+ return {
2067
+ kind: "bin",
2068
+ op: negated ? "!==" : "===",
2069
+ left: idLeft,
2070
+ right: idRight,
2071
+ type: BOOL,
2072
+ loc,
2073
+ };
2074
+ }
2075
+ // A Date converts to a new checked-dynamic Date on each crossing; its
2076
+ // identity has no representation, so equality keeps the fence.
2077
+ if (idLeft.type.kind !== "date" &&
2078
+ idRight.type.kind !== "date" &&
2079
+ lowerer.dynConvertible(idLeft.type) &&
2080
+ lowerer.dynConvertible(idRight.type)) {
2081
+ return {
2082
+ kind: "dynScalarEq",
2083
+ left: lowerer.coerceToExpected(idLeft, DYN),
2084
+ right: lowerer.coerceToExpected(idRight, DYN),
2085
+ ...(negated ? { negated: true } : {}),
2086
+ type: BOOL,
2087
+ loc,
2088
+ };
2089
+ }
2090
+ return lowerer.unsupported("SC1043", node);
2091
+ }
2092
+ function lowerLogicalChain(lowerer, expr) {
2093
+ // Logical chains have a left-nested AST. Keep the native stack bounded
2094
+ // while retaining each pair's checker type and lazy operand evaluation.
2095
+ const parents = [];
2096
+ let current = expr;
2097
+ let result;
2098
+ while (true) {
2099
+ if (current.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
2100
+ const fallback = lowerAbsenceAwareOrChain(lowerer, current);
2101
+ if (fallback !== null) {
2102
+ result = fallback;
2103
+ break;
2104
+ }
2105
+ }
2106
+ const left = current.left;
2107
+ if (ts.isBinaryExpression(left) &&
2108
+ (left.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
2109
+ left.operatorToken.kind === ts.SyntaxKind.BarBarToken) &&
2110
+ !lowerer.chainRecvByNode.has(left)) {
2111
+ parents.push(current);
2112
+ current = left;
2113
+ continue;
2114
+ }
2115
+ result = lowerLogicalPair(lowerer, current, current.operatorToken.kind === ts.SyntaxKind.BarBarToken
2116
+ ? lowerPresenceOperand(lowerer, left)
2117
+ : (lowerAbsenceProbe(lowerer, left) ?? lowerer.lowerExpr(left)));
2118
+ break;
2119
+ }
2120
+ for (let i = parents.length - 1; i >= 0; i--) {
2121
+ result = lowerLogicalPair(lowerer, parents[i], result);
2122
+ }
2123
+ return result;
2124
+ }
2125
+ function lowerLogicalPair(lowerer, expr, left) {
2126
+ const op = expr.operatorToken.kind;
2127
+ const loc = locOf(expr);
2128
+ // Preserve short-circuiting during lowering too: an unreachable member
2129
+ // on a specialized value must not poison the surrounding JS statement.
2130
+ if (left.kind === "boolLit") {
2131
+ const takeRight = op === ts.SyntaxKind.AmpersandAmpersandToken ? left.value : !left.value;
2132
+ return takeRight ? lowerer.lowerExpr(expr.right) : left;
2133
+ }
2134
+ if (left.kind === "unitLit" && op === ts.SyntaxKind.AmpersandAmpersandToken)
2135
+ return left;
2136
+ if (op === ts.SyntaxKind.BarBarToken && REF_TRUTHY_KINDS.has(left.type.kind))
2137
+ return left;
2138
+ const right = lowerer.lowerExpr(expr.right);
2139
+ // A LITERAL-unit left operand (a compile-time undefined/null — the
2140
+ // capability-probe members: `process.features.inspector ||
2141
+ // !flag.startsWith('--inspect')` reads undefined in a compiled
2142
+ // binary): statically falsy, so the operator folds JS-exactly —
2143
+ // `unit || X` IS X, `unit && X` IS the unit (X's side effects never
2144
+ // run in JS either; the lowered right is simply dropped). Literal
2145
+ // units only — computed unit-typed values keep the fences below.
2146
+ if (left.kind === "unitLit") {
2147
+ return op === ts.SyntaxKind.BarBarToken ? right : left;
2148
+ }
2149
+ // JS objects and symbols are always truthy. In `ref || fallback`
2150
+ // the fallback is therefore unreachable and the result is the
2151
+ // already-evaluated left value — the browser-fallback idiom used by
2152
+ // packages for `process.argv || []` and `process.env || {}`. The
2153
+ // operand itself remains in the IR, preserving reads/calls that
2154
+ // produce the reference; only the unreachable right lowering drops.
2155
+ if (op === ts.SyntaxKind.BarBarToken && REF_TRUTHY_KINDS.has(left.type.kind)) {
2156
+ return left;
2157
+ }
2158
+ if (left.type.kind === "dyn" || right.type.kind === "dyn") {
2159
+ // A checked-dynamic operand (`fn.name || '<anonymous>'` —
2160
+ // test/common's _mustCallInner): both sides live in the checked-dynamic tree and
2161
+ // the deciding test is ToBoolean over the dyn kind
2162
+ // (scr_dyn_truthy) — JS value semantics exactly, result dyn. The
2163
+ // non-dyn side converts through the usual boundary; a value with
2164
+ // no dyn representation keeps the fence.
2165
+ const l = lowerer.coerceToExpected(left, DYN);
2166
+ const r = lowerer.coerceToExpected(right, DYN);
2167
+ if (l.type.kind !== "dyn" || r.type.kind !== "dyn") {
2168
+ lowerer.unsupported("SC1100", expr, "logical operators on 'unknown' values");
2169
+ }
2170
+ return {
2171
+ kind: "logical",
2172
+ op: op === ts.SyntaxKind.AmpersandAmpersandToken ? "&&" : "||",
2173
+ left: l,
2174
+ right: r,
2175
+ type: DYN,
2176
+ loc,
2177
+ };
2178
+ }
2179
+ if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
2180
+ op === ts.SyntaxKind.AmpersandAmpersandToken &&
2181
+ left.type.kind === "union" &&
2182
+ lowerer.unions.get(left.type.unionId)?.arms.some((arm) => arm.kind === "bool") &&
2183
+ !typeEquals(left.type, right.type) &&
2184
+ lowerer.dynConvertible(left.type) &&
2185
+ lowerer.dynConvertible(right.type)) {
2186
+ return {
2187
+ kind: "logical",
2188
+ op: "&&",
2189
+ left: lowerer.coerceToExpected(left, DYN),
2190
+ right: lowerer.coerceToExpected(right, DYN),
2191
+ type: DYN,
2192
+ loc,
2193
+ };
2194
+ }
2195
+ if (left.type.kind === "union" || right.type.kind === "union") {
2196
+ // Test the deciding operand in its own representation. The result
2197
+ // contains only the values that can survive short-circuit evaluation.
2198
+ let target = lowerer.mapTypeOf(lowerer.typeOf(expr));
2199
+ // Index reads can be absent without noUncheckedIndexedAccess. Their
2200
+ // explicit nullish fallback still runs, even if the checker discarded it.
2201
+ if (target !== null) {
2202
+ const returned = [
2203
+ right.type,
2204
+ ...(op === ts.SyntaxKind.AmpersandAmpersandToken ? [left.type] : []),
2205
+ ];
2206
+ for (const type of returned) {
2207
+ const arms = type.kind === "union" ? (lowerer.unions.get(type.unionId)?.arms ?? []) : [type];
2208
+ for (const arm of arms) {
2209
+ if (arm.kind === "undefinedT" && !isUnitType(target))
2210
+ target = lowerer.runtimeOptionalType(target);
2211
+ if (arm.kind === "nullT")
2212
+ target = withUnitArm(target, arm.kind, lowerer.unions) ?? target;
2213
+ }
2214
+ }
2215
+ }
2216
+ // A broad-JSDoc npm-static body can leave the CHECKER result `any`
2217
+ // even after declaration-backed specialization has recovered both
2218
+ // operands (`helpOption && args.find(...)` in commander). When the
2219
+ // left consists only of always-truthy references and falsy units,
2220
+ // the static result is exactly the right operand plus those units.
2221
+ if (op === ts.SyntaxKind.AmpersandAmpersandToken &&
2222
+ target === null &&
2223
+ lowerer.implicitParamTypes !== null &&
2224
+ npmStaticPackageOfPath(ts.getSourceFileOfNode(expr).fileName) !== null &&
2225
+ (lowerer.typeOf(expr).flags & ts.TypeFlags.Any) !== 0 &&
2226
+ left.type.kind === "union") {
2227
+ const leftArms = lowerer.unions.get(left.type.unionId)?.arms;
2228
+ const rightArms = right.type.kind === "union" ? lowerer.unions.get(right.type.unionId)?.arms : [right.type];
2229
+ const rightIsStatic = rightArms?.every((arm) => arm.kind !== "dyn" && arm.kind !== "caught" && arm.kind !== "void") ?? false;
2230
+ if (leftArms &&
2231
+ rightArms &&
2232
+ rightIsStatic &&
2233
+ leftArms.some(isUnitType) &&
2234
+ leftArms.every((arm) => isUnitType(arm) || REF_TRUTHY_KINDS.has(arm.kind))) {
2235
+ const byKey = new Map();
2236
+ for (const arm of [...rightArms, ...leftArms.filter(isUnitType)]) {
2237
+ byKey.set(typeKey(arm), arm);
2238
+ }
2239
+ const arms = [...byKey.values()].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
2240
+ if (arms.length > 1) {
2241
+ const source = right.type.kind === "union" ? lowerer.unions.get(right.type.unionId) : undefined;
2242
+ target = {
2243
+ kind: "union",
2244
+ unionId: source ? lowerer.unions.transform(source, arms) : lowerer.unions.intern(arms),
2245
+ };
2246
+ }
2247
+ }
2248
+ }
2249
+ // `&&` over an always-truthy plain left operand (an array, object or
2250
+ // function value) whose result union has no arm for it: every JS
2251
+ // object is truthy, so `list && list[0]` evaluates the left for its
2252
+ // effects and answers the right. Coercing the left into that union
2253
+ // would trap at run time where Node answers the right operand.
2254
+ if (op === ts.SyntaxKind.AmpersandAmpersandToken &&
2255
+ target?.kind === "union" &&
2256
+ REF_TRUTHY_KINDS.has(left.type.kind) &&
2257
+ lowerer.armTag(target.unionId, left.type) < 0) {
2258
+ return {
2259
+ kind: "seqExpr",
2260
+ stmts: [{ kind: "exprStmt", expr: left, loc }],
2261
+ result: lowerer.coerceInto(expr.right, right, target),
2262
+ type: target,
2263
+ loc,
2264
+ };
2265
+ }
2266
+ if (target?.kind === "union") {
2267
+ // `&&` whose left does NOT fit the result union: the checker
2268
+ // built that result by DROPPING left arms which are always
2269
+ // truthy (`Option | undefined && string | undefined` answers
2270
+ // `string | undefined`, not `Option | string | undefined`).
2271
+ // Evaluate the left once, test it in its own union, and retag it
2272
+ // only on the falsy path. Any stranded reference arms are
2273
+ // unreachable there because every JS object is truthy.
2274
+ if (op === ts.SyntaxKind.AmpersandAmpersandToken &&
2275
+ left.type.kind === "union" &&
2276
+ !typeEquals(left.type, target)) {
2277
+ const def = lowerer.unions.get(left.type.unionId);
2278
+ const trappable = new Set();
2279
+ def?.arms.forEach((arm, tag) => {
2280
+ if (lowerer.armTag(target.unionId, arm) < 0 && REF_TRUTHY_KINDS.has(arm.kind)) {
2281
+ trappable.add(tag);
2282
+ }
2283
+ });
2284
+ const retag = trappable.size === 0
2285
+ ? null
2286
+ : lowerer.unionRetagHelper(left.type.unionId, target.unionId, loc, trappable);
2287
+ if (retag) {
2288
+ lowerer.requireTruthyUnion(left.type.unionId, expr);
2289
+ const stmts = [];
2290
+ let stable = left;
2291
+ if (!isSafeToRepeat(left)) {
2292
+ const local = lowerer.declareHiddenLocal("%and", left.type);
2293
+ stmts.push({ kind: "varDecl", localId: local.id, init: left, loc });
2294
+ stable = varRef(local.id, left.type, loc);
2295
+ }
2296
+ const result = {
2297
+ kind: "ternary",
2298
+ cond: lowerer.ensureBool(stable, expr.left),
2299
+ then: lowerer.coerceInto(expr.right, right, target),
2300
+ else_: { kind: "call", callee: retag, args: [stable], type: target, loc },
2301
+ type: target,
2302
+ loc,
2303
+ };
2304
+ return stmts.length === 0
2305
+ ? result
2306
+ : { kind: "seqExpr", stmts, result, type: target, loc };
2307
+ }
2308
+ }
2309
+ // `||` whose left does NOT fit the result union: the checker built
2310
+ // that result by DROPPING the left's falsy arms (`process.env.X ||
2311
+ // null` is `string | null`, `|| 3000` is `string | number` — the
2312
+ // `undefined` is gone from both), so coercing the left eagerly, as
2313
+ // the shared shape below does, retags an arm the test is about to
2314
+ // rule out and throws where Node yields the default. Single-eval
2315
+ // instead: test the left in its OWN union and retag only on the
2316
+ // truthy side, where the dropped arms are unreachable.
2317
+ if (op === ts.SyntaxKind.BarBarToken &&
2318
+ left.type.kind === "union" &&
2319
+ !typeEquals(left.type, target)) {
2320
+ const retag = lowerer.unionRetagHelper(left.type.unionId, target.unionId, loc);
2321
+ if (retag) {
2322
+ lowerer.requireTruthyUnion(left.type.unionId, expr);
2323
+ return {
2324
+ kind: "orDefault",
2325
+ left,
2326
+ right: lowerer.coerceInto(expr.right, right, target),
2327
+ retag,
2328
+ type: target,
2329
+ loc,
2330
+ };
2331
+ }
2332
+ }
2333
+ lowerer.requireTruthyUnion(target.unionId, expr);
2334
+ return {
2335
+ kind: "logical",
2336
+ op: op === ts.SyntaxKind.AmpersandAmpersandToken ? "&&" : "||",
2337
+ left: lowerer.coerceInto(expr.left, left, target),
2338
+ right: lowerer.coerceInto(expr.right, right, target),
2339
+ type: target,
2340
+ loc,
2341
+ };
2342
+ }
2343
+ // `u || d` NARROWED by the default: the checker types the result
2344
+ // as u's single non-unit arm (`marker() || "default"`) — evaluate
2345
+ // u once, truthy extracts the arm, falsy takes d lazily (the
2346
+ // orDefault node, nullish's truthiness sibling). An UNMAPPABLE
2347
+ // checker result takes the same rule (`options.runner ||
2348
+ // defaultRunner` — tsc's union of two structurally-compatible
2349
+ // function types has no representation, while the left's one
2350
+ // non-unit arm is the only representable answer): the default
2351
+ // must coerce into the arm or fence on its own.
2352
+ if (op === ts.SyntaxKind.BarBarToken && left.type.kind === "union") {
2353
+ const def = lowerer.unions.get(left.type.unionId);
2354
+ const rest = def ? def.arms.filter((a) => !isUnitType(a)) : [];
2355
+ const funcArmDefault = rest[0]?.kind === "func" && (target === null || target.kind === "func");
2356
+ if (rest.length === 1 &&
2357
+ ((target !== null && typeEquals(target, rest[0])) || funcArmDefault)) {
2358
+ lowerer.requireTruthyUnion(left.type.unionId, expr);
2359
+ const dflt = lowerer.lowerExprExpecting(expr.right, rest[0]);
2360
+ return { kind: "orDefault", left, right: dflt, type: rest[0], loc };
2361
+ }
2362
+ }
2363
+ // JavaScript defaults can join differently inferred object layouts.
2364
+ // When both operands have native checked representations, preserve
2365
+ // the deciding value and short-circuit evaluation in that domain.
2366
+ if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
2367
+ lowerer.dynConvertible(left.type) &&
2368
+ lowerer.dynConvertible(right.type)) {
2369
+ return {
2370
+ kind: "logical",
2371
+ op: op === ts.SyntaxKind.AmpersandAmpersandToken ? "&&" : "||",
2372
+ left: lowerer.coerceInto(expr.left, left, DYN),
2373
+ right: lowerer.coerceInto(expr.right, right, DYN),
2374
+ type: DYN,
2375
+ loc,
2376
+ };
2377
+ }
2378
+ lowerer.unsupported("SC1090", expr, `logical operators on union-typed values outside conditions (${NARROW_FIRST})`);
2379
+ }
2380
+ const kind = left.type.kind;
2381
+ if (kind !== right.type.kind || (kind !== "f64" && kind !== "string" && kind !== "bool")) {
2382
+ // Mixed PLAIN operands (`value || null`, `flag || undefined`,
2383
+ // `s || 0`): JS value semantics still compile when the checker
2384
+ // types the RESULT as one union both operands coerce into — the
2385
+ // same lift the union-operand path above takes, arriving here
2386
+ // with two plain arm values instead.
2387
+ const target = lowerer.mapTypeOf(lowerer.typeOf(expr));
2388
+ // An always-truthy left operand (a record, object, array or function
2389
+ // value: every JS object is truthy): `o && x` evaluates `o` for its
2390
+ // effects and answers `x`; `o || x` answers `o` and never evaluates
2391
+ // `x`. supports-color's `stream && stream.isTTY` is the shape. Ahead
2392
+ // of the union lift below exactly where that lift would store the
2393
+ // object in a result union with no arm for it; a union holding the
2394
+ // operand keeps the lift.
2395
+ if (REF_TRUTHY_KINDS.has(kind) &&
2396
+ (target?.kind !== "union" ||
2397
+ (op === ts.SyntaxKind.AmpersandAmpersandToken &&
2398
+ lowerer.armTag(target.unionId, left.type) < 0))) {
2399
+ const and = op === ts.SyntaxKind.AmpersandAmpersandToken;
2400
+ const answer = and ? right : left;
2401
+ const answerT = target ?? answer.type;
2402
+ if (answerT.kind !== "void") {
2403
+ const value = lowerer.coerceInto(and ? expr.right : expr.left, answer, answerT);
2404
+ if (!and)
2405
+ return value;
2406
+ return {
2407
+ kind: "seqExpr",
2408
+ stmts: [{ kind: "exprStmt", expr: left, loc }],
2409
+ result: value,
2410
+ type: answerT,
2411
+ loc,
2412
+ };
2413
+ }
2414
+ }
2415
+ if (target?.kind === "union") {
2416
+ lowerer.requireTruthyUnion(target.unionId, expr);
2417
+ return {
2418
+ kind: "logical",
2419
+ op: op === ts.SyntaxKind.AmpersandAmpersandToken ? "&&" : "||",
2420
+ left: lowerer.coerceInto(expr.left, left, target),
2421
+ right: lowerer.coerceInto(expr.right, right, target),
2422
+ type: target,
2423
+ loc,
2424
+ };
2425
+ }
2426
+ lowerer.unsupported("SC1042", expr);
2427
+ }
2428
+ return {
2429
+ kind: "logical",
2430
+ op: op === ts.SyntaxKind.AmpersandAmpersandToken ? "&&" : "||",
2431
+ left,
2432
+ right,
2433
+ type: left.type,
2434
+ loc,
2435
+ };
2436
+ }
2437
+ function lowerAbsenceAwareOrChain(lowerer, expr) {
2438
+ const nodes = [];
2439
+ const pending = [expr];
2440
+ while (pending.length !== 0) {
2441
+ const node = pending.pop();
2442
+ if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
2443
+ pending.push(node.right, node.left);
2444
+ }
2445
+ else {
2446
+ nodes.push(node);
2447
+ }
2448
+ }
2449
+ if (nodes.length < 3)
2450
+ return null;
2451
+ const lowered = nodes.map((node) => lowerAbsenceProbe(lowerer, node) ?? lowerer.lowerExpr(node));
2452
+ if (!lowered.some((value) => value.type.kind === "union" && lowerer.armTag(value.type.unionId, UNDEFINED_T) >= 0)) {
2453
+ return null;
2454
+ }
2455
+ let result = lowered[lowered.length - 1];
2456
+ for (let i = lowered.length - 2; i >= 0; i--) {
2457
+ const left = lowered[i];
2458
+ const loc = locOf(nodes[i]);
2459
+ if (left.type.kind === "union") {
2460
+ const def = lowerer.unions.get(left.type.unionId);
2461
+ const nonUnit = def?.arms.filter((arm) => !isUnitType(arm)) ?? [];
2462
+ if (nonUnit.length !== 1 || !typeEquals(nonUnit[0], result.type))
2463
+ return null;
2464
+ lowerer.requireTruthyUnion(left.type.unionId, expr);
2465
+ result = { kind: "orDefault", left, right: result, type: result.type, loc };
2466
+ continue;
2467
+ }
2468
+ if (!typeEquals(left.type, result.type))
2469
+ return null;
2470
+ result = { kind: "logical", op: "||", left, right: result, type: result.type, loc };
2471
+ }
2472
+ return result;
2473
+ }
2474
+ /** `typeof WebAssembly === "object"` and `typeof WebAssembly.<member> ===
2475
+ * "function"`: the operand needs no value, so the test folds as bare typeof
2476
+ * does (builtins/webassembly.ts) before any dyn-typed operand lowers. */
2477
+ function lowerWebAssemblyTypeofTest(lowerer, expr, loc) {
2478
+ const negated = expr.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken;
2479
+ for (const [a, b] of operandPairs(expr)) {
2480
+ if (!ts.isTypeOfExpression(a) || !ts.isStringLiteral(b))
2481
+ continue;
2482
+ const folded = lowerWebAssemblyTypeof(lowerer, a.expression);
2483
+ if (folded?.kind !== "strLit")
2484
+ continue;
2485
+ return { kind: "boolLit", value: (folded.value === b.text) !== negated, type: BOOL, loc };
2486
+ }
2487
+ return null;
2488
+ }
2489
+ /** `typeof v === "lit"` / `typeof v !== "lit"` where v is UNION-typed: the
2490
+ * arms whose static typeof answer equals the literal form a tag set, and
2491
+ * the test is a runtime tag test — one `unionIsTag` for a single matching
2492
+ * arm (the operand embeds once, so even effectful operands compose), a
2493
+ * short-circuit chain for several (pure reads only — the operand rides
2494
+ * every test, exactly the `== null` composition rule). When every arm
2495
+ * answers the same way the comparison is statically decided and folds to
2496
+ * a bool literal — dropping only a side-effect-free read, the same
2497
+ * trust-the-checker bet as lowerUnitComparison. tsc's control-flow
2498
+ * narrowing then types the branches, and reads bridge through
2499
+ * maybeNarrow's unionNarrow as usual. Null when neither side is a typeof
2500
+ * over a union-typed operand or the literal side isn't a literal (the
2501
+ * bare-typeof value form then composes with strEq for pure operands). */
2502
+ function lowerUnionTypeofTest(lowerer, expr, loc) {
2503
+ const negated = expr.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken;
2504
+ for (const [a, b] of operandPairs(expr)) {
2505
+ if (!ts.isTypeOfExpression(a))
2506
+ continue;
2507
+ const stored = runtimeOptionalStorageOperand(lowerer, a.expression);
2508
+ if (stored === null && lowerer.mapTypeOf(lowerer.typeOf(a.expression))?.kind !== "union")
2509
+ continue;
2510
+ if (!ts.isStringLiteral(b))
2511
+ continue; // bare-typeof + strEq handles pure operands
2512
+ const value = stored ?? lowerer.lowerExpr(a.expression);
2513
+ if (value.type.kind !== "union")
2514
+ continue; // defensive: an already-narrowed use
2515
+ const unionId = value.type.unionId;
2516
+ const def = lowerer.unions.get(unionId);
2517
+ const answers = def?.arms.map(typeofAnswer);
2518
+ if (!def || !answers || !answers.every((s) => s !== null))
2519
+ continue;
2520
+ const tags = answers.flatMap((s, i) => (s === b.text ? [i] : []));
2521
+ if (tags.length === 0 || tags.length === def.arms.length) {
2522
+ if (!isSafeToRepeat(value)) {
2523
+ lowerer.unsupported("SC1090", expr, "statically-decided 'typeof' tests over effectful operands (bind the value to a const first)");
2524
+ }
2525
+ return { kind: "boolLit", value: (tags.length !== 0) !== negated, type: BOOL, loc };
2526
+ }
2527
+ const isTag = (tag) => ({
2528
+ kind: "unionIsTag",
2529
+ unionId,
2530
+ tag,
2531
+ negated,
2532
+ value,
2533
+ type: BOOL,
2534
+ loc,
2535
+ });
2536
+ if (tags.length === 1)
2537
+ return isTag(tags[0]);
2538
+ if (!isSafeToRepeat(value)) {
2539
+ lowerer.unsupported("SC1090", expr, "'typeof' tests matching several union arms over operands that aren't plain reads (bind the value to a const first)");
2540
+ }
2541
+ // Tag-in-set as a short-circuit chain (De Morgan for `!==`).
2542
+ let acc = isTag(tags[0]);
2543
+ for (const t of tags.slice(1)) {
2544
+ acc = {
2545
+ kind: "logical",
2546
+ op: negated ? "&&" : "||",
2547
+ left: acc,
2548
+ right: isTag(t),
2549
+ type: BOOL,
2550
+ loc,
2551
+ };
2552
+ }
2553
+ return acc;
2554
+ }
2555
+ return null;
2556
+ }
2557
+ //# sourceMappingURL=binary.js.map