@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,3787 @@
1
+ /* Property reads (`a.b`): lowerExprInner's property-access branch, intrinsic and union properties, field reads and targets, and match-group reads. */
2
+ import { staticallySelected } from "../static-typeof.js";
3
+ import * as ts from "../../ts7/adapter.js";
4
+ import { lowerHistogramProperty } from "../builtins/performance.js";
5
+ import { staticFunctionNameRead } from "../static-function-names.js";
6
+ import { typedArgumentsArity } from "../typed-arguments.js";
7
+ import { isThisParameter } from "../call-signatures.js";
8
+ import { localPrivateBrandClass } from "../private-brands.js";
9
+ import { PoisonError, jsFuncNameOf, neverTaintedJsType, own } from "../lowerer.js";
10
+ import { ARRAY_METHODS, MAP_METHODS, NARROW_FIRST, OBJECT_CALLABLE_VALUES, SET_METHODS, STDLIB_SURFACE, STRING_INDEX_METHODS, STR_METHODS, isChildSurfaceMember, stdlibGlobalNameOf, } from "../surfaces.js";
11
+ import { isGenericCallableMemberType, isLegacyUrlSymbol, isOsConstantsType, isParseArgsDynTypeName, } from "../../type-mapper.js";
12
+ import { BOOL, BYTES_ELEMENT_NAME, BYTES_U8, DYN, F64, NULL_T, SEARCH_PARAMS_T, STRING, SYMBOL_T, UNDEFINED_T, arrayOf, canBoxFuncIntoDyn, funcOf, isDynTypedRefType, isUnitType, typeEquals, typeKey, unionContainerArmsOk, BYTES_ELEMENT_SIZE, } from "../../../ir/ir.js";
13
+ import { lowerNavigatorMember } from "../builtins/navigator.js";
14
+ import { NODE_COMPAT_VERSION } from "../builtins/process.js";
15
+ import { inlineNamespaceRequireOf, lowerWithInlineRequireInit, wholeExportValue, } from "../cjs-inline-require.js";
16
+ import { cjsAccessorCall, constInitializerOf, exactUnionWidening, hasClassPayload, lowerExpr, matchAllCallbackRegexOf, matchAllRegexOf, namedCaptureGroupsOfPattern, primitiveCtorClosure, recordKeyResultOk, representedClassFieldTarget, staticRegexPatternOf, } from "../lower-exprs.js";
17
+ import { cjsInFileExportGlobalOf, isCjsExportsIdentifier, lowerCjsExportsObjectValue, } from "../cjs-exports-object.js";
18
+ import { tscInteropDefaultValueOf } from "../cjs-tsc-interop.js";
19
+ import { lifetimeRegionMemberOf } from "../../experimental-import.js";
20
+ import { lowerInternTableProperty } from "../intern-tables.js";
21
+ import { lowerThreadSlotsProperty } from "../thread-slots.js";
22
+ import { builtinClassRefOf, runtimeClassValueOfType } from "../builtins/class-values.js";
23
+ import { lowerRuntimeConstructor, lowerRuntimeConstructorName, runtimeConstructorReceiver, } from "../builtins/runtime-constructor.js";
24
+ import { findGenericMethodOn, lowerStaticFieldRead } from "../lower-classes.js";
25
+ import { lowerClassPrototypeData } from "../class-prototypes.js";
26
+ import { lowerEnumAccess } from "../lower-enums.js";
27
+ import { hasOptionalChainGuard, isOptionalChainTail, isRequireMainFilename, } from "./optional-chains.js";
28
+ import { isCjsModuleGlobal, lowerNodeModuleProperty, lowerRequireMainProperty, } from "../lower-node-module.js";
29
+ import { dynUndefinedExpr, nodeThrowExpr, numLit, strLit, varRef } from "../../../ir/build.js";
30
+ import { typedArrayLacksMember } from "../builtins/typed-array-members.js";
31
+ import { TEMPORAL_GLOBAL } from "../../builtin-modules.js";
32
+ import { tryLowerExpression } from "./try-lower-expression.js";
33
+ import { cjsClassExprWholeExportOf, cjsExportAssignmentOf, cjsExportDiscardReason, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, isNodeEsmFile, locOf, } from "../../program.js";
34
+ import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, contextualUndefReadType, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead, } from "../lower-namespaces.js";
35
+ import { expandoMemberRead } from "../lower-expando.js";
36
+ import { lowerProtocolPropertyRead } from "../class-protocol-dispatch.js";
37
+ import { lowerReadlineProperty } from "../builtins/readline.js";
38
+ import { lowerEventStaticProperty } from "../builtins/numbers.js";
39
+ import { lowerStreamProperty, lowerStreamStateProperty, streamSidesOf } from "../lower-stream.js";
40
+ import { lowerEventObjectProperty } from "../lower-event-target.js";
41
+ import { iteratorResultValueRead } from "../lower-generators.js";
42
+ import { lowerGlobalValue } from "../lower-global-value.js";
43
+ import { nullishGenericBindingUnitOf } from "../binding-analysis.js";
44
+ import { blockedBindingUseDiag } from "../../../diagnostics/diagnostic.js";
45
+ import { npmStaticPackageOfPath } from "../../npm-static.js";
46
+ import { importMetaField, isImportMeta } from "../import-meta.js";
47
+ import { builtinPrototypeMethod, lowerArrayIsArrayValue, lowerCheckedPredicateValue, lowerNumberParserValue, lowerObjectAssignValue, lowerStringCodesValue, } from "../lower-builtin-values.js";
48
+ import { lowerArrayFromValue } from "../containers/array-construction.js";
49
+ import { lowerNetAddressStaticRead } from "../builtins/net-address.js";
50
+ import { STATS_TYPE_TESTS } from "../builtins/filesystem.js";
51
+ import { arrayValueRead, arrayValueType } from "../array-values.js";
52
+ import { lowerClassMethodValue } from "../class-method-values.js";
53
+ import { objLitGenericFnInfoOf, objLitGenericFnNodeOf, requireObjLitGenericReceiver, } from "../generic-functions.js";
54
+ import { narrowStoredClassValue, structuralReadType } from "../class-unions.js";
55
+ import { InternalCompilerError } from "../../../errors.js";
56
+ import { lowerUnionFieldRead } from "./union-fields.js";
57
+ import { errorPropertyRead } from "../error-methods.js";
58
+ import { isSafeToDiscard, isSafeToRepeat } from "./evaluation-safety.js";
59
+ import { isZlibStreamMember, lowerZlibStreamBytesWritten } from "../builtins/compression.js";
60
+ import { isFsStreamMember, lowerFsStreamProperty } from "../builtins/fs-streams.js";
61
+ import { keyedFieldRead } from "./keyed-field-targets.js";
62
+ import { promisePrototypeValue } from "../thenables.js";
63
+ import { lowerChildPropertyRead } from "../handle-properties.js";
64
+ /** True when a property access names an ABSTRACT property declaration
65
+ * (`abstract p: number` — a PropertyDeclaration, not an accessor).
66
+ * These uses need concrete property dispatch because the base has no slot. */
67
+ export function abstractPropertyDeclOf(lowerer, expr) {
68
+ const sym = lowerer.checker.getSymbolAtLocation(expr.name);
69
+ if (!sym)
70
+ return false;
71
+ return sym.declarations.some((d) => ts.isPropertyDeclaration(d) &&
72
+ ts.getModifiers(d)?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword) === true);
73
+ }
74
+ /** A field declared by node:util's parseArgs checked-dynamic type family.
75
+ * Narrowing a ParseArgsToken exposes one anonymous union arm, so its alias
76
+ * identity no longer reaches mapType; declaration ancestry is the stable
77
+ * provenance check. */
78
+ /** The Uint8Array base64/hex prototype methods (ES2026) Node 24 lacks. */
79
+ const UINT8ARRAY_BASE64_METHODS = new Set([
80
+ "toBase64",
81
+ "toHex",
82
+ "setFromBase64",
83
+ "setFromHex",
84
+ ]);
85
+ /** `Uint8Array.prototype.<base64/hex method>` read off the global. */
86
+ function isUint8ArrayBase64Probe(lowerer, expr) {
87
+ if (!UINT8ARRAY_BASE64_METHODS.has(expr.name.text))
88
+ return false;
89
+ const proto = expr.expression;
90
+ return (ts.isPropertyAccessExpression(proto) &&
91
+ !proto.questionDotToken &&
92
+ proto.name.text === "prototype" &&
93
+ stdlibGlobalNameOf(lowerer, proto.expression) === "Uint8Array");
94
+ }
95
+ function isParseArgsDynProperty(lowerer, expr) {
96
+ const sym = lowerer.checker.getSymbolAtLocation(expr.name);
97
+ if (!sym)
98
+ return false;
99
+ return sym.declarations.some((d) => {
100
+ if (!lowerer.isStdlibFile(ts.getSourceFileOfNode(d)))
101
+ return false;
102
+ let inParseArgsType = false;
103
+ for (let node = d.parent; node; node = node.parent) {
104
+ if ((ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node)) &&
105
+ isParseArgsDynTypeName(node.name.text)) {
106
+ inParseArgsType = true;
107
+ }
108
+ if (ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name)) {
109
+ return inParseArgsType && (node.name.text === "util" || node.name.text === "node:util");
110
+ }
111
+ }
112
+ return false;
113
+ });
114
+ }
115
+ function isStatFsDynProperty(lowerer, expr) {
116
+ if (!["type", "bsize", "blocks", "bfree", "bavail", "files", "ffree", "bigint"].includes(expr.name.text))
117
+ return false;
118
+ const symbol = lowerer.checker.getSymbolAtLocation(expr.name);
119
+ return (!!symbol &&
120
+ symbol.declarations.some((declaration) => {
121
+ if (!lowerer.isStdlibFile(ts.getSourceFileOfNode(declaration)))
122
+ return false;
123
+ const parent = declaration.parent;
124
+ if (!ts.isInterfaceDeclaration(parent))
125
+ return false;
126
+ if (expr.name.text === "bigint"
127
+ ? parent.name.text !== "StatFsOptions"
128
+ : !["StatsFsBase", "StatsFs", "BigIntStatsFs"].includes(parent.name.text))
129
+ return false;
130
+ for (let node = parent.parent; node; node = node.parent) {
131
+ if (ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name))
132
+ return node.name.text === "fs" || node.name.text === "node:fs";
133
+ }
134
+ return false;
135
+ }));
136
+ }
137
+ /** The dgram.Socket methods its checked-dynamic handle answers as
138
+ * function values (scr_dgram.c's scr_dgram_dyn_method_names). */
139
+ const DGRAM_METHOD_VALUES = new Set([
140
+ "on",
141
+ "once",
142
+ "addListener",
143
+ "removeListener",
144
+ "off",
145
+ "emit",
146
+ "send",
147
+ "close",
148
+ "bind",
149
+ "connect",
150
+ "disconnect",
151
+ "address",
152
+ "ref",
153
+ "unref",
154
+ ]);
155
+ export function lowerPropertyAccessExpr(lowerer, expr, loc) {
156
+ if (!expr.questionDotToken) {
157
+ const navigator = lowerNavigatorMember(lowerer, expr, NODE_COMPAT_VERSION);
158
+ if (navigator)
159
+ return navigator;
160
+ }
161
+ // A dgram socket's method read as a value in JavaScript (`emit:
162
+ // socket.emit.bind(socket)`): the socket crosses as its checked-dynamic
163
+ // handle, whose methods are function values that dispatch on their
164
+ // receiver, as the prototype methods do. The receiver is a native
165
+ // socket whatever its declaration spells (the shipped types declare no
166
+ // EventEmitter members), so the name decides.
167
+ if (!expr.questionDotToken &&
168
+ DGRAM_METHOD_VALUES.has(expr.name.text) &&
169
+ isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
170
+ lowerer.mapTypeOf(lowerer.typeOf(expr.expression))?.kind === "dgramSocket") {
171
+ return {
172
+ kind: "dynKeyGet",
173
+ value: lowerer.coerceToExpected(lowerer.lowerExpr(expr.expression), DYN),
174
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
175
+ type: DYN,
176
+ loc,
177
+ };
178
+ }
179
+ // `fn.name` on a function parameter of a generic instance keyed by
180
+ // its argument's static name (call-site specialization).
181
+ {
182
+ const staticName = staticFunctionNameRead(lowerer, expr);
183
+ if (staticName !== null)
184
+ return { kind: "strLit", value: staticName, type: STRING, loc };
185
+ }
186
+ // An IntervalHistogram's readings (min, max, mean, stddev, count, exceeds).
187
+ {
188
+ const reading = lowerHistogramProperty(lowerer, expr);
189
+ if (reading)
190
+ return reading;
191
+ }
192
+ // `.length` of a forwarded fixed tuple (a typed `arguments`, a tuple
193
+ // rest parameter, an alias of either): the signature's arity.
194
+ if (expr.name.text === "length" && !expr.questionDotToken) {
195
+ const arity = typedArgumentsArity(lowerer, expr.expression);
196
+ if (arity !== null)
197
+ return { kind: "numLit", value: arity, type: F64, loc };
198
+ }
199
+ // `require("./x").member` over a program module's export table: the
200
+ // module's %init at this position, then the member read exactly like
201
+ // a `const m = require("./x")` binding's (cjs-inline-require.ts).
202
+ if (!expr.questionDotToken) {
203
+ const req = inlineNamespaceRequireOf(lowerer, expr.expression);
204
+ if (req !== null && !lowerer.inlineRequireInitDone.has(req.call)) {
205
+ return lowerWithInlineRequireInit(lowerer, req, () => lowerExpr(lowerer, expr));
206
+ }
207
+ // `module.exports` compared by identity inside its own module, or
208
+ // refused by name as any other value (cjs-exports-object.ts).
209
+ if (expr.name.text === "exports") {
210
+ const exportsValue = lowerCjsExportsObjectValue(lowerer, expr);
211
+ if (exportsValue)
212
+ return exportsValue;
213
+ }
214
+ // tsc's `x_1.default` over a dependency whose whole export is one
215
+ // value: that value (cjs-tsc-interop.ts).
216
+ const interop = tscInteropDefaultValueOf(lowerer, expr);
217
+ if (interop !== null) {
218
+ const value = wholeExportValue(lowerer, interop.dep, expr);
219
+ if (value !== null)
220
+ return value;
221
+ }
222
+ }
223
+ {
224
+ const member = lifetimeRegionMemberOf(lowerer.program, expr, lowerer.experimentalFiles);
225
+ if (member !== null)
226
+ lowerer.noLowering(`LifetimeRegion.${member} (@scriptc/experimental) as a value`, expr, `call region.${member}(${member === "run" ? "fn" : ""}) directly`);
227
+ }
228
+ {
229
+ const table = lowerInternTableProperty(lowerer, expr);
230
+ if (table)
231
+ return table;
232
+ }
233
+ lowerThreadSlotsProperty(lowerer, expr);
234
+ // `EventEmitter.name`, `zlib.Gzip.name`, `C.name` over a builtin
235
+ // class alias.
236
+ if (expr.name.text === "name" && !expr.questionDotToken) {
237
+ const ref = builtinClassRefOf(lowerer, expr.expression);
238
+ if (ref !== null)
239
+ return { kind: "strLit", value: ref.name, type: STRING, loc };
240
+ }
241
+ // `x.constructor.name` and `x.constructor` on an instance of
242
+ // EventEmitter or a stream class (builtins/runtime-constructor.ts).
243
+ if (expr.name.text === "name" && !expr.questionDotToken) {
244
+ const ctor = runtimeConstructorReceiver(lowerer, expr.expression);
245
+ if (ctor)
246
+ return lowerRuntimeConstructorName(lowerer, ctor.receiver, loc);
247
+ }
248
+ {
249
+ const ctor = runtimeConstructorReceiver(lowerer, expr);
250
+ if (ctor)
251
+ return lowerRuntimeConstructor(lowerer, expr, ctor.info);
252
+ }
253
+ // `C.name` through a runtime-provided class VALUE (a `typeof Readable`
254
+ // parameter): the class object's stored name.
255
+ if (expr.name.text === "name" &&
256
+ !expr.questionDotToken &&
257
+ runtimeClassValueOfType(lowerer, lowerer.typeOf(expr.expression)) !== null) {
258
+ const read = lowerer.lowerFieldRead(expr);
259
+ if (read)
260
+ return read;
261
+ }
262
+ // Expando statics may still be absent even when JS inference sees
263
+ // the eventual assignment's scalar type. Preserve the checked value.
264
+ const staticField = lowerStaticFieldRead(lowerer, expr);
265
+ if (staticField)
266
+ return staticField;
267
+ const prototypeData = lowerClassPrototypeData(lowerer, expr);
268
+ if (prototypeData)
269
+ return prototypeData;
270
+ if (ts.isPropertyAccessExpression(expr.expression) && expr.expression.name.text === "prototype") {
271
+ const prototype = lowerClassPrototypeData(lowerer, expr.expression);
272
+ if (prototype)
273
+ return {
274
+ kind: "dynKeyGet",
275
+ value: prototype,
276
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
277
+ type: DYN,
278
+ loc,
279
+ };
280
+ }
281
+ // `super.x`: the base chain's GETTER, called directly (super
282
+ // dispatch is static in JS — never through the dynamic class).
283
+ // super.method() calls are routed at the call site; a bare super
284
+ // property read lands here.
285
+ if (expr.expression.kind === ts.SyntaxKind.SuperKeyword) {
286
+ return lowerer.lowerSuperAccessorRead(expr);
287
+ }
288
+ // Enum member reads (`E.A`) fold to their compile-time constants —
289
+ // claimed FIRST so no receiver-shaped path (records, the
290
+ // identifier fence on the enum object) sees them. lower-enums.ts.
291
+ {
292
+ const en = lowerEnumAccess(lowerer, expr);
293
+ if (en)
294
+ return en;
295
+ }
296
+ // `import.meta.<field>` — the file-backed ESM metadata that survives
297
+ // compilation as a constant. Only direct, identifier-named reads are
298
+ // claimed here; the bare meta object, computed access, writes, and
299
+ // unsupported members continue through the generic module-loader fence
300
+ // below. The source file is the module identity, so imported modules
301
+ // receive their own filename/dirname and only the entry receives main.
302
+ const importMeta = importMetaProperty(lowerer, expr);
303
+ if (importMeta)
304
+ return importMeta;
305
+ // `require.main.filename` / `require.main?.filename` — CommonJS
306
+ // entry-module identity: in a compiled binary require.main IS the
307
+ // entry module (never undefined in a CJS graph, so the chain's guard
308
+ // folds away), and its filename is the ENTRY file's real path —
309
+ // Node's exact value when the same tree runs in place, exactly the
310
+ // __filename stance. Checked BEFORE the optional-chain gate: the
311
+ // checker types the chain `string | undefined`, but the value is a
312
+ // compile-time string.
313
+ if (isRequireMainFilename(lowerer, expr)) {
314
+ return { kind: "strLit", value: lowerer.entry.fileName, type: STRING, loc };
315
+ }
316
+ const requireMain = lowerRequireMainProperty(lowerer, expr);
317
+ if (requireMain)
318
+ return requireMain;
319
+ const moduleProperty = lowerNodeModuleProperty(lowerer, expr);
320
+ if (moduleProperty)
321
+ return moduleProperty;
322
+ if (stdlibGlobalNameOf(lowerer, expr.expression) === "Symbol" &&
323
+ [
324
+ "iterator",
325
+ "asyncIterator",
326
+ "toStringTag",
327
+ "toPrimitive",
328
+ "hasInstance",
329
+ "isConcatSpreadable",
330
+ "match",
331
+ "matchAll",
332
+ "replace",
333
+ "search",
334
+ "split",
335
+ "species",
336
+ "unscopables",
337
+ "dispose",
338
+ "asyncDispose",
339
+ ].includes(expr.name.text)) {
340
+ return {
341
+ kind: "libCall",
342
+ fn: "sym.wellKnown",
343
+ args: [{ kind: "strLit", value: expr.name.text, type: STRING, loc }],
344
+ type: { kind: "symbol" },
345
+ loc,
346
+ };
347
+ }
348
+ if (lowerer.stdlibGlobalMember(expr, "Object") === "freeze") {
349
+ const name = "%builtin.Object.freeze";
350
+ if (!lowerer.liftedFns.some((fn) => fn.name === name))
351
+ lowerer.liftedFns.push({
352
+ name,
353
+ params: [{ localId: "value", name: "value", type: DYN }],
354
+ locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
355
+ returnType: DYN,
356
+ body: [
357
+ {
358
+ kind: "return",
359
+ value: {
360
+ kind: "libCall",
361
+ fn: "dyn.freeze",
362
+ args: [varRef("value", DYN, loc)],
363
+ type: DYN,
364
+ loc,
365
+ },
366
+ loc,
367
+ },
368
+ ],
369
+ loc,
370
+ });
371
+ return { kind: "closure", fnName: name, captures: [], type: funcOf([DYN], DYN), loc };
372
+ }
373
+ // An Hmac has no copy() (Hash does): Node answers undefined, which
374
+ // `typeof mac.copy` feature checks read. TypeScript rejects the read.
375
+ if (expr.name.text === "copy" &&
376
+ lowerer.mapTypeOf(lowerer.typeOf(expr.expression))?.kind === "cryptoHmac") {
377
+ return {
378
+ kind: "seqExpr",
379
+ stmts: [{ kind: "exprStmt", expr: lowerer.lowerExpr(expr.expression), loc }],
380
+ result: dynUndefinedExpr(loc),
381
+ type: DYN,
382
+ loc,
383
+ };
384
+ }
385
+ if (lowerer.stdlibGlobalMember(expr, "globalThis") === "console") {
386
+ return { kind: "libCall", fn: "console.native", args: [], type: DYN, loc };
387
+ }
388
+ if (lowerer.stdlibGlobalMember(expr, "console") !== null) {
389
+ return {
390
+ kind: "dynKeyGet",
391
+ value: { kind: "libCall", fn: "console.native", args: [], type: DYN, loc },
392
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
393
+ type: DYN,
394
+ loc,
395
+ };
396
+ }
397
+ // Missing host globals (Bun/Deno capability probes) have no binding
398
+ // in a native program. Declared globals retain their own lowering;
399
+ // arbitrary global-object mutation remains fenced. Preserve a dyn
400
+ // undefined value so stored probes compose with optional calls.
401
+ if (stdlibGlobalNameOf(lowerer, expr.expression) === "globalThis" &&
402
+ !lowerer.checker.getPropertyOfType(lowerer.typeOf(staticallySelected(lowerer, expr.expression)), expr.name.text)) {
403
+ return dynUndefinedExpr(loc);
404
+ }
405
+ // `Uint8Array.prototype.toBase64` and its siblings, the base64/hex
406
+ // feature probes libraries such as jose make: the methods are newer
407
+ // than Node 24, whose Uint8Array prototype answers undefined for them.
408
+ if (isUint8ArrayBase64Probe(lowerer, expr))
409
+ return dynUndefinedExpr(loc);
410
+ if (expr.questionDotToken && expr.name.text === "electron") {
411
+ const processProperty = lowerer.lowerProcessProperty(expr);
412
+ if (processProperty)
413
+ return processProperty;
414
+ }
415
+ // Optional chaining `a?.b`: the guard lowers here (a tag test around
416
+ // the plain property lowering below); the handled marker keeps this
417
+ // re-entrant dispatch from looping.
418
+ if (expr.questionDotToken && !lowerer.chainHandled.has(expr)) {
419
+ return lowerer.lowerOptionalChain(expr);
420
+ }
421
+ // `a?.b.c` — the tail of a chain whose token sits deeper: the whole
422
+ // tail short-circuits with the guard.
423
+ if (!expr.questionDotToken && isOptionalChainTail(lowerer, expr)) {
424
+ return lowerer.lowerOptionalChain(expr);
425
+ }
426
+ // Known Web handles retain their declared surface even when their
427
+ // storage uses checked values. Apply this before generic reads.
428
+ lowerer.fenceStaticAbortControllerMemberRead(expr);
429
+ lowerer.fenceStaticResponseMember(expr, "read");
430
+ lowerer.fenceStaticHeadersMember(expr, "read");
431
+ lowerer.fenceStaticReadableStreamMember(expr, "read");
432
+ // — reading off null/undefined — bridged catchably like everything
433
+ // at the boundary). `o?.x` arrives here too, through the chain
434
+ // lowering's re-dispatch (a questionDotToken past the gate above is
435
+ // always chain-handled; the receiver reads back as the chain's
436
+ // bound handle).
437
+ // `m.index` on a for-of-over-matchAll binding reads the companion-
438
+ // index array at this iteration's cursor — always a number: every
439
+ // drained row matched, so the lib's `.index` is never undefined
440
+ // here (lowerForOfMatchAll).
441
+ if (expr.name.text === "index" && !expr.questionDotToken && ts.isIdentifier(expr.expression)) {
442
+ const sym = lowerer.checker.getSymbolAtLocation(expr.expression);
443
+ const companion = sym !== undefined ? lowerer.matchAllIndexBindings.get(sym) : undefined;
444
+ if (companion !== undefined) {
445
+ return {
446
+ kind: "arrayGet",
447
+ arr: { kind: "varRef", localId: companion.idxsLocalId, type: arrayOf(F64), loc },
448
+ index: { kind: "varRef", localId: companion.curLocalId, type: F64, loc },
449
+ type: F64,
450
+ loc,
451
+ };
452
+ }
453
+ }
454
+ if ((expr.name.text === "index" || expr.name.text === "input") && !expr.questionDotToken) {
455
+ const represented = tryLowerExpression(lowerer, expr.expression);
456
+ if (represented &&
457
+ isMatchSliceType(lowerer, represented.type) &&
458
+ (lowerer.isStdlibMember(expr) || isJsSourceFile(ts.getSourceFileOfNode(expr)))) {
459
+ const recv = represented;
460
+ const key = { kind: "strLit", value: expr.name.text, type: STRING, loc };
461
+ // A plain slice answers from its match source without a dynamic copy.
462
+ const read = typeEquals(recv.type, arrayOf(STRING))
463
+ ? { kind: "libCall", fn: "regex.resultProp", args: [recv, key], type: DYN, loc }
464
+ : { kind: "dynKeyGet", value: lowerer.coerceToExpected(recv, DYN), key, type: DYN, loc };
465
+ return lowerer.maybeNarrow(read, expr);
466
+ }
467
+ }
468
+ // `m.groups` on a match result whose regex is statically known:
469
+ // the compile-time record projection over the honest slice (or
470
+ // Node's undefined when the pattern has no named groups) — see
471
+ // lowerMatchGroupsRead.
472
+ {
473
+ const g = lowerMatchGroupsRead(lowerer, expr);
474
+ if (g !== null)
475
+ return g;
476
+ }
477
+ // `arguments.length` in a TYPED function whose signature is
478
+ // FIXED-ARITY (no optional/default/rest parameters): tsc enforces
479
+ // exact arity at every call site and call/apply/bind indirection is
480
+ // fenced, so the actual count IS the declared count — a compile-time
481
+ // constant. Arrows don't bind `arguments` (the walk skips them,
482
+ // exactly JS's scoping); variable-arity signatures keep the fence
483
+ // (the count would need a hidden argc). The JS-source variadic
484
+ // `arguments` object (dynRest) was claimed at identifier lowering.
485
+ if (expr.name.text === "length" &&
486
+ !expr.questionDotToken &&
487
+ ts.isIdentifier(expr.expression) &&
488
+ expr.expression.text === "arguments" &&
489
+ !lowerer.ctx.argumentsLocal &&
490
+ ts.symbolNameOf(lowerer.typeOf(expr.expression).getSymbol()) === "IArguments" &&
491
+ lowerer.isStdlibSymbol(lowerer.typeOf(expr.expression).getSymbol())) {
492
+ let fn = expr.parent;
493
+ while (fn !== undefined &&
494
+ !ts.isFunctionDeclaration(fn) &&
495
+ !ts.isFunctionExpression(fn) &&
496
+ !ts.isMethodDeclaration(fn) &&
497
+ !ts.isConstructorDeclaration(fn) &&
498
+ !ts.isGetAccessorDeclaration(fn) &&
499
+ !ts.isSetAccessorDeclaration(fn)) {
500
+ fn = ts.isSourceFile(fn) ? undefined : fn.parent;
501
+ }
502
+ if (fn !== undefined) {
503
+ const fixedArity = fn.parameters.nodes.every((p) => p.questionToken === undefined &&
504
+ p.initializer === undefined &&
505
+ p.dotDotDotToken === undefined);
506
+ if (fixedArity) {
507
+ // A `this` parameter is type-only: callers never pass it.
508
+ return {
509
+ kind: "numLit",
510
+ value: fn.parameters.nodes.filter((p) => !isThisParameter(p)).length,
511
+ type: F64,
512
+ loc,
513
+ };
514
+ }
515
+ lowerer.unsupported("SC1090", expr, "'arguments.length' in functions with optional, default, or rest parameters (the count varies per call — a fixed-arity signature folds to a constant)");
516
+ }
517
+ }
518
+ // CommonJS namespace binding (`const lib = require("./lib.js")`):
519
+ // `lib.member` IS the member — the export table is alias plumbing,
520
+ // so the NAME resolves exactly like a bare identifier reference
521
+ // (resolveValueSymbol lands on the exporter's declaration and every
522
+ // existing path — globals, function values, classes — applies).
523
+ if (!expr.questionDotToken && lowerer.cjsLocalModuleBindingOf(expr.expression)) {
524
+ // A binding whose dep is a class-expression WHOLE export
525
+ // (`module.exports = class {…}`): the member surface is the
526
+ // CLASS's — `C.name` folds to NamedEvaluation's answer and own
527
+ // statics read their globals (lowerStaticFieldRead resolves the
528
+ // binding through the expression's own symbol). The plain
529
+ // member-name delegation below would resolve `name` against the
530
+ // stdlib var instead — a wrong VALUE, not a fence. Unknown
531
+ // members fall through to the delegation (expando statics ride
532
+ // their pre-registered export globals).
533
+ const viaClass = lowerStaticFieldRead(lowerer, expr);
534
+ if (viaClass)
535
+ return viaClass;
536
+ return lowerExpr(lowerer, expr.name);
537
+ }
538
+ // `module.exports` READ in a CommonJS file whose whole export IS a
539
+ // class expression (`module.exports = class …{}`): the read answers
540
+ // the class VALUE — `new module.exports()` inside the module is the
541
+ // requirer's `new C()` spelled locally. Top-level reads ABOVE the
542
+ // assignment fall through to their existing fences (Node still
543
+ // answers the original export object there); function bodies
544
+ // resolve unconditionally — they run after the module evaluated,
545
+ // the same approximation identifier exports already make. Every
546
+ // other module.exports read keeps its existing story.
547
+ if (!expr.questionDotToken &&
548
+ isModuleExportsAccess(expr) &&
549
+ isCjsJsFile(ts.getSourceFileOfNode(expr), lowerer.program)) {
550
+ const whole = cjsClassExprWholeExportOf(ts.getSourceFileOfNode(expr));
551
+ if (whole) {
552
+ let inBody = false;
553
+ for (let p = expr.parent; p !== undefined && !ts.isSourceFile(p); p = p.parent) {
554
+ if (ts.isFunctionLike(p) || ts.isClassDeclaration(p) || ts.isClassExpression(p)) {
555
+ inBody = true;
556
+ break;
557
+ }
558
+ }
559
+ if (inBody || ts.tokenStartOfNode(expr) > whole.stmt.end) {
560
+ return lowerer.classValueRef(lowerer.lowerClassExpressionInfo(whole.classExpr), expr);
561
+ }
562
+ }
563
+ }
564
+ // `module.exports.Sub` / `exports.Sub` READ in the same module: an
565
+ // EXPRESSION-valued member rides its pre-registered export global —
566
+ // exactly what requirers see through `require('./x').Sub`, and the
567
+ // global IS the storage every `exports.Sub =` statement assigns, so
568
+ // the read is Node's live member. Identifier-valued members have no
569
+ // global (pure alias plumbing) and fall through unchanged; write
570
+ // positions belong to the export-assignment machinery.
571
+ {
572
+ const writePos = ts.isBinaryExpression(expr.parent) &&
573
+ expr.parent.left === expr &&
574
+ expr.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken;
575
+ const g = cjsInFileExportGlobalOf(lowerer, expr);
576
+ if (g && !writePos)
577
+ return { kind: "varRef", localId: g.id, type: g.type, loc };
578
+ }
579
+ // Namespace-qualified reads (`N.x`, `A.B.C.f`, import= alias
580
+ // chains): the member is a compile-time-known declaration of a
581
+ // lowered namespace block — it resolves exactly like a bare
582
+ // identifier reference (globals, function values, classes), guarded
583
+ // by the namespace source-order fences (lower-namespaces.ts).
584
+ if (!expr.questionDotToken) {
585
+ const nsMember = nsMemberIdentOf(lowerer, expr);
586
+ if (nsMember) {
587
+ const memberSym = lowerer.checker.getSymbolAtLocation(nsMember);
588
+ if (memberSym)
589
+ fenceEarlyNsMemberRef(lowerer, expr, memberSym);
590
+ return lowerExpr(lowerer, nsMember);
591
+ }
592
+ // Expando function members (`foo.bar` after `foo.bar = 12`): the
593
+ // member's module global (lower-expando.ts), before the ambient-
594
+ // namespace fence — a declare-namespace merge over a real function
595
+ // (`declare namespace Foo { var baz: number }` + `function Foo`)
596
+ // reads its assigned members, not the ambient ReferenceError.
597
+ {
598
+ const ex = expandoMemberRead(lowerer, expr);
599
+ if (ex)
600
+ return lowerer.maybeNarrow(ex, expr);
601
+ }
602
+ // An AMBIENT namespace receiver (`M.x` where only `declare
603
+ // namespace M` exists): the namespace object never exists at
604
+ // runtime — Node's exact catchable ReferenceError at the access,
605
+ // the ambient `declare const` stance.
606
+ const ambientRoot = ambientNsRootOf(lowerer, expr.expression);
607
+ if (ambientRoot !== null) {
608
+ const t = ambientUndefReadType(lowerer, expr);
609
+ if (t)
610
+ return nsUndefRead(lowerer, ambientRoot.text, expr, t);
611
+ }
612
+ }
613
+ // `exports.<name>` READS in a module whose export object was
614
+ // REPLACED (`module.exports = ...`): `exports` still references the
615
+ // ORIGINAL object — Node's aliasing rule — so when nothing ever
616
+ // attached this name to it (`exports.<name> =` nowhere in the
617
+ // file), the honest answer is undefined. tsc types the read off the
618
+ // REPLACEMENT (its CJS model is identity-blind), which is exactly
619
+ // the undiagnosed divergence this lowering closes. Reads in modules with
620
+ // real `exports.<name> =` attachments keep their fences.
621
+ {
622
+ const ex = lowerReplacedExportsRead(lowerer, expr);
623
+ if (ex)
624
+ return ex;
625
+ }
626
+ // `this.<name>` inside a CJS export-table getter: Node binds the
627
+ // receiver to module.exports — the read is the sibling getter's
628
+ // lifted call.
629
+ {
630
+ const tm = lowerCjsExportTableThisMember(lowerer, expr);
631
+ if (tm)
632
+ return tm;
633
+ }
634
+ // Property signatures of class-backed protocols read implementing
635
+ // classes' fields directly.
636
+ if (!hasOptionalChainGuard(expr.expression)) {
637
+ const typed = lowerProtocolPropertyRead(lowerer, expr);
638
+ if (typed)
639
+ return typed;
640
+ }
641
+ {
642
+ const promiseMember = lowerPromiseConstructorRead(lowerer, expr);
643
+ if (promiseMember)
644
+ return promiseMember;
645
+ }
646
+ const handled = lowerer.lowerProcessEnvGet(expr) ??
647
+ lowerer.lowerServerProperty(expr) ??
648
+ // diagnostics_channel Channel receivers — name/hasSubscribers
649
+ // over the f64 channel handle.
650
+ lowerer.lowerDiagnosticsChannelProperty(expr) ??
651
+ // readline Interface receivers — the history and option members
652
+ // over the f64 interface handle.
653
+ lowerReadlineProperty(lowerer, expr) ??
654
+ // TracingChannel receivers — the five event channels and
655
+ // hasSubscribers over the f64 tracing handle.
656
+ lowerer.lowerTracingChannelProperty(expr) ??
657
+ lowerer.lowerTestCtxProperty(expr) ??
658
+ lowerer.lowerProcessProperty(expr) ??
659
+ lowerer.lowerProcessStreamProperty(expr) ??
660
+ lowerer.lowerFsConstantsProperty(expr) ??
661
+ // http2.constants.NGHTTP2_CANCEL (any constants-object spelling):
662
+ // the baked-literal table.
663
+ lowerer.lowerBuiltinConstantsProperty(expr) ??
664
+ // Builtin namespace imports (`path.sep`, `os.EOL`,
665
+ // `fs.constants.R_OK` where the root is `import * as ...`): the
666
+ // same constants and per-member fences as named builtin imports.
667
+ lowerer.lowerNamespaceBuiltinProperty(expr) ??
668
+ lowerer.lowerJsonProperty(expr) ??
669
+ lowerer.lowerErrorCodeProperty(expr) ??
670
+ lowerer.lowerNumberStaticProperty(expr) ??
671
+ lowerEventStaticProperty(lowerer, expr) ??
672
+ lowerer.lowerMathProperty(expr) ??
673
+ lowerer.lowerIntrinsicProperty(expr) ??
674
+ // The _readableState/_writableState scalar READS (the suite's
675
+ // asserts) — checked before the generic stream property surface:
676
+ // the inner access maps no type of its own.
677
+ lowerStreamStateProperty(lowerer, expr) ??
678
+ lowerStreamObjectProperty(lowerer, expr) ??
679
+ lowerEventObjectProperty(lowerer, expr) ??
680
+ lowerer.lowerUnionProperty(expr) ??
681
+ // A builtin constructor reached through another binding (`const D =
682
+ // Date; D.prototype`) holds its interned function value, which
683
+ // models only name, length and constructor: a static member or the
684
+ // prototype that no lowering above claimed keeps the SC2020 fence
685
+ // rather than reading undefined through the field and dynamic reads.
686
+ fenceBuiltinConstructorStaticRead(lowerer, expr) ??
687
+ lowerer.lowerFieldRead(expr);
688
+ // A union-typed field read narrows like an identifier when the
689
+ // checker has narrowed this use to one arm.
690
+ if (handled) {
691
+ if (handled.type.kind === "union" &&
692
+ lowerer.armTag(handled.type.unionId, UNDEFINED_T) >= 0 &&
693
+ handled.kind === "recordGet" &&
694
+ lowerer.isRuntimeOptionalField(handled.shapeId, handled.field))
695
+ return handled;
696
+ // A class field assigned a missing read: the checker narrows this
697
+ // read to the assigned value's bare type, but the stored undefined
698
+ // arm is real (`obj.n = bytes[i]; obj.n` is undefined in Node).
699
+ if (runtimeOptionalClassField(lowerer, handled, expr))
700
+ return handled;
701
+ return iteratorResultValueRead(lowerer, handled, expr) ?? lowerer.maybeNarrow(handled, expr);
702
+ }
703
+ // `globalThis.<name>` that no lowering above claimed
704
+ // (globalThis.crypto, globalThis.SubtleCrypto, globalThis.localStorage
705
+ // — the harness's capability-conditional knownGlobals adds): the
706
+ // PROPERTY spelling of the identifier chokepoint's JS rule — a stdlib
707
+ // global taken as a VALUE in a JavaScript source is the same opaque
708
+ // IDENTITY TOKEN the bare spelling answers (`globalThis.crypto` IS
709
+ // `crypto` — one global, one token, or identity flows through Sets
710
+ // and === would disagree between the two spellings). TypeScript
711
+ // sources keep the SC2020 member fence below, like the bare form.
712
+ if (!expr.questionDotToken &&
713
+ stdlibGlobalNameOf(lowerer, expr.expression) === "globalThis" &&
714
+ isJsSourceFile(ts.getSourceFileOfNode(expr))) {
715
+ const canonical = stdlibGlobalNameOf(lowerer, expr);
716
+ if (canonical !== null) {
717
+ if (canonical === "globalThis")
718
+ return lowerGlobalValue(lowerer, expr);
719
+ // Typed for the programs that name it, absent in Node 24.
720
+ if (canonical === TEMPORAL_GLOBAL)
721
+ return dynUndefinedExpr(loc);
722
+ if (canonical === "ArrayBuffer")
723
+ return { kind: "libCall", fn: "arrayBuffer.constructor", args: [], type: DYN, loc };
724
+ if (canonical === "fetch")
725
+ return { kind: "libCall", fn: "fetch.function", args: [], type: DYN, loc };
726
+ if (Object.values(BYTES_ELEMENT_NAME).includes(canonical))
727
+ return {
728
+ kind: "libCall",
729
+ fn: "bytes.constructor",
730
+ args: [{ kind: "strLit", value: canonical, type: STRING, loc }],
731
+ type: DYN,
732
+ loc,
733
+ };
734
+ return (builtinGlobalValueAt(lowerer, expr, canonical, loc, true) ?? {
735
+ kind: "strLit",
736
+ value: `[builtin ${canonical}]`,
737
+ type: STRING,
738
+ loc,
739
+ });
740
+ }
741
+ }
742
+ // A JS receiver whose CHECKER type has no mapping (`mustCallChecks
743
+ // .length` where the binding is an evolving any[] living as a
744
+ // checked-dynamic global): the stdlib member fence below would blame
745
+ // the unmappable checker type (`any[].length`), but the VALUE is a
746
+ // dyn node — lower the receiver first and read through the dyn keyed
747
+ // read (ARR answers length; everything else JS's own-property
748
+ // answer). Mapped receivers keep the fence-first order: their
749
+ // members' gaps are real surface gaps ([1,2].entries), not
750
+ // representation artifacts. `.length` on a receiver whose checker
751
+ // ARRAY type lowers to the checked-dynamic representation —
752
+ // `unknown[]`, the collapsed `(string | object)[]`, and the `any[]`
753
+ // an Array.isArray guard narrows a collapsed union to — is the checked-dynamic tree
754
+ // array's OWN length (a keyed read the ARR kind answers exactly),
755
+ // never an `Array.prototype` surface gap; both source languages.
756
+ // Prototype-method VALUE reads (`ps.map` unparenthesized) keep the
757
+ // fence-first order: a stored-member undefined would mis-answer
758
+ // them, and calls dispatch through the dyn method machinery
759
+ // instead.
760
+ if ((isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
761
+ (lowerer.mapTypeOf(lowerer.typeOf(expr.expression)) === null ||
762
+ (lowerer.typeOf(expr.expression).flags & ts.TypeFlags.Never) !== 0 ||
763
+ // A never-tainted receiver type maps (never rides as f64) but
764
+ // its VALUE lowered checked-dynamic — same dyn read.
765
+ neverTaintedJsType(lowerer, expr.expression, lowerer.typeOf(expr.expression)))) ||
766
+ (expr.name.text === "length" &&
767
+ (lowerer.checkerAnyArray(expr.expression) ||
768
+ (lowerer.checker.isArrayType(lowerer.typeOf(expr.expression)) &&
769
+ lowerer.mapTypeOf(lowerer.typeOf(expr.expression))?.kind === "dyn")))) {
770
+ const recv = lowerer.lowerExpr(expr.expression);
771
+ if (recv.type.kind === "dyn") {
772
+ const key = {
773
+ kind: "strLit",
774
+ value: expr.name.text,
775
+ type: STRING,
776
+ loc: locOf(expr.name),
777
+ };
778
+ const opt = hasOptionalChainGuard(expr.expression, lowerer);
779
+ return lowerer.maybeNarrow({
780
+ kind: "dynKeyGet",
781
+ key,
782
+ ...(opt ? { optional: true } : {}),
783
+ value: recv,
784
+ type: DYN,
785
+ loc,
786
+ }, expr);
787
+ }
788
+ if (expr.name.text === "length" &&
789
+ (recv.type.kind === "array" || recv.type.kind === "string")) {
790
+ return recv.type.kind === "array"
791
+ ? { kind: "arrIntrinsic", method: "length", receiver: recv, args: [], type: F64, loc }
792
+ : { kind: "strIntrinsic", method: "length", receiver: recv, args: [], type: F64, loc };
793
+ }
794
+ }
795
+ if (isJsSourceFile(ts.getSourceFileOfNode(expr)) && expr.name.text === "constructor") {
796
+ const receiver = tryLowerExpression(lowerer, expr.expression);
797
+ if (receiver?.type.kind === "dyn" ||
798
+ (receiver?.type.kind === "object" &&
799
+ !lowerer.classes.get(receiver.type.className)?.fields.has("constructor"))) {
800
+ return {
801
+ kind: "dynKeyGet",
802
+ value: lowerer.coerceToExpected(receiver, DYN),
803
+ key: { kind: "strLit", value: "constructor", type: STRING, loc },
804
+ type: DYN,
805
+ loc,
806
+ };
807
+ }
808
+ }
809
+ // A plain record's inherited Object.prototype members READ as values
810
+ // (`o.constructor`, `o.valueOf`, `({}).toString`, the isPlainObject and
811
+ // deep-equal idioms): the record boxes into its dynamic view, whose
812
+ // read answers the interned Object constructor and Object.prototype
813
+ // methods — the same values `Object` and `Object.prototype.valueOf`
814
+ // read, so identity comparisons are exact. Calls keep their own
815
+ // lowerings; a record declaring the name reads its field.
816
+ if (OBJECT_PROTOTYPE_VALUE_READS.has(expr.name.text) &&
817
+ !isCalleeOf(expr) &&
818
+ // `X.prototype.toString` keeps the builtin prototype-method lowering.
819
+ !(ts.isPropertyAccessExpression(expr.expression) && expr.expression.name.text === "prototype")) {
820
+ const receiver = tryLowerExpression(lowerer, expr.expression);
821
+ const name = expr.name.text;
822
+ const shape = receiver?.type.kind === "record" ? lowerer.shapes.get(receiver.type.shapeId) : undefined;
823
+ const info = receiver?.type.kind === "object" ? lowerer.classes.get(receiver.type.className) : undefined;
824
+ const inherits = receiver?.type.kind === "dyn" ||
825
+ (shape !== undefined && !shape.tuple && !shape.fields.some((field) => field.name === name)) ||
826
+ (info !== undefined &&
827
+ name !== "constructor" &&
828
+ !info.fields.has(name) &&
829
+ !lowerer.findMethodOn(info, name) &&
830
+ !lowerer.findMethodOn(info, `get:${name}`));
831
+ if (receiver !== null && receiver !== undefined && inherits) {
832
+ return {
833
+ kind: "dynKeyGet",
834
+ value: lowerer.coerceToExpected(receiver, DYN),
835
+ key: { kind: "strLit", value: name, type: STRING, loc },
836
+ type: DYN,
837
+ loc,
838
+ };
839
+ }
840
+ }
841
+ // `f.name` / `f.length` / own properties on a FUNCTION-typed JS
842
+ // value (the mustCall wrapper's function-instance members): read
843
+ // through the dyn box — the closure's own-property table answers
844
+ // first (defineProperties writes land there), then the box's
845
+ // best-effort static name and the declared arity; anything else is
846
+ // the own-property answer, undefined. Function.prototype METHOD
847
+ // names stay fenced (a stored-member undefined would mis-answer
848
+ // `f.call` as a value). Static callable values keep the existing TS fence; checked callable
849
+ // storage can expose its own name and length in both source languages.
850
+ if (!["apply", "bind", "call", "toString", "caller", "arguments"].includes(expr.name.text) &&
851
+ (isJsSourceFile(ts.getSourceFileOfNode(expr)) ||
852
+ expr.name.text === "name" ||
853
+ expr.name.text === "length" ||
854
+ expr.name.text === "constructor")) {
855
+ const probed = tryLowerExpression(lowerer, expr.expression);
856
+ // Inferred callable returns can use checked storage even when the
857
+ // checker still describes a function. Read its actual dyn value;
858
+ // the ambient Function member must not hide its own properties.
859
+ const receiverType = lowerer.typeOf(expr.expression);
860
+ const receiverSymbol = receiverType.getSymbol();
861
+ const checkedFunction = lowerer.checker.getCallSignatures(receiverType).length > 0 ||
862
+ (receiverSymbol !== undefined &&
863
+ ts.symbolName(receiverSymbol) === "Function" &&
864
+ lowerer.isStdlibSymbol(receiverSymbol));
865
+ if (probed?.type.kind === "dyn" && checkedFunction) {
866
+ const key = {
867
+ kind: "strLit",
868
+ value: expr.name.text,
869
+ type: STRING,
870
+ loc: locOf(expr.name),
871
+ };
872
+ const opt = hasOptionalChainGuard(expr.expression, lowerer);
873
+ return lowerer.maybeNarrow({
874
+ kind: "dynKeyGet",
875
+ key,
876
+ value: probed,
877
+ ...(opt ? { optional: true } : {}),
878
+ type: DYN,
879
+ loc,
880
+ }, expr);
881
+ }
882
+ if ((isJsSourceFile(ts.getSourceFileOfNode(expr)) || expr.name.text === "constructor") &&
883
+ probed?.type.kind === "func" &&
884
+ canBoxFuncIntoDyn(probed.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
885
+ const fnName = jsFuncNameOf(expr.expression);
886
+ const boxed = {
887
+ kind: "dynFrom",
888
+ value: probed,
889
+ type: DYN,
890
+ ...(fnName !== null ? { fnName } : {}),
891
+ loc,
892
+ };
893
+ const key = {
894
+ kind: "strLit",
895
+ value: expr.name.text,
896
+ type: STRING,
897
+ loc: locOf(expr.name),
898
+ };
899
+ return lowerer.maybeNarrow({ kind: "dynKeyGet", key, value: boxed, type: DYN, loc }, expr);
900
+ }
901
+ }
902
+ // A NARROWED IteratorResult receiver (`if (!r.done) r.value` — the
903
+ // checker narrows to IteratorYieldResult/IteratorReturnResult, whose
904
+ // own type cannot map: the shared record shape needs BOTH channels):
905
+ // the receiver's LOWERED record still carries the field, so the read
906
+ // is an ordinary recordGet — maybeNarrow then bridges the union slot
907
+ // to the checker's narrowed arm, exactly like a union field read.
908
+ if (expr.name.text === "done" || expr.name.text === "value") {
909
+ const receiverType = lowerer.typeOf(expr.expression);
910
+ const recvSym = ts.symbolNameOf(receiverType.getAliasSymbol()) === "IteratorResult"
911
+ ? receiverType.getAliasSymbol()
912
+ : receiverType.getSymbol();
913
+ if (((recvSym !== undefined && ts.symbolName(recvSym) === "IteratorResult") ||
914
+ (recvSym !== undefined && ts.symbolName(recvSym) === "IteratorYieldResult") ||
915
+ (recvSym !== undefined && ts.symbolName(recvSym) === "IteratorReturnResult")) &&
916
+ recvSym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isTypeAliasDeclaration(d)) &&
917
+ lowerer.isStdlibFile(ts.getSourceFileOfNode(d)))) {
918
+ const recv = lowerer.lowerExpr(expr.expression);
919
+ if (recv.type.kind === "dyn")
920
+ return lowerer.maybeNarrow({
921
+ kind: "dynKeyGet",
922
+ value: recv,
923
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
924
+ type: DYN,
925
+ loc,
926
+ }, expr);
927
+ if (recv.type.kind === "record") {
928
+ const shape = lowerer.shapes.get(recv.type.shapeId);
929
+ const field = shape?.fields.find((f) => f.name === expr.name.text);
930
+ if (field) {
931
+ const read = {
932
+ kind: "recordGet",
933
+ obj: recv,
934
+ shapeId: recv.type.shapeId,
935
+ field: field.name,
936
+ type: field.type,
937
+ loc,
938
+ };
939
+ return iteratorResultValueRead(lowerer, read, expr) ?? lowerer.maybeNarrow(read, expr);
940
+ }
941
+ }
942
+ }
943
+ }
944
+ // A chain rooted at an initializer-less ambient `declare const/var`
945
+ // whose declared type has NO mapping (mappable roots compose through
946
+ // the bare-read undefRead and never reach here): Node throws the
947
+ // catchable ReferenceError at the ROOT read before any member
948
+ // matters, so the whole access lowers to that throw — typed by the
949
+ // use site, or by the context it flows into (the throw never
950
+ // returns, so the dummy is never observed).
951
+ {
952
+ const ambientRoot = ambientUndefVarRootOf(lowerer, expr);
953
+ if (ambientRoot !== null) {
954
+ const t = ambientUndefReadType(lowerer, expr) ?? contextualUndefReadType(lowerer, expr);
955
+ if (t)
956
+ return nsUndefRead(lowerer, ambientRoot.text, expr, t);
957
+ }
958
+ }
959
+ // Checked-dynamic stdlib results retain ambient property symbols,
960
+ // including parseArgs tokens narrowed to anonymous union arms. Only
961
+ // members owned by these implemented families bypass the stdlib fence.
962
+ const segmentDataSymbol = lowerer.typeOf(expr.expression).getSymbol();
963
+ const segmentDataProperty = segmentDataSymbol !== undefined &&
964
+ ts.symbolName(segmentDataSymbol) === "SegmentData" &&
965
+ lowerer.isStdlibSymbol(segmentDataSymbol) &&
966
+ ["segment", "index", "input", "isWordLike"].includes(expr.name.text);
967
+ // os.constants members vary by platform (the declared groups list
968
+ // every platform's names): a number member reads as `number |
969
+ // undefined`, like an array element, and a group stays checked.
970
+ const osConstants = isOsConstantsType(lowerer.typeOf(expr.expression), lowerer);
971
+ if (isParseArgsDynProperty(lowerer, expr) ||
972
+ isStatFsDynProperty(lowerer, expr) ||
973
+ segmentDataProperty ||
974
+ osConstants ||
975
+ isLegacyUrlSymbol(lowerer.checker.getSymbolAtLocation(expr.name), lowerer)) {
976
+ const recv = lowerer.lowerExpr(expr.expression);
977
+ if (recv.type.kind === "dyn") {
978
+ const key = {
979
+ kind: "strLit",
980
+ value: expr.name.text,
981
+ type: STRING,
982
+ loc: locOf(expr.name),
983
+ };
984
+ const opt = hasOptionalChainGuard(expr.expression, lowerer);
985
+ const read = {
986
+ kind: "dynKeyGet",
987
+ key,
988
+ ...(opt ? { optional: true } : {}),
989
+ value: recv,
990
+ type: DYN,
991
+ loc,
992
+ };
993
+ if (osConstants) {
994
+ return lowerer.mapTypeOf(lowerer.typeOf(expr))?.kind === "f64"
995
+ ? lowerer.coerceToExpected(read, lowerer.withUndefinedArm(F64))
996
+ : read;
997
+ }
998
+ return lowerer.maybeNarrow(read, expr);
999
+ }
1000
+ }
1001
+ // A member read through a NULLISH generic binding (`const i: I<A &
1002
+ // B> = null as any; const _i: I<A> = i.something` — the receiver
1003
+ // provably holds null/undefined forever): the read throws Node's
1004
+ // exact TypeError at the access.
1005
+ if (ts.isIdentifier(expr.expression) && expr.questionDotToken === undefined) {
1006
+ const unit = nullishGenericBindingUnitOf(lowerer, lowerer.resolveValueSymbol(expr.expression));
1007
+ if (unit !== null) {
1008
+ const t = ambientUndefReadType(lowerer, expr) ?? contextualUndefReadType(lowerer, expr) ?? F64;
1009
+ return nodeThrowExpr(1, "", `Cannot read properties of ${unit} (reading '${expr.name.text}')`, t, loc);
1010
+ }
1011
+ }
1012
+ // A stdlib-declared member (`message` of an interface extending Error)
1013
+ // on a catch binding narrowed to a structural type: the binding reads
1014
+ // as its checked-dynamic value, so the member does too.
1015
+ if (!expr.questionDotToken && lowerer.caughtLocalOf(expr.expression)) {
1016
+ const recv = lowerer.lowerExpr(expr.expression);
1017
+ if (recv.kind === "caughtToDyn") {
1018
+ const read = {
1019
+ kind: "dynKeyGet",
1020
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
1021
+ value: recv,
1022
+ type: DYN,
1023
+ loc,
1024
+ };
1025
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(expr));
1026
+ return declared && declared.kind !== "void" ? lowerer.coerceToExpected(read, declared) : read;
1027
+ }
1028
+ }
1029
+ // The lib fence's PROPERTY chokepoint: a stdlib-declared member that
1030
+ // no lowering above claimed ([1,2].entries, Math.SQRT2, Promise.all,
1031
+ // re.exec as a value, ...) reports SC2020 here.
1032
+ lowerer.stdlibMemberFence(expr);
1033
+ // The npm chokepoint: a member on a package-typed receiver in a
1034
+ // static build — attributed to the package, like every other site.
1035
+ lowerer.npmMemberFence(expr);
1036
+ // A property read rooted at a BLOCKED binding: the declaration
1037
+ // carries the real diagnostic — the SC2004 cascade, not a generic
1038
+ // "property access" rejection.
1039
+ {
1040
+ let root = expr.expression;
1041
+ while (ts.isPropertyAccessExpression(root))
1042
+ root = root.expression;
1043
+ if (ts.isIdentifier(root) && lowerer.isBlockedBinding(lowerer.resolveValueSymbol(root))) {
1044
+ lowerer.pushDiag(blockedBindingUseDiag(root.text, loc));
1045
+ throw new PoisonError();
1046
+ }
1047
+ }
1048
+ // Nothing claimed the member. Lower the RECEIVER before rejecting:
1049
+ // when the receiver itself is the blocker (`(await import(x)).y` —
1050
+ // the dynamic import is the unsupported part), ITS diagnostic is the
1051
+ // honest one, not a generic recitation about the outer dot. A
1052
+ // receiver that lowers cleanly means the MEMBER is the gap — name
1053
+ // the property and the receiver's type instead of "property access".
1054
+ const recvLowered = lowerer.lowerExpr(expr.expression);
1055
+ // A dyn receiver — JSON.parse's `any`, or `unknown` the checker
1056
+ // narrowed to `object` — reads through the dyn keyed read: member
1057
+ // or undefined (JS's own-property answer), throwing JS's TypeError
1058
+ // on undefined/null receivers unless an earlier `?.` guards the
1059
+ // chain. Scalar-narrowed occurrences bridge via maybeNarrow's
1060
+ // validated dynCheck as usual.
1061
+ if (recvLowered.type.kind === "dyn" ||
1062
+ (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
1063
+ (["f64", "bool", "bigint", "string", "symbol"].includes(recvLowered.type.kind) ||
1064
+ (recvLowered.type.kind === "union" && lowerer.dynConvertible(recvLowered.type))))) {
1065
+ const key = {
1066
+ kind: "strLit",
1067
+ value: expr.name.text,
1068
+ type: STRING,
1069
+ loc: locOf(expr.name),
1070
+ };
1071
+ const opt = hasOptionalChainGuard(expr.expression, lowerer);
1072
+ return lowerer.maybeNarrow({
1073
+ kind: "dynKeyGet",
1074
+ key,
1075
+ ...(opt ? { optional: true } : {}),
1076
+ value: lowerer.coerceToExpected(recvLowered, DYN),
1077
+ type: DYN,
1078
+ loc,
1079
+ }, expr);
1080
+ }
1081
+ // The lowered receiver is a RECORD the checker spelled wider —
1082
+ // `s.match(re).groups.key` in a JS file: the checker says
1083
+ // `{ [key: string]: string } | undefined`, but the groups
1084
+ // projection already answered the record arm (its null trap
1085
+ // included). Declared fields read directly; an index-signature
1086
+ // shape serves undeclared keys through the overflow read, exactly
1087
+ // the dot-access rule on checker-spelled hybrids.
1088
+ if (recvLowered.type.kind === "record") {
1089
+ const recvShape = lowerer.shapes.get(recvLowered.type.shapeId);
1090
+ const field = recvShape?.fields.find((f) => f.name === expr.name.text);
1091
+ if (field) {
1092
+ return lowerer.maybeNarrow({
1093
+ kind: "recordGet",
1094
+ obj: recvLowered,
1095
+ shapeId: recvLowered.type.shapeId,
1096
+ field: field.name,
1097
+ type: field.type,
1098
+ loc,
1099
+ }, expr);
1100
+ }
1101
+ if (recvShape?.indexValue !== undefined && !recvShape.tuple) {
1102
+ return lowerer.maybeNarrow({
1103
+ kind: "recordKeyGet",
1104
+ obj: recvLowered,
1105
+ shapeId: recvLowered.type.shapeId,
1106
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
1107
+ overflowOnly: true,
1108
+ type: recvShape.indexValue,
1109
+ loc,
1110
+ }, expr);
1111
+ }
1112
+ // An inferred package-JS call specializes a parameter to the
1113
+ // caller's own record shape. Optional option names omitted by that
1114
+ // caller read undefined; the missing field is not a failed type
1115
+ // assertion. Known prototype members were handled/fenced above.
1116
+ if (recvShape &&
1117
+ !recvShape.tuple &&
1118
+ lowerer.implicitParamTypes !== null &&
1119
+ isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
1120
+ npmStaticPackageOfPath(ts.getSourceFileOfNode(expr).fileName) !== null) {
1121
+ return {
1122
+ kind: "seqExpr",
1123
+ stmts: [{ kind: "exprStmt", expr: recvLowered, loc }],
1124
+ result: dynUndefinedExpr(loc),
1125
+ type: DYN,
1126
+ loc,
1127
+ };
1128
+ }
1129
+ }
1130
+ // An ABSTRACT property through an abstract-typed receiver: the
1131
+ // declaration is erased at runtime — Node defines no field for it,
1132
+ // each concrete subclass declares its OWN (at its own layout
1133
+ // position), so no shared base slot exists to read. Abstract
1134
+ // ACCESSORS are the supported spelling: they declare a vtable slot.
1135
+ if (recvLowered.type.kind === "object" && abstractPropertyDeclOf(lowerer, expr)) {
1136
+ lowerer.unsupported("SC1090", expr, `reading the abstract property '${expr.name.text}' through a '${lowerer.checker.typeToString(lowerer.typeOf(expr.expression))}'-typed receiver (abstract property declarations are erased at runtime, so no shared slot exists — type the receiver as the concrete class, or declare an abstract getter instead)`);
1137
+ }
1138
+ // Array reads may add an undefined arm even when the checker still
1139
+ // reports a class. Its property bag must remain reachable, while
1140
+ // an absent element takes the normal checked-value TypeError.
1141
+ const nativeReceiver = lowerer.stripUndefinedArm(recvLowered.type);
1142
+ if (ts.isPrivateIdentifier(expr.name) && recvLowered.type.kind === "object") {
1143
+ const field = lowerer.classes.get(recvLowered.type.className)?.fields.get(expr.name.text);
1144
+ if (field)
1145
+ return {
1146
+ kind: "fieldGet",
1147
+ obj: recvLowered,
1148
+ className: recvLowered.type.className,
1149
+ field: expr.name.text,
1150
+ type: field,
1151
+ loc,
1152
+ };
1153
+ }
1154
+ if (nativeReceiver.kind === "object" && nativeReceiver.className === "%Error") {
1155
+ return lowerer.maybeNarrow({
1156
+ kind: "dynKeyGet",
1157
+ value: lowerer.coerceToExpected(recvLowered, DYN),
1158
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
1159
+ type: DYN,
1160
+ loc,
1161
+ }, expr);
1162
+ }
1163
+ if (isDynTypedRefType(nativeReceiver)) {
1164
+ const info = lowerer.classes.get(nativeReceiver.className);
1165
+ if (info &&
1166
+ !info.def.runtime &&
1167
+ !info.builtinError &&
1168
+ !info.builtinEmitter &&
1169
+ !info.builtinStream) {
1170
+ return lowerer.maybeNarrow({
1171
+ kind: "dynKeyGet",
1172
+ value: lowerer.coerceToExpected(recvLowered, DYN),
1173
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
1174
+ type: DYN,
1175
+ loc,
1176
+ }, expr);
1177
+ }
1178
+ }
1179
+ // A member a JavaScript module attached to one of its functions
1180
+ // (`status.message = codes; module.exports = status`), read from
1181
+ // TypeScript: JavaScript stores such members on the function's own
1182
+ // property table (`fn.member = v` writes through the function's
1183
+ // checked-dynamic face), so the read takes the same path and enters
1184
+ // the static code at the type inference gave the member.
1185
+ if (recvLowered.type.kind === "func" && jsFunctionExpandoMember(lowerer, expr)) {
1186
+ const read = {
1187
+ kind: "dynKeyGet",
1188
+ value: lowerer.coerceToExpected(recvLowered, DYN),
1189
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
1190
+ type: DYN,
1191
+ loc,
1192
+ };
1193
+ const mapped = lowerer.mapTypeOf(lowerer.typeOf(expr));
1194
+ return mapped && mapped.kind !== "void" ? lowerer.coerceInto(expr, read, mapped) : read;
1195
+ }
1196
+ const asserted = assertedMemberRead(lowerer, expr, recvLowered, loc);
1197
+ if (asserted)
1198
+ return asserted;
1199
+ // A checker-`any` receiver whose value is a FRESH typed result of an
1200
+ // earlier step in the chain (`out.split(" ").length`, where split
1201
+ // extracted the string and answered a native string[]): the member read
1202
+ // goes through the boxed checked-dynamic value, as the method-call twin
1203
+ // does. The box copies; a call result has no other holder to observe it.
1204
+ if ((lowerer.typeOf(expr.expression).flags & ts.TypeFlags.Any) !== 0 &&
1205
+ isFreshCallResult(expr.expression) &&
1206
+ lowerer.dynConvertible(recvLowered.type)) {
1207
+ return lowerer.maybeNarrow({
1208
+ kind: "dynKeyGet",
1209
+ value: lowerer.coerceToExpected(recvLowered, DYN),
1210
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
1211
+ type: DYN,
1212
+ loc,
1213
+ }, expr);
1214
+ }
1215
+ const childProperty = lowerChildPropertyRead(lowerer, expr);
1216
+ if (childProperty)
1217
+ return childProperty;
1218
+ // A member a typed array's type does not declare (a JavaScript read, or
1219
+ // one under @ts-ignore), such as the feature probe `typeof bytes.toHex`:
1220
+ // when Node's prototype chain for the value lacks the name too, the read
1221
+ // answers undefined, as GetV does there. Names Node has keep the fence.
1222
+ // The element size reads the same way where the checker's type of the
1223
+ // receiver no longer names a typed array (`a instanceof Uint8Array ||
1224
+ // a.BYTES_PER_ELEMENT === 1`, whose right side narrows `a` to never).
1225
+ if (recvLowered.type.kind === "bytes" && expr.name.text === "BYTES_PER_ELEMENT") {
1226
+ return afterReceiver(recvLowered, numLit(BYTES_ELEMENT_SIZE[recvLowered.type.elem], loc), loc);
1227
+ }
1228
+ if (recvLowered.type.kind === "bytes" &&
1229
+ !declaredMemberOf(lowerer, expr.expression, expr.name.text) &&
1230
+ typedArrayLacksMember(expr.name.text, recvLowered.type.elem === "u8")) {
1231
+ return afterReceiver(recvLowered, dynUndefinedExpr(loc), loc);
1232
+ }
1233
+ lowerer.unsupported("SC1090", expr, `reading '${expr.name.text}' from a value of type '${lowerer.checker.typeToString(lowerer.typeOf(expr.expression))}'`);
1234
+ }
1235
+ /** `result` after evaluating `receiver` for its effects (none to keep when
1236
+ * the read is safe to discard). */
1237
+ function afterReceiver(receiver, result, loc) {
1238
+ if (isSafeToDiscard(receiver))
1239
+ return result;
1240
+ return {
1241
+ kind: "seqExpr",
1242
+ stmts: [{ kind: "exprStmt", expr: receiver, loc }],
1243
+ result,
1244
+ type: result.type,
1245
+ loc,
1246
+ };
1247
+ }
1248
+ /** A call expression, through parentheses: its value has no other holder. */
1249
+ function isFreshCallResult(node) {
1250
+ let e = node;
1251
+ while (ts.isParenthesizedExpression(e))
1252
+ e = e.expression;
1253
+ return ts.isCallExpression(e);
1254
+ }
1255
+ /** `(source as { repoName: string }).repoName` where the assertion names a
1256
+ * member some arms of the stored union of records do not declare: Node
1257
+ * reads the property off whichever object it is, so arms that declare it
1258
+ * answer their slot, and the others answer undefined (native records are
1259
+ * closed, so they cannot hold it). The result keeps that undefined arm
1260
+ * whatever the assertion claims; a consumer that needs the asserted type
1261
+ * checks it like any other narrowing. The arms that declare the member
1262
+ * must agree on its type. Null when the receiver is not such an
1263
+ * assertion over records, or no arm declares the member. */
1264
+ function assertedMemberRead(lowerer, expr, recv, loc) {
1265
+ let receiverNode = expr.expression;
1266
+ while (ts.isParenthesizedExpression(receiverNode))
1267
+ receiverNode = receiverNode.expression;
1268
+ if (!ts.isAsExpression(receiverNode) && !ts.isTypeAssertion(receiverNode))
1269
+ return null;
1270
+ if (recv.type.kind !== "union")
1271
+ return null;
1272
+ const unionId = recv.type.unionId;
1273
+ const arms = lowerer.unions.get(unionId)?.arms ?? [];
1274
+ const name = expr.name.text;
1275
+ let resultType = null;
1276
+ let records = 0;
1277
+ const declaring = [];
1278
+ const units = [];
1279
+ for (let tag = 0; tag < arms.length; tag++) {
1280
+ const arm = arms[tag];
1281
+ if (isUnitType(arm)) {
1282
+ units.push(tag);
1283
+ continue;
1284
+ }
1285
+ if (arm.kind !== "record")
1286
+ return null;
1287
+ records++;
1288
+ const shape = lowerer.shapes.get(arm.shapeId);
1289
+ if (!shape || shape.tuple || shape.indexValue)
1290
+ return null;
1291
+ const field = shape.fields.find((f) => f.name === name);
1292
+ if (!field)
1293
+ continue;
1294
+ // The declaring arms agree up to an undefined arm (`string` beside
1295
+ // `string | undefined`).
1296
+ const armResult = lowerer.withUndefinedArmOf(field.type);
1297
+ if (!armResult || (resultType && !typeEquals(resultType, armResult)))
1298
+ return null;
1299
+ resultType = armResult;
1300
+ declaring.push({ tag, shapeId: arm.shapeId, type: field.type });
1301
+ }
1302
+ if (!resultType || declaring.length === records)
1303
+ return null;
1304
+ const stable = lowerer.declareHiddenLocal("%assertedRecv", recv.type);
1305
+ const ref = () => ({ kind: "varRef", localId: stable.id, type: recv.type, loc });
1306
+ let result = lowerer.wrappedUndefined(resultType, loc);
1307
+ if (!result)
1308
+ return null;
1309
+ // A unit arm the checker narrowed away reads like Node would read it.
1310
+ for (const tag of units) {
1311
+ const unit = arms[tag].kind === "nullT" ? "null" : "undefined";
1312
+ result = {
1313
+ kind: "ternary",
1314
+ cond: { kind: "unionIsTag", unionId, tag, negated: false, value: ref(), type: BOOL, loc },
1315
+ then: nodeThrowExpr(1, "", `Cannot read properties of ${unit} (reading '${name}')`, resultType, loc),
1316
+ else_: result,
1317
+ type: resultType,
1318
+ loc,
1319
+ };
1320
+ }
1321
+ for (const { tag, shapeId, type: fieldType } of declaring) {
1322
+ const read = {
1323
+ kind: "recordGet",
1324
+ obj: { kind: "unionNarrow", unionId, tag, value: ref(), type: arms[tag], loc },
1325
+ shapeId,
1326
+ field: name,
1327
+ type: fieldType,
1328
+ loc,
1329
+ };
1330
+ result = {
1331
+ kind: "ternary",
1332
+ cond: { kind: "unionIsTag", unionId, tag, negated: false, value: ref(), type: BOOL, loc },
1333
+ then: lowerer.coerceToExpected(read, resultType),
1334
+ else_: result,
1335
+ type: resultType,
1336
+ loc,
1337
+ };
1338
+ }
1339
+ return {
1340
+ kind: "seqExpr",
1341
+ stmts: [{ kind: "varDecl", localId: stable.id, init: recv, loc }],
1342
+ result,
1343
+ type: resultType,
1344
+ loc,
1345
+ };
1346
+ }
1347
+ function importMetaProperty(lowerer, expr) {
1348
+ return isImportMeta(expr.expression) ? importMetaField(lowerer, expr, expr.name.text) : null;
1349
+ }
1350
+ /** The TypeError of a deferred-init field read that finds the field
1351
+ * unassigned where its declared type cannot hold undefined. */
1352
+ export const DEFERRED_READ_MESSAGE = "undefined is not representable in the target union (a value narrowed or asserted past it still held it)";
1353
+ /** Property access on a string or array receiver: `.length` lowers to the
1354
+ * matching intrinsic; a bare method reference (`const f = s.slice` — a
1355
+ * function value) is rejected with a specific message. Returns null for
1356
+ * other receivers (the generic property-access rejection applies). Both
1357
+ * the receiver type AND the ambient-file provenance of the member are
1358
+ * verified — the name alone proves nothing. */
1359
+ export function lowerIntrinsicProperty(lowerer, expr) {
1360
+ for (const name of ["String", "Number", "Boolean", "BigInt"]) {
1361
+ if (!lowerer.chainBlocked(expr) && lowerer.isStdlibGlobal(expr, name)) {
1362
+ return primitiveCtorClosure(lowerer, name, locOf(expr), isJsSourceFile(ts.getSourceFileOfNode(expr)));
1363
+ }
1364
+ }
1365
+ if (lowerer.stdlibGlobalMember(expr, "Reflect") === "ownKeys") {
1366
+ const value = lowerer.lowerNativeCallableValue({
1367
+ fn: "dyn.ownKeys",
1368
+ params: [DYN],
1369
+ result: DYN,
1370
+ valueParams: [{ mode: "required", type: DYN }],
1371
+ }, "Reflect.ownKeys", locOf(expr));
1372
+ return { kind: "dynFrom", value, fnName: "ownKeys", type: DYN, loc: locOf(expr) };
1373
+ }
1374
+ if (lowerer.chainBlocked(expr))
1375
+ return null;
1376
+ // Object.prototype.constructor: the Object constructor value.
1377
+ if (expr.name.text === "constructor" &&
1378
+ ts.isPropertyAccessExpression(expr.expression) &&
1379
+ lowerer.stdlibGlobalMember(expr.expression, "Object") === "prototype")
1380
+ return builtinGlobalValue("Object", locOf(expr));
1381
+ const builtinPrototype = builtinPrototypeMethod(lowerer, expr);
1382
+ if (builtinPrototype)
1383
+ return {
1384
+ kind: "libCall",
1385
+ fn: "dyn.builtinMethod",
1386
+ args: [
1387
+ { kind: "strLit", value: builtinPrototype, type: STRING, loc: locOf(expr) },
1388
+ { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
1389
+ ],
1390
+ type: DYN,
1391
+ loc: locOf(expr),
1392
+ };
1393
+ if (ts.isPropertyAccessExpression(expr.expression) &&
1394
+ lowerer.stdlibGlobalMember(expr.expression, "Array") === "prototype") {
1395
+ return {
1396
+ kind: "dynKeyGet",
1397
+ value: {
1398
+ kind: "libCall",
1399
+ fn: "dyn.arrayPrototype",
1400
+ args: [],
1401
+ type: DYN,
1402
+ loc: locOf(expr.expression),
1403
+ },
1404
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
1405
+ type: DYN,
1406
+ loc: locOf(expr),
1407
+ };
1408
+ }
1409
+ if (expr.name.text === "apply" &&
1410
+ ts.isPropertyAccessExpression(expr.expression) &&
1411
+ lowerer.stdlibGlobalMember(expr.expression, "Function") === "prototype")
1412
+ return { kind: "libCall", fn: "dyn.functionApply", args: [], type: DYN, loc: locOf(expr) };
1413
+ if (lowerer.stdlibGlobalMember(expr, "Array") === "prototype")
1414
+ return { kind: "libCall", fn: "dyn.arrayPrototype", args: [], type: DYN, loc: locOf(expr) };
1415
+ if (lowerer.stdlibGlobalMember(expr, "Object") === "prototype")
1416
+ return { kind: "libCall", fn: "dyn.objectPrototype", args: [], type: DYN, loc: locOf(expr) };
1417
+ // Function.prototype as a VALUE (a prototype-chain link:
1418
+ // `Object.setPrototypeOf(F.prototype, Function.prototype)`): one
1419
+ // anonymous function answering undefined, length 0 — a zero-capture
1420
+ // closure of a compiler helper, so every read is the same function
1421
+ // (closure identity) and shares its property table. Reads through it
1422
+ // find the function members the checked runtime models for every
1423
+ // function (apply, constructor, name, length). Member forms keep their
1424
+ // own lowerings.
1425
+ if (lowerer.stdlibGlobalMember(expr, "Function") === "prototype") {
1426
+ const loc = locOf(expr);
1427
+ const name = "%dyn.functionPrototype";
1428
+ if (!lowerer.liftedFns.some((fn) => fn.name === name))
1429
+ lowerer.liftedFns.push({
1430
+ name,
1431
+ params: [],
1432
+ locals: [],
1433
+ returnType: DYN,
1434
+ body: [{ kind: "return", value: dynUndefinedExpr(loc), loc }],
1435
+ loc,
1436
+ });
1437
+ return {
1438
+ kind: "dynFrom",
1439
+ value: { kind: "closure", fnName: name, captures: [], type: funcOf([], DYN), loc },
1440
+ fnName: "",
1441
+ type: DYN,
1442
+ loc,
1443
+ };
1444
+ }
1445
+ if (lowerer.stdlibGlobalMember(expr, "Array") === "isArray")
1446
+ return lowerArrayIsArrayValue(lowerer, locOf(expr));
1447
+ if (lowerer.stdlibGlobalMember(expr, "Array") === "from")
1448
+ return lowerArrayFromValue(lowerer, locOf(expr));
1449
+ const stringMember = lowerer.stdlibGlobalMember(expr, "String");
1450
+ if (stringMember === "fromCharCode" || stringMember === "fromCodePoint")
1451
+ return lowerStringCodesValue(lowerer, stringMember, locOf(expr));
1452
+ const numberMember = lowerer.stdlibGlobalMember(expr, "Number");
1453
+ if (numberMember === "parseInt" || numberMember === "parseFloat")
1454
+ return lowerNumberParserValue(lowerer, numberMember, locOf(expr));
1455
+ if (lowerer.stdlibGlobalMember(expr, "Buffer") === "poolSize")
1456
+ return { kind: "libCall", fn: "buffer.poolSize", args: [], type: F64, loc: locOf(expr) };
1457
+ const netAddressStatic = lowerNetAddressStaticRead(lowerer, expr);
1458
+ if (netAddressStatic)
1459
+ return netAddressStatic;
1460
+ if (lowerer.stdlibGlobalMember(expr, "Buffer") === "isBuffer")
1461
+ return lowerCheckedPredicateValue(lowerer, "Buffer.isBuffer", "buffer", locOf(expr));
1462
+ // Buffer statics as function values (`Buffer.byteLength.bind(Buffer)` in
1463
+ // truncate-utf8-bytes): the checked forms take any argument as Node does.
1464
+ if (lowerer.stdlibGlobalMember(expr, "Buffer") === "byteLength")
1465
+ return lowerer.lowerNativeCallableValue({
1466
+ fn: "buffer.byteLenValue",
1467
+ params: [DYN, DYN],
1468
+ result: F64,
1469
+ valueParams: [
1470
+ { mode: "required", type: DYN },
1471
+ { mode: "optional", type: DYN, defaultValue: undefined },
1472
+ ],
1473
+ }, "Buffer.byteLength", locOf(expr));
1474
+ if (lowerer.stdlibGlobalMember(expr, "Buffer") === "alloc")
1475
+ return bufferAllocValue(lowerer, locOf(expr));
1476
+ if (lowerer.stdlibGlobalMember(expr, "Buffer") === "compare")
1477
+ return lowerer.lowerNativeCallableValue({
1478
+ fn: "buffer.compareChk",
1479
+ params: [DYN, DYN],
1480
+ result: F64,
1481
+ valueParams: [
1482
+ { mode: "required", type: DYN },
1483
+ { mode: "required", type: DYN },
1484
+ ],
1485
+ }, "Buffer.compare", locOf(expr));
1486
+ if (lowerer.stdlibGlobalMember(expr, "Date") === "now")
1487
+ return lowerer.lowerNativeCallableValue({
1488
+ fn: "date.now",
1489
+ params: [],
1490
+ result: F64,
1491
+ valueParams: [],
1492
+ }, "Date.now", locOf(expr));
1493
+ if (stdlibGlobalNameOf(lowerer, expr.expression) === "Object") {
1494
+ if (expr.name.text === "assign")
1495
+ return lowerObjectAssignValue(lowerer, locOf(expr));
1496
+ const fn = own(OBJECT_CALLABLE_VALUES, expr.name.text);
1497
+ if (fn)
1498
+ return lowerer.lowerNativeCallableValue(fn, `Object.${expr.name.text}`, locOf(expr));
1499
+ }
1500
+ // A never-tainted JS receiver type lowered checked-dynamic
1501
+ // (neverTaintedJsType — `cmd.length` on `const cmd = ['pwd', []]`):
1502
+ // stand down so the dyn keyed read below the chain answers, instead
1503
+ // of an array libCall over a dyn receiver hitting the boundary fence.
1504
+ let kind = neverTaintedJsType(lowerer, expr.expression, lowerer.typeOf(expr.expression))
1505
+ ? undefined
1506
+ : lowerer.mapTypeOf(lowerer.typeOf(expr.expression))?.kind;
1507
+ // A checker-`any[]` receiver (the readonly-array Array.isArray quirk)
1508
+ // whose VALUE lowers to a real static array (maybeNarrow's isArray
1509
+ // bridge): `.length` and friends ride the array path on the lowered
1510
+ // value (re-lowering is pure IR construction).
1511
+ if (kind === undefined && lowerer.checkerAnyArray(expr.expression)) {
1512
+ const probe = lowerer.lowerExpr(expr.expression);
1513
+ if (probe.type.kind === "array")
1514
+ kind = "array";
1515
+ }
1516
+ if (kind !== "string" &&
1517
+ kind !== "array" &&
1518
+ kind !== "map" &&
1519
+ kind !== "set" &&
1520
+ kind !== "f64" &&
1521
+ kind !== "date" &&
1522
+ kind !== "regex" &&
1523
+ kind !== "url" &&
1524
+ kind !== "searchParams" &&
1525
+ kind !== "stats" &&
1526
+ kind !== "spawnRes" &&
1527
+ kind !== "child" &&
1528
+ kind !== "bytes" &&
1529
+ kind !== "symbol") {
1530
+ return null;
1531
+ }
1532
+ // child receivers also admit the user's own child-shaped interface
1533
+ // members (the NgrokChildProcess duck rule — see isChildSurfaceMember).
1534
+ // The EMPTY tuple `[]` rides the array REPRESENTATION (type-mapper.ts), but
1535
+ // its `length` member is the tuple's own synthesized property, not
1536
+ // Array.prototype's — provenance alone would refuse it. It reads the
1537
+ // runtime length (always 0) through the array intrinsic like any other
1538
+ // array; non-empty tuples never reach here (they map to records and
1539
+ // fold their arity constant on the record path).
1540
+ const tupleLengthOnArray = kind === "array" &&
1541
+ expr.name.text === "length" &&
1542
+ lowerer.checker.isTupleType(lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(expr.expression)));
1543
+ if (kind === "child"
1544
+ ? !isChildSurfaceMember(lowerer, expr)
1545
+ : !tupleLengthOnArray && !lowerer.isStdlibMember(expr))
1546
+ return null;
1547
+ const name = expr.name.text;
1548
+ if (kind === "array" && name === "constructor" && isJsSourceFile(ts.getSourceFileOfNode(expr))) {
1549
+ const receiver = lowerer.lowerExpr(expr.expression);
1550
+ if (receiver.type.kind === "dyn")
1551
+ return {
1552
+ kind: "dynKeyGet",
1553
+ value: receiver,
1554
+ key: { kind: "strLit", value: name, type: STRING, loc: locOf(expr) },
1555
+ type: DYN,
1556
+ loc: locOf(expr),
1557
+ };
1558
+ const result = {
1559
+ kind: "libCall",
1560
+ fn: "dyn.arrayConstructor",
1561
+ args: [],
1562
+ type: DYN,
1563
+ loc: locOf(expr),
1564
+ };
1565
+ return {
1566
+ kind: "seqExpr",
1567
+ stmts: [{ kind: "exprStmt", expr: receiver, loc: locOf(expr) }],
1568
+ result,
1569
+ type: DYN,
1570
+ loc: locOf(expr),
1571
+ };
1572
+ }
1573
+ const strictReceiver = (expected) => {
1574
+ const value = lowerer.lowerExpr(expr.expression);
1575
+ if (value.type.kind === "dyn") {
1576
+ if (isJsSourceFile(ts.getSourceFileOfNode(expr)) && name === "length")
1577
+ return value;
1578
+ return lowerer.coerceInto(expr.expression, value, expected);
1579
+ }
1580
+ return lowerer.runtimeOptionalPropertyReceiver(expr.expression, value, expected, name) ?? value;
1581
+ };
1582
+ if (kind === "child") {
1583
+ const loc = locOf(expr);
1584
+ // The lifecycle reads, Node's exact shapes (SEMANTICS.md pins the
1585
+ // matrix): pid is `number | undefined` (undefined = spawn failure),
1586
+ // exitCode `number | null` (null while running and after a signal
1587
+ // death; -errno once a spawn failure settled), killed the
1588
+ // sent-a-signal flag. The unions build type-directedly in the
1589
+ // backend (the spawnRes.status pattern); a checker-narrowed read
1590
+ // extracts through maybeNarrow like any union member.
1591
+ if (name === "pid") {
1592
+ const receiver = lowerer.lowerExpr(expr.expression);
1593
+ const type = { kind: "union", unionId: lowerer.unions.intern([F64, UNDEFINED_T]) };
1594
+ return { kind: "libCall", fn: "child.pid", args: [receiver], type, loc };
1595
+ }
1596
+ if (name === "exitCode") {
1597
+ const receiver = lowerer.lowerExpr(expr.expression);
1598
+ const type = { kind: "union", unionId: lowerer.unions.intern([F64, NULL_T]) };
1599
+ return { kind: "libCall", fn: "child.exitCode", args: [receiver], type, loc };
1600
+ }
1601
+ if (name === "killed") {
1602
+ const receiver = lowerer.lowerExpr(expr.expression);
1603
+ return { kind: "libCall", fn: "child.killed", args: [receiver], type: BOOL, loc };
1604
+ }
1605
+ if (name === "on" || name === "once" || name === "kill" || name === "unref") {
1606
+ lowerer.unsupported("SC1090", expr, `child methods as values (call '${name}' directly)`);
1607
+ }
1608
+ lowerer.noLowering(`ChildProcess.${name}`, expr, 'on/once("exit" | "close" | "error", cb), pid, exitCode, killed, kill(signal?), and unref() are the supported ChildProcess members', lowerer.checker.getSymbolAtLocation(expr.name));
1609
+ }
1610
+ if (kind === "spawnRes") {
1611
+ // The spawnSync-result reads. status is the interned `number | null`
1612
+ // union (null = signal death or spawn failure); stdout/stderr are
1613
+ // the captured utf8 strings — under @types/node WITHOUT the
1614
+ // {encoding: "utf8"} options argument the checker types them Buffer,
1615
+ // which is re-fenced here (the call site already said so).
1616
+ const loc = locOf(expr);
1617
+ if (name === "status") {
1618
+ // Always the interned `number | null` union; a checker-NARROWED
1619
+ // read (`missing.status === null ? ... : ${missing.status}`)
1620
+ // bridges through maybeNarrow like any union read.
1621
+ const receiver = lowerer.lowerExpr(expr.expression);
1622
+ const type = { kind: "union", unionId: lowerer.unions.intern([F64, NULL_T]) };
1623
+ const read = { kind: "libCall", fn: "spawnRes.status", args: [receiver], type, loc };
1624
+ return lowerer.maybeNarrow(read, expr);
1625
+ }
1626
+ if (name === "stdout" || name === "stderr") {
1627
+ if (lowerer.mapTypeOf(lowerer.typeOf(expr))?.kind !== "string") {
1628
+ lowerer.noLowering(`spawnSync's ${name} without the "utf8" encoding`, expr, 'Buffer captures are not representable — call spawnSync(cmd, args, { encoding: "utf8" }) so the outputs are strings');
1629
+ }
1630
+ const receiver = lowerer.lowerExpr(expr.expression);
1631
+ const fn = name === "stdout" ? "spawnRes.stdout" : "spawnRes.stderr";
1632
+ return { kind: "libCall", fn, args: [receiver], type: STRING, loc };
1633
+ }
1634
+ if (name === "error") {
1635
+ // Node's spawn-failure carrier: `Error | undefined` — a fresh
1636
+ // %Error ("spawnSync <file> ENOENT", `code` stamped) when the
1637
+ // spawn itself failed, the undefined arm otherwise. The libCall
1638
+ // always carries the interned union (the declared `error?: Error`),
1639
+ // and a checker-NARROWED read (`if (r.error) r.error.message`)
1640
+ // bridges through maybeNarrow like any union read.
1641
+ const receiver = lowerer.lowerExpr(expr.expression);
1642
+ const type = lowerer.withUndefinedArmOf({ kind: "object", className: "%Error" });
1643
+ if (!type)
1644
+ lowerer.badType(expr, lowerer.typeOf(expr));
1645
+ const read = { kind: "libCall", fn: "spawnRes.error", args: [receiver], type, loc };
1646
+ return lowerer.maybeNarrow(read, expr);
1647
+ }
1648
+ lowerer.noLowering(`SpawnSyncReturns.${name}`, expr, "status, stdout, stderr, and error are the supported spawnSync-result members", lowerer.checker.getSymbolAtLocation(expr.name));
1649
+ }
1650
+ if (kind === "stats") {
1651
+ if (name === "size") {
1652
+ const receiver = lowerer.lowerExpr(expr.expression);
1653
+ return { kind: "libCall", fn: "stats.size", args: [receiver], type: F64, loc: locOf(expr) };
1654
+ }
1655
+ if (Object.hasOwn(STATS_TYPE_TESTS, name)) {
1656
+ lowerer.unsupported("SC1090", expr, `Stats methods as values (call '${name}' directly)`);
1657
+ }
1658
+ lowerer.noLowering(`Stats.${name}`, expr, "isFile(), isDirectory(), isSymbolicLink(), isBlockDevice(), isCharacterDevice(), isFIFO(), isSocket(), dev, mode, nlink, uid, gid, rdev, blksize, ino, size, blocks, atimeMs, mtimeMs, ctimeMs, birthtimeMs, atime, mtime, ctime, and birthtime are the supported Stats members", lowerer.checker.getSymbolAtLocation(expr.name));
1659
+ }
1660
+ if (kind === "date") {
1661
+ const methods = new Set([
1662
+ "getTime",
1663
+ "valueOf",
1664
+ "toISOString",
1665
+ "getFullYear",
1666
+ "getUTCFullYear",
1667
+ "getMonth",
1668
+ "getUTCMonth",
1669
+ "getDate",
1670
+ "getUTCDate",
1671
+ "getDay",
1672
+ "getUTCDay",
1673
+ "getHours",
1674
+ "getUTCHours",
1675
+ "getMinutes",
1676
+ "getUTCMinutes",
1677
+ "getSeconds",
1678
+ "getUTCSeconds",
1679
+ "getMilliseconds",
1680
+ "getUTCMilliseconds",
1681
+ "getTimezoneOffset",
1682
+ ]);
1683
+ if (methods.has(name)) {
1684
+ lowerer.unsupported("SC1090", expr, `Date methods as values (call '${name}' directly)`);
1685
+ }
1686
+ lowerer.noLowering(`Date.prototype.${name}`, expr, "getTime(), valueOf(), toISOString(), the local/UTC calendar getters, and getTimezoneOffset() are supported; Date setters and locale/string formatters have no lowering", lowerer.checker.getSymbolAtLocation(expr.name));
1687
+ }
1688
+ if (kind === "symbol") {
1689
+ const loc = locOf(expr);
1690
+ // `.description`: the checker's `string | undefined` — undefined
1691
+ // exactly for the description-less Symbol()/Symbol(undefined) forms
1692
+ // (Symbol("") answers the EMPTY STRING arm, like Node). The interned
1693
+ // union builds in the backend from the runtime's +1-or-NULL answer
1694
+ // (the child.stdout pattern); a checker-narrowed read extracts
1695
+ // through maybeNarrow like any union member.
1696
+ if (name === "description") {
1697
+ const receiver = lowerer.coerceToExpected(lowerer.lowerExpr(expr.expression), SYMBOL_T);
1698
+ const type = { kind: "union", unionId: lowerer.unions.intern([STRING, UNDEFINED_T]) };
1699
+ return { kind: "libCall", fn: "sym.desc", args: [receiver], type, loc };
1700
+ }
1701
+ if (name === "toString" || name === "valueOf") {
1702
+ lowerer.unsupported("SC1090", expr, `symbol methods as values (call '${name}' directly)`);
1703
+ }
1704
+ lowerer.noLowering(`Symbol.prototype.${name}`, expr, "description and toString() are the supported symbol members", lowerer.checker.getSymbolAtLocation(expr.name));
1705
+ }
1706
+ if (kind === "url") {
1707
+ // The supported URL getters. Everything else the lib declares
1708
+ // (searchParams, setters-as-reads, ...) fences with the
1709
+ // member-qualified name and the supported list. `host` is the WHATWG
1710
+ // serialization: lowercased hostname, `:port` appended exactly when
1711
+ // a non-default port is present (scr_url_host — Node-exact,
1712
+ // opaque-path URLs answer ""); `hostname` is the stored port-less
1713
+ // host field verbatim, including IPv6 brackets.
1714
+ if (name === "protocol" ||
1715
+ name === "origin" ||
1716
+ name === "username" ||
1717
+ name === "password" ||
1718
+ name === "pathname" ||
1719
+ name === "href" ||
1720
+ name === "host" ||
1721
+ name === "hostname" ||
1722
+ name === "port" ||
1723
+ name === "search" ||
1724
+ name === "hash") {
1725
+ const receiver = lowerer.lowerExpr(expr.expression);
1726
+ const fn = name === "protocol"
1727
+ ? "url.protocol"
1728
+ : name === "origin"
1729
+ ? "url.origin"
1730
+ : name === "username"
1731
+ ? "url.username"
1732
+ : name === "password"
1733
+ ? "url.password"
1734
+ : name === "pathname"
1735
+ ? "url.pathname"
1736
+ : name === "host"
1737
+ ? "url.host"
1738
+ : name === "hostname"
1739
+ ? "url.hostname"
1740
+ : name === "port"
1741
+ ? "url.port"
1742
+ : name === "search"
1743
+ ? "url.search"
1744
+ : name === "hash"
1745
+ ? "url.hash"
1746
+ : "url.href";
1747
+ return { kind: "libCall", fn, args: [receiver], type: STRING, loc: locOf(expr) };
1748
+ }
1749
+ // `u.searchParams`: the LIVE cached view (one identity per URL —
1750
+ // mutations through it re-serialize into the URL's query, so href
1751
+ // reflects immediately; Node's binding exactly).
1752
+ if (name === "searchParams") {
1753
+ const receiver = lowerer.lowerExpr(expr.expression);
1754
+ return {
1755
+ kind: "libCall",
1756
+ fn: "url.searchParams",
1757
+ args: [receiver],
1758
+ type: SEARCH_PARAMS_T,
1759
+ loc: locOf(expr),
1760
+ };
1761
+ }
1762
+ if (name === "toString" || name === "toJSON") {
1763
+ lowerer.unsupported("SC1090", expr, `URL methods as values (call '${name}' directly)`);
1764
+ }
1765
+ lowerer.noLowering(`URL.${name}`, expr, "protocol, origin, username, password, pathname, href, host, hostname, port, search, hash, searchParams, and toString() are the supported URL members", lowerer.checker.getSymbolAtLocation(expr.name));
1766
+ }
1767
+ if (kind === "searchParams") {
1768
+ const SEARCH_PARAMS_METHODS = new Set([
1769
+ "get",
1770
+ "getAll",
1771
+ "set",
1772
+ "append",
1773
+ "delete",
1774
+ "has",
1775
+ "sort",
1776
+ "toString",
1777
+ "forEach",
1778
+ "keys",
1779
+ "values",
1780
+ "entries",
1781
+ ]);
1782
+ // The one data property; every method lowers at its CALL
1783
+ // (lowerSearchParamsMethodCall) — bare method references fence.
1784
+ if (name === "size") {
1785
+ const receiver = lowerer.lowerExpr(expr.expression);
1786
+ return { kind: "libCall", fn: "sp.size", args: [receiver], type: F64, loc: locOf(expr) };
1787
+ }
1788
+ if (SEARCH_PARAMS_METHODS.has(name)) {
1789
+ lowerer.unsupported("SC1090", expr, `URLSearchParams methods as values (call '${name}' directly)`);
1790
+ }
1791
+ lowerer.noLowering(`URLSearchParams.${name}`, expr, "get, getAll, set, append, delete, has, sort, size, toString(), forEach, and for-of iteration are the supported URLSearchParams members", lowerer.checker.getSymbolAtLocation(expr.name));
1792
+ }
1793
+ if (kind === "regex") {
1794
+ if (name === "lastIndex") {
1795
+ return {
1796
+ kind: "regexIntrinsic",
1797
+ method: "lastIndex",
1798
+ receiver: strictReceiver({ kind: "regex" }),
1799
+ args: [],
1800
+ type: F64,
1801
+ loc: locOf(expr),
1802
+ };
1803
+ }
1804
+ if (name === "source" || name === "flags") {
1805
+ const receiver = strictReceiver({ kind: "regex" });
1806
+ return {
1807
+ kind: "regexIntrinsic",
1808
+ method: name,
1809
+ receiver,
1810
+ args: [],
1811
+ type: STRING,
1812
+ loc: locOf(expr),
1813
+ };
1814
+ }
1815
+ // The flag getters answer whether `flags` holds the flag's letter.
1816
+ const flag = REGEX_FLAG_GETTERS.get(name);
1817
+ if (flag !== undefined) {
1818
+ const loc = locOf(expr);
1819
+ const flags = {
1820
+ kind: "regexIntrinsic",
1821
+ method: "flags",
1822
+ receiver: strictReceiver({ kind: "regex" }),
1823
+ args: [],
1824
+ type: STRING,
1825
+ loc,
1826
+ };
1827
+ return {
1828
+ kind: "strIntrinsic",
1829
+ method: "includes",
1830
+ receiver: flags,
1831
+ args: [{ kind: "strLit", value: flag, type: STRING, loc }],
1832
+ type: BOOL,
1833
+ loc,
1834
+ };
1835
+ }
1836
+ if (name === "test") {
1837
+ lowerer.unsupported("SC1090", expr, "regex methods as values (call 'test' directly)");
1838
+ }
1839
+ return null;
1840
+ }
1841
+ if (kind === "f64") {
1842
+ if (own(STDLIB_SURFACE.number, name) !== undefined) {
1843
+ lowerer.unsupported("SC1090", expr, `number methods as values (call '${name}' directly)`);
1844
+ }
1845
+ return null;
1846
+ }
1847
+ if (kind === "bytes") {
1848
+ const loc = locOf(expr);
1849
+ if (name === "constructor") {
1850
+ const expected = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
1851
+ const receiver = expected?.kind === "bytes" ? strictReceiver(expected) : lowerer.lowerExpr(expr.expression);
1852
+ return {
1853
+ kind: "dynKeyGet",
1854
+ value: lowerer.coerceInto(expr.expression, receiver, DYN),
1855
+ key: { kind: "strLit", value: name, type: STRING, loc },
1856
+ type: DYN,
1857
+ loc,
1858
+ };
1859
+ }
1860
+ // The element size: a constant of the element kind (1 for a Buffer).
1861
+ if (name === "BYTES_PER_ELEMENT") {
1862
+ const expected = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
1863
+ const receiver = expected?.kind === "bytes" ? strictReceiver(expected) : lowerer.lowerExpr(expr.expression);
1864
+ if (receiver.type.kind === "bytes")
1865
+ return afterReceiver(receiver, numLit(BYTES_ELEMENT_SIZE[receiver.type.elem], loc), loc);
1866
+ }
1867
+ if (name === "length" || name === "byteLength") {
1868
+ const expected = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
1869
+ let receiver = expected?.kind === "bytes" ? strictReceiver(expected) : lowerer.lowerExpr(expr.expression);
1870
+ if (receiver.type.kind === "dyn")
1871
+ return {
1872
+ kind: "dynCheck",
1873
+ value: {
1874
+ kind: "dynKeyGet",
1875
+ value: receiver,
1876
+ key: { kind: "strLit", value: name, type: STRING, loc: locOf(expr) },
1877
+ type: DYN,
1878
+ loc: locOf(expr),
1879
+ },
1880
+ type: F64,
1881
+ loc: locOf(expr),
1882
+ };
1883
+ if (receiver.type.kind === "union" &&
1884
+ lowerer.armTag(receiver.type.unionId, UNDEFINED_T) >= 0) {
1885
+ const present = lowerer.stripUndefinedArm(receiver.type);
1886
+ const helper = present.kind === "bytes"
1887
+ ? lowerer.narrowedArmHelper(receiver.type.unionId, present, locOf(expr.expression))
1888
+ : null;
1889
+ receiver = helper
1890
+ ? lowerer.checkedNarrowCall(helper, receiver, present, locOf(expr.expression))
1891
+ : lowerer.maybeNarrow(receiver, expr.expression);
1892
+ }
1893
+ // property read, exiting at the declared number type (the array
1894
+ return { kind: "bytesIntrinsic", method: name, receiver, args: [], type: F64, loc };
1895
+ }
1896
+ if (name === "byteOffset") {
1897
+ // 0 for owners (scriptc typed arrays own their whole storage —
1898
+ // SEMANTICS.md notes the divergence from Node's Buffer pooling),
1899
+ // the view's real offset for a DataView. A runtime read, so the
1900
+ // receiver's evaluation is never discarded.
1901
+ const expected = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
1902
+ const receiver = expected?.kind === "bytes" ? strictReceiver(expected) : lowerer.lowerExpr(expr.expression);
1903
+ return { kind: "bytesIntrinsic", method: "byteOffset", receiver, args: [], type: F64, loc };
1904
+ }
1905
+ if (name === "buffer") {
1906
+ const expected = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
1907
+ const receiver = expected?.kind === "bytes" ? strictReceiver(expected) : lowerer.lowerExpr(expr.expression);
1908
+ return { kind: "bytesIntrinsic", method: "buffer", receiver, args: [], type: DYN, loc };
1909
+ }
1910
+ if (name === "slice" || name === "subarray" || name === "set" || name === "toString") {
1911
+ lowerer.unsupported("SC1090", expr, `typed-array methods as values (call '${name}' directly)`);
1912
+ }
1913
+ return null; // fill, reverse, ... → the SC2020 member fence
1914
+ }
1915
+ if (kind === "map") {
1916
+ if (name === "size") {
1917
+ const expected = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
1918
+ const receiver = expected?.kind === "map" ? strictReceiver(expected) : lowerer.lowerExpr(expr.expression);
1919
+ return {
1920
+ kind: "mapIntrinsic",
1921
+ method: "size",
1922
+ receiver,
1923
+ args: [],
1924
+ type: F64,
1925
+ loc: locOf(expr),
1926
+ };
1927
+ }
1928
+ if (MAP_METHODS.has(name) || name === "forEach") {
1929
+ lowerer.unsupported("SC1090", expr, `Map methods as values (call '${name}' directly)`);
1930
+ }
1931
+ return null;
1932
+ }
1933
+ if (kind === "set") {
1934
+ if (name === "size") {
1935
+ const expected = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
1936
+ const receiver = expected?.kind === "set" ? strictReceiver(expected) : lowerer.lowerExpr(expr.expression);
1937
+ return {
1938
+ kind: "setIntrinsic",
1939
+ method: "size",
1940
+ receiver,
1941
+ args: [],
1942
+ type: F64,
1943
+ loc: locOf(expr),
1944
+ };
1945
+ }
1946
+ if (SET_METHODS.has(name)) {
1947
+ lowerer.unsupported("SC1090", expr, `Set methods as values (call '${name}' directly)`);
1948
+ }
1949
+ return null;
1950
+ }
1951
+ if (name === "length") {
1952
+ const expected = kind === "string" ? STRING : lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
1953
+ let receiver = lowerer.lowerExpr(expr.expression);
1954
+ if (receiver.type.kind !== "dyn" &&
1955
+ expected &&
1956
+ (expected.kind === "string" || expected.kind === "array")) {
1957
+ receiver =
1958
+ lowerer.runtimeOptionalPropertyReceiver(expr.expression, receiver, expected, name) ??
1959
+ receiver;
1960
+ }
1961
+ if (receiver.type.kind === "union" &&
1962
+ lowerer.armTag(receiver.type.unionId, UNDEFINED_T) >= 0 &&
1963
+ kind === "array") {
1964
+ const present = lowerer.stripUndefinedArm(receiver.type);
1965
+ const helper = present.kind === "array"
1966
+ ? lowerer.narrowedArmHelper(receiver.type.unionId, present, locOf(expr.expression))
1967
+ : null;
1968
+ receiver = helper
1969
+ ? lowerer.checkedNarrowCall(helper, receiver, present, locOf(expr.expression))
1970
+ : lowerer.maybeNarrow(receiver, expr.expression);
1971
+ }
1972
+ // A CHECKED-DYNAMIC value behind an array-typed checker spelling
1973
+ // (`Object.keys(u).length` — the dyn walk answers a dyn array while
1974
+ // tsc spells string[]): the runtime-world dispatch — a dyn keyed
1975
+ // read validated into the declared number (a lying length throws
1976
+ // the catchable TypeError, the dynCheck stance).
1977
+ if (receiver.type.kind === "dyn") {
1978
+ const read = {
1979
+ kind: "dynKeyGet",
1980
+ key: { kind: "strLit", value: "length", type: STRING, loc: locOf(expr) },
1981
+ ...(expr.questionDotToken ? { optional: true } : {}),
1982
+ value: receiver,
1983
+ type: DYN,
1984
+ loc: locOf(expr),
1985
+ };
1986
+ if (expr.questionDotToken)
1987
+ return read;
1988
+ return { kind: "dynCheck", value: read, type: F64, loc: locOf(expr) };
1989
+ }
1990
+ return kind === "string"
1991
+ ? { kind: "strIntrinsic", method: "length", receiver, args: [], type: F64, loc: locOf(expr) }
1992
+ : { kind: "arrIntrinsic", method: "length", receiver, args: [], type: F64, loc: locOf(expr) };
1993
+ }
1994
+ if (kind === "string"
1995
+ ? own(STR_METHODS, name) !== undefined ||
1996
+ STRING_INDEX_METHODS.has(name) ||
1997
+ own(STDLIB_SURFACE.string, name) !== undefined
1998
+ : ARRAY_METHODS.has(name)) {
1999
+ // A JavaScript string method read as a value (smol-toml's
2000
+ // `!!(''.isWellFormed)` feature probe): String.prototype's method, the
2001
+ // runtime's interned function that runs it on its receiver.
2002
+ if (kind === "string" && isJsSourceFile(expr.getSourceFile()) && !expr.questionDotToken) {
2003
+ const receiver = lowerer.lowerExpr(expr.expression);
2004
+ const method = {
2005
+ kind: "libCall",
2006
+ fn: "dyn.builtinMethod",
2007
+ args: [
2008
+ { kind: "strLit", value: "String", type: STRING, loc: locOf(expr) },
2009
+ { kind: "strLit", value: name, type: STRING, loc: locOf(expr.name) },
2010
+ ],
2011
+ type: DYN,
2012
+ loc: locOf(expr),
2013
+ };
2014
+ return isSafeToDiscard(receiver)
2015
+ ? method
2016
+ : {
2017
+ kind: "seqExpr",
2018
+ stmts: [{ kind: "exprStmt", expr: receiver, loc: locOf(expr.expression) }],
2019
+ result: method,
2020
+ type: DYN,
2021
+ loc: locOf(expr),
2022
+ };
2023
+ }
2024
+ lowerer.unsupported("SC1090", expr, `${kind} methods as values (call '${name}' directly)`);
2025
+ }
2026
+ return null;
2027
+ }
2028
+ /** Buffer.alloc as a function value (`var alloc = Buffer.alloc` in
2029
+ * tar-stream): the runtime checks the size, allocates and fills with
2030
+ * `fill` and `encoding` as Node's alloc does. */
2031
+ function bufferAllocValue(lowerer, loc) {
2032
+ const name = "%builtin.Buffer.alloc";
2033
+ if (!lowerer.builtinCallableValueFns.has(name)) {
2034
+ lowerer.builtinCallableValueFns.set(name, name);
2035
+ const params = ["size", "fill", "encoding"].map((id) => ({ localId: id, name: id, type: DYN }));
2036
+ lowerer.liftedFns.push({
2037
+ name,
2038
+ params,
2039
+ returnType: BYTES_U8,
2040
+ locals: params.map((p) => ({ id: p.localId, name: p.name, type: DYN, mutable: false })),
2041
+ loc,
2042
+ body: [
2043
+ {
2044
+ kind: "return",
2045
+ value: {
2046
+ kind: "libCall",
2047
+ fn: "buffer.allocValue",
2048
+ args: params.map((p) => varRef(p.localId, DYN, loc)),
2049
+ type: BYTES_U8,
2050
+ loc,
2051
+ },
2052
+ loc,
2053
+ },
2054
+ ],
2055
+ });
2056
+ }
2057
+ return {
2058
+ kind: "dynFrom",
2059
+ value: {
2060
+ kind: "closure",
2061
+ fnName: name,
2062
+ captures: [],
2063
+ type: { kind: "func", params: [DYN, DYN, DYN], ret: BYTES_U8 },
2064
+ loc,
2065
+ },
2066
+ fnName: "alloc",
2067
+ type: DYN,
2068
+ loc,
2069
+ };
2070
+ }
2071
+ /** A `T | undefined` class field read that the checker narrowed to `T`
2072
+ * where the field was assigned a value that may be missing (an unchecked
2073
+ * indexed read). TypeScript's assignment narrowing is not a runtime fact
2074
+ * there, so the read keeps the stored union instead of extracting `T`. */
2075
+ function runtimeOptionalClassField(lowerer, value, node) {
2076
+ if (value.kind !== "fieldGet" || value.type.kind !== "union")
2077
+ return false;
2078
+ if (lowerer.armTag(value.type.unionId, UNDEFINED_T) < 0)
2079
+ return false;
2080
+ if ((lowerer.unions.get(value.type.unionId)?.arms.length ?? 0) !== 2)
2081
+ return false;
2082
+ const symbol = lowerer.checker.getSymbolAtLocation(node.name);
2083
+ if (!symbol || !lowerer.runtimeOptionalAssignedSymbols.has(symbol))
2084
+ return false;
2085
+ const narrowed = lowerer.mapTypeOf(lowerer.typeOf(node));
2086
+ return narrowed !== null && typeEquals(narrowed, lowerer.stripUndefinedArm(value.type));
2087
+ }
2088
+ /** `exports.<name>` in a JS module whose `module.exports =` REPLACED the
2089
+ * export object, with no `exports.<name> =` attachment anywhere in the
2090
+ * file: the read observes the ORIGINAL (empty-here) exports object, so
2091
+ * the honest value is undefined (Node's object identity exactly; tsc's
2092
+ * CJS model types the read off the replacement — identity-blind). Null
2093
+ * everywhere else: no replacement, a real attachment of this name, a
2094
+ * shadowing binding named `exports`, or write position. */
2095
+ function lowerReplacedExportsRead(lowerer, expr) {
2096
+ if (expr.questionDotToken)
2097
+ return null;
2098
+ const recv = expr.expression;
2099
+ if (!ts.isIdentifier(recv) || recv.text !== "exports")
2100
+ return null;
2101
+ const sf = ts.getSourceFileOfNode(expr);
2102
+ if (!isJsSourceFile(sf) || isNodeEsmFile(sf, lowerer.program))
2103
+ return null;
2104
+ if (lowerer.peekLocal(recv) || lowerer.globalOf(recv))
2105
+ return null; // a user binding shadows
2106
+ // Write position is the export-assignment machinery's territory.
2107
+ if (ts.isBinaryExpression(expr.parent) &&
2108
+ expr.parent.left === expr &&
2109
+ expr.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
2110
+ return null;
2111
+ }
2112
+ let replaced = false;
2113
+ for (const stmt of sf.statements.nodes) {
2114
+ const cjs = cjsExportAssignmentOf(stmt);
2115
+ if (!cjs)
2116
+ continue;
2117
+ if (cjs.kind === "table" && cjsExportDiscardReason(stmt) === null)
2118
+ replaced = true;
2119
+ if (cjs.kind === "member" && ts.isIdentifier(cjs.name) && cjs.name.text === expr.name.text) {
2120
+ return null; // a real attachment of this name exists somewhere
2121
+ }
2122
+ }
2123
+ if (!replaced)
2124
+ return null;
2125
+ return { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc: locOf(expr) };
2126
+ }
2127
+ /** `this.<name>` INSIDE a CJS export-table accessor (test/common's
2128
+ * `get localhostIPv4() { if (this.inFreeBSDJail) ... }`): Node binds the
2129
+ * getter's receiver to module.exports, so the read is the SIBLING table
2130
+ * property — a sibling GETTER's lifted call (per-read evaluation, like
2131
+ * any accessor read). Only arrows inherit the binding (a nested function
2132
+ * expression's `this` is its own). Null everywhere else — non-getter
2133
+ * siblings and absent names keep their per-site fences (none of the
2134
+ * probed suite shapes read them). */
2135
+ function lowerCjsExportTableThisMember(lowerer, expr) {
2136
+ if (expr.expression.kind !== ts.SyntaxKind.ThisKeyword || expr.questionDotToken)
2137
+ return null;
2138
+ if (!isJsSourceFile(ts.getSourceFileOfNode(expr)))
2139
+ return null;
2140
+ // The enclosing accessor, crossing only arrow boundaries (arrows
2141
+ // inherit `this`; any other function form rebinds it).
2142
+ let n = expr.parent;
2143
+ while (n !== undefined && !ts.isGetAccessorDeclaration(n) && !ts.isSetAccessorDeclaration(n)) {
2144
+ if (ts.isFunctionLike(n) && !ts.isArrowFunction(n))
2145
+ return null;
2146
+ if (ts.isSourceFile(n))
2147
+ return null;
2148
+ n = n.parent;
2149
+ }
2150
+ if (n === undefined ||
2151
+ !ts.isObjectLiteralExpression(n.parent) ||
2152
+ !isCjsExportTableLiteral(n.parent)) {
2153
+ return null;
2154
+ }
2155
+ const sibling = n.parent.properties.nodes.find((p) => ts.isGetAccessorDeclaration(p) && ts.isIdentifier(p.name) && p.name.text === expr.name.text);
2156
+ if (!sibling)
2157
+ return null;
2158
+ return cjsAccessorCall(lowerer, sibling, locOf(expr));
2159
+ }
2160
+ /** RegExp.prototype's flag getters and the flag each one reads. */
2161
+ const REGEX_FLAG_GETTERS = new Map([
2162
+ ["hasIndices", "d"],
2163
+ ["global", "g"],
2164
+ ["ignoreCase", "i"],
2165
+ ["multiline", "m"],
2166
+ ["dotAll", "s"],
2167
+ ["unicode", "u"],
2168
+ ["unicodeSets", "v"],
2169
+ ["sticky", "y"],
2170
+ ]);
2171
+ /** The named-group table of the regex that PRODUCED a match-result
2172
+ * expression — the `.groups` desugar's provenance question. Traces
2173
+ * (through parens, `!`, and const bindings):
2174
+ * - `re.exec(s)` / `s.match(re)` → re's static pattern
2175
+ * - a matchAll ROW: `rows[i]`, the for-of binding over a direct
2176
+ * `s.matchAll(re)` or a stored const drain → re's static pattern
2177
+ * Answers null when the producing regex isn't statically known (the
2178
+ * caller keeps its fence), or the groups list (possibly empty — a
2179
+ * traced regex WITHOUT named groups is the Node-undefined case). */
2180
+ export function matchResultNamedGroupsOf(lowerer, e) {
2181
+ let producer = e;
2182
+ while (ts.isParenthesizedExpression(producer) || ts.isNonNullExpression(producer))
2183
+ producer = producer.expression;
2184
+ if (ts.isIdentifier(producer)) {
2185
+ const init = constInitializerOf(lowerer, producer);
2186
+ if (init !== null)
2187
+ return matchResultNamedGroupsOf(lowerer, init);
2188
+ }
2189
+ const reExpr = matchProducerRegexOf(lowerer, e);
2190
+ if (reExpr === null)
2191
+ return null;
2192
+ if (ts.isCallExpression(producer) &&
2193
+ ts.isPropertyAccessExpression(producer.expression) &&
2194
+ producer.expression.name.text === "match") {
2195
+ const flags = staticRegexFlagsOf(lowerer, reExpr);
2196
+ if (flags === null)
2197
+ return null;
2198
+ // Global String.match returns whole matches without a groups
2199
+ // property, even when the pattern contains named captures.
2200
+ if (flags.includes("g"))
2201
+ return [];
2202
+ }
2203
+ const pattern = staticRegexPatternOf(lowerer, reExpr);
2204
+ if (pattern === null)
2205
+ return null;
2206
+ return namedCaptureGroupsOfPattern(pattern);
2207
+ }
2208
+ function staticRegexFlagsOf(lowerer, node) {
2209
+ let expr = node;
2210
+ while (ts.isParenthesizedExpression(expr) || ts.isNonNullExpression(expr))
2211
+ expr = expr.expression;
2212
+ if (ts.isRegularExpressionLiteral(expr))
2213
+ return expr.text.slice(expr.text.lastIndexOf("/") + 1);
2214
+ if (ts.isIdentifier(expr)) {
2215
+ const init = constInitializerOf(lowerer, expr);
2216
+ return init !== null ? staticRegexFlagsOf(lowerer, init) : null;
2217
+ }
2218
+ if (ts.isNewExpression(expr) &&
2219
+ ts.isIdentifier(expr.expression) &&
2220
+ lowerer.isStdlibGlobal(expr.expression, "RegExp")) {
2221
+ const flags = expr.arguments?.nodes[1];
2222
+ if (!flags)
2223
+ return "";
2224
+ if (ts.isStringLiteral(flags) || ts.isNoSubstitutionTemplateLiteral(flags))
2225
+ return flags.text;
2226
+ }
2227
+ return null;
2228
+ }
2229
+ /** The regex EXPRESSION whose match produced `e` (see
2230
+ * matchResultNamedGroupsOf for the traced shapes). */
2231
+ function matchProducerRegexOf(lowerer, e) {
2232
+ let expr = e;
2233
+ for (;;) {
2234
+ if (ts.isParenthesizedExpression(expr) || ts.isNonNullExpression(expr)) {
2235
+ expr = expr.expression;
2236
+ continue;
2237
+ }
2238
+ break;
2239
+ }
2240
+ // The direct producers: re.exec(s) / s.match(re) — the receiver's
2241
+ // mapped type pins the STDLIB operation (a regex for exec, a string
2242
+ // or its nullable spelling for match — the claim string-and-regexp
2243
+ // makes), so a user method that happens to be named `match` with a
2244
+ // regex argument never traces.
2245
+ if (ts.isCallExpression(expr) && ts.isPropertyAccessExpression(expr.expression)) {
2246
+ const name = expr.expression.name.text;
2247
+ const recvT = lowerer.mapTypeOf(lowerer.typeOf(expr.expression.expression));
2248
+ if (name === "exec" && expr.arguments.nodes.length === 1 && recvT?.kind === "regex") {
2249
+ return expr.expression.expression;
2250
+ }
2251
+ if (name === "match" &&
2252
+ expr.arguments.nodes.length === 1 &&
2253
+ (recvT?.kind === "string" ||
2254
+ (recvT !== null && recvT !== undefined && nullableStringType(lowerer, recvT))) &&
2255
+ lowerer.mapTypeOf(lowerer.typeOf(expr.arguments.nodes[0]))?.kind === "regex") {
2256
+ return expr.arguments.nodes[0];
2257
+ }
2258
+ }
2259
+ // A matchAll ROW by element access: rows[i] with rows tracing to the
2260
+ // drain call — or the direct s.matchAll(re)[i] spelling.
2261
+ if (ts.isElementAccessExpression(expr)) {
2262
+ return matchAllRegexOf(lowerer, expr.expression);
2263
+ }
2264
+ // A row picked by `rows.find(cb)`, `rows.findLast(cb)` or `rows.at(i)`.
2265
+ if (ts.isCallExpression(expr) &&
2266
+ ts.isPropertyAccessExpression(expr.expression) &&
2267
+ MATCH_ROW_PICK_METHODS.has(expr.expression.name.text) &&
2268
+ lowerer.isStdlibMember(expr.expression)) {
2269
+ return matchAllRegexOf(lowerer, expr.expression.expression);
2270
+ }
2271
+ if (ts.isIdentifier(expr)) {
2272
+ // The for-of binding over a matchAll drain: `for (const m of
2273
+ // s.matchAll(re))` (or over a stored const rows).
2274
+ const sym = lowerer.resolveValueSymbol(expr);
2275
+ const decl = sym ? sym.valueDeclaration : undefined;
2276
+ if (decl !== undefined &&
2277
+ ts.isVariableDeclaration(decl) &&
2278
+ ts.isVariableDeclarationList(decl.parent) &&
2279
+ ts.isForOfStatement(decl.parent.parent)) {
2280
+ return matchAllRegexOf(lowerer, decl.parent.parent.expression);
2281
+ }
2282
+ // A stored const match result: `const m = re.exec(s)`.
2283
+ const init = constInitializerOf(lowerer, expr);
2284
+ if (init !== null)
2285
+ return matchProducerRegexOf(lowerer, init);
2286
+ // The element parameter of an array callback over matchAll rows:
2287
+ // `[...s.matchAll(re)].map((m) => m.groups)`, and Array.from's
2288
+ // mapping function over `s.matchAll(re)`.
2289
+ if (decl !== undefined && ts.isParameter(decl))
2290
+ return matchAllCallbackRegexOf(lowerer, decl);
2291
+ }
2292
+ return null;
2293
+ }
2294
+ /** Array methods that return one row of the receiver. */
2295
+ const MATCH_ROW_PICK_METHODS = new Set(["find", "findLast", "at"]);
2296
+ /** `m.groups` on a match result whose producing regex is statically
2297
+ * known: the honest slice already HOLDS every named group's value at
2298
+ * its capture index, so the groups object is a compile-time record
2299
+ * projection — `{ year: m[1], month: m[2] }` — built by one interned
2300
+ * helper per (shape, index list, receiver type). Node's exact shape
2301
+ * decisions:
2302
+ * - no named groups → `undefined` (the identifier-receiver shapes —
2303
+ * a call receiver would lose its own null trap, so those keep the
2304
+ * member fence);
2305
+ * - a nullable receiver (the JS `s.match(re).groups` idiom) throws
2306
+ * Node's exact TypeError on the unit arms;
2307
+ * - every declared name is a key (nonparticipating groups hold undefined,
2308
+ * exactly the slice elements they project);
2309
+ * - ES2025 duplicate names (distinct alternatives) project the first
2310
+ * participating occurrence, including a participating empty string;
2311
+ * - key order is group declaration order (declaredOrder), Node's own.
2312
+ * The record has a null prototype, like Node's groups object. A
2313
+ * JavaScript callback parameter holds the row as a dynamic array; the
2314
+ * projection reads its elements through dynamic reads. Null when the
2315
+ * receiver isn't a match slice or the regex isn't traceable — the
2316
+ * caller's member fence (with the groups hint) names the gap. */
2317
+ function lowerMatchGroupsRead(lowerer, expr) {
2318
+ if (expr.name.text !== "groups")
2319
+ return null;
2320
+ // `m?.groups` re-dispatches through the optional-chain machinery, which
2321
+ // narrows the receiver to its match arm first.
2322
+ if (expr.questionDotToken !== undefined && !lowerer.chainHandled.has(expr))
2323
+ return null;
2324
+ const loc = locOf(expr);
2325
+ const strArr = arrayOf(STRING);
2326
+ const recvT = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
2327
+ if (!recvT || !isMatchSliceType(lowerer, recvT) || !lowerer.isStdlibMember(expr))
2328
+ return null;
2329
+ const groups = matchResultNamedGroupsOf(lowerer, expr.expression);
2330
+ // An untraced regex: TypeScript reaches the member fence; JavaScript
2331
+ // would otherwise read the slice's absent expando as undefined.
2332
+ if (groups === null && isJsSourceFile(ts.getSourceFileOfNode(expr)))
2333
+ lowerer.stdlibMemberFence(expr);
2334
+ if (groups === null)
2335
+ return null;
2336
+ if (groups.length === 0) {
2337
+ // Node: a match result of a group-less regex answers undefined —
2338
+ // the unit literal, exactly the `undefined` identifier's lowering.
2339
+ // Identifier receivers only (evaluation-free): a CALL receiver's
2340
+ // exec/match must still run and null-trap, which a folded unit
2341
+ // cannot carry — those keep the fence.
2342
+ let r = expr.expression;
2343
+ while (ts.isParenthesizedExpression(r) || ts.isNonNullExpression(r))
2344
+ r = r.expression;
2345
+ if (ts.isIdentifier(r) && typeEquals(recvT, strArr)) {
2346
+ return { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc };
2347
+ }
2348
+ return null;
2349
+ }
2350
+ const recv = lowerer.lowerExpr(expr.expression);
2351
+ // A JavaScript callback parameter holds the row as a dynamic array.
2352
+ const dynRow = recv.type.kind === "dyn" && isJsSourceFile(ts.getSourceFileOfNode(expr));
2353
+ if (!dynRow && !isMatchSliceType(lowerer, recv.type))
2354
+ return null;
2355
+ return lowerGroupsProjection(lowerer, recv, groups, loc);
2356
+ }
2357
+ /** True when the IR type is a string-or-units union — the Dict<string>
2358
+ * member spelling (`process.versions.openssl`), match's nullable
2359
+ * receiver claim. */
2360
+ function nullableStringType(lowerer, t) {
2361
+ if (t.kind !== "union")
2362
+ return false;
2363
+ const arms = lowerer.unions.get(t.unionId)?.arms ?? [];
2364
+ return (arms.some((a) => a.kind === "string") && arms.every((a) => a.kind === "string" || isUnitType(a)));
2365
+ }
2366
+ /** True when the IR type is the honest match slice — `string[]`, or a
2367
+ * union of it with unit arms only (`string[] | null`). The groups
2368
+ * projection's receiver gate, shared with the destructure interception. */
2369
+ export function isMatchSliceType(lowerer, t) {
2370
+ if (typeEquals(t, arrayOf(STRING)))
2371
+ return true;
2372
+ return t.kind === "union" && matchSliceUnionArms(lowerer, t.unionId) !== null;
2373
+ }
2374
+ /** The union-arm layout of a nullable match slice (`string[] | null`,
2375
+ * matchAll's checker spellings with undefined arms included): the
2376
+ * string[] arm's tag plus each unit arm's tag and spelling. Null when
2377
+ * the union holds anything else. */
2378
+ function matchSliceUnionArms(lowerer, unionId) {
2379
+ const def = lowerer.unions.get(unionId);
2380
+ if (!def)
2381
+ return null;
2382
+ const strArr = arrayOf(STRING);
2383
+ const arrTag = def.arms.findIndex((a) => typeEquals(a, strArr));
2384
+ if (arrTag < 0)
2385
+ return null;
2386
+ const units = [];
2387
+ for (let i = 0; i < def.arms.length; i++) {
2388
+ if (i === arrTag)
2389
+ continue;
2390
+ const a = def.arms[i];
2391
+ if (!isUnitType(a))
2392
+ return null;
2393
+ units.push({ tag: i, unit: a.kind === "nullT" ? "null" : "undefined" });
2394
+ }
2395
+ return { arrTag, units };
2396
+ }
2397
+ /** Node's TypeError for `.groups` read off null or undefined. */
2398
+ function groupsReadTypeError(unit, loc) {
2399
+ return {
2400
+ kind: "throw",
2401
+ value: {
2402
+ kind: "libCall",
2403
+ fn: "error.new",
2404
+ args: [strLit(`Cannot read properties of ${unit} (reading 'groups')`, loc)],
2405
+ type: { kind: "object", className: "%TypeError" },
2406
+ loc,
2407
+ },
2408
+ loc,
2409
+ };
2410
+ }
2411
+ /** The groups-record projection holds string | undefined values, including
2412
+ * an own overflow entry for every nonparticipating capture. One lifted helper per
2413
+ * (index list, receiver representation) builds it; see
2414
+ * lowerMatchGroupsRead for the semantics the body encodes. */
2415
+ export function lowerGroupsProjection(lowerer, recv, groups, loc) {
2416
+ // Name → its capture indices, in declaration order (duplicates keep
2417
+ // every occurrence — the projection picks the participating one).
2418
+ const order = [];
2419
+ const indicesByName = new Map();
2420
+ for (const g of groups) {
2421
+ const got = indicesByName.get(g.name);
2422
+ if (got) {
2423
+ got.push(g.index);
2424
+ }
2425
+ else {
2426
+ indicesByName.set(g.name, [g.index]);
2427
+ order.push(g.name);
2428
+ }
2429
+ }
2430
+ const valueType = arrayValueType(lowerer, STRING);
2431
+ const shapeId = lowerer.shapes.intern([], false, valueType);
2432
+ const recordT = { kind: "record", shapeId };
2433
+ const recvKey = recv.type.kind === "union" ? recv.type.unionId : recv.type.kind === "dyn" ? "dyn" : "arr";
2434
+ const key = `regexgroups:${shapeId}:${groups.map((g) => `${g.name}=${g.index}`).join(",")}:${recvKey}`;
2435
+ let helper = lowerer.valueHelpers.get(key);
2436
+ if (!helper) {
2437
+ helper = `%regex.groups.${lowerer.valueHelpers.size}`;
2438
+ lowerer.valueHelpers.set(key, helper);
2439
+ const body = [];
2440
+ const locals = [{ id: "m.0", name: "m", type: recv.type, mutable: true }];
2441
+ let mRef = { kind: "varRef", localId: "m.0", type: recv.type, loc };
2442
+ if (recv.type.kind === "union") {
2443
+ // Node's exact TypeError per unit arm, then the checked narrow.
2444
+ const arms = matchSliceUnionArms(lowerer, recv.type.unionId);
2445
+ for (const u of arms.units) {
2446
+ body.push({
2447
+ kind: "if",
2448
+ cond: {
2449
+ kind: "unionIsTag",
2450
+ unionId: recv.type.unionId,
2451
+ tag: u.tag,
2452
+ negated: false,
2453
+ value: mRef,
2454
+ type: BOOL,
2455
+ loc,
2456
+ },
2457
+ then: [groupsReadTypeError(u.unit, loc)],
2458
+ else_: null,
2459
+ loc,
2460
+ });
2461
+ }
2462
+ const narrowed = {
2463
+ kind: "unionNarrow",
2464
+ unionId: recv.type.unionId,
2465
+ tag: arms.arrTag,
2466
+ value: mRef,
2467
+ type: arrayOf(STRING),
2468
+ loc,
2469
+ };
2470
+ locals.push({ id: "arr.0", name: "arr", type: arrayOf(STRING), mutable: false });
2471
+ body.push({ kind: "varDecl", localId: "arr.0", init: narrowed, loc });
2472
+ mRef = { kind: "varRef", localId: "arr.0", type: arrayOf(STRING), loc };
2473
+ }
2474
+ else if (recv.type.kind === "dyn") {
2475
+ // A JavaScript callback parameter holds the row as a dynamic array:
2476
+ // Node's TypeError for null and undefined, then dynamic element reads.
2477
+ for (const unit of ["null", "undefined"]) {
2478
+ body.push({
2479
+ kind: "if",
2480
+ cond: { kind: "dynTest", test: unit, value: mRef, type: BOOL, loc },
2481
+ then: [groupsReadTypeError(unit, loc)],
2482
+ else_: null,
2483
+ loc,
2484
+ });
2485
+ }
2486
+ }
2487
+ const elem = (index) => mRef.type.kind === "dyn"
2488
+ ? lowerer.coerceToExpected({
2489
+ kind: "dynKeyGet",
2490
+ value: mRef,
2491
+ key: strLit(String(index), loc),
2492
+ type: DYN,
2493
+ loc,
2494
+ }, valueType)
2495
+ : arrayValueRead(lowerer, mRef, numLit(index, loc), STRING, loc);
2496
+ const values = new Map();
2497
+ order.forEach((name, i) => {
2498
+ const idxs = indicesByName.get(name);
2499
+ if (idxs.length === 1) {
2500
+ values.set(name, elem(idxs[0]));
2501
+ return;
2502
+ }
2503
+ // Duplicates: the first participating occurrence. Empty strings
2504
+ // participate; undefined means this alternative did not match.
2505
+ const id = `g${i}.0`;
2506
+ locals.push({ id, name: `g${i}`, type: valueType, mutable: true });
2507
+ body.push({ kind: "varDecl", localId: id, init: elem(idxs[0]), loc });
2508
+ const gRef = { kind: "varRef", localId: id, type: valueType, loc };
2509
+ for (const idx of idxs.slice(1)) {
2510
+ body.push({
2511
+ kind: "if",
2512
+ cond: {
2513
+ kind: "unionIsTag",
2514
+ unionId: valueType.kind === "union" ? valueType.unionId : "",
2515
+ tag: valueType.kind === "union" ? lowerer.armTag(valueType.unionId, UNDEFINED_T) : -1,
2516
+ negated: false,
2517
+ value: gRef,
2518
+ type: BOOL,
2519
+ loc,
2520
+ },
2521
+ then: [{ kind: "assign", localId: id, value: elem(idx), loc }],
2522
+ else_: null,
2523
+ loc,
2524
+ });
2525
+ }
2526
+ values.set(name, gRef);
2527
+ });
2528
+ body.push({
2529
+ kind: "return",
2530
+ value: {
2531
+ kind: "recordLit",
2532
+ fields: order.map((name) => ({ name, value: values.get(name), overflow: true })),
2533
+ nullProto: true,
2534
+ type: recordT,
2535
+ loc,
2536
+ },
2537
+ loc,
2538
+ });
2539
+ lowerer.liftedFns.push({
2540
+ name: helper,
2541
+ params: [{ localId: "m.0", name: "m", type: recv.type }],
2542
+ returnType: recordT,
2543
+ locals,
2544
+ body,
2545
+ loc,
2546
+ });
2547
+ }
2548
+ return { kind: "call", callee: helper, args: [recv], type: recordT, loc };
2549
+ }
2550
+ /** Field reads use the shared FieldTarget union. Native method reads select
2551
+ * an interned unbound callable; invocation supplies its receiver separately. */
2552
+ export function lowerFieldRead(lowerer, expr) {
2553
+ // A checked receiver already owns its property table. An ambient
2554
+ // generic method signature must not divert its value into native
2555
+ // object-literal specialization (Array.prototype.map is one example).
2556
+ if (ts.isIdentifier(expr.expression)) {
2557
+ const stored = lowerer.peekLocal(expr.expression) ?? lowerer.globalOf(expr.expression);
2558
+ if (stored?.type.kind === "dyn") {
2559
+ const value = lowerer.lowerExpr(expr.expression);
2560
+ if (value.type.kind === "dyn")
2561
+ return {
2562
+ kind: "dynKeyGet",
2563
+ value,
2564
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
2565
+ ...(expr.questionDotToken || hasOptionalChainGuard(expr.expression, lowerer)
2566
+ ? { optional: true }
2567
+ : {}),
2568
+ type: DYN,
2569
+ loc: locOf(expr),
2570
+ };
2571
+ }
2572
+ }
2573
+ const target = lowerer.fieldTarget(expr);
2574
+ if (target)
2575
+ return lowerer.fieldGetExpr(target, locOf(expr), expr);
2576
+ if (expr.questionDotToken)
2577
+ return null;
2578
+ let receiverIr = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
2579
+ // The readonly-tuple Array.isArray narrow has no directly mappable
2580
+ // checker type (`Result & any[]`), but maybeNarrow extracted the tuple
2581
+ // record behind it. Route tuple properties such as `.length` from that
2582
+ // lowered value, the element-access bridge's twin.
2583
+ const checkerArray = lowerer.checkerArrayValue(expr.expression);
2584
+ if (checkerArray?.type.kind === "record")
2585
+ receiverIr = checkerArray.type;
2586
+ if (receiverIr?.kind === "object" &&
2587
+ (lowerer.findMethodOn(lowerer.classes.get(receiverIr.className) ?? null, expr.name.text) ||
2588
+ findGenericMethodOn(lowerer, lowerer.classes.get(receiverIr.className) ?? null, expr.name.text))) {
2589
+ const info = lowerer.classes.get(receiverIr.className);
2590
+ if (info)
2591
+ return lowerClassMethodValue(lowerer, expr, info);
2592
+ }
2593
+ // An object-literal GENERIC method as a VALUE (`o.m` — the member is
2594
+ // excluded from the record shape): the pinned-value rule verbatim when
2595
+ // the receiver is the defining literal's own const binding (the value
2596
+ // is the pinned instance's closure — no `this` exists); anything else
2597
+ // fences by name inside the helpers.
2598
+ {
2599
+ const propSym = lowerer.checker.getPropertyOfType(lowerer.typeOf(expr.expression), expr.name.text);
2600
+ if (receiverIr?.kind !== "object" &&
2601
+ propSym &&
2602
+ isGenericCallableMemberType(lowerer.checker.getTypeOfSymbol(propSym), lowerer.checker) &&
2603
+ // CLASS members keep the class-path fences (a poisoned class's own
2604
+ // diagnostics, the bound-method fence above).
2605
+ !propSym.declarations.some((d) => d.parent !== undefined &&
2606
+ (ts.isClassDeclaration(d.parent) || ts.isClassExpression(d.parent)))) {
2607
+ const found = objLitGenericFnNodeOf(lowerer, propSym);
2608
+ if (!found) {
2609
+ lowerer.unsupported("SC1090", expr, `the generic method '${expr.name.text}' as a value with no defining object literal (only methods declared with a body in an object literal compile)`);
2610
+ }
2611
+ requireObjLitGenericReceiver(lowerer, expr, expr.expression, found.literal, expr.name.text);
2612
+ return lowerer.lowerGenericFnValue(expr, objLitGenericFnInfoOf(lowerer, expr, expr.name.text, found));
2613
+ }
2614
+ }
2615
+ // Dot access to an UNDECLARED key of an index-signature shape
2616
+ // (`bag.count` on `Record<string, number>`): tsc allows it without
2617
+ // noPropertyAccessFromIndexSignature, but the bracket spelling is the
2618
+ // canonical index-signature form here — point at it.
2619
+ if (receiverIr?.kind === "record") {
2620
+ const shape = lowerer.shapes.get(receiverIr.shapeId);
2621
+ if (shape?.indexValue && !shape.fields.some((f) => f.name === expr.name.text)) {
2622
+ const actual = tryLowerExpression(lowerer, expr.expression);
2623
+ if (actual?.type.kind === "dyn")
2624
+ return {
2625
+ kind: "dynKeyGet",
2626
+ value: actual,
2627
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
2628
+ type: DYN,
2629
+ loc: locOf(expr),
2630
+ };
2631
+ if (actual?.type.kind === "record") {
2632
+ const field = lowerer.shapes
2633
+ .get(actual.type.shapeId)
2634
+ ?.fields.find((field) => field.name === expr.name.text);
2635
+ if (field)
2636
+ return {
2637
+ kind: "recordGet",
2638
+ obj: actual,
2639
+ shapeId: actual.type.shapeId,
2640
+ field: field.name,
2641
+ type: field.type,
2642
+ loc: locOf(expr),
2643
+ };
2644
+ }
2645
+ // A member the checker declares on the receiver, stored in a pure
2646
+ // index-signature record (an object literal that spread one, see
2647
+ // dictSpreadLiteralShape): the key is always present, so the keyed
2648
+ // read answers the member through the slot type.
2649
+ if (actual?.type.kind === "record" &&
2650
+ shape.fields.length === 0 &&
2651
+ declaredMemberOf(lowerer, expr.expression, expr.name.text)) {
2652
+ return lowerer.maybeNarrow({
2653
+ kind: "recordKeyGet",
2654
+ obj: actual,
2655
+ shapeId: actual.type.shapeId,
2656
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
2657
+ type: shape.indexValue,
2658
+ loc: locOf(expr),
2659
+ }, expr);
2660
+ }
2661
+ lowerer.unsupported("SC1090", expr, `dot access to index-signature keys (spell it r["${expr.name.text}"] — brackets are the index-signature form)`);
2662
+ }
2663
+ }
2664
+ // `t.length` on a tuple: the arity CONSTANT (tuples are fixed-shape —
2665
+ // the checker types it as the literal arity too). Folding discards the
2666
+ // receiver's evaluation, so only side-effect-free receivers fold;
2667
+ // anything else (a call result) binds to a const first.
2668
+ if (receiverIr?.kind === "record" && expr.name.text === "length") {
2669
+ const shape = lowerer.shapes.get(receiverIr.shapeId);
2670
+ if (shape?.tuple) {
2671
+ let root = expr.expression;
2672
+ while (ts.isPropertyAccessExpression(root))
2673
+ root = root.expression;
2674
+ if (!ts.isIdentifier(root) && root.kind !== ts.SyntaxKind.ThisKeyword) {
2675
+ lowerer.unsupported("SC1090", expr, "'.length' of a computed tuple expression (the arity is a constant — bind the tuple to a const first)");
2676
+ }
2677
+ return { kind: "numLit", value: shape.fields.length, type: F64, loc: locOf(expr) };
2678
+ }
2679
+ }
2680
+ return null;
2681
+ }
2682
+ /** Shared-field read `r.f` on a UNION receiver: supported exactly when
2683
+ * every arm is a record/class possessing the field with ONE shared IR
2684
+ * type — the discriminant pattern (`r.kind`, primitive) and the
2685
+ * shared-payload pattern (`spec.config` where every ServiceSpec arm
2686
+ * carries the same record). Lowers to `unionDisc` (the backend switches
2687
+ * on the runtime tag and reads the field from the concrete arm), which
2688
+ * composes with existing strEq/bin/switch nodes, so `r.kind === "ok"`
2689
+ * and `switch (r.kind)` work without dedicated test nodes. Anything else
2690
+ * on a union receiver is rejected specifically (narrow first). */
2691
+ export function lowerUnionProperty(lowerer, expr) {
2692
+ if (lowerer.chainBlocked(expr))
2693
+ return null;
2694
+ const receiverIr = structuralReadType(lowerer, expr.expression) ??
2695
+ lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
2696
+ if (receiverIr?.kind !== "union")
2697
+ return null;
2698
+ // Lower the receiver first: its runtime value can still carry the full
2699
+ // binding union even when the checker has removed several variants.
2700
+ let value = lowerer.lowerExpr(expr.expression);
2701
+ // A guard can remove several variants without selecting one record.
2702
+ // Materialize that sub-union before looking for common fields; arms
2703
+ // ruled out by the guard must not veto a field shared by the survivors.
2704
+ if (value.type.kind === "union" && !typeEquals(value.type, receiverIr)) {
2705
+ const helper = lowerer.narrowedRetagHelper(expr.expression, value.type.unionId, receiverIr.unionId, locOf(expr));
2706
+ if (helper)
2707
+ value = { kind: "call", callee: helper, args: [value], type: receiverIr, loc: locOf(expr) };
2708
+ // Optional storage of a base class (a runtime-optional binding holding
2709
+ // `Base | undefined`) that `instanceof` narrowed to several subclasses:
2710
+ // extract the instance and test its class, as typed slots do.
2711
+ else
2712
+ value = narrowStoredClassValue(lowerer, value, receiverIr) ?? value;
2713
+ }
2714
+ // A checker-union receiver whose VALUE lowered to a plain RECORD (the
2715
+ // merged-signature fiction — `runner(cmd, args)` where runner joined
2716
+ // a structural runner type with spawnSync's, and the local adopted
2717
+ // the record arm): read the record field directly, the dyn-receiver
2718
+ // fallback's discipline.
2719
+ // A checker-union receiver whose VALUE lowered checked-dynamic (a
2720
+ // never-tainted JS chain — `cmd[1].length` on `const cmd = ['pwd',
2721
+ // []]`, where the element read stayed a dyn node): read through the
2722
+ // dyn keyed read like the unmappable-receiver path below the chain.
2723
+ if (value.type.kind === "dyn") {
2724
+ const key = {
2725
+ kind: "strLit",
2726
+ value: expr.name.text,
2727
+ type: STRING,
2728
+ loc: locOf(expr.name),
2729
+ };
2730
+ return { kind: "dynKeyGet", key, value, type: DYN, loc: locOf(expr) };
2731
+ }
2732
+ if (value.type.kind === "record") {
2733
+ const shape = lowerer.shapes.get(value.type.shapeId);
2734
+ const f = shape?.fields.find((x) => x.name === expr.name.text);
2735
+ if (f) {
2736
+ return {
2737
+ kind: "recordGet",
2738
+ obj: value,
2739
+ shapeId: value.type.shapeId,
2740
+ field: f.name,
2741
+ type: f.type,
2742
+ loc: locOf(expr),
2743
+ };
2744
+ }
2745
+ return null;
2746
+ }
2747
+ // A class instance the checker sees through a wider union (`(concrete
2748
+ // as A | B).value`): the value is that class's instance, so read its
2749
+ // field directly.
2750
+ if (value.type.kind === "object") {
2751
+ const className = value.type.className;
2752
+ const info = lowerer.classes.get(className) ?? null;
2753
+ const field = expr.name.text;
2754
+ const fieldType = info?.fields.get(field);
2755
+ if (fieldType !== undefined)
2756
+ return lowerer.fieldGetExpr({ container: "class", obj: value, className, field, fieldType }, locOf(expr), expr);
2757
+ const getter = lowerer.findMethodOn(info, `get:${field}`);
2758
+ if (getter)
2759
+ return lowerer.fieldGetExpr({ container: "accessor", obj: value, className, field, fieldType: getter.sig.ret }, locOf(expr), expr);
2760
+ }
2761
+ if (value.type.kind !== "union") {
2762
+ lowerer.unsupported("SC1090", expr, "shared property access without a represented union receiver");
2763
+ }
2764
+ const def = lowerer.unions.get(value.type.unionId);
2765
+ if (!def)
2766
+ throw new InternalCompilerError(`lowerer bug: unknown union ${value.type.unionId}`);
2767
+ const field = expr.name.text;
2768
+ if (field === "length") {
2769
+ const presentArms = def.arms.filter((arm) => !isUnitType(arm));
2770
+ const present = presentArms.length === 1 ? presentArms[0] : null;
2771
+ if (present?.kind === "string" || present?.kind === "array") {
2772
+ const receiver = lowerer.runtimeOptionalPropertyReceiver(expr.expression, value, present, field);
2773
+ if (receiver !== null) {
2774
+ return present.kind === "string"
2775
+ ? {
2776
+ kind: "strIntrinsic",
2777
+ method: "length",
2778
+ receiver,
2779
+ args: [],
2780
+ type: F64,
2781
+ loc: locOf(expr),
2782
+ }
2783
+ : {
2784
+ kind: "arrIntrinsic",
2785
+ method: "length",
2786
+ receiver,
2787
+ args: [],
2788
+ type: F64,
2789
+ loc: locOf(expr),
2790
+ };
2791
+ }
2792
+ }
2793
+ }
2794
+ const nonUnitArms = def.arms.filter((arm) => !isUnitType(arm));
2795
+ if (nonUnitArms.length === 1 && nonUnitArms[0]?.kind === "object") {
2796
+ const objectType = nonUnitArms[0];
2797
+ const fieldType = lowerer.classes.get(objectType.className)?.fields.get(field);
2798
+ if (fieldType !== undefined) {
2799
+ let receiver = lowerer.runtimeOptionalPropertyReceiver(expr.expression, value, objectType, field);
2800
+ if (receiver === null) {
2801
+ const helper = lowerer.narrowedArmHelper(value.type.unionId, objectType, locOf(expr.expression));
2802
+ if (helper !== null)
2803
+ receiver = lowerer.checkedNarrowCall(helper, value, objectType, locOf(expr.expression));
2804
+ }
2805
+ if (receiver !== null) {
2806
+ return {
2807
+ kind: "fieldGet",
2808
+ obj: receiver,
2809
+ className: objectType.className,
2810
+ field,
2811
+ type: fieldType,
2812
+ loc: locOf(expr),
2813
+ };
2814
+ }
2815
+ }
2816
+ }
2817
+ let common = null;
2818
+ for (const arm of def.arms) {
2819
+ let ft;
2820
+ if (arm.kind === "record") {
2821
+ ft = lowerer.shapes.get(arm.shapeId)?.fields.find((f) => f.name === field)?.type;
2822
+ }
2823
+ else if (arm.kind === "object") {
2824
+ ft = lowerer.classes.get(arm.className)?.fields.get(field);
2825
+ }
2826
+ if (!ft || ft.kind === "void" || isUnitType(ft) || (common && !typeEquals(common, ft))) {
2827
+ common = null;
2828
+ break;
2829
+ }
2830
+ common = ft;
2831
+ }
2832
+ if (common) {
2833
+ return {
2834
+ kind: "unionDisc",
2835
+ unionId: value.type.unionId,
2836
+ field,
2837
+ value,
2838
+ type: common,
2839
+ loc: locOf(expr),
2840
+ };
2841
+ }
2842
+ // The arms answer DIFFERENT types (or through index signatures / unit
2843
+ // arms): the JOIN path — `env.PORTLESS_PORT` on `ProcessEnv |
2844
+ // Record<string, string>`, the tail read of `loaded?.config.script`.
2845
+ const key = { kind: "strLit", value: field, type: STRING, loc: locOf(expr.name) };
2846
+ const keyed = lowerUnionKeyedRead(lowerer, expr, value.type.unionId, value, key, field);
2847
+ if (keyed)
2848
+ return keyed;
2849
+ // Class arms declaring the field with compatible but different types
2850
+ // (`T | undefined` beside `T`): per-arm slot reads widened to one type.
2851
+ const widened = lowerUnionFieldRead(lowerer, expr, value);
2852
+ if (widened)
2853
+ return widened;
2854
+ // JavaScript overloads commonly inspect a class brand on a scalar-or-
2855
+ // instance argument (e.g. Matrix4.makeTranslation). Preserve primitive
2856
+ // missing-property semantics and dispatch class data through its native
2857
+ // capsule instead of demanding a field shared by every union arm.
2858
+ if (isJsSourceFile(ts.getSourceFileOfNode(expr)) && lowerer.dynConvertible(value.type)) {
2859
+ return {
2860
+ kind: "dynKeyGet",
2861
+ value: lowerer.coerceToExpected(value, DYN),
2862
+ key,
2863
+ ...(hasOptionalChainGuard(expr.expression, lowerer) ? { optional: true } : {}),
2864
+ type: DYN,
2865
+ loc: locOf(expr),
2866
+ };
2867
+ }
2868
+ lowerer.unsupported("SC1090", expr, `reading '${field}' on a union-typed value (every arm must be an object/record ` +
2869
+ `with a same-typed field '${field}'; ` +
2870
+ `${NARROW_FIRST})`);
2871
+ }
2872
+ /** The unionDisc generalization: a keyed read on a union receiver whose
2873
+ * arms answer DIFFERENT (but joinable) types. Each arm contributes its
2874
+ * declared answer — an array element's type (number keys), a declared field's type (literal keys), an
2875
+ * index-signature arm's value type (plus its declared fields' types for
2876
+ * runtime keys, which reach them through the keyed-read helper), and
2877
+ * UNDEFINED for unit arms (reachable only through optional-chain tails,
2878
+ * where JS short-circuits to undefined; a unit arm the checker narrowed
2879
+ * away is simply unreachable). The result type is the JOIN of those
2880
+ * answers; every arm's answer must be the join itself, one of its
2881
+ * arms, or a sub-union whose payload representations are unchanged.
2882
+ * Array reads retain the ordinary invalid-index trap policy.
2883
+ * Returns null when any arm cannot answer — the caller owns the fence
2884
+ * message. The caller (the property/element dispatch) maybeNarrows. */
2885
+ export function lowerUnionKeyedRead(lowerer, expr, unionId, value, key, literalField) {
2886
+ const def = lowerer.unions.get(unionId);
2887
+ if (!def)
2888
+ return null;
2889
+ // Pass 1: per-arm declared answers, joined into the result type.
2890
+ const joinArms = [];
2891
+ const seen = new Set();
2892
+ const push = (t) => {
2893
+ const k = typeKey(t);
2894
+ if (!seen.has(k)) {
2895
+ seen.add(k);
2896
+ joinArms.push(t);
2897
+ }
2898
+ };
2899
+ const pushAnswer = (t) => {
2900
+ if (t.kind === "void")
2901
+ return false;
2902
+ if (t.kind === "union") {
2903
+ const inner = lowerer.unions.get(t.unionId);
2904
+ if (!inner)
2905
+ return false;
2906
+ for (const a of inner.arms)
2907
+ push(a);
2908
+ return true;
2909
+ }
2910
+ push(t);
2911
+ return true;
2912
+ };
2913
+ for (const arm of def.arms) {
2914
+ if (isUnitType(arm)) {
2915
+ push(UNDEFINED_T);
2916
+ continue;
2917
+ }
2918
+ if (key.type.kind === "f64") {
2919
+ if (arm.kind !== "array" || !pushAnswer(arm.elem))
2920
+ return null;
2921
+ continue;
2922
+ }
2923
+ if (arm.kind !== "record")
2924
+ return null;
2925
+ const shape = lowerer.shapes.get(arm.shapeId);
2926
+ if (!shape || shape.tuple)
2927
+ return null;
2928
+ const declared = literalField !== null ? shape.fields.find((f) => f.name === literalField)?.type : undefined;
2929
+ if (declared) {
2930
+ if (!pushAnswer(declared))
2931
+ return null;
2932
+ continue;
2933
+ }
2934
+ // Runtime keys can reach the declared fields through the keyed-read
2935
+ // helper's string switch — every one joins.
2936
+ if (literalField === null) {
2937
+ for (const f of shape.fields)
2938
+ if (!pushAnswer(f.type))
2939
+ return null;
2940
+ }
2941
+ if (!shape.indexValue) {
2942
+ if (literalField === null && shape.fields.length > 0)
2943
+ continue;
2944
+ return null;
2945
+ }
2946
+ if (!pushAnswer(shape.indexValue))
2947
+ return null;
2948
+ }
2949
+ if (joinArms.length === 0)
2950
+ return null;
2951
+ // The join must satisfy native union invariants. The caller owns the
2952
+ // diagnostic when a container or opaque arm prevents that join.
2953
+ if (joinArms.length > 1 &&
2954
+ (!unionContainerArmsOk(joinArms) ||
2955
+ joinArms.some((a) => a.kind === "dyn" || a.kind === "generator" || a.kind === "caught"))) {
2956
+ return null;
2957
+ }
2958
+ joinArms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
2959
+ const type = joinArms.length === 1
2960
+ ? joinArms[0]
2961
+ : { kind: "union", unionId: lowerer.unions.intern(joinArms) };
2962
+ // Pass 2: every arm's answer must SURFACE as the join, and index arms
2963
+ // must pass the single-record keyed-read constraints (the helper is
2964
+ // shared with recordKeyGet, its missing-key policy included).
2965
+ const surfaces = (t) => typeEquals(t, type) ||
2966
+ (type.kind === "union" && lowerer.armTag(type.unionId, t) >= 0) ||
2967
+ exactUnionWidening(lowerer, t, type);
2968
+ for (const arm of def.arms) {
2969
+ if (isUnitType(arm)) {
2970
+ if (!(type.kind === "union" && lowerer.armTag(type.unionId, UNDEFINED_T) >= 0))
2971
+ return null;
2972
+ continue;
2973
+ }
2974
+ if (key.type.kind === "f64") {
2975
+ if (arm.kind !== "array" || !surfaces(arm.elem))
2976
+ return null;
2977
+ continue;
2978
+ }
2979
+ if (arm.kind !== "record")
2980
+ return null;
2981
+ const shape = lowerer.shapes.get(arm.shapeId);
2982
+ if (!shape)
2983
+ return null;
2984
+ const declared = literalField !== null ? shape.fields.find((f) => f.name === literalField)?.type : undefined;
2985
+ if (declared) {
2986
+ if (!surfaces(declared))
2987
+ return null;
2988
+ continue;
2989
+ }
2990
+ const ovfShape = literalField !== null && shape.indexValue ? { ...shape, fields: [] } : shape;
2991
+ if (!recordKeyResultOk(lowerer, ovfShape, type))
2992
+ return null;
2993
+ }
2994
+ return { kind: "unionKeyGet", unionId, key, value, type, loc: locOf(expr) };
2995
+ }
2996
+ /** A structural TypeScript view does not change a nominal object's layout
2997
+ * or accessor dispatch. Resolve the property from the represented class;
2998
+ * the optional checker view must not turn its getter into a record read. */
2999
+ export function classFieldTarget(lowerer, receiverNode, receiverType, fieldName, saved) {
3000
+ const represented = saved ?? lowerer.lowerExpr(receiverNode);
3001
+ if (represented.type.kind === "dyn" &&
3002
+ isJsSourceFile(ts.getSourceFileOfNode(receiverNode)) &&
3003
+ !fieldName.startsWith("#")) {
3004
+ return { container: "dynamic", obj: represented, field: fieldName, fieldType: DYN };
3005
+ }
3006
+ const info = lowerer.classes.get(receiverType.className);
3007
+ if (!info) {
3008
+ // A receiver typed as a class whose collection deferred: the
3009
+ // deferred diagnostics are what explains the miss.
3010
+ lowerer.flushDeferredClass(receiverType.className);
3011
+ return null;
3012
+ }
3013
+ const fieldType = info.fields.get(fieldName);
3014
+ const lowerObjectReceiver = () => {
3015
+ let obj = represented;
3016
+ if (obj.type.kind === "union") {
3017
+ // A receiver that may hold a missing value (a field assigned an
3018
+ // unchecked read): Node's member-read TypeError for the unit arm.
3019
+ const present = lowerer.runtimeOptionalPropertyReceiver(receiverNode, obj, receiverType, fieldName);
3020
+ if (present)
3021
+ return present;
3022
+ const helper = lowerer.narrowedArmHelper(obj.type.unionId, receiverType, locOf(receiverNode));
3023
+ obj = helper
3024
+ ? lowerer.checkedNarrowCall(helper, obj, receiverType, locOf(receiverNode))
3025
+ : lowerer.maybeNarrow(obj, receiverNode);
3026
+ }
3027
+ return lowerer.coerceInto(receiverNode, obj, receiverType);
3028
+ };
3029
+ if (fieldName === "cause" && receiverType.className !== "%DOMException") {
3030
+ let root = info;
3031
+ while (root.base)
3032
+ root = root.base;
3033
+ if (root.def.name === "%Error") {
3034
+ return {
3035
+ container: "errorCause",
3036
+ obj: lowerObjectReceiver(),
3037
+ field: "cause",
3038
+ fieldType: DYN,
3039
+ };
3040
+ }
3041
+ }
3042
+ if (fieldType) {
3043
+ const obj = lowerObjectReceiver();
3044
+ if (isJsSourceFile(ts.getSourceFileOfNode(receiverNode)) &&
3045
+ !fieldName.startsWith("#") &&
3046
+ [...lowerer.classes.values()].some((candidate) => lowerer.isSubclassOf(candidate.def.name, receiverType.className) &&
3047
+ (candidate.methods.has(`get:${fieldName}`) || candidate.methods.has(`set:${fieldName}`)))) {
3048
+ return {
3049
+ container: "dynamic",
3050
+ obj: lowerer.coerceToExpected(obj, DYN),
3051
+ field: fieldName,
3052
+ fieldType: DYN,
3053
+ };
3054
+ }
3055
+ return {
3056
+ container: "class",
3057
+ obj,
3058
+ className: receiverType.className,
3059
+ field: fieldName,
3060
+ fieldType,
3061
+ };
3062
+ }
3063
+ // Accessor property: either half declared anywhere on the chain
3064
+ // makes the name an accessor target (fields and accessors share a
3065
+ // namespace — tsc rejects mixing them, so the halves agree on kind).
3066
+ const getF = lowerer.findMethodOn(info, `get:${fieldName}`);
3067
+ const setF = lowerer.findMethodOn(info, `set:${fieldName}`);
3068
+ if (getF || setF) {
3069
+ const obj = lowerObjectReceiver();
3070
+ return {
3071
+ container: "accessor",
3072
+ obj,
3073
+ className: receiverType.className,
3074
+ field: fieldName,
3075
+ fieldType: getF ? getF.sig.ret : setF.sig.params[0].type,
3076
+ };
3077
+ }
3078
+ if (info.decl && isJsSourceFile(ts.getSourceFileOfNode(info.decl))) {
3079
+ const property = lowerer.checker.getPropertyOfType(lowerer.checker.getTypeAtLocation(receiverNode), fieldName);
3080
+ if (property &&
3081
+ property.declarations.some((declaration) => ts.isPropertyAccessExpression(declaration) ||
3082
+ ts.isBinaryExpression(declaration) ||
3083
+ ts.isElementAccessExpression(declaration))) {
3084
+ return {
3085
+ container: "dynamic",
3086
+ obj: lowerer.coerceToExpected(lowerObjectReceiver(), DYN),
3087
+ field: fieldName,
3088
+ fieldType: DYN,
3089
+ };
3090
+ }
3091
+ }
3092
+ return null;
3093
+ }
3094
+ /** Recognizes `obj.field` as an assignable field target: receiver is a
3095
+ * known class instance OR a record, and the member is a field or (class
3096
+ * receivers) a declared accessor property. Returns the pieces of a
3097
+ * fieldSet/recordSet/accessor-call (minus value/kind) or null. */
3098
+ export function fieldTarget(lowerer, access) {
3099
+ if (lowerer.cjsLocalModuleBindingOf(access.expression))
3100
+ return null;
3101
+ // `module.exports` / `module.id`: CommonJS module surface, never a field.
3102
+ if (isCjsModuleGlobal(lowerer, access.expression))
3103
+ return null;
3104
+ if (isCjsExportsIdentifier(lowerer, access.expression))
3105
+ return null;
3106
+ if (lowerer.chainBlocked(access))
3107
+ return null;
3108
+ if (access.name.text === "stackTraceLimit" &&
3109
+ lowerer.isStdlibGlobal(access.expression, "Error")) {
3110
+ return {
3111
+ container: "errorStackLimit",
3112
+ obj: { kind: "numLit", value: 0, type: F64, loc: locOf(access) },
3113
+ field: "stackTraceLimit",
3114
+ fieldType: F64,
3115
+ };
3116
+ }
3117
+ // `this.#x` in a function-local class's prototype method: the field of
3118
+ // the brand-checked receiver (checkedPrivateReceiver).
3119
+ if (ts.isPrivateIdentifier(access.name) &&
3120
+ access.expression.kind === ts.SyntaxKind.ThisKeyword &&
3121
+ lowerer.resolveThis()?.type.kind === "dyn") {
3122
+ const owner = localPrivateBrandClass(lowerer, access.name);
3123
+ if (owner) {
3124
+ const ownerType = {
3125
+ kind: "object",
3126
+ className: owner.info.def.name,
3127
+ };
3128
+ return classFieldTarget(lowerer, access.expression, ownerType, access.name.text);
3129
+ }
3130
+ }
3131
+ const stored = ts.isIdentifier(access.expression)
3132
+ ? (lowerer.peekLocal(access.expression)?.type ?? lowerer.globalOf(access.expression)?.type)
3133
+ : undefined;
3134
+ const narrowed = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
3135
+ // Structural record views retain their storage layout, while a nominal
3136
+ // subclass guard proves a more specific layout of the same object.
3137
+ const receiverIr = stored?.kind === "record"
3138
+ ? stored
3139
+ : stored?.kind === "object" &&
3140
+ !(narrowed?.kind === "object" &&
3141
+ lowerer.isSubclassOf(narrowed.className, stored.className))
3142
+ ? stored
3143
+ : narrowed;
3144
+ if (receiverIr?.kind === "object") {
3145
+ const target = classFieldTarget(lowerer, access.expression, receiverIr, access.name.text);
3146
+ if (target)
3147
+ return target;
3148
+ // Abstract properties declare no base storage. Resolve the concrete
3149
+ // instance's live field or accessor through the existing class bridge;
3150
+ // inventing a shared field offset would misread subclass layouts.
3151
+ if (abstractPropertyDeclOf(lowerer, access)) {
3152
+ return {
3153
+ container: "dynamic",
3154
+ obj: lowerer.coerceInto(access.expression, lowerer.lowerExpr(access.expression), DYN),
3155
+ field: access.name.text,
3156
+ fieldType: lowerer.irTypeOf(access),
3157
+ };
3158
+ }
3159
+ return null;
3160
+ }
3161
+ if (receiverIr?.kind === "union" && hasClassPayload(lowerer, receiverIr)) {
3162
+ return representedClassFieldTarget(lowerer, access.expression, access.name.text, lowerer.lowerExpr(access.expression));
3163
+ }
3164
+ if (receiverIr?.kind === "record") {
3165
+ const shape = lowerer.shapes.get(receiverIr.shapeId);
3166
+ const fieldType = shape?.fields.find((f) => f.name === access.name.text)?.type;
3167
+ if (fieldType) {
3168
+ let obj = lowerer.lowerExpr(access.expression);
3169
+ const nominal = representedClassFieldTarget(lowerer, access.expression, access.name.text, obj);
3170
+ if (nominal)
3171
+ return nominal;
3172
+ // A checker-record receiver whose VALUE stayed dyn (the erased
3173
+ // all-unknown-fields cast — `(err as { code?: unknown }).code`):
3174
+ // decline, and the dyn keyed-read fallback answers.
3175
+ if (obj.type.kind === "union" && lowerer.armTag(obj.type.unionId, UNDEFINED_T) >= 0) {
3176
+ // A nested property read such as `rows[i].value` or
3177
+ // `table[k].value`: the outer read can miss. Validate the record
3178
+ // arm before fieldGet/recordGet so a missing outer value raises
3179
+ // Node's TypeError rather than reaching the backend with a union
3180
+ // receiver.
3181
+ const present = lowerer.stripUndefinedArm(obj.type);
3182
+ const parent = access.parent;
3183
+ const written = parent !== undefined &&
3184
+ ts.isBinaryExpression(parent) &&
3185
+ parent.left === access &&
3186
+ parent.operatorToken.kind === ts.SyntaxKind.EqualsToken;
3187
+ const helper = present.kind === "record"
3188
+ ? lowerer.narrowedArmHelper(obj.type.unionId, present, locOf(access.expression))
3189
+ : null;
3190
+ obj =
3191
+ (present.kind === "record"
3192
+ ? lowerer.runtimeOptionalPropertyReceiver(access.expression, obj, present, access.name.text, written ? "set" : "read")
3193
+ : null) ??
3194
+ (helper
3195
+ ? lowerer.checkedNarrowCall(helper, obj, present, locOf(access.expression))
3196
+ : lowerer.maybeNarrow(obj, access.expression));
3197
+ }
3198
+ if (obj.type.kind !== "record")
3199
+ return null;
3200
+ const actualShape = lowerer.shapes.get(obj.type.shapeId);
3201
+ const actualField = actualShape?.fields.find((f) => f.name === access.name.text);
3202
+ return {
3203
+ container: "record",
3204
+ obj,
3205
+ shapeId: obj.type.shapeId,
3206
+ field: access.name.text,
3207
+ fieldType: actualField?.type ?? fieldType,
3208
+ };
3209
+ }
3210
+ // A RECORD accessor property: either slot present makes the name an
3211
+ // accessor target (get/set share the property namespace — tsc
3212
+ // rejects mixing an accessor with a data property, so the halves
3213
+ // agree). Reads dispatch the %get: closure, writes the %set: one.
3214
+ {
3215
+ const getSlot = shape?.fields.find((f) => f.name === `%get:${access.name.text}`)?.type;
3216
+ const setSlot = shape?.fields.find((f) => f.name === `%set:${access.name.text}`)?.type;
3217
+ if (getSlot?.kind === "func" || setSlot?.kind === "func") {
3218
+ const obj = lowerer.lowerExpr(access.expression);
3219
+ if (obj.type.kind !== "record")
3220
+ return null; // dyn-valued receiver: the keyed fallback answers
3221
+ const getType = getSlot?.kind === "func" ? getSlot : undefined;
3222
+ const setType = setSlot?.kind === "func" ? setSlot : undefined;
3223
+ return {
3224
+ container: "recordAccessor",
3225
+ obj,
3226
+ shapeId: receiverIr.shapeId,
3227
+ field: access.name.text,
3228
+ fieldType: getType ? getType.ret : setType.params[0],
3229
+ ...(getType ? { getType } : {}),
3230
+ ...(setType ? { setType } : {}),
3231
+ };
3232
+ }
3233
+ }
3234
+ // Dot access to an UNDECLARED key of an index-signature shape: tsc
3235
+ // types it through the signature — the access resolves to NO property
3236
+ // symbol (mapped types like Record<string, T>) or to the signature's
3237
+ // own `__index` symbol (interface-declared signatures). A real member
3238
+ // symbol means a lib member like `toString` — not an index access;
3239
+ // those keep their fences below. It IS the bracket access in dot
3240
+ // spelling — the same overflow path.
3241
+ const nameSym = lowerer.checker.getSymbolAtLocation(access.name);
3242
+ if (shape?.indexValue && !shape.tuple) {
3243
+ // A member the shape CANONICALIZATION dropped into the overflow
3244
+ // (the header family: @types declares `host?: string` on
3245
+ // IncomingHttpHeaders while the canonical shape is a pure index
3246
+ // record) is the bracket access in dot spelling too: a PROPERTY
3247
+ // declaration whose own type fits within the index value. METHOD
3248
+ // members (`toString` — the lib's inherited surface) keep their
3249
+ // fences: JS finds the prototype function, never an overflow miss.
3250
+ const canonicalized = () => {
3251
+ if (!nameSym)
3252
+ return false;
3253
+ const nameDecls = nameSym.declarations;
3254
+ if (!nameDecls.length)
3255
+ return false;
3256
+ if (!nameDecls.every((d) => ts.isPropertySignature(d)))
3257
+ return false;
3258
+ const declared = lowerer.mapTypeOf(lowerer.typeOf(access));
3259
+ if (!declared)
3260
+ return false;
3261
+ const iv = shape.indexValue;
3262
+ if (typeEquals(declared, iv))
3263
+ return true;
3264
+ if (iv.kind !== "union")
3265
+ return false;
3266
+ const ivArms = lowerer.unions.get(iv.unionId)?.arms;
3267
+ if (!ivArms)
3268
+ return false;
3269
+ const declaredArms = declared.kind === "union"
3270
+ ? (lowerer.unions.get(declared.unionId)?.arms ?? [declared])
3271
+ : [declared];
3272
+ return declaredArms.every((a) => ivArms.some((b) => typeEquals(a, b)));
3273
+ };
3274
+ if (!nameSym || ts.symbolName(nameSym) === ts.InternalSymbolName.Index || canonicalized()) {
3275
+ let obj = lowerer.lowerExpr(access.expression);
3276
+ if (obj.type.kind === "union" && lowerer.armTag(obj.type.unionId, UNDEFINED_T) >= 0) {
3277
+ const present = lowerer.stripUndefinedArm(obj.type);
3278
+ obj =
3279
+ present.kind === "record"
3280
+ ? (lowerer.runtimeOptionalPropertyReceiver(access.expression, obj, present, access.name.text) ?? obj)
3281
+ : lowerer.maybeNarrow(obj, access.expression);
3282
+ }
3283
+ if (obj.type.kind !== "record")
3284
+ return null;
3285
+ const actualShape = lowerer.shapes.get(obj.type.shapeId);
3286
+ if (!actualShape?.indexValue)
3287
+ return null;
3288
+ return {
3289
+ container: "recordOvf",
3290
+ obj,
3291
+ shapeId: obj.type.shapeId,
3292
+ field: access.name.text,
3293
+ fieldType: actualShape.indexValue,
3294
+ };
3295
+ }
3296
+ }
3297
+ return null;
3298
+ }
3299
+ return null;
3300
+ }
3301
+ /** The read expression for a field target (fieldGet / recordGet /
3302
+ * getter call). `blame` locates the rejection of a setter-only read —
3303
+ * tsc-clean (the property types as the setter's param), but Node yields
3304
+ * undefined, which these property types cannot represent. */
3305
+ export function fieldGetExpr(lowerer, target, loc, blame) {
3306
+ // A member read through an unassigned deferred-init field throws Node's
3307
+ // member-read TypeError instead of the generic checked extraction.
3308
+ if (target.container === "class" &&
3309
+ ts.isPropertyAccessExpression(blame) &&
3310
+ target.obj.type.kind === "object" &&
3311
+ lowerer.deferredFieldSlot(target.obj) !== null) {
3312
+ const checked = lowerer.runtimeOptionalPropertyReceiver(blame.expression, target.obj, target.obj.type, target.field);
3313
+ if (checked)
3314
+ target = { ...target, obj: checked };
3315
+ }
3316
+ if (target.container === "recordKeyed")
3317
+ return keyedFieldRead(lowerer, target, loc);
3318
+ if (target.container === "dynamic")
3319
+ return lowerer.coerceInto(blame, {
3320
+ kind: "dynKeyGet",
3321
+ value: target.obj,
3322
+ key: { kind: "strLit", value: target.field, type: STRING, loc },
3323
+ type: DYN,
3324
+ loc,
3325
+ }, target.fieldType);
3326
+ if (target.container === "class" &&
3327
+ (target.field === "message" || target.field === "name") &&
3328
+ (target.className === "%Error" || lowerer.isSubclassOf(target.className, "%Error")))
3329
+ return errorPropertyRead(lowerer, target.obj, target.field);
3330
+ if (target.container === "errorStackLimit") {
3331
+ return { kind: "libCall", fn: "error.stackLimitGet", args: [], type: F64, loc };
3332
+ }
3333
+ if (target.container === "errorCause") {
3334
+ return { kind: "libCall", fn: "error.cause", args: [target.obj], type: DYN, loc };
3335
+ }
3336
+ // A record-shaped CHECKER target whose receiver VALUE lives in the checked-dynamic tree
3337
+ // (a JS file-scope object-literal global): the checked-dynamic keyed
3338
+ // read — dynKeyGet (a missing key answers the dyn undefined, exactly
3339
+ // JS); consumers validate (dynCheck) where a static type is required.
3340
+ if ((target.container === "record" || target.container === "recordOvf") &&
3341
+ target.obj.type.kind === "dyn") {
3342
+ return {
3343
+ kind: "dynKeyGet",
3344
+ key: { kind: "strLit", value: target.field, type: STRING, loc },
3345
+ value: target.obj,
3346
+ type: DYN,
3347
+ loc,
3348
+ };
3349
+ }
3350
+ if (target.container === "accessor") {
3351
+ const getF = lowerer.findMethodOn(lowerer.classes.get(target.className) ?? null, `get:${target.field}`);
3352
+ if (!getF) {
3353
+ lowerer.unsupported("SC1090", blame, `reading a property that has only a setter ('${target.field}' — Node would yield undefined)`);
3354
+ }
3355
+ if (!target.field.startsWith("#") &&
3356
+ isJsSourceFile(ts.getSourceFileOfNode(blame)) &&
3357
+ lowerer.dynConvertible(getF.sig.ret)) {
3358
+ const value = {
3359
+ kind: "dynKeyGet",
3360
+ value: lowerer.coerceToExpected(target.obj, DYN),
3361
+ key: { kind: "strLit", value: target.field, type: STRING, loc },
3362
+ type: DYN,
3363
+ loc,
3364
+ };
3365
+ return lowerer.coerceToExpected(value, getF.sig.ret);
3366
+ }
3367
+ return lowerer.accessorCall(target.className, `get:${target.field}`, target.obj, [], getF.sig.ret, loc);
3368
+ }
3369
+ // Record accessor properties: the read IS a call of the %get: closure
3370
+ // — once per read, side effects and all (JS's evaluation). The
3371
+ // setter-only read keeps the class-path fence: the property types as
3372
+ // the setter's param where Node yields undefined.
3373
+ if (target.container === "recordAccessor") {
3374
+ if (!target.getType) {
3375
+ lowerer.unsupported("SC1090", blame, `reading a property that has only a setter ('${target.field}' — Node would yield undefined)`);
3376
+ }
3377
+ const closure = {
3378
+ kind: "recordGet",
3379
+ obj: target.obj,
3380
+ shapeId: target.shapeId,
3381
+ field: `%get:${target.field}`,
3382
+ type: target.getType,
3383
+ loc,
3384
+ };
3385
+ return { kind: "callValue", callee: closure, args: [], type: target.getType.ret, loc };
3386
+ }
3387
+ // Overflow dot reads: exactly the bracket read with a literal key —
3388
+ // recordKeyGet, overflowOnly (the name declares no field by
3389
+ // construction), typed as the index value armed with undefined
3390
+ // (mirroring lowerRecordKeyRead).
3391
+ if (target.container === "recordOvf") {
3392
+ let obj = target.obj;
3393
+ if (obj.type.kind === "union" && ts.isPropertyAccessExpression(blame)) {
3394
+ const present = lowerer.stripUndefinedArm(obj.type);
3395
+ if (present.kind === "record") {
3396
+ obj =
3397
+ lowerer.runtimeOptionalPropertyReceiver(blame.expression, obj, present, target.field) ??
3398
+ obj;
3399
+ }
3400
+ }
3401
+ if (obj.type.kind !== "record") {
3402
+ lowerer.unsupported("SC1090", blame, `reading '${target.field}' on a non-record receiver (narrow first)`);
3403
+ }
3404
+ const shape = lowerer.shapes.get(obj.type.shapeId);
3405
+ if (!shape?.indexValue)
3406
+ lowerer.unsupported("SC1090", blame, `reading '${target.field}' on a record without an index signature`);
3407
+ let t = shape.indexValue;
3408
+ if (t.kind !== "dyn") {
3409
+ const armed = lowerer.withUndefinedArmOf(t);
3410
+ if (!armed)
3411
+ lowerer.badType(blame, lowerer.typeOf(blame));
3412
+ t = armed;
3413
+ }
3414
+ return {
3415
+ kind: "recordKeyGet",
3416
+ obj,
3417
+ shapeId: obj.type.shapeId,
3418
+ key: { kind: "strLit", value: target.field, type: STRING, loc },
3419
+ overflowOnly: true,
3420
+ type: t,
3421
+ loc,
3422
+ };
3423
+ }
3424
+ if (target.container === "class") {
3425
+ const read = {
3426
+ kind: "fieldGet",
3427
+ obj: target.obj,
3428
+ className: target.className,
3429
+ field: target.field,
3430
+ type: target.fieldType,
3431
+ loc,
3432
+ };
3433
+ // DEFERRED-INIT fields (`stream!: T` assigned past the constructor's
3434
+ // top level — ClassInfo.deferredInitFields): the SLOT is the
3435
+ // undefined-armed union; the read CHECKED-extracts the declared type
3436
+ // — a genuinely unassigned read throws the catchable TypeError
3437
+ // where Node reads an undefined the declared type cannot hold.
3438
+ if (lowerer.classes.get(target.className)?.deferredInitFields?.has(target.field) === true &&
3439
+ target.fieldType.kind === "union") {
3440
+ const inner = lowerer.stripUndefinedArm(target.fieldType);
3441
+ // Reference arms over a stable receiver check inline: the present
3442
+ // arm is a plain projection of the slot, so ordinary reads keep their
3443
+ // borrowed form and only an unassigned slot reaches the throw.
3444
+ const unionId = target.fieldType.unionId;
3445
+ const presentTag = lowerer.armTag(unionId, inner);
3446
+ const undefTag = lowerer.armTag(unionId, UNDEFINED_T);
3447
+ if (inner.kind === "object" &&
3448
+ presentTag >= 0 &&
3449
+ undefTag >= 0 &&
3450
+ lowerer.unions.get(unionId)?.arms.length === 2 &&
3451
+ isSafeToRepeat(read)) {
3452
+ return {
3453
+ kind: "ternary",
3454
+ cond: {
3455
+ kind: "unionIsTag",
3456
+ unionId,
3457
+ tag: undefTag,
3458
+ negated: false,
3459
+ value: read,
3460
+ type: BOOL,
3461
+ loc,
3462
+ },
3463
+ then: nodeThrowExpr(1, "", DEFERRED_READ_MESSAGE, inner, loc),
3464
+ else_: { kind: "unionNarrow", unionId, tag: presentTag, value: read, type: inner, loc },
3465
+ type: inner,
3466
+ loc,
3467
+ };
3468
+ }
3469
+ const helper = lowerer.deferredReadHelper(target.fieldType.unionId, inner, loc);
3470
+ if (helper)
3471
+ return { kind: "call", callee: helper, args: [read], type: inner, loc };
3472
+ }
3473
+ return read;
3474
+ }
3475
+ return {
3476
+ kind: "recordGet",
3477
+ obj: target.obj,
3478
+ shapeId: target.shapeId,
3479
+ field: target.field,
3480
+ type: target.fieldType,
3481
+ loc,
3482
+ };
3483
+ }
3484
+ /** Stream-rooted receivers' property surface (readableEnded, destroyed,
3485
+ * ...): the receiver's mapped class dispatches into lower-stream.ts.
3486
+ * Null off the stream hierarchy or for names the spoke does not own. */
3487
+ function lowerStreamObjectProperty(lowerer, expr) {
3488
+ if (expr.questionDotToken && !lowerer.chainHandled.has(expr))
3489
+ return null;
3490
+ const recvT = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
3491
+ if (recvT?.kind !== "object")
3492
+ return null;
3493
+ const info = lowerer.classes.get(recvT.className);
3494
+ if (!info || streamSidesOf(lowerer, info) === null)
3495
+ return null;
3496
+ if (expr.name.text === "bytesWritten" && isZlibStreamMember(lowerer, expr)) {
3497
+ return lowerZlibStreamBytesWritten(lowerer, expr);
3498
+ }
3499
+ if (isFsStreamMember(lowerer, expr)) {
3500
+ const member = lowerFsStreamProperty(lowerer, expr);
3501
+ if (member)
3502
+ return member;
3503
+ }
3504
+ return lowerStreamProperty(lowerer, expr, info);
3505
+ }
3506
+ /** The builtin constructors JavaScript sources read as real function
3507
+ * values rather than identity tokens: the runtime interns one function per
3508
+ * constructor, and dynamic values answer `.constructor` with the same one,
3509
+ * so `o.constructor === Object` is an exact identity test. */
3510
+ const GLOBAL_CONSTRUCTOR_VALUES = new Set([
3511
+ "Object",
3512
+ "Function",
3513
+ "Date",
3514
+ "RegExp",
3515
+ "Map",
3516
+ "Set",
3517
+ "Promise",
3518
+ "WeakMap",
3519
+ "WeakSet",
3520
+ ]);
3521
+ /** The builtin global functions JavaScript sources read as interned
3522
+ * function values (the `cond ? setImmediate : process.nextTick` feature
3523
+ * probe of bcryptjs and async libraries): typeof answers "function",
3524
+ * identity holds across spellings, and calls run the timer APIs. */
3525
+ const GLOBAL_FUNCTION_VALUES = new Set([
3526
+ "setTimeout",
3527
+ "setInterval",
3528
+ "setImmediate",
3529
+ "clearTimeout",
3530
+ "clearInterval",
3531
+ "clearImmediate",
3532
+ "queueMicrotask",
3533
+ ]);
3534
+ /** A builtin function value: one interned runtime function per name. */
3535
+ export function builtinFunctionValue(name, loc) {
3536
+ return {
3537
+ kind: "libCall",
3538
+ fn: "dyn.builtinFunction",
3539
+ args: [{ kind: "strLit", value: name, type: STRING, loc }],
3540
+ type: DYN,
3541
+ loc,
3542
+ };
3543
+ }
3544
+ /** The value a source reads for the stdlib global `canonical` (builtin
3545
+ * constructors in both languages, builtin functions in JavaScript), or
3546
+ * null when it stays an identity token (JavaScript) or fenced. */
3547
+ export function builtinGlobalValue(canonical, loc, js = false) {
3548
+ if (js && GLOBAL_FUNCTION_VALUES.has(canonical))
3549
+ return builtinFunctionValue(canonical, loc);
3550
+ if (GLOBAL_CONSTRUCTOR_VALUES.has(canonical)) {
3551
+ return {
3552
+ kind: "libCall",
3553
+ fn: "dyn.globalConstructor",
3554
+ args: [{ kind: "strLit", value: canonical, type: STRING, loc }],
3555
+ type: DYN,
3556
+ loc,
3557
+ };
3558
+ }
3559
+ return null;
3560
+ }
3561
+ /** The members the interned builtin function values model (the runtime
3562
+ * answers each one as Node does); any other member read through them would
3563
+ * answer undefined, so it keeps its static lowering or its fence. */
3564
+ const BUILTIN_VALUE_MEMBERS = new Set(["name", "length", "constructor"]);
3565
+ /** The Object statics whose answers for an interned builtin function value
3566
+ * match Node's (identity, and the empty enumerable own-key lists). */
3567
+ const BUILTIN_VALUE_REFLECTION = new Set(["is", "keys", "values", "entries"]);
3568
+ /** The value `builtinGlobalValue` gives the stdlib global `expr` read at its
3569
+ * use site: null when the use reads the global's members (they keep their
3570
+ * lowerings and fences), and SC2020 when it is the target of reflection or
3571
+ * redefinition (`Object.hasOwn(Object, "hasOwn")`,
3572
+ * `Object.defineProperty(Promise, ...)`, `hasOwnProperty.call(Map, ...)`),
3573
+ * which would observe or change members the interned value does not
3574
+ * model. */
3575
+ export function builtinGlobalValueAt(lowerer, expr, canonical, loc, js) {
3576
+ if (readsBuiltinGlobalMembers(expr))
3577
+ return null;
3578
+ const value = builtinGlobalValue(canonical, loc, js);
3579
+ if (value === null)
3580
+ return null;
3581
+ let node = expr;
3582
+ while (node.parent !== undefined && ts.isParenthesizedExpression(node.parent))
3583
+ node = node.parent;
3584
+ const call = node.parent;
3585
+ if (call !== undefined &&
3586
+ ts.isCallExpression(call) &&
3587
+ call.expression !== node &&
3588
+ ts.isPropertyAccessExpression(call.expression)) {
3589
+ const callee = call.expression;
3590
+ const owner = stdlibGlobalNameOf(lowerer, callee.expression);
3591
+ const reflects = owner === "Reflect" ||
3592
+ (owner === "Object" && !BUILTIN_VALUE_REFLECTION.has(callee.name.text)) ||
3593
+ ((callee.name.text === "call" || callee.name.text === "apply") &&
3594
+ call.arguments.nodes[0] === node &&
3595
+ lowerer.isStdlibSymbol(lowerer.checker.getSymbolAtLocation(ts.isPropertyAccessExpression(callee.expression)
3596
+ ? callee.expression.name
3597
+ : callee.expression)));
3598
+ if (reflects) {
3599
+ const name = owner !== null
3600
+ ? `${owner}.${callee.name.text}`
3601
+ : ts.getTextOfNode(callee).replace(/\s+/g, "");
3602
+ lowerer.noLowering(`${name}(${canonical}, ...)`, expr, "builtin constructor and function values model only name, length and constructor, so reflecting on or redefining their members has no lowering");
3603
+ }
3604
+ }
3605
+ return value;
3606
+ }
3607
+ /** Whether the stdlib global `expr` is read for its members (`Map.prototype`,
3608
+ * `Date["UTC"]`, `"prototype" in Map`) rather than as a value. Those reads
3609
+ * keep the global's member lowerings and fences: its interned function value
3610
+ * models only BUILTIN_VALUE_MEMBERS. */
3611
+ function readsBuiltinGlobalMembers(expr) {
3612
+ let node = expr;
3613
+ while (node.parent !== undefined && ts.isParenthesizedExpression(node.parent))
3614
+ node = node.parent;
3615
+ const parent = node.parent;
3616
+ if (parent === undefined)
3617
+ return false;
3618
+ if (ts.isPropertyAccessExpression(parent) && parent.expression === node)
3619
+ return !BUILTIN_VALUE_MEMBERS.has(parent.name.text);
3620
+ if (ts.isElementAccessExpression(parent) && parent.expression === node)
3621
+ return true;
3622
+ return (ts.isBinaryExpression(parent) &&
3623
+ parent.operatorToken.kind === ts.SyntaxKind.InKeyword &&
3624
+ parent.right === node);
3625
+ }
3626
+ /** Reports SC2020 when `access` reads a stdlib static member or the
3627
+ * prototype of a builtin constructor with an interned function value through
3628
+ * a receiver the checker types as the constructor's static side
3629
+ * (`MapConstructor`); null otherwise. Calls that lower statically never
3630
+ * reach the member read. */
3631
+ function fenceBuiltinConstructorStaticRead(lowerer, access) {
3632
+ if (BUILTIN_VALUE_MEMBERS.has(access.name.text))
3633
+ return null;
3634
+ const symbol = lowerer.typeOf(access.expression).getSymbol();
3635
+ if (symbol !== undefined &&
3636
+ ts.symbolName(symbol).endsWith("Constructor") &&
3637
+ GLOBAL_CONSTRUCTOR_VALUES.has(ts.symbolName(symbol).slice(0, -"Constructor".length)) &&
3638
+ lowerer.isStdlibSymbol(symbol))
3639
+ lowerer.stdlibMemberFence(access);
3640
+ return null;
3641
+ }
3642
+ /** Object.prototype members a plain record inherits, read as values. */
3643
+ const OBJECT_PROTOTYPE_VALUE_READS = new Set([
3644
+ "constructor",
3645
+ "valueOf",
3646
+ "toString",
3647
+ "hasOwnProperty",
3648
+ "propertyIsEnumerable",
3649
+ ]);
3650
+ /** Whether `expr` is the callee of a call (`o.toString()`), which keeps its
3651
+ * call lowering rather than reading the member as a value. */
3652
+ function isCalleeOf(expr) {
3653
+ let node = expr;
3654
+ while (node.parent !== undefined && ts.isParenthesizedExpression(node.parent))
3655
+ node = node.parent;
3656
+ const parent = node.parent;
3657
+ return (parent !== undefined &&
3658
+ (ts.isCallExpression(parent) || ts.isNewExpression(parent)) &&
3659
+ parent.expression === node);
3660
+ }
3661
+ /** The constructor a primitive dynamic value answers for `.constructor`:
3662
+ * the same interned closure the `Number`/`String`/`Boolean`/`BigInt`
3663
+ * identifiers read (dequal's `(ctor = foo.constructor) === bar.constructor`
3664
+ * over numbers), or `otherwise` for non-primitives. `value` must be safe to
3665
+ * read repeatedly. */
3666
+ export function primitiveConstructorOr(lowerer, value, otherwise, loc) {
3667
+ let result = otherwise;
3668
+ for (const [test, name] of [
3669
+ ["bigint", "BigInt"],
3670
+ ["boolean", "Boolean"],
3671
+ ["string", "String"],
3672
+ ["number", "Number"],
3673
+ ]) {
3674
+ result = {
3675
+ kind: "ternary",
3676
+ cond: { kind: "dynTest", test, value, type: BOOL, loc },
3677
+ then: {
3678
+ kind: "dynFrom",
3679
+ value: primitiveCtorClosure(lowerer, name, loc, true),
3680
+ type: DYN,
3681
+ loc,
3682
+ },
3683
+ else_: result,
3684
+ type: DYN,
3685
+ loc,
3686
+ };
3687
+ }
3688
+ return result;
3689
+ }
3690
+ /** True when `access` reads a member that JavaScript sources attach to a
3691
+ * function by assignment (`fn.member = value`): the receiver's type is
3692
+ * callable and every declaration of the member is such an assignment in a
3693
+ * JS file. */
3694
+ function jsFunctionExpandoMember(lowerer, access) {
3695
+ if (access.questionDotToken || !ts.isIdentifier(access.name))
3696
+ return false;
3697
+ const recvType = lowerer.typeOf(access.expression);
3698
+ if (lowerer.checker.getCallSignatures(recvType).length === 0)
3699
+ return false;
3700
+ const member = lowerer.checker.getPropertyOfType(recvType, access.name.text);
3701
+ const decls = member ? member.declarations : [];
3702
+ return (decls.length > 0 &&
3703
+ decls.every((d) => {
3704
+ if (!isJsSourceFile(ts.getSourceFileOfNode(d)))
3705
+ return false;
3706
+ const assign = ts.isBinaryExpression(d) ? d : d.parent;
3707
+ return (assign !== undefined &&
3708
+ ts.isBinaryExpression(assign) &&
3709
+ assign.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
3710
+ ts.isPropertyAccessExpression(assign.left));
3711
+ }));
3712
+ }
3713
+ /** Whether the checker declares `name` as a property of `receiver`'s type
3714
+ * (as opposed to reading it through an index signature). */
3715
+ export function declaredMemberOf(lowerer, receiver, name) {
3716
+ const symbol = lowerer.checker.getPropertyOfType(lowerer.typeOf(receiver), name);
3717
+ return !!symbol && symbol.declarations.length > 0;
3718
+ }
3719
+ /** Whether `expr` reads Promise.prototype, directly or as
3720
+ * `promise.constructor.prototype`. The checker types it Promise<any>, but
3721
+ * the value is an ordinary object, so a binding inferred from it stays
3722
+ * checked-dynamic (as in Node, promise methods called on it throw). */
3723
+ export function isPromisePrototypeRead(lowerer, expr) {
3724
+ if (!expr)
3725
+ return false;
3726
+ while (ts.isParenthesizedExpression(expr))
3727
+ expr = expr.expression;
3728
+ if (!ts.isPropertyAccessExpression(expr) || expr.questionDotToken)
3729
+ return false;
3730
+ if (expr.name.text !== "prototype")
3731
+ return false;
3732
+ if (lowerer.stdlibGlobalMember(expr, "Promise") === "prototype")
3733
+ return true;
3734
+ const inner = expr.expression;
3735
+ return (ts.isPropertyAccessExpression(inner) &&
3736
+ !inner.questionDotToken &&
3737
+ inner.name.text === "constructor" &&
3738
+ lowerer.mapTypeOf(lowerer.typeOf(inner.expression))?.kind === "promise");
3739
+ }
3740
+ /** A promise's `constructor` (the Promise constructor value), and
3741
+ * Promise.prototype read as `promise.constructor.prototype` or
3742
+ * `Promise.prototype` (execa's `(async () => {})().constructor.prototype`):
3743
+ * an object holding the runtime's then, catch and finally (thenables.ts).
3744
+ * Null for other reads. */
3745
+ function lowerPromiseConstructorRead(lowerer, expr) {
3746
+ if (expr.questionDotToken)
3747
+ return null;
3748
+ const loc = locOf(expr);
3749
+ const isPromise = (node) => lowerer.mapTypeOf(lowerer.typeOf(node))?.kind === "promise";
3750
+ if (expr.name.text === "prototype") {
3751
+ if (lowerer.stdlibGlobalMember(expr, "Promise") === "prototype")
3752
+ return promisePrototypeValue(lowerer, loc);
3753
+ const inner = expr.expression;
3754
+ if (ts.isPropertyAccessExpression(inner) &&
3755
+ !inner.questionDotToken &&
3756
+ inner.name.text === "constructor" &&
3757
+ isPromise(inner.expression)) {
3758
+ const receiver = lowerer.lowerExpr(inner.expression);
3759
+ const prototype = promisePrototypeValue(lowerer, loc);
3760
+ return isSafeToDiscard(receiver)
3761
+ ? prototype
3762
+ : {
3763
+ kind: "seqExpr",
3764
+ stmts: [{ kind: "exprStmt", expr: receiver, loc }],
3765
+ result: prototype,
3766
+ type: DYN,
3767
+ loc,
3768
+ };
3769
+ }
3770
+ return null;
3771
+ }
3772
+ if (expr.name.text === "constructor" && isPromise(expr.expression)) {
3773
+ const receiver = lowerer.lowerExpr(expr.expression);
3774
+ const ctor = builtinGlobalValue("Promise", loc);
3775
+ return isSafeToDiscard(receiver)
3776
+ ? ctor
3777
+ : {
3778
+ kind: "seqExpr",
3779
+ stmts: [{ kind: "exprStmt", expr: receiver, loc }],
3780
+ result: ctor,
3781
+ type: DYN,
3782
+ loc,
3783
+ };
3784
+ }
3785
+ return null;
3786
+ }
3787
+ //# sourceMappingURL=property-access.js.map