@scriptc/compiler 0.4.6 → 0.4.7

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 (652) hide show
  1. package/ambient/node-fallback/events.d.ts +6 -1
  2. package/ambient/node-fallback/fs-promises.d.ts +1 -1
  3. package/ambient/node-fallback/fs.d.ts +54 -10
  4. package/ambient/node-fallback/http.d.ts +3 -1
  5. package/ambient/node-fallback/net.d.ts +19 -0
  6. package/ambient/node-fallback/querystring.d.ts +3 -3
  7. package/ambient/scriptc-node-fallback.d.ts +58 -13
  8. package/dist/backend/executable-features.js +13 -0
  9. package/dist/backend/executable-features.js.map +1 -1
  10. package/dist/backend/immutability.d.ts +12 -1
  11. package/dist/backend/immutability.js +50 -4
  12. package/dist/backend/immutability.js.map +1 -1
  13. package/dist/backend/immutability.test.js +95 -1
  14. package/dist/backend/immutability.test.js.map +1 -1
  15. package/dist/backend/library-pack.js +2 -0
  16. package/dist/backend/library-pack.js.map +1 -1
  17. package/dist/backend/linker.d.ts +11 -0
  18. package/dist/backend/linker.js +31 -3
  19. package/dist/backend/linker.js.map +1 -1
  20. package/dist/backend/lld.d.ts +7 -2
  21. package/dist/backend/lld.js +5 -3
  22. package/dist/backend/lld.js.map +1 -1
  23. package/dist/backend/lld.test.js +10 -4
  24. package/dist/backend/lld.test.js.map +1 -1
  25. package/dist/backend/llvm/constant-callbacks.test.js +50 -1
  26. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  27. package/dist/backend/llvm/cpu-dispatch.js +6 -5
  28. package/dist/backend/llvm/cpu-dispatch.js.map +1 -1
  29. package/dist/backend/llvm/dyn.d.ts +53 -1
  30. package/dist/backend/llvm/dyn.js +221 -9
  31. package/dist/backend/llvm/dyn.js.map +1 -1
  32. package/dist/backend/llvm/emit-function.js +1 -1
  33. package/dist/backend/llvm/emit-function.js.map +1 -1
  34. package/dist/backend/llvm/emit-module.js +148 -50
  35. package/dist/backend/llvm/emit-module.js.map +1 -1
  36. package/dist/backend/llvm/emit-statements.js +39 -19
  37. package/dist/backend/llvm/emit-statements.js.map +1 -1
  38. package/dist/backend/llvm/emitter.d.ts +29 -2
  39. package/dist/backend/llvm/emitter.js +86 -7
  40. package/dist/backend/llvm/emitter.js.map +1 -1
  41. package/dist/backend/llvm/expr-calls.d.ts +4 -1
  42. package/dist/backend/llvm/expr-calls.js +20 -4
  43. package/dist/backend/llvm/expr-calls.js.map +1 -1
  44. package/dist/backend/llvm/expr-dynamic.js +209 -16
  45. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  46. package/dist/backend/llvm/expr-primitives.js +94 -11
  47. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  48. package/dist/backend/llvm/expr-stream-bridges.d.ts +8 -0
  49. package/dist/backend/llvm/expr-stream-bridges.js +42 -2
  50. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  51. package/dist/backend/llvm/expr-stream-callbacks.d.ts +16 -0
  52. package/dist/backend/llvm/expr-stream-callbacks.js +206 -20
  53. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  54. package/dist/backend/llvm/integer-values.d.ts +2 -0
  55. package/dist/backend/llvm/integer-values.js +6 -0
  56. package/dist/backend/llvm/integer-values.js.map +1 -1
  57. package/dist/backend/llvm/js-ic.d.ts +38 -0
  58. package/dist/backend/llvm/js-ic.js +295 -1
  59. package/dist/backend/llvm/js-ic.js.map +1 -1
  60. package/dist/backend/llvm/lib-dispatch.js +20 -0
  61. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  62. package/dist/backend/llvm/lib-filesystem.js +116 -11
  63. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  64. package/dist/backend/llvm/lib-process.js +136 -24
  65. package/dist/backend/llvm/lib-process.js.map +1 -1
  66. package/dist/backend/llvm/lib-shared.js +70 -0
  67. package/dist/backend/llvm/lib-shared.js.map +1 -1
  68. package/dist/backend/llvm/lib-stream.js +67 -0
  69. package/dist/backend/llvm/lib-stream.js.map +1 -1
  70. package/dist/backend/llvm/loop-entry-versions.d.ts +2 -2
  71. package/dist/backend/llvm/loop-entry-versions.js +43 -21
  72. package/dist/backend/llvm/loop-entry-versions.js.map +1 -1
  73. package/dist/backend/llvm/loop-state.d.ts +7 -1
  74. package/dist/backend/llvm/loop-state.js +20 -2
  75. package/dist/backend/llvm/loop-state.js.map +1 -1
  76. package/dist/backend/llvm/map-number-lookup.d.ts +3 -1
  77. package/dist/backend/llvm/map-number-lookup.js +7 -3
  78. package/dist/backend/llvm/map-number-lookup.js.map +1 -1
  79. package/dist/backend/llvm/map-number-lookup.test.js +52 -11
  80. package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
  81. package/dist/backend/llvm/receiver-brackets.test.d.ts +1 -0
  82. package/dist/backend/llvm/receiver-brackets.test.js +68 -0
  83. package/dist/backend/llvm/receiver-brackets.test.js.map +1 -0
  84. package/dist/backend/llvm/record-views.d.ts +22 -2
  85. package/dist/backend/llvm/record-views.js +139 -10
  86. package/dist/backend/llvm/record-views.js.map +1 -1
  87. package/dist/backend/llvm/record-views.test.js +76 -0
  88. package/dist/backend/llvm/record-views.test.js.map +1 -1
  89. package/dist/backend/llvm/reference-writes.js +1 -0
  90. package/dist/backend/llvm/reference-writes.js.map +1 -1
  91. package/dist/backend/llvm/shapes.d.ts +3 -0
  92. package/dist/backend/llvm/shapes.js +18 -3
  93. package/dist/backend/llvm/shapes.js.map +1 -1
  94. package/dist/backend/llvm/shapes.test.js +4 -0
  95. package/dist/backend/llvm/shapes.test.js.map +1 -1
  96. package/dist/backend/llvm/speculative-integers.d.ts +10 -1
  97. package/dist/backend/llvm/speculative-integers.js +59 -8
  98. package/dist/backend/llvm/speculative-integers.js.map +1 -1
  99. package/dist/backend/llvm/unwind-abi.d.ts +3 -3
  100. package/dist/backend/llvm/unwind-abi.js +8 -3
  101. package/dist/backend/llvm/unwind-abi.js.map +1 -1
  102. package/dist/backend/llvm/walkers.js +1 -1
  103. package/dist/backend/llvm/walkers.js.map +1 -1
  104. package/dist/backend/native/contracts.d.ts +54 -0
  105. package/dist/backend/native/executable.js +87 -5
  106. package/dist/backend/native/executable.js.map +1 -1
  107. package/dist/backend/native/library.js +1 -1
  108. package/dist/backend/native/library.js.map +1 -1
  109. package/dist/backend/native/runtime-inputs.js +5 -1
  110. package/dist/backend/native/runtime-inputs.js.map +1 -1
  111. package/dist/backend/native/vendor.d.ts +1 -1
  112. package/dist/backend/native/vendor.js +1 -1
  113. package/dist/backend/native/vendor.js.map +1 -1
  114. package/dist/backend/native-codegen.js +3 -0
  115. package/dist/backend/native-codegen.js.map +1 -1
  116. package/dist/backend/native-link-info-core.d.ts +43 -0
  117. package/dist/backend/native-link-info-core.js.map +1 -1
  118. package/dist/backend/native-link-info.js +1 -0
  119. package/dist/backend/native-link-info.js.map +1 -1
  120. package/dist/backend/native-profile.d.ts +4 -1
  121. package/dist/backend/native-profile.js +12 -1
  122. package/dist/backend/native-profile.js.map +1 -1
  123. package/dist/backend/native-profile.test.js +10 -0
  124. package/dist/backend/native-profile.test.js.map +1 -1
  125. package/dist/backend/publication.d.ts +4 -1
  126. package/dist/backend/publication.js +4 -2
  127. package/dist/backend/publication.js.map +1 -1
  128. package/dist/backend/runtime-abi.d.ts +2 -2
  129. package/dist/backend/runtime-abi.js +2 -2
  130. package/dist/backend/runtime-pack-core.d.ts +31 -7
  131. package/dist/backend/runtime-pack-core.js +21 -1
  132. package/dist/backend/runtime-pack-core.js.map +1 -1
  133. package/dist/backend/runtime-pack-native.d.ts +18 -1
  134. package/dist/backend/runtime-pack-native.js +138 -29
  135. package/dist/backend/runtime-pack-native.js.map +1 -1
  136. package/dist/backend/runtime-pack-native.test.js +166 -4
  137. package/dist/backend/runtime-pack-native.test.js.map +1 -1
  138. package/dist/backend/runtime-pack-targets.test.js +3 -1
  139. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  140. package/dist/backend/runtime-pack.d.ts +7 -0
  141. package/dist/backend/runtime-pack.js +25 -3
  142. package/dist/backend/runtime-pack.js.map +1 -1
  143. package/dist/backend/runtime-pack.test.js +3 -11
  144. package/dist/backend/runtime-pack.test.js.map +1 -1
  145. package/dist/backend/vendor-archives.d.ts +4 -1
  146. package/dist/backend/vendor-archives.js +264 -3
  147. package/dist/backend/vendor-archives.js.map +1 -1
  148. package/dist/backend/vendor-inputs.d.ts +36 -0
  149. package/dist/backend/vendor-inputs.js +42 -0
  150. package/dist/backend/vendor-inputs.js.map +1 -1
  151. package/dist/backend/vendor-inputs.test.js +28 -1
  152. package/dist/backend/vendor-inputs.test.js.map +1 -1
  153. package/dist/backend/warm-cache.js +2 -0
  154. package/dist/backend/warm-cache.js.map +1 -1
  155. package/dist/compat/fetch-profile.d.ts +7 -1
  156. package/dist/compat/fetch-profile.js +23 -10
  157. package/dist/compat/fetch-profile.js.map +1 -1
  158. package/dist/compile-types.d.ts +7 -0
  159. package/dist/contracts/check.d.ts +3 -0
  160. package/dist/contracts/check.js +18 -5
  161. package/dist/contracts/check.js.map +1 -1
  162. package/dist/coverage/surface-manifest.js +1 -1
  163. package/dist/coverage/surface-manifest.js.map +1 -1
  164. package/dist/diagnostics/codes.d.ts +6 -0
  165. package/dist/diagnostics/codes.js +6 -0
  166. package/dist/diagnostics/codes.js.map +1 -1
  167. package/dist/diagnostics/diagnostic.d.ts +50 -0
  168. package/dist/diagnostics/diagnostic.js +142 -3
  169. package/dist/diagnostics/diagnostic.js.map +1 -1
  170. package/dist/diagnostics/dynamic-tier.js +3 -1
  171. package/dist/diagnostics/dynamic-tier.js.map +1 -1
  172. package/dist/executable/executable-cache.d.ts +29 -0
  173. package/dist/executable/executable-cache.js +18 -0
  174. package/dist/executable/executable-cache.js.map +1 -1
  175. package/dist/executable/executable-cache.test.js +5 -1
  176. package/dist/executable/executable-cache.test.js.map +1 -1
  177. package/dist/executable/prepare.d.ts +13 -3
  178. package/dist/executable/prepare.js +271 -18
  179. package/dist/executable/prepare.js.map +1 -1
  180. package/dist/frontend/early-errors.d.ts +14 -0
  181. package/dist/frontend/early-errors.js +305 -0
  182. package/dist/frontend/early-errors.js.map +1 -0
  183. package/dist/frontend/early-errors.test.d.ts +1 -0
  184. package/dist/frontend/early-errors.test.js +42 -0
  185. package/dist/frontend/early-errors.test.js.map +1 -0
  186. package/dist/frontend/inferred-js-diagnostics.test.js +23 -0
  187. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
  188. package/dist/frontend/input-tracker.d.ts +47 -0
  189. package/dist/frontend/input-tracker.js +173 -36
  190. package/dist/frontend/input-tracker.js.map +1 -1
  191. package/dist/frontend/input-tracker.test.js +86 -2
  192. package/dist/frontend/input-tracker.test.js.map +1 -1
  193. package/dist/frontend/js-inference.d.ts +2 -0
  194. package/dist/frontend/js-inference.js +18 -0
  195. package/dist/frontend/js-inference.js.map +1 -0
  196. package/dist/frontend/lowering/binding-analysis.d.ts +2 -1
  197. package/dist/frontend/lowering/binding-analysis.js +65 -1
  198. package/dist/frontend/lowering/binding-analysis.js.map +1 -1
  199. package/dist/frontend/lowering/builtin-calls.js +9 -0
  200. package/dist/frontend/lowering/builtin-calls.js.map +1 -1
  201. package/dist/frontend/lowering/builtin-namespaces.d.ts +1 -1
  202. package/dist/frontend/lowering/builtin-namespaces.js +19 -2
  203. package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
  204. package/dist/frontend/lowering/builtins/child-process-methods.d.ts +7 -0
  205. package/dist/frontend/lowering/builtins/child-process-methods.js +50 -10
  206. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  207. package/dist/frontend/lowering/builtins/child-process.js +5 -1
  208. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  209. package/dist/frontend/lowering/builtins/dates.d.ts +1 -1
  210. package/dist/frontend/lowering/builtins/dates.js +23 -1
  211. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  212. package/dist/frontend/lowering/builtins/environment.d.ts +55 -0
  213. package/dist/frontend/lowering/builtins/environment.js +213 -2
  214. package/dist/frontend/lowering/builtins/environment.js.map +1 -1
  215. package/dist/frontend/lowering/builtins/filesystem-calls.js +47 -16
  216. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  217. package/dist/frontend/lowering/builtins/filesystem.d.ts +25 -7
  218. package/dist/frontend/lowering/builtins/filesystem.js +185 -16
  219. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  220. package/dist/frontend/lowering/builtins/module-calls.js +39 -2
  221. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  222. package/dist/frontend/lowering/builtins/module-resolution.d.ts +8 -0
  223. package/dist/frontend/lowering/builtins/module-resolution.js +31 -5
  224. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
  225. package/dist/frontend/lowering/builtins/operating-system.d.ts +3 -2
  226. package/dist/frontend/lowering/builtins/operating-system.js +5 -4
  227. package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
  228. package/dist/frontend/lowering/builtins/process.d.ts +17 -1
  229. package/dist/frontend/lowering/builtins/process.js +285 -19
  230. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  231. package/dist/frontend/lowering/builtins/querystring.d.ts +8 -0
  232. package/dist/frontend/lowering/builtins/querystring.js +202 -18
  233. package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
  234. package/dist/frontend/lowering/builtins/readline.js +21 -3
  235. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  236. package/dist/frontend/lowering/builtins/reflection.js +60 -1
  237. package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
  238. package/dist/frontend/lowering/builtins/text-codecs.js +208 -59
  239. package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
  240. package/dist/frontend/lowering/builtins/url.js +20 -1
  241. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  242. package/dist/frontend/lowering/builtins/v8.d.ts +5 -5
  243. package/dist/frontend/lowering/builtins/v8.js +7 -5
  244. package/dist/frontend/lowering/builtins/v8.js.map +1 -1
  245. package/dist/frontend/lowering/builtins/web-streams-dyn.d.ts +17 -2
  246. package/dist/frontend/lowering/builtins/web-streams-dyn.js +97 -9
  247. package/dist/frontend/lowering/builtins/web-streams-dyn.js.map +1 -1
  248. package/dist/frontend/lowering/call-signatures.js +77 -0
  249. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  250. package/dist/frontend/lowering/cjs-exports-object.d.ts +3 -0
  251. package/dist/frontend/lowering/cjs-exports-object.js +1 -1
  252. package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
  253. package/dist/frontend/lowering/cjs-inline-require.js +5 -0
  254. package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
  255. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +5 -0
  256. package/dist/frontend/lowering/class-dynamic-dispatch.js +114 -0
  257. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  258. package/dist/frontend/lowering/class-protocols.js +59 -10
  259. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  260. package/dist/frontend/lowering/class-runtime-statics.js +15 -0
  261. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  262. package/dist/frontend/lowering/class-views.d.ts +13 -0
  263. package/dist/frontend/lowering/class-views.js +51 -0
  264. package/dist/frontend/lowering/class-views.js.map +1 -0
  265. package/dist/frontend/lowering/coercions/function-adapters.d.ts +15 -1
  266. package/dist/frontend/lowering/coercions/function-adapters.js +54 -10
  267. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  268. package/dist/frontend/lowering/coercions/state.d.ts +7 -0
  269. package/dist/frontend/lowering/coercions/state.js +7 -0
  270. package/dist/frontend/lowering/coercions/state.js.map +1 -1
  271. package/dist/frontend/lowering/coercions/structural-plans.js +60 -3
  272. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  273. package/dist/frontend/lowering/coercions/structural.js +29 -1
  274. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  275. package/dist/frontend/lowering/containers/array-callbacks.d.ts +8 -1
  276. package/dist/frontend/lowering/containers/array-callbacks.js +132 -28
  277. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  278. package/dist/frontend/lowering/containers/array-construction.js +16 -5
  279. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  280. package/dist/frontend/lowering/containers/array-methods.js +16 -0
  281. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  282. package/dist/frontend/lowering/containers/bytes.js +4 -0
  283. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  284. package/dist/frontend/lowering/containers/callback-arguments.d.ts +11 -0
  285. package/dist/frontend/lowering/containers/callback-arguments.js +53 -0
  286. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  287. package/dist/frontend/lowering/containers/filter-predicates.d.ts +10 -0
  288. package/dist/frontend/lowering/containers/filter-predicates.js +69 -3
  289. package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
  290. package/dist/frontend/lowering/containers/indexed-objects.js +46 -2
  291. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  292. package/dist/frontend/lowering/expressions/array-literals.d.ts +14 -0
  293. package/dist/frontend/lowering/expressions/array-literals.js +26 -10
  294. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
  295. package/dist/frontend/lowering/expressions/binary.js +104 -12
  296. package/dist/frontend/lowering/expressions/binary.js.map +1 -1
  297. package/dist/frontend/lowering/expressions/element-access.js +121 -4
  298. package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
  299. package/dist/frontend/lowering/expressions/identifiers.js +143 -3
  300. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
  301. package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +11 -1
  302. package/dist/frontend/lowering/expressions/keyed-field-targets.js +22 -1
  303. package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -1
  304. package/dist/frontend/lowering/expressions/narrowing.js +25 -1
  305. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
  306. package/dist/frontend/lowering/expressions/object-literals.d.ts +5 -1
  307. package/dist/frontend/lowering/expressions/object-literals.js +778 -229
  308. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  309. package/dist/frontend/lowering/expressions/optional-chains.js +66 -20
  310. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  311. package/dist/frontend/lowering/expressions/property-access.d.ts +31 -0
  312. package/dist/frontend/lowering/expressions/property-access.js +796 -12
  313. package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
  314. package/dist/frontend/lowering/expressions/relational.js +29 -1
  315. package/dist/frontend/lowering/expressions/relational.js.map +1 -1
  316. package/dist/frontend/lowering/expressions/typeof.js +17 -0
  317. package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
  318. package/dist/frontend/lowering/expressions/updates.js +132 -17
  319. package/dist/frontend/lowering/expressions/updates.js.map +1 -1
  320. package/dist/frontend/lowering/frozen-records.d.ts +6 -0
  321. package/dist/frontend/lowering/frozen-records.js +10 -4
  322. package/dist/frontend/lowering/frozen-records.js.map +1 -1
  323. package/dist/frontend/lowering/frozen-records.test.d.ts +1 -0
  324. package/dist/frontend/lowering/frozen-records.test.js +44 -0
  325. package/dist/frontend/lowering/frozen-records.test.js.map +1 -0
  326. package/dist/frontend/lowering/function-names.d.ts +9 -0
  327. package/dist/frontend/lowering/function-names.js +95 -0
  328. package/dist/frontend/lowering/function-names.js.map +1 -0
  329. package/dist/frontend/lowering/function-returns.js +5 -3
  330. package/dist/frontend/lowering/function-returns.js.map +1 -1
  331. package/dist/frontend/lowering/generic-functions.d.ts +49 -0
  332. package/dist/frontend/lowering/generic-functions.js +365 -7
  333. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  334. package/dist/frontend/lowering/global-values.d.ts +9 -0
  335. package/dist/frontend/lowering/global-values.js +44 -0
  336. package/dist/frontend/lowering/global-values.js.map +1 -1
  337. package/dist/frontend/lowering/handle-properties.js +34 -1
  338. package/dist/frontend/lowering/handle-properties.js.map +1 -1
  339. package/dist/frontend/lowering/key-order-witness.d.ts +54 -0
  340. package/dist/frontend/lowering/key-order-witness.js +546 -5
  341. package/dist/frontend/lowering/key-order-witness.js.map +1 -1
  342. package/dist/frontend/lowering/lib-boundary.js +14 -0
  343. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  344. package/dist/frontend/lowering/lower-assert.js +110 -1
  345. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  346. package/dist/frontend/lowering/lower-builtin-values.d.ts +36 -6
  347. package/dist/frontend/lowering/lower-builtin-values.js +332 -58
  348. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  349. package/dist/frontend/lowering/lower-calls.d.ts +22 -1
  350. package/dist/frontend/lowering/lower-calls.js +427 -48
  351. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  352. package/dist/frontend/lowering/lower-calls.test.d.ts +1 -0
  353. package/dist/frontend/lowering/lower-calls.test.js +78 -0
  354. package/dist/frontend/lowering/lower-calls.test.js.map +1 -0
  355. package/dist/frontend/lowering/lower-classes.d.ts +16 -5
  356. package/dist/frontend/lowering/lower-classes.js +168 -51
  357. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  358. package/dist/frontend/lowering/lower-event-emitter.d.ts +9 -0
  359. package/dist/frontend/lowering/lower-event-emitter.js +383 -41
  360. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  361. package/dist/frontend/lowering/lower-exprs.d.ts +14 -0
  362. package/dist/frontend/lowering/lower-exprs.js +25 -0
  363. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  364. package/dist/frontend/lowering/lower-functions.js +2 -0
  365. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  366. package/dist/frontend/lowering/lower-inspect.js +80 -33
  367. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  368. package/dist/frontend/lowering/lower-modules.js +87 -25
  369. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  370. package/dist/frontend/lowering/lower-node-island.d.ts +35 -4
  371. package/dist/frontend/lowering/lower-node-island.js +456 -61
  372. package/dist/frontend/lowering/lower-node-island.js.map +1 -1
  373. package/dist/frontend/lowering/lower-server.js +160 -9
  374. package/dist/frontend/lowering/lower-server.js.map +1 -1
  375. package/dist/frontend/lowering/lower-shared-modules.js +13 -1
  376. package/dist/frontend/lowering/lower-shared-modules.js.map +1 -1
  377. package/dist/frontend/lowering/lower-stdlib.d.ts +3 -2
  378. package/dist/frontend/lowering/lower-stdlib.js +32 -18
  379. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  380. package/dist/frontend/lowering/lower-stmts.d.ts +21 -4
  381. package/dist/frontend/lowering/lower-stmts.js +580 -103
  382. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  383. package/dist/frontend/lowering/lower-stream.js +126 -8
  384. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  385. package/dist/frontend/lowering/lower-timers.js +133 -21
  386. package/dist/frontend/lowering/lower-timers.js.map +1 -1
  387. package/dist/frontend/lowering/lowerer.d.ts +139 -3
  388. package/dist/frontend/lowering/lowerer.js +579 -43
  389. package/dist/frontend/lowering/lowerer.js.map +1 -1
  390. package/dist/frontend/lowering/lowerer.test.js +1 -1
  391. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  392. package/dist/frontend/lowering/module-namespace-elements.js +15 -0
  393. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  394. package/dist/frontend/lowering/new-target.js +2 -2
  395. package/dist/frontend/lowering/nullish-empty-pattern.d.ts +17 -0
  396. package/dist/frontend/lowering/nullish-empty-pattern.js +118 -0
  397. package/dist/frontend/lowering/nullish-empty-pattern.js.map +1 -0
  398. package/dist/frontend/lowering/partial-assertions.d.ts +39 -0
  399. package/dist/frontend/lowering/partial-assertions.js +195 -0
  400. package/dist/frontend/lowering/partial-assertions.js.map +1 -0
  401. package/dist/frontend/lowering/primitive-wrappers.d.ts +34 -0
  402. package/dist/frontend/lowering/primitive-wrappers.js +220 -0
  403. package/dist/frontend/lowering/primitive-wrappers.js.map +1 -0
  404. package/dist/frontend/lowering/private-statics.d.ts +46 -0
  405. package/dist/frontend/lowering/private-statics.js +322 -0
  406. package/dist/frontend/lowering/private-statics.js.map +1 -0
  407. package/dist/frontend/lowering/record-sources.d.ts +12 -1
  408. package/dist/frontend/lowering/record-sources.js +60 -0
  409. package/dist/frontend/lowering/record-sources.js.map +1 -1
  410. package/dist/frontend/lowering/strict-equality.d.ts +4 -0
  411. package/dist/frontend/lowering/strict-equality.js +14 -0
  412. package/dist/frontend/lowering/strict-equality.js.map +1 -1
  413. package/dist/frontend/lowering/surfaces.d.ts +27 -0
  414. package/dist/frontend/lowering/surfaces.js +135 -62
  415. package/dist/frontend/lowering/surfaces.js.map +1 -1
  416. package/dist/frontend/lowering/unit-journal.d.ts +128 -17
  417. package/dist/frontend/lowering/unit-journal.js +310 -53
  418. package/dist/frontend/lowering/unit-journal.js.map +1 -1
  419. package/dist/frontend/lowering/unit-journal.test.js +91 -3
  420. package/dist/frontend/lowering/unit-journal.test.js.map +1 -1
  421. package/dist/frontend/lowering/unit-reuse.d.ts +92 -0
  422. package/dist/frontend/lowering/unit-reuse.js +1008 -0
  423. package/dist/frontend/lowering/unit-reuse.js.map +1 -0
  424. package/dist/frontend/lowering/width-lift.d.ts +12 -0
  425. package/dist/frontend/npm-file-import.test.d.ts +1 -0
  426. package/dist/frontend/npm-file-import.test.js +76 -0
  427. package/dist/frontend/npm-file-import.test.js.map +1 -0
  428. package/dist/frontend/npm-static.js +17 -2
  429. package/dist/frontend/npm-static.js.map +1 -1
  430. package/dist/frontend/npm.d.ts +9 -0
  431. package/dist/frontend/npm.js +82 -0
  432. package/dist/frontend/npm.js.map +1 -1
  433. package/dist/frontend/pipeline-native.js +2 -1
  434. package/dist/frontend/pipeline-native.js.map +1 -1
  435. package/dist/frontend/pipeline.d.ts +4 -0
  436. package/dist/frontend/pipeline.js +68 -7
  437. package/dist/frontend/pipeline.js.map +1 -1
  438. package/dist/frontend/program-node.d.ts +3 -0
  439. package/dist/frontend/program-node.js +13 -6
  440. package/dist/frontend/program-node.js.map +1 -1
  441. package/dist/frontend/program.d.ts +9 -0
  442. package/dist/frontend/program.js +159 -7
  443. package/dist/frontend/program.js.map +1 -1
  444. package/dist/frontend/provenance-core.js +4 -0
  445. package/dist/frontend/provenance-core.js.map +1 -1
  446. package/dist/frontend/services.d.ts +14 -0
  447. package/dist/frontend/services.js +52 -2
  448. package/dist/frontend/services.js.map +1 -1
  449. package/dist/frontend/services.test.js +61 -1
  450. package/dist/frontend/services.test.js.map +1 -1
  451. package/dist/frontend/shape-inference/analyze.d.ts +5 -0
  452. package/dist/frontend/shape-inference/analyze.js +104 -4
  453. package/dist/frontend/shape-inference/analyze.js.map +1 -1
  454. package/dist/frontend/shape-inference/domain.js +0 -1
  455. package/dist/frontend/shape-inference/domain.js.map +1 -1
  456. package/dist/frontend/shape-inference/index.js +5 -1
  457. package/dist/frontend/shape-inference/index.js.map +1 -1
  458. package/dist/frontend/shape-inference/memo.d.ts +2 -1
  459. package/dist/frontend/shape-inference/memo.js +6 -2
  460. package/dist/frontend/shape-inference/memo.js.map +1 -1
  461. package/dist/frontend/shape-inference/overlay.d.ts +1 -1
  462. package/dist/frontend/shape-inference/overlay.js +116 -2
  463. package/dist/frontend/shape-inference/overlay.js.map +1 -1
  464. package/dist/frontend/shape-inference/static-objects.js +11 -6
  465. package/dist/frontend/shape-inference/static-objects.js.map +1 -1
  466. package/dist/frontend/source-phase-imports.test.d.ts +1 -0
  467. package/dist/frontend/source-phase-imports.test.js +37 -0
  468. package/dist/frontend/source-phase-imports.test.js.map +1 -0
  469. package/dist/frontend/ts7/ast-node.d.ts +6 -1
  470. package/dist/frontend/ts7/ast-node.js +12 -0
  471. package/dist/frontend/ts7/ast-node.js.map +1 -1
  472. package/dist/frontend/ts7/ast-wire-protocols.test.js +11 -3
  473. package/dist/frontend/ts7/ast-wire-protocols.test.js.map +1 -1
  474. package/dist/frontend/ts7/ast-wire.js +3 -5
  475. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  476. package/dist/frontend/ts7/checker-backend.d.ts +13 -0
  477. package/dist/frontend/ts7/checker-backend.js +84 -2
  478. package/dist/frontend/ts7/checker-backend.js.map +1 -1
  479. package/dist/frontend/ts7/checker-backend.test.js +126 -2
  480. package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
  481. package/dist/frontend/ts7/program-host.d.ts +22 -1
  482. package/dist/frontend/ts7/program-host.js +49 -4
  483. package/dist/frontend/ts7/program-host.js.map +1 -1
  484. package/dist/frontend/ts7/program-host.test.js +83 -0
  485. package/dist/frontend/ts7/program-host.test.js.map +1 -1
  486. package/dist/frontend/ts7/rpc-process.d.ts +16 -1
  487. package/dist/frontend/ts7/rpc-process.js +170 -92
  488. package/dist/frontend/ts7/rpc-process.js.map +1 -1
  489. package/dist/frontend/ts7/rpc-process.test.js +49 -21
  490. package/dist/frontend/ts7/rpc-process.test.js.map +1 -1
  491. package/dist/frontend/tsc-codes.js +70 -0
  492. package/dist/frontend/tsc-codes.js.map +1 -1
  493. package/dist/frontend/type-mapper.d.ts +7 -2
  494. package/dist/frontend/type-mapper.js +148 -1
  495. package/dist/frontend/type-mapper.js.map +1 -1
  496. package/dist/index.d.ts +1 -1
  497. package/dist/index.js +152 -8
  498. package/dist/index.js.map +1 -1
  499. package/dist/ir/api.d.ts +1 -1
  500. package/dist/ir/api.js +1 -1
  501. package/dist/ir/api.js.map +1 -1
  502. package/dist/ir/build.d.ts +3 -2
  503. package/dist/ir/build.js +4 -2
  504. package/dist/ir/build.js.map +1 -1
  505. package/dist/ir/builtin-effects.js +53 -0
  506. package/dist/ir/builtin-effects.js.map +1 -1
  507. package/dist/ir/builtin-signatures.d.ts +1 -1
  508. package/dist/ir/builtin-signatures.js +211 -10
  509. package/dist/ir/builtin-signatures.js.map +1 -1
  510. package/dist/ir/codec.d.ts +82 -0
  511. package/dist/ir/codec.generated.d.ts +13 -0
  512. package/dist/ir/codec.generated.js +5274 -0
  513. package/dist/ir/codec.generated.js.map +1 -0
  514. package/dist/ir/codec.js +325 -0
  515. package/dist/ir/codec.js.map +1 -0
  516. package/dist/ir/codec.test.d.ts +1 -0
  517. package/dist/ir/codec.test.js +225 -0
  518. package/dist/ir/codec.test.js.map +1 -0
  519. package/dist/ir/fields.generated.d.ts +20 -10
  520. package/dist/ir/fields.generated.js +1031 -11
  521. package/dist/ir/fields.generated.js.map +1 -1
  522. package/dist/ir/fields.test.js +46 -2
  523. package/dist/ir/fields.test.js.map +1 -1
  524. package/dist/ir/function-references.d.ts +5 -4
  525. package/dist/ir/function-references.js +8 -4
  526. package/dist/ir/function-references.js.map +1 -1
  527. package/dist/ir/function-references.test.js +7 -0
  528. package/dist/ir/function-references.test.js.map +1 -1
  529. package/dist/ir/inline-array-sources.js +4 -1
  530. package/dist/ir/inline-array-sources.js.map +1 -1
  531. package/dist/ir/inline-array-views.d.ts +13 -0
  532. package/dist/ir/inline-array-views.js +944 -0
  533. package/dist/ir/inline-array-views.js.map +1 -0
  534. package/dist/ir/inline-arrays.d.ts +7 -0
  535. package/dist/ir/inline-arrays.js +190 -55
  536. package/dist/ir/inline-arrays.js.map +1 -1
  537. package/dist/ir/inline-arrays.test.js +140 -2
  538. package/dist/ir/inline-arrays.test.js.map +1 -1
  539. package/dist/ir/integer-ranges.js +16 -6
  540. package/dist/ir/integer-ranges.js.map +1 -1
  541. package/dist/ir/ir.d.ts +75 -44
  542. package/dist/ir/ir.js.map +1 -1
  543. package/dist/ir/js-ic.d.ts +10 -9
  544. package/dist/ir/js-ic.js +28 -20
  545. package/dist/ir/js-ic.js.map +1 -1
  546. package/dist/ir/js-ic.test.js +10 -2
  547. package/dist/ir/js-ic.test.js.map +1 -1
  548. package/dist/ir/jsval.js +374 -63
  549. package/dist/ir/jsval.js.map +1 -1
  550. package/dist/ir/jsval.test.js +96 -2
  551. package/dist/ir/jsval.test.js.map +1 -1
  552. package/dist/ir/loop-entry-ranges.js +112 -9
  553. package/dist/ir/loop-entry-ranges.js.map +1 -1
  554. package/dist/ir/loop-entry-ranges.test.js +40 -0
  555. package/dist/ir/loop-entry-ranges.test.js.map +1 -1
  556. package/dist/ir/parameter-versions.d.ts +2 -1
  557. package/dist/ir/parameter-versions.js +3 -1
  558. package/dist/ir/parameter-versions.js.map +1 -1
  559. package/dist/ir/receiver-readers.js +58 -2
  560. package/dist/ir/receiver-readers.js.map +1 -1
  561. package/dist/ir/runtime-features.d.ts +60 -1
  562. package/dist/ir/runtime-features.js +277 -2
  563. package/dist/ir/runtime-features.js.map +1 -1
  564. package/dist/ir/runtime-features.test.js +165 -1
  565. package/dist/ir/runtime-features.test.js.map +1 -1
  566. package/dist/ir/saturating-loop-jams.d.ts +8 -1
  567. package/dist/ir/saturating-loop-jams.js +46 -7
  568. package/dist/ir/saturating-loop-jams.js.map +1 -1
  569. package/dist/ir/saturating-loop-jams.test.js +39 -1
  570. package/dist/ir/saturating-loop-jams.test.js.map +1 -1
  571. package/dist/ir/self-captures.js +8 -1
  572. package/dist/ir/self-captures.js.map +1 -1
  573. package/dist/ir/self-captures.test.js +15 -0
  574. package/dist/ir/self-captures.test.js.map +1 -1
  575. package/dist/ir/serialize.d.ts +3 -2
  576. package/dist/ir/serialize.js +6 -2
  577. package/dist/ir/serialize.js.map +1 -1
  578. package/dist/ir/validate.js +82 -4
  579. package/dist/ir/validate.js.map +1 -1
  580. package/dist/ir/validate.test.js +46 -0
  581. package/dist/ir/validate.test.js.map +1 -1
  582. package/dist/library/ir-policy.js +3 -0
  583. package/dist/library/ir-policy.js.map +1 -1
  584. package/dist/native/cache.js +2 -0
  585. package/dist/native/cache.js.map +1 -1
  586. package/dist/native/cli.js +2 -0
  587. package/dist/native/cli.js.map +1 -1
  588. package/dist/native/compiler.js +8 -2
  589. package/dist/native/compiler.js.map +1 -1
  590. package/dist/native/prepare.js +32 -3
  591. package/dist/native/prepare.js.map +1 -1
  592. package/dist/native/sanitizer.js +53 -3
  593. package/dist/native/sanitizer.js.map +1 -1
  594. package/dist/native/sanitizer.test.js +88 -2
  595. package/dist/native/sanitizer.test.js.map +1 -1
  596. package/dist/native/toolchain.js +9 -2
  597. package/dist/native/toolchain.js.map +1 -1
  598. package/dist/node-islands/boundary.d.ts +25 -1
  599. package/dist/node-islands/boundary.js +28 -2
  600. package/dist/node-islands/boundary.js.map +1 -1
  601. package/dist/node-islands/detect.d.ts +18 -1
  602. package/dist/node-islands/detect.js +365 -40
  603. package/dist/node-islands/detect.js.map +1 -1
  604. package/dist/node-islands/detect.test.js +151 -4
  605. package/dist/node-islands/detect.test.js.map +1 -1
  606. package/dist/node-islands/effect-gate.js +30 -20
  607. package/dist/node-islands/effect-gate.js.map +1 -1
  608. package/dist/node-islands/effect-gate.test.js +4 -1
  609. package/dist/node-islands/effect-gate.test.js.map +1 -1
  610. package/dist/node-islands/libnode.d.ts +1 -1
  611. package/dist/node-islands/libnode.js +1 -1
  612. package/dist/node-islands/libnode.js.map +1 -1
  613. package/dist/node-islands/modules.d.ts +28 -0
  614. package/dist/node-islands/modules.js +156 -0
  615. package/dist/node-islands/modules.js.map +1 -1
  616. package/dist/node-islands/modules.test.js +105 -1
  617. package/dist/node-islands/modules.test.js.map +1 -1
  618. package/dist/node-islands/policy.js +2 -3
  619. package/dist/node-islands/policy.js.map +1 -1
  620. package/dist/node-islands/probe-recorder.d.ts +1 -0
  621. package/dist/node-islands/probe-recorder.js +596 -0
  622. package/dist/node-islands/probe-recorder.js.map +1 -0
  623. package/dist/node-islands/probe-recorder.test.d.ts +1 -0
  624. package/dist/node-islands/probe-recorder.test.js +80 -0
  625. package/dist/node-islands/probe-recorder.test.js.map +1 -0
  626. package/dist/node-islands/report.test.js +2 -0
  627. package/dist/node-islands/report.test.js.map +1 -1
  628. package/dist/node-islands/rules.js +4 -0
  629. package/dist/node-islands/rules.js.map +1 -1
  630. package/dist/node-islands/scan.d.ts +7 -1
  631. package/dist/node-islands/scan.js +51 -2
  632. package/dist/node-islands/scan.js.map +1 -1
  633. package/dist/node-islands/snapshot.d.ts +38 -1
  634. package/dist/node-islands/snapshot.js +165 -161
  635. package/dist/node-islands/snapshot.js.map +1 -1
  636. package/dist/node-islands/snapshot.test.js +63 -2
  637. package/dist/node-islands/snapshot.test.js.map +1 -1
  638. package/dist/node-islands/summary.js +8 -0
  639. package/dist/node-islands/summary.js.map +1 -1
  640. package/dist/node-islands/type-strip.d.ts +11 -0
  641. package/dist/node-islands/type-strip.js +157 -0
  642. package/dist/node-islands/type-strip.js.map +1 -0
  643. package/dist/node-islands/type-strip.test.d.ts +1 -0
  644. package/dist/node-islands/type-strip.test.js +31 -0
  645. package/dist/node-islands/type-strip.test.js.map +1 -0
  646. package/dist/project-config.d.ts +4 -0
  647. package/dist/project-config.js +19 -0
  648. package/dist/project-config.js.map +1 -1
  649. package/dist/project-config.test.js +10 -0
  650. package/dist/project-config.test.js.map +1 -1
  651. package/package.json +20 -20
  652. package/surface-manifest.json +43 -11
@@ -1,23 +1,26 @@
1
+ import { lowerStaticPrivateAssignment } from "./private-statics.js";
1
2
  import { keepsInitializerLayout, notePreservedLayout } from "./structural-instances.js";
3
+ import { partialFieldRead } from "./partial-assertions.js";
2
4
  import { jsGlobalValueByName } from "./global-values.js";
3
5
  import { lowerTupleAliasDecl, stripTypeWrappers } from "./typed-arguments.js";
4
- import { islandHandleBinding, lowerIslandExpr, lowerIslandSubclass } from "./lower-node-island.js";
6
+ import { islandHandleBinding, lowerIslandExpr, isIslandRequireSpec, lowerIslandRequireAtStatement, lowerIslandSubclass, } from "./lower-node-island.js";
5
7
  import { isIslandSubclassDecl } from "../../node-islands/boundary.js";
6
8
  import { allBytesArms, indexedUnionArms, lowerIndexedUnionMember, lowerIndexedUnionNumberRead, lowerIndexedUnionRead, } from "./indexed-unions.js";
7
- import { declaredMemberOf, isPromisePrototypeRead, lowerUnionKeyedRead, } from "./expressions/property-access.js";
9
+ import { declaredMemberOf, fenceDatePrototypeWrite, isPromisePrototypeRead, lowerUnionKeyedRead, } from "./expressions/property-access.js";
8
10
  import { hostedStorageView, hostsAll } from "./expressions/hosted-narrowing.js";
9
11
  import { requestGeneralStreamSurface } from "./general-streams.js";
10
12
  import { lowerForAwaitDynStream, nodeStreamInterfaceSide } from "./dyn-streams.js";
11
13
  import { lowerForAwaitValueStream } from "./builtins/hash-stream.js";
12
14
  import { lowerChildPropertyWrite } from "./handle-properties.js";
13
15
  import { matchAllRowsReadByElements, storedMatchAllRowsReadByElements, } from "./containers/match-row-uses.js";
14
- import { dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../ir/build.js";
16
+ import { dynUndefinedExpr, nodeThrowExpr, numLit, strLit, varRef } from "../../ir/build.js";
15
17
  import { runtimeKeyPatternRead } from "./expressions/keyed-field-targets.js";
16
18
  import { declaresHoistedBinding, staticCondition } from "./static-typeof.js";
17
19
  import { lowerCollectionSpread } from "./containers/collection-methods.js";
18
20
  import { lowerEventObjectPropertyWrite } from "./lower-event-target.js";
19
21
  import { lowerDynObjectLiteral } from "./expressions/object-literals.js";
20
22
  import { importMetaBindingSource } from "./import-meta.js";
23
+ import { nullishEmptyPatternSource } from "./nullish-empty-pattern.js";
21
24
  import { anyResidueReplacedBy } from "./any-collection-residue.js";
22
25
  import { iteratorCanStep, iteratorValue } from "./iterator-consumption.js";
23
26
  import { notIterableSpelling } from "./iterable-spelling.js";
@@ -31,6 +34,7 @@ import { isWebStreamValueInJavaScript, typeInvolvesWebStream } from "./builtins/
31
34
  import * as ts from "../ts7/adapter.js";
32
35
  import { lowerOptionalIndex } from "./undefined-index.js";
33
36
  import { processDataMemberValue, programReadsExitCode } from "./builtins/process.js";
37
+ import { heldEnvValueType, refuseHeldEnvCopyHold } from "./builtins/environment.js";
34
38
  import { requireInitFlagStmt } from "./require-initialization.js";
35
39
  import { isJsonRequireDecl } from "./json-require.js";
36
40
  import { isTimeValueDateDeclaration } from "./date-values.js";
@@ -43,7 +47,7 @@ import { isDeadTscHelperDecl, tscInteropBindingOfDecl } from "./cjs-tsc-interop.
43
47
  import { arrayValueRead, arrayValueStore, arrayValueType, unionArrayValueRead, lowerSafeIndexRead, } from "./array-values.js";
44
48
  import { lowerForAwaitGenerator, lowerForOfGenerator, lowerYieldStarStatement, } from "./lower-generators.js";
45
49
  import { classAsyncGeneratorIterator, lowerForAwaitBuiltin } from "./lower-async-iteration.js";
46
- import { BOOL, BYTES_U8, CAUGHT, DATE_T, DYN, F64, SEARCH_PARAMS_T, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals, } from "../../ir/ir.js";
50
+ import { BOOL, BYTES_U8, CAUGHT, DATE_T, DYN_HANDLE_KINDS, DYN, F64, SEARCH_PARAMS_T, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals, } from "../../ir/ir.js";
47
51
  import { PoisonError, boundIdentifiersOf, dynFallbackType, neverTaintedJsType, staticImportNamespaceType, } from "./lowerer.js";
48
52
  import { enforceLibBoundary, lowerSurplusCalls } from "./lib-boundary.js";
49
53
  import { cjsExportAssignmentOf, cjsExportChainOf, cjsVoidInitPreambleReals, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile, locOf, requireEarlyReference, requireSpecOf, } from "../program.js";
@@ -734,8 +738,11 @@ function lowerOneStatement(lowerer, stmt, out, usingMarkers, diagsBefore, deferF
734
738
  if (deferFences && lowerer.diagSink === null && lowerer.diags.length > diagsBefore) {
735
739
  const flushed = lowerer.diags.splice(diagsBefore);
736
740
  const ice = flushed.filter((d) => d.code === "SC9001");
737
- lowerer.diags.push(...ice);
738
- lowerer.runtimeFences.push(...flushed.filter((d) => d.code !== "SC9001"));
741
+ for (const d of ice)
742
+ lowerer.diags.push(d);
743
+ for (const d of flushed)
744
+ if (d.code !== "SC9001")
745
+ lowerer.runtimeFences.push(d);
739
746
  }
740
747
  }
741
748
  /** Whether a statement list belongs to a function body (at any block
@@ -883,6 +890,11 @@ export function predeclareForwardCapture(lowerer, symbol) {
883
890
  lowerer.isStdlibGlobal(decl.initializer.expression.expression, "Object"))) &&
884
891
  lowerer.dynConvertible(type))
885
892
  type = DYN;
893
+ // An island handle binding holds a checked-dynamic value whatever its
894
+ // declared type says: its own declaration lowers as one, and so must
895
+ // the slot a closure captured first.
896
+ if (islandHandleBinding(lowerer, decl.name))
897
+ type = DYN;
886
898
  if (!TDZ_KINDS.has(type.kind) || isUnitType(type))
887
899
  return false;
888
900
  const name = decl.name.text;
@@ -995,8 +1007,11 @@ export function predeclareForwardFnDecl(lowerer, symbol) {
995
1007
  }
996
1008
  catch (e) {
997
1009
  entry.ctx.hoistedFnDecls.delete(decl);
998
- if (previousSink !== null)
999
- previousSink.push(...lowerer.diags.splice(diagsBefore));
1010
+ if (previousSink !== null) {
1011
+ const flushed = lowerer.diags.splice(diagsBefore);
1012
+ for (const d of flushed)
1013
+ previousSink.push(d);
1014
+ }
1000
1015
  throw e;
1001
1016
  }
1002
1017
  finally {
@@ -1023,7 +1038,9 @@ function hostVariableDeclarationOf(name) {
1023
1038
  while (ts.isBindingElement(n) || ts.isArrayBindingPattern(n) || ts.isObjectBindingPattern(n)) {
1024
1039
  n = n.parent;
1025
1040
  }
1026
- return ts.isVariableDeclaration(n) ? n : null;
1041
+ // A catch parameter is a VariableDeclaration of the CatchClause: its
1042
+ // bindings are scoped to the clause, and each execution makes new ones.
1043
+ return ts.isVariableDeclaration(n) && !ts.isCatchClause(n.parent) ? n : null;
1027
1044
  }
1028
1045
  /** `for (var x of ...)` loop variables: the ONE function-scoped binding
1029
1046
  * every for-of desugar must ASSIGN per iteration instead of declaring a
@@ -1483,10 +1500,12 @@ const THROWN_AS_DYN = new Set([
1483
1500
  ]);
1484
1501
  /** A `return` at the top level of a CommonJS module (preflight admits it
1485
1502
  * there only): it ends the module's evaluation, and its value is
1486
- * evaluated and discarded, as Node's module wrapper does. Top-level
1487
- * bindings and export assignments after it would be left uninitialized
1488
- * where Node leaves them in their temporal dead zone or absent, so a
1489
- * module with any keeps a refusal. Null for a return inside a function. */
1503
+ * evaluated and discarded, as Node's module wrapper does. Bindings
1504
+ * declared after it stay uninitialized when it is taken, which only code
1505
+ * that exists by then can observe: a function created before the return,
1506
+ * or a hoisted function declaration. A module whose such functions read a
1507
+ * later binding, or that assigns exports after the return, keeps a
1508
+ * refusal. Null for a return inside a function. */
1490
1509
  function lowerModuleLevelReturn(lowerer, stmt) {
1491
1510
  let top = stmt;
1492
1511
  while (top.parent !== undefined && !ts.isSourceFile(top.parent)) {
@@ -1498,9 +1517,25 @@ function lowerModuleLevelReturn(lowerer, stmt) {
1498
1517
  if (sf === undefined || !ts.isSourceFile(sf))
1499
1518
  return null;
1500
1519
  const stmts = sf.statements.nodes;
1501
- const later = stmts.slice(stmts.indexOf(top) + 1);
1502
- if (later.some((s) => ts.isVariableStatement(s) || ts.isClassDeclaration(s) || cjsExportAssignmentOf(s) !== null)) {
1503
- lowerer.unsupported("SC1090", stmt, "a top-level return in a CommonJS module that declares variables or classes, or assigns exports, after it");
1520
+ const index = stmts.indexOf(top);
1521
+ const later = stmts.slice(index + 1);
1522
+ if (later.some((s) => cjsExportAssignmentOf(s) !== null)) {
1523
+ lowerer.unsupported("SC1090", stmt, "a top-level return in a CommonJS module that assigns exports after it");
1524
+ }
1525
+ const laterBindings = laterModuleBindings(lowerer, later);
1526
+ if (laterBindings.size > 0) {
1527
+ // Functions that exist when the return is taken: every function in the
1528
+ // statements up to the return, and the hoisted declarations after it.
1529
+ const reachable = [
1530
+ ...stmts.slice(0, index + 1),
1531
+ ...later.filter((s) => ts.isFunctionDeclaration(s)),
1532
+ ];
1533
+ const read = reachable
1534
+ .map((s) => functionReadOf(lowerer, s, laterBindings, ts.isFunctionDeclaration(s)))
1535
+ .find((r) => r !== null);
1536
+ if (read) {
1537
+ lowerer.unsupported("SC1090", read, `reading '${read.text}', declared after a top-level CommonJS return, from a function that can run once the return is taken`);
1538
+ }
1504
1539
  }
1505
1540
  const loc = locOf(stmt);
1506
1541
  const ret = { kind: "return", value: null, loc };
@@ -1512,6 +1547,50 @@ function lowerModuleLevelReturn(lowerer, stmt) {
1512
1547
  loc,
1513
1548
  };
1514
1549
  }
1550
+ /** The module-scope bindings `stmts` declare: variables and classes, with
1551
+ * `var` declarations in nested blocks. Bindings inside functions are not
1552
+ * module-scope and are skipped. */
1553
+ function laterModuleBindings(lowerer, stmts) {
1554
+ const bindings = new Set();
1555
+ const addName = (name) => {
1556
+ if (ts.isIdentifier(name)) {
1557
+ const symbol = lowerer.checker.getSymbolAtLocation(name);
1558
+ if (symbol)
1559
+ bindings.add(symbol);
1560
+ return;
1561
+ }
1562
+ for (const element of name.elements.nodes) {
1563
+ if (ts.isBindingElement(element) && element.name)
1564
+ addName(element.name);
1565
+ }
1566
+ };
1567
+ const visit = (node) => {
1568
+ if (ts.isFunctionLike(node) || ts.isClassStaticBlockDeclaration(node))
1569
+ return;
1570
+ if (ts.isVariableDeclaration(node))
1571
+ addName(node.name);
1572
+ if (ts.isClassDeclaration(node) && node.name)
1573
+ addName(node.name);
1574
+ ts.forEachChild(node, visit);
1575
+ };
1576
+ for (const stmt of stmts)
1577
+ visit(stmt);
1578
+ return bindings;
1579
+ }
1580
+ /** The first identifier inside a function or class in `node` (anywhere in
1581
+ * `node` when `inFunction`) that reads one of `bindings`, or null. */
1582
+ function functionReadOf(lowerer, node, bindings, inFunction) {
1583
+ if (inFunction && ts.isIdentifier(node)) {
1584
+ const symbol = lowerer.resolveValueSymbol(node);
1585
+ return symbol && bindings.has(symbol) ? node : null;
1586
+ }
1587
+ // Class bodies count as functions: field initializers run per instance.
1588
+ const nested = inFunction ||
1589
+ ts.isFunctionLike(node) ||
1590
+ ts.isClassDeclaration(node) ||
1591
+ ts.isClassExpression(node);
1592
+ return (ts.forEachChild(node, (child) => functionReadOf(lowerer, child, bindings, nested) ?? undefined) ?? null);
1593
+ }
1515
1594
  export function lowerStmt(lowerer, stmt) {
1516
1595
  if (ownPrototypeResetStatement(lowerer, stmt))
1517
1596
  return { kind: "block", body: [], loc: locOf(stmt) };
@@ -1865,6 +1944,11 @@ function lowerVarDeclarator(lowerer, stmt, decl, isConst, isLet) {
1865
1944
  if (lowerer.externalTypes.has(spec))
1866
1945
  lowerer.externalHostFence(spec, decl, false);
1867
1946
  if (ts.isSourceFile(stmt.parent)) {
1947
+ // `const x = require("<island>")` and `const { name } = …`: the
1948
+ // island module loads here, at the statement (lower-node-island.ts).
1949
+ const island = lowerIslandRequireAtStatement(lowerer, decl);
1950
+ if (island !== null)
1951
+ return [island];
1868
1952
  const init = lowerer.requireInitStmt(spec, decl);
1869
1953
  const out = init ? [init] : [];
1870
1954
  // Nested patterns destructure the named export's value right after
@@ -1883,6 +1967,12 @@ function lowerVarDeclarator(lowerer, stmt, decl, isConst, isLet) {
1883
1967
  // same routing top-level requires use, and no statement remains.
1884
1968
  // Relative requires keep the fence: their module-init-at-position
1885
1969
  // semantics needs storage this model doesn't represent.
1970
+ // A nested require of an island package is an ordinary binding of the
1971
+ // island module, loaded at the statement (lower-node-island.ts).
1972
+ if (isIslandRequireSpec(lowerer, ts.getSourceFileOfNode(decl).fileName, spec)) {
1973
+ const lowered = lowerer.lowerVarDecl(decl, isLet);
1974
+ return lowered ? [lowered] : [];
1975
+ }
1886
1976
  if (canonicalBuiltinModule(spec) !== null) {
1887
1977
  return canonicalBuiltinModule(spec) === "punycode"
1888
1978
  ? [lowerer.punycodeRequireWarning(decl)]
@@ -2142,6 +2232,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
2142
2232
  return tokenBound;
2143
2233
  }
2144
2234
  let init = importMetaBindingSource(lowerer, decl.name, decl.initializer) ??
2235
+ nullishEmptyPatternSource(lowerer, decl.name, decl.initializer) ??
2145
2236
  lowerer.lowerExpr(decl.initializer);
2146
2237
  const parseArgsDynObject = init.type.kind === "dyn" &&
2147
2238
  isParseArgsDynCheckerType(lowerer, lowerer.typeOf(decl.initializer));
@@ -2187,13 +2278,26 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
2187
2278
  }
2188
2279
  }
2189
2280
  const out = [];
2281
+ // V8's destructuring TypeError spells STATIC sources: an identifier
2282
+ // source reads "<name> is not iterable", an identifier-callee call
2283
+ // "<name> is not a function or its return value is not iterable";
2284
+ // everything else (property reads, method calls, parameters) gets the
2285
+ // runtime kind wording — exactly V8's CallPrinter behavior. The DYN
2286
+ // pattern arm and the unit arms of a narrowed union consume this.
2287
+ const src = decl.initializer;
2288
+ const dynSpell = ts.isIdentifier(src)
2289
+ ? `${src.text} is not iterable`
2290
+ : ts.isCallExpression(src) && ts.isIdentifier(src.expression)
2291
+ ? `${src.expression.text} is not a function or its return value is not iterable`
2292
+ : undefined;
2190
2293
  // JS: a union source with exactly ONE destructurable arm beside unit
2191
2294
  // arms (`nameAndArgs.match(re)` — `RegExpMatchArray | null`, the
2192
2295
  // always-matches idiom) destructures through a VALIDATED narrow: the
2193
- // unit arms throw at runtime exactly where Node's TypeError would
2194
- // (the message is the fence's — a unit value here is the failure
2195
- // path either way). TypeScript keeps the fence: narrowing first is
2196
- // the annotated fix.
2296
+ // unit arms throw Node's TypeError, through the checks a dyn source
2297
+ // takes (RequireObjectCoercible for an object pattern, GetIterator for
2298
+ // an array pattern). An object pattern whose source has no V8
2299
+ // spelling keeps the fence. TypeScript keeps the fence: narrowing
2300
+ // first is the annotated fix.
2197
2301
  if (isJsSourceFile(ts.getSourceFileOfNode(decl)) && init.type.kind === "union") {
2198
2302
  const def = lowerer.unions.get(init.type.unionId);
2199
2303
  const dataArms = (def?.arms ?? []).filter((a) => !isUnitType(a));
@@ -2204,9 +2308,56 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
2204
2308
  def.arms.every((a) => a === arm || isUnitType(a)) &&
2205
2309
  (arm.kind === "array" || arm.kind === "record")) {
2206
2310
  const tag = def.arms.indexOf(arm);
2311
+ const unionId = init.type.unionId;
2207
2312
  const utmp = lowerer.declareHiddenLocal("%destrU", init.type);
2208
2313
  out.push({ kind: "varDecl", localId: utmp.id, init, loc });
2209
2314
  const uref = { kind: "varRef", localId: utmp.id, type: init.type, loc };
2315
+ // The failure branch holds one of the unit arms: the check reads it
2316
+ // as the dyn null or undefined it is, so the data arm needs no dyn
2317
+ // form (a record holding a generator has none).
2318
+ const unitValue = () => {
2319
+ const unitOf = (t) => lowerer.coerceToExpected({ kind: "unitLit", unit: t.kind === "nullT" ? "null" : "undefined", type: t, loc }, DYN);
2320
+ const units = def.arms.filter(isUnitType);
2321
+ const last = units[units.length - 1];
2322
+ return units.slice(0, -1).reduceRight((rest, t) => ({
2323
+ kind: "ternary",
2324
+ cond: {
2325
+ kind: "unionIsTag",
2326
+ unionId,
2327
+ tag: def.arms.indexOf(t),
2328
+ negated: false,
2329
+ value: uref,
2330
+ type: BOOL,
2331
+ loc,
2332
+ },
2333
+ then: unitOf(t),
2334
+ else_: rest,
2335
+ type: DYN,
2336
+ loc,
2337
+ }), unitOf(last));
2338
+ };
2339
+ const spelling = destrSpellingOf(src);
2340
+ const check = ts.isArrayBindingPattern(decl.name)
2341
+ ? {
2342
+ kind: "dynIterN",
2343
+ value: unitValue(),
2344
+ count: decl.name.elements.nodes.length,
2345
+ ...(dynSpell ? { notIterableMessage: dynSpell } : {}),
2346
+ type: DYN,
2347
+ loc,
2348
+ }
2349
+ : firstReadsWithDefault(decl.name)
2350
+ ? firstKeyRead(lowerer, decl.name, unitValue, loc)
2351
+ : spelling !== null
2352
+ ? {
2353
+ kind: "dynDestrCheck",
2354
+ value: unitValue(),
2355
+ spelling,
2356
+ ...firstPatternProp(lowerer, decl.name),
2357
+ type: DYN,
2358
+ loc,
2359
+ }
2360
+ : null;
2210
2361
  out.push({
2211
2362
  kind: "if",
2212
2363
  cond: {
@@ -2219,6 +2370,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
2219
2370
  loc,
2220
2371
  },
2221
2372
  then: [
2373
+ ...(check !== null ? [{ kind: "exprStmt", expr: check, loc }] : []),
2222
2374
  {
2223
2375
  kind: "runtimeFence",
2224
2376
  code: "SC1031",
@@ -2241,58 +2393,40 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
2241
2393
  // value: RequireObjectCoercible with V8's own TypeError ("Cannot
2242
2394
  // destructure property 'a' of 'f(...)' as it is null.") for the source
2243
2395
  // spellings the assignment form reproduces; other sources are refused,
2244
- // as in the assignment form. JavaScript files keep their existing
2245
- // per-read errors, except that a runtime computed first key checks the
2246
- // source first: Node throws before it evaluates any key, and V8's bare
2247
- // message names the source.
2248
- const jsRuntimeKeyCheck = init.type.kind === "dyn" &&
2396
+ // as in the assignment form. A JavaScript object pattern over a dyn
2397
+ // source checks the source first in the same way when V8 can spell it,
2398
+ // so a null or undefined source throws Node's message before any key
2399
+ // is read or evaluated; other sources keep their per-read errors. V8
2400
+ // skips the check when the first element has a default and a static
2401
+ // key: the read of that key throws ("Cannot read properties of null
2402
+ // (reading 'a')"), and so does the lowering's.
2403
+ const jsSourceCheck = init.type.kind === "dyn" &&
2249
2404
  ts.isObjectBindingPattern(decl.name) &&
2250
2405
  isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
2251
- (decl.name.elements.nodes.length === 0 || startsWithRuntimeKey(lowerer, decl.name)) &&
2252
2406
  destrSpellingOf(decl.initializer) !== null;
2253
- if (jsRuntimeKeyCheck ||
2407
+ if ((jsSourceCheck ||
2254
2408
  (init.type.kind === "dyn" &&
2255
2409
  ts.isObjectBindingPattern(decl.name) &&
2256
2410
  !isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
2257
- lowerer.anyOrigin(decl.initializer))) {
2411
+ lowerer.anyOrigin(decl.initializer))) &&
2412
+ !firstReadsWithDefault(decl.name)) {
2258
2413
  const spelling = destrSpellingOf(decl.initializer);
2259
2414
  if (spelling === null) {
2260
2415
  lowerer.unsupported("SC1031", decl.initializer, "destructuring declaration from an `any` source whose expression spelling is unsupported (use a variable, ordinary property chain, or ordinary call)");
2261
2416
  }
2262
- const first = decl.name.elements.nodes[0];
2263
- const firstKey = first === undefined || first.dotDotDotToken !== undefined
2264
- ? undefined
2265
- : (first.propertyName ?? first.name);
2266
- // V8 names the first property when its key is an identifier, a string
2267
- // or a number; a computed first key takes the bare (source-only) form.
2268
- const firstProp = firstKey === undefined || ts.isComputedPropertyName(firstKey)
2269
- ? undefined
2270
- : (patternKeyNameOf(lowerer, firstKey) ?? undefined);
2271
2417
  out.push({
2272
2418
  kind: "exprStmt",
2273
2419
  expr: {
2274
2420
  kind: "dynDestrCheck",
2275
2421
  value: { kind: "varRef", localId: tmp.id, type: init.type, loc },
2276
2422
  spelling,
2277
- ...(firstProp !== undefined ? { firstProp } : {}),
2423
+ ...firstPatternProp(lowerer, decl.name),
2278
2424
  type: init.type,
2279
2425
  loc,
2280
2426
  },
2281
2427
  loc,
2282
2428
  });
2283
2429
  }
2284
- // V8's destructuring TypeError spells STATIC sources: an identifier
2285
- // source reads "<name> is not iterable", an identifier-callee call
2286
- // "<name> is not a function or its return value is not iterable";
2287
- // everything else (property reads, method calls, parameters) gets the
2288
- // runtime kind wording — exactly V8's CallPrinter behavior. Only the
2289
- // DYN pattern arm consumes this.
2290
- const src = decl.initializer;
2291
- const dynSpell = ts.isIdentifier(src)
2292
- ? `${src.text} is not iterable`
2293
- : ts.isCallExpression(src) && ts.isIdentifier(src.expression)
2294
- ? `${src.expression.text} is not a function or its return value is not iterable`
2295
- : undefined;
2296
2430
  lowerer.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: init.type, loc }), init.type, isLet, out, dynSpell, parseArgsDynObject);
2297
2431
  return out;
2298
2432
  }
@@ -3198,6 +3332,10 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
3198
3332
  type: fieldType,
3199
3333
  loc,
3200
3334
  };
3335
+ // A field some partial record assertion leaves unwritten (a partial
3336
+ // record view, partial-assertions.ts): the element read throws the
3337
+ // catchable TypeError instead of reading a slot the view lacks.
3338
+ value = partialFieldRead(lowerer, srcRef(), srcType.shapeId, propName, fieldType, loc) ?? value;
3201
3339
  // `{ tld = "localhost" }`: the element default applies exactly when
3202
3340
  // the field holds the undefined arm — the same undefined test and
3203
3341
  // narrow/retag as a defaulted parameter's prologue (declareParams).
@@ -4643,9 +4781,13 @@ export function lowerVarDeclList(lowerer, list) {
4643
4781
  const out = [];
4644
4782
  for (const decl of list.declarations.nodes) {
4645
4783
  if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
4646
- // Destructuring produces nested initialization blocks; copying
4647
- // their captured bindings still needs a distinct head-scope plan.
4648
- lowerer.unsupported("SC1031", decl.name, "let/const destructuring in for-loop initializers (declare the pattern before the loop, or use var)");
4784
+ // The pattern desugars to a flat statement list whose bindings are
4785
+ // ordinary head declarations (`for (let [a, b] = xs; ...)`: `%destr`
4786
+ // plus `a`, `b`), so the loop emitter finds them as head lets and
4787
+ // freshens the captured ones per iteration like any other
4788
+ // declarator (emit-statements: capturedLets).
4789
+ out.push(...lowerer.lowerDestructuringDecl(decl, isLet));
4790
+ continue;
4649
4791
  }
4650
4792
  const lowered = lowerer.lowerVarDecl(decl, isLet);
4651
4793
  if (!lowered)
@@ -4864,17 +5006,24 @@ function evolvingArrayHolderType(lowerer, decl) {
4864
5006
  /** A single static type for an initializer-less JavaScript `let` whose
4865
5007
  * later plain writes all agree. An evolving JS local reads as `undefined`
4866
5008
  * until control flow proves a write, so a scalar slot is sound only when
4867
- * every ordinary use already has that concrete flow type. Any closure
4868
- * capture stays checked-dynamic: it can observe the local before an outer
4869
- * assignment, and the checker deliberately leaves captured evolving lets
4870
- * broad. */
4871
- function inferredEvolvingLetType(lowerer, decl) {
5009
+ * every ordinary use already has that concrete flow type. A write's call
5010
+ * counts when its signature is declared in the standard library, whose
5011
+ * return types are declared rather than inferred from JavaScript. A
5012
+ * closure capture can observe the local before an outer assignment, and
5013
+ * the checker leaves captured evolving lets broad: a captured runtime
5014
+ * handle (`let child; if (...) child = spawn(...)`) takes the handle or
5015
+ * `undefined`, which nested functions read as a checked-dynamic value
5016
+ * (closureDynLets), and other captured bindings stay checked-dynamic. */
5017
+ export function inferredEvolvingLetType(lowerer, decl) {
4872
5018
  if (!ts.isIdentifier(decl.name))
4873
5019
  return null;
4874
5020
  const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
4875
5021
  const scope = decl.parent?.parent?.parent;
4876
5022
  if (symbol === undefined || (!ts.isBlock(scope) && !ts.isSourceFile(scope)))
4877
5023
  return null;
5024
+ // Another module reads an exported binding, which this scan does not see.
5025
+ if (ts.getCombinedModifierFlags(decl) & ts.ModifierFlags.Export)
5026
+ return null;
4878
5027
  // A shorthand property's name (`{ width }`) resolves to the property
4879
5028
  // symbol, but it reads the binding: the checker's shorthand-value symbol.
4880
5029
  const refersToBinding = (node) => (ts.isShorthandPropertyAssignment(node.parent) && node.parent.name === node
@@ -4904,10 +5053,19 @@ function inferredEvolvingLetType(lowerer, decl) {
4904
5053
  const writes = [];
4905
5054
  const reads = [];
4906
5055
  let invalid = false;
4907
- ts.walkPreorder(scope, (node) => {
4908
- if (node !== scope && ts.isFunctionLike(node)) {
4909
- if (captures(node))
4910
- invalid = true;
5056
+ let captured = false;
5057
+ // The capturing closure being scanned: reads inside one carry the
5058
+ // checker's broad type, so only its writes are collected.
5059
+ let closure = null;
5060
+ const visit = (node) => {
5061
+ if (node !== scope && node !== closure && ts.isFunctionLike(node)) {
5062
+ if (captures(node)) {
5063
+ captured = true;
5064
+ const outer = closure;
5065
+ closure = node;
5066
+ ts.walkPreorder(node, visit);
5067
+ closure = outer;
5068
+ }
4911
5069
  return "skip";
4912
5070
  }
4913
5071
  if (ts.isBinaryExpression(node)) {
@@ -4919,9 +5077,7 @@ function inferredEvolvingLetType(lowerer, decl) {
4919
5077
  invalid = true;
4920
5078
  return "stop";
4921
5079
  }
4922
- if (ts.isCallExpression(node.right) &&
4923
- (implicitMethodCallInfersReturn(lowerer, node.right) ||
4924
- isJsSourceFile(ts.getSourceFileOfNode(node.right)))) {
5080
+ if (ts.isCallExpression(node.right) && !stdlibDeclaredCall(lowerer, node.right)) {
4925
5081
  invalid = true;
4926
5082
  return "stop";
4927
5083
  }
@@ -4948,23 +5104,40 @@ function inferredEvolvingLetType(lowerer, decl) {
4948
5104
  invalid = true;
4949
5105
  return "stop";
4950
5106
  }
4951
- if (ts.isIdentifier(node) &&
5107
+ if (closure === null &&
5108
+ ts.isIdentifier(node) &&
4952
5109
  node !== decl.name &&
4953
5110
  refersToBinding(node) &&
4954
5111
  !isPlainAssignmentTarget(node)) {
4955
5112
  reads.push(node);
4956
5113
  }
4957
5114
  return undefined;
4958
- });
5115
+ };
5116
+ ts.walkPreorder(scope, visit);
4959
5117
  const first = writes[0];
4960
5118
  if (invalid || first === undefined || !writes.every((write) => typeEquals(write, first)))
4961
5119
  return null;
4962
- return reads.every((read) => {
5120
+ if (!reads.every((read) => {
4963
5121
  const mapped = lowerer.mapTypeOf(lowerer.typeOf(read));
4964
5122
  return mapped !== null && typeEquals(mapped, first);
4965
- })
4966
- ? first
4967
- : null;
5123
+ }))
5124
+ return null;
5125
+ if (!captured)
5126
+ return first;
5127
+ if (!DYN_HANDLE_KINDS.has(first.kind))
5128
+ return null;
5129
+ lowerer.closureDynLets.add(symbol);
5130
+ return { kind: "union", unionId: lowerer.unions.intern([first, UNDEFINED_T]) };
5131
+ }
5132
+ /** Whether a call's resolved signature is declared in the standard library
5133
+ * (`spawn(...)`), so its declared return type is the value's type. Calls of
5134
+ * JavaScript functions, and implicit generic methods, infer theirs, and a
5135
+ * `require(...)` result is a module rather than a value of its type. */
5136
+ function stdlibDeclaredCall(lowerer, call) {
5137
+ if (implicitMethodCallInfersReturn(lowerer, call) || requireSpecOf(call) !== null)
5138
+ return false;
5139
+ const declaration = lowerer.checker.getResolvedSignature(call)?.declaration;
5140
+ return declaration !== undefined && lowerer.isStdlibFile(ts.getSourceFileOfNode(declaration));
4968
5141
  }
4969
5142
  export function lowerVarDecl(lowerer, decl, isLet) {
4970
5143
  // --provenance-sources: an elided pure-annotated dead const emits
@@ -5001,6 +5174,10 @@ export function lowerVarDecl(lowerer, decl, isLet) {
5001
5174
  }
5002
5175
  if (!ts.isIdentifier(decl.name))
5003
5176
  lowerer.unsupported("SC1031", decl.name);
5177
+ // A binding that holds `process.env` under any type but the env record
5178
+ // is a snapshot copy whose reads would drift from Node's live table
5179
+ // (refuseHeldEnvCopyHold); refuse it here, at the hold itself.
5180
+ refuseHeldEnvCopyHold(lowerer, decl.name, decl);
5004
5181
  {
5005
5182
  const alias = lowerTupleAliasDecl(lowerer, decl);
5006
5183
  if (alias)
@@ -5444,6 +5621,13 @@ export function lowerVarDecl(lowerer, decl, isLet) {
5444
5621
  type = init.type;
5445
5622
  notePreservedLayout(lowerer, decl);
5446
5623
  }
5624
+ // A JavaScript binding assigned values outside its declared type
5625
+ // (analyzeJsWidenedBindings in lowerer.ts) holds them as checked-dynamic.
5626
+ {
5627
+ const symbol = lowerer.resolveValueSymbol(decl.name);
5628
+ if (symbol && lowerer.jsWidenedBindings.has(symbol))
5629
+ type = DYN;
5630
+ }
5447
5631
  // A typed-arguments function expression (typed-arguments.ts): the
5448
5632
  // checker types the binding variadic, but its value has the fixed
5449
5633
  // signature every use asserts.
@@ -6129,10 +6313,14 @@ export function jsBindingHasOpenWrites(lowerer, decl) {
6129
6313
  return false;
6130
6314
  if (candidates.some((node) => (lowerer.typeOf(node.right).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0))
6131
6315
  return true;
6132
- // A `+=` of a string turns a number or boolean binding into a string
6133
- // (`n += "px"`); the checker keeps the declared type.
6316
+ // A `+=` of a string, or of a value that may be one, turns a number or
6317
+ // boolean binding into a string (`n += "px"`); the checker keeps the
6318
+ // declared type.
6319
+ const mayBeString = (type) => type.flags & ts.TypeFlags.Union
6320
+ ? constituentTypes(type).some(mayBeString)
6321
+ : (type.flags & ts.TypeFlags.StringLike) !== 0;
6134
6322
  if (candidates.some((node) => node.operatorToken.kind === ts.SyntaxKind.PlusEqualsToken &&
6135
- (lowerer.typeOf(node.right).flags & ts.TypeFlags.StringLike) !== 0)) {
6323
+ mayBeString(lowerer.typeOf(node.right)))) {
6136
6324
  const declared = lowerer.mapTypeOf(lowerer.typeOf(decl.name));
6137
6325
  if (declared?.kind === "f64" || declared?.kind === "bool")
6138
6326
  return true;
@@ -6163,6 +6351,11 @@ export function jsBindingHasOpenWrites(lowerer, decl) {
6163
6351
  return false;
6164
6352
  return differing.some((node) => {
6165
6353
  const written = lowerer.mapTypeOf(lowerer.typeOf(node.right));
6354
+ // A union a primitive binding cannot hold (`x = c ? 1 : "a"` into
6355
+ // `var x = 0`).
6356
+ if (written?.kind === "union" &&
6357
+ (declared.kind === "f64" || declared.kind === "bool" || declared.kind === "string"))
6358
+ return true;
6166
6359
  return (written !== null &&
6167
6360
  written.kind !== "dyn" &&
6168
6361
  written.kind !== "union" &&
@@ -6480,10 +6673,15 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
6480
6673
  * === "string"/"number"/"boolean"`), reads under a proven narrow
6481
6674
  * (caughtRead bridges them with caughtNarrow, verified at run time like
6482
6675
  * unionNarrow), and rethrow (`throw e`). Unsupported raw uses and
6483
- * assignments are fenced (SC1063 and friends); destructuring patterns
6484
- * are SC1062. Captures retain the snapshot beyond the catch scope.
6485
- * The `: any` / `: unknown` annotations tsc admits both
6486
- * lower the same way (tsc narrows either through the tests).
6676
+ * assignments are fenced (SC1063 and friends). The `: any` /
6677
+ * `: unknown` annotations tsc admits both lower the same way (tsc
6678
+ * narrows either through the tests). Captures retain the snapshot
6679
+ * beyond the catch scope.
6680
+ * - `catch ([a])` / `catch ({ p })` binds the thrown value through a
6681
+ * destructuring pattern: the exception cell keeps its hidden CAUGHT
6682
+ * local, and the pattern reads its checked-dynamic view
6683
+ * (caughtToDyn), so a JS catch parameter that destructures lowers the
6684
+ * way the same pattern does over an `any` source.
6487
6685
  * - `finally` runs on normal completion, exception paths, and every
6488
6686
  * abrupt completion that crosses it. Return values are snapshotted
6489
6687
  * before cleanup; an abrupt completion inside the finally replaces the
@@ -6496,9 +6694,6 @@ export function lowerTry(lowerer, stmt) {
6496
6694
  let catchLocalId = null;
6497
6695
  if (stmt.catchClause) {
6498
6696
  const vd = stmt.catchClause.variableDeclaration;
6499
- if (vd && !ts.isIdentifier(vd.name)) {
6500
- lowerer.unsupported("SC1062", vd);
6501
- }
6502
6697
  if (vd && ts.isIdentifier(vd.name)) {
6503
6698
  lowerer.scopes.push(new Map());
6504
6699
  try {
@@ -6511,7 +6706,59 @@ export function lowerTry(lowerer, stmt) {
6511
6706
  }
6512
6707
  }
6513
6708
  else {
6514
- catchBody = lowerer.lowerScopedBlock(stmt.catchClause.block);
6709
+ lowerer.scopes.push(new Map());
6710
+ try {
6711
+ if (vd) {
6712
+ // `catch ([a])` / `catch ({ a })`: the thrown value crosses into
6713
+ // the checked-dynamic tree and the pattern binds through the same
6714
+ // per-read fences a dyn source takes — GetIterator for an array
6715
+ // pattern (positions past the end bind undefined, an iterator
6716
+ // with values left closes) and RequireObjectCoercible plus keyed
6717
+ // reads for an object pattern. The hidden CAUGHT local is the
6718
+ // exception cell every other catch path binds; the dyn conversion
6719
+ // is its identity-preserving view (caughtToDyn).
6720
+ const loc = locOf(vd);
6721
+ const local = lowerer.declareHiddenLocal("%caught", CAUGHT);
6722
+ catchLocalId = local.id;
6723
+ const tmp = lowerer.declareHiddenLocal("%destr", DYN);
6724
+ const out = [
6725
+ {
6726
+ kind: "varDecl",
6727
+ localId: tmp.id,
6728
+ init: { kind: "caughtToDyn", value: varRef(local.id, CAUGHT, loc), type: DYN, loc },
6729
+ loc,
6730
+ },
6731
+ ];
6732
+ // V8 spells the catch parameter's source '.catch' in the
6733
+ // RequireObjectCoercible TypeError ("Cannot destructure property
6734
+ // 'a' of '.catch' as it is null."), except when the first element
6735
+ // has a default: V8 reads that key first, so a nullish source
6736
+ // throws the read's TypeError, which the pattern's own first read
6737
+ // throws.
6738
+ if (ts.isObjectBindingPattern(vd.name) && !firstReadsWithDefault(vd.name))
6739
+ out.push({
6740
+ kind: "exprStmt",
6741
+ expr: {
6742
+ kind: "dynDestrCheck",
6743
+ value: varRef(tmp.id, DYN, loc),
6744
+ spelling: ".catch",
6745
+ ...firstPatternProp(lowerer, vd.name),
6746
+ type: DYN,
6747
+ loc,
6748
+ },
6749
+ loc,
6750
+ });
6751
+ lowerer.lowerBindingPattern(vd.name, () => varRef(tmp.id, DYN, loc), DYN, true, // catch bindings are mutable
6752
+ out);
6753
+ catchBody = [...out, ...lowerer.lowerScopedBlock(stmt.catchClause.block)];
6754
+ }
6755
+ else {
6756
+ catchBody = lowerer.lowerScopedBlock(stmt.catchClause.block);
6757
+ }
6758
+ }
6759
+ finally {
6760
+ lowerer.scopes.pop();
6761
+ }
6515
6762
  }
6516
6763
  }
6517
6764
  const finallyBody = stmt.finallyBlock ? lowerer.lowerScopedBlock(stmt.finallyBlock) : null;
@@ -6524,13 +6771,45 @@ export function lowerTry(lowerer, stmt) {
6524
6771
  loc: locOf(stmt),
6525
6772
  };
6526
6773
  }
6774
+ /** The refusal for `delete` of an optional `unknown`/`any` field, whose
6775
+ * slot is the checked-dynamic one and so has no ABSENT state to write. */
6776
+ const OPTIONAL_CHECKED_DYN_DELETE = "'delete' of optional 'unknown'/'any' fields (the checked-dynamic slot has no absent state yet — an omitted such field already reads as present)";
6777
+ /** TypeScript's declaration marks property `name` of `receiver` optional
6778
+ * (`?:`), in every union constituent. A mapped IR type cannot tell an
6779
+ * optional `unknown`/`any` field from a required one — both ride the
6780
+ * checked-dynamic slot — so a refused `delete`'s real reason comes from
6781
+ * the declaration. */
6782
+ function declaredOptionalProperty(lowerer, receiver, name) {
6783
+ const receiverType = lowerer.typeOf(receiver);
6784
+ const parts = receiverType.flags & ts.TypeFlags.Union ? constituentTypes(receiverType) : [receiverType];
6785
+ return parts.every((part) => {
6786
+ const property = lowerer.checker.getPropertyOfType(part, name);
6787
+ return property !== undefined && (property.flags & ts.SymbolFlags.Optional) !== 0;
6788
+ });
6789
+ }
6790
+ /** `type` — a record or a union whose every arm is a non-tuple record —
6791
+ * declares `name` in the checked-dynamic slot, which has no ABSENT state:
6792
+ * an optional such field cannot be removed by a `delete`. */
6793
+ function declaresCheckedDynField(lowerer, type, name) {
6794
+ if (type.kind === "record") {
6795
+ const shape = lowerer.shapes.get(type.shapeId);
6796
+ if (!shape || shape.tuple)
6797
+ return false;
6798
+ return shape.fields.find((f) => f.name === name)?.type.kind === "dyn";
6799
+ }
6800
+ if (type.kind !== "union")
6801
+ return false;
6802
+ const arms = lowerer.unions.get(type.unionId)?.arms ?? [];
6803
+ return arms.length > 0 && arms.every((arm) => declaresCheckedDynField(lowerer, arm, name));
6804
+ }
6527
6805
  /** Statement-position `delete`: process.env keys → process.envUnset
6528
6806
  * (unsetenv), pure `Record<string, T>` keys → recordKeyDelete (the
6529
6807
  * overflow Map delete), declared OPTIONAL fields → the field's ABSENT
6530
6808
  * state (the slot reads undefined and no longer counts as an own
6531
6809
  * property). Everything else
6532
6810
  * fences with the honest reason — a required field is a struct slot no
6533
- * runtime can remove. */
6811
+ * runtime can remove, and an optional `unknown`/`any` field maps to the
6812
+ * checked-dynamic slot, which has no ABSENT state yet. */
6534
6813
  function lowerDeleteStatement(lowerer, expr) {
6535
6814
  const loc = locOf(expr);
6536
6815
  let target = expr.expression;
@@ -6539,6 +6818,9 @@ function lowerDeleteStatement(lowerer, expr) {
6539
6818
  if (!ts.isElementAccessExpression(target) && !ts.isPropertyAccessExpression(target)) {
6540
6819
  lowerer.unsupported("SC1090", expr, "'delete' of non-property expressions");
6541
6820
  }
6821
+ // Deleting a member of `Date.prototype` is a write through the read-only
6822
+ // prototype value (property-access.ts's fence).
6823
+ fenceDatePrototypeWrite(lowerer, target);
6542
6824
  fenceNodeModuleMutation(lowerer, target, "delete");
6543
6825
  if (ts.isPropertyAccessExpression(target) && target.name.text === "cause") {
6544
6826
  const field = lowerer.fieldTarget(target);
@@ -6564,7 +6846,8 @@ function lowerDeleteStatement(lowerer, expr) {
6564
6846
  return { kind: "strLit", value: target.name.text, type: STRING, loc: locOf(target.name) };
6565
6847
  }
6566
6848
  const keyNode = target.argumentExpression;
6567
- let key = lowerer.isProcessEnv(target.expression)
6849
+ let key = lowerer.isProcessEnv(target.expression) ||
6850
+ heldEnvValueType(lowerer, target.expression) !== null
6568
6851
  ? lowerEnvironmentKey(lowerer, keyNode)
6569
6852
  : lowerer.lowerExpr(keyNode);
6570
6853
  if (key.type.kind === "dyn") {
@@ -6578,7 +6861,8 @@ function lowerDeleteStatement(lowerer, expr) {
6578
6861
  }
6579
6862
  return key;
6580
6863
  };
6581
- if (lowerer.isProcessEnv(target.expression)) {
6864
+ if (lowerer.isProcessEnv(target.expression) ||
6865
+ heldEnvValueType(lowerer, target.expression) !== null) {
6582
6866
  return {
6583
6867
  kind: "exprStmt",
6584
6868
  expr: { kind: "libCall", fn: "process.envUnset", args: [lowerKey()], type: VOID, loc },
@@ -6670,6 +6954,20 @@ function lowerDeleteStatement(lowerer, expr) {
6670
6954
  loc,
6671
6955
  };
6672
6956
  }
6957
+ // The constant property key of the target (dot access or a literal
6958
+ // bracket), when there is one.
6959
+ const constantKey = ts.isPropertyAccessExpression(target)
6960
+ ? target.name.text
6961
+ : ts.isStringLiteral(target.argumentExpression)
6962
+ ? target.argumentExpression.text
6963
+ : null;
6964
+ // An OPTIONAL `unknown`/`any` field rides the checked-dynamic slot,
6965
+ // which has no ABSENT state yet (an omitted such field already reads as
6966
+ // present), so it cannot delete. Name that reason instead of calling
6967
+ // the field required or blaming the receiver.
6968
+ const optionalCheckedDynDelete = constantKey !== null &&
6969
+ declaresCheckedDynField(lowerer, obj.type, constantKey) &&
6970
+ declaredOptionalProperty(lowerer, target.expression, constantKey);
6673
6971
  if (obj.type.kind === "record") {
6674
6972
  const shape = lowerer.shapes.get(obj.type.shapeId);
6675
6973
  if (shape?.indexValue && shape.fields.length === 0 && !shape.tuple) {
@@ -6682,13 +6980,8 @@ function lowerDeleteStatement(lowerer, expr) {
6682
6980
  // while a later write makes it present again. Constant keys only
6683
6981
  // (dot access or a literal bracket); required fields keep the honest
6684
6982
  // fence below.
6685
- const fieldName = ts.isPropertyAccessExpression(target)
6686
- ? target.name.text
6687
- : ts.isStringLiteral(target.argumentExpression)
6688
- ? target.argumentExpression.text
6689
- : null;
6690
- const field = fieldName !== null && !shape?.tuple
6691
- ? shape?.fields.find((f) => f.name === fieldName)
6983
+ const field = constantKey !== null && !shape?.tuple
6984
+ ? shape?.fields.find((f) => f.name === constantKey)
6692
6985
  : undefined;
6693
6986
  if (field) {
6694
6987
  const absent = lowerer.absentFieldValue(field.type, loc);
@@ -6706,8 +6999,14 @@ function lowerDeleteStatement(lowerer, expr) {
6706
6999
  if (shape?.indexValue) {
6707
7000
  lowerer.unsupported("SC1090", expr, "'delete' of hybrid index-signature keys (declared struct slots and overflow entries answer differently — model deletable dynamic keys with a pure Record<string, T>)");
6708
7001
  }
7002
+ if (optionalCheckedDynDelete) {
7003
+ lowerer.unsupported("SC1090", expr, OPTIONAL_CHECKED_DYN_DELETE);
7004
+ }
6709
7005
  lowerer.unsupported("SC1090", expr, "'delete' of required record fields (a monomorphic shape cannot remove its slot — only optional fields delete, becoming the undefined arm)");
6710
7006
  }
7007
+ if (optionalCheckedDynDelete) {
7008
+ lowerer.unsupported("SC1090", expr, OPTIONAL_CHECKED_DYN_DELETE);
7009
+ }
6711
7010
  lowerer.unsupported("SC1090", expr, `'delete' on '${lowerer.fmt(obj.type)}' receivers (process.env keys and pure Record<string, T> keys delete)`);
6712
7011
  }
6713
7012
  /** True when the `var`/`let` binding `nameNode` names cannot change after
@@ -7384,6 +7683,13 @@ export function lowerExprStatement(lowerer, expr) {
7384
7683
  return { kind: "exprStmt", expr: urlWrite, loc: locOf(expr) };
7385
7684
  }
7386
7685
  if (opKind === ts.SyntaxKind.EqualsToken) {
7686
+ // A write through `Date.prototype` or one of its members keeps its
7687
+ // fence: the prototype value is a read surface (property-access.ts).
7688
+ if (ts.isPropertyAccessExpression(expr.left) || ts.isElementAccessExpression(expr.left))
7689
+ fenceDatePrototypeWrite(lowerer, expr.left);
7690
+ const staticPrivateWrite = lowerStaticPrivateAssignment(lowerer, expr);
7691
+ if (staticPrivateWrite)
7692
+ return { kind: "exprStmt", expr: staticPrivateWrite, loc: locOf(expr) };
7387
7693
  const callableWrite = lowerNativeFunctionAssignment(lowerer, expr);
7388
7694
  if (callableWrite)
7389
7695
  return { kind: "exprStmt", expr: callableWrite, loc: locOf(expr) };
@@ -7431,7 +7737,12 @@ export function lowerExprStatement(lowerer, expr) {
7431
7737
  // (Node stringifies everything; a non-string RHS fences instead
7432
7738
  // of diverging from Node). The computed-key form lands in
7433
7739
  // lowerElementWrite.
7434
- if (lowerer.isProcessEnv(expr.left.expression) && !expr.left.questionDotToken) {
7740
+ // The same setenv for a value HELD from process.env (`const env =
7741
+ // process.env; env.X = v`): the hold aliases the live table, as
7742
+ // Node's does.
7743
+ if (!expr.left.questionDotToken &&
7744
+ (lowerer.isProcessEnv(expr.left.expression) ||
7745
+ heldEnvValueType(lowerer, expr.left.expression) !== null)) {
7435
7746
  const loc = locOf(expr);
7436
7747
  const key = {
7437
7748
  kind: "strLit",
@@ -7901,6 +8212,39 @@ export function lowerExprStatement(lowerer, expr) {
7901
8212
  };
7902
8213
  }
7903
8214
  }
8215
+ // process.stdout.write = fn (and stderr): replace the stream object's
8216
+ // write slot. Every later write to the stream — console output, typed
8217
+ // write calls (programPatchesStdio), runtime writers — goes through it.
8218
+ if (ts.isPropertyAccessExpression(expr.left) && expr.left.name.text === "write") {
8219
+ const recv = expr.left.expression;
8220
+ const stream = ts.isPropertyAccessExpression(recv)
8221
+ ? lowerer.stdlibGlobalMember(recv, "process")
8222
+ : null;
8223
+ if (stream === "stdout" || stream === "stderr") {
8224
+ const loc = locOf(expr);
8225
+ return {
8226
+ kind: "exprStmt",
8227
+ expr: {
8228
+ kind: "libCall",
8229
+ fn: "dyn.keySet",
8230
+ args: [
8231
+ {
8232
+ kind: "libCall",
8233
+ fn: "process.stdioSlot",
8234
+ args: [numLit(stream === "stdout" ? 1 : 2, loc)],
8235
+ type: DYN,
8236
+ loc,
8237
+ },
8238
+ strLit("write", locOf(expr.left.name)),
8239
+ lowerer.lowerExprExpecting(expr.right, DYN),
8240
+ ],
8241
+ type: VOID,
8242
+ loc,
8243
+ },
8244
+ loc,
8245
+ };
8246
+ }
8247
+ }
7904
8248
  if (!ts.isIdentifier(expr.left)) {
7905
8249
  lowerer.unsupported("SC1090", expr.left, "assignment to non-variables");
7906
8250
  }
@@ -7933,6 +8277,8 @@ export function lowerExprStatement(lowerer, expr) {
7933
8277
  const compound = COMPOUND_ASSIGN_OPS[opKind];
7934
8278
  if (compound !== undefined) {
7935
8279
  // Desugar `x op= e` to `x = x op e` — reads x before e, like JS.
8280
+ if (ts.isPropertyAccessExpression(expr.left) || ts.isElementAccessExpression(expr.left))
8281
+ fenceDatePrototypeWrite(lowerer, expr.left);
7936
8282
  if (ts.isElementAccessExpression(expr.left)) {
7937
8283
  // `this[kLimit] += v` — a declared symbol-keyed class field is
7938
8284
  // the dotted compound in element spelling. Array and byte-view
@@ -7974,6 +8320,7 @@ export function lowerExprStatement(lowerer, expr) {
7974
8320
  (expr.operator === ts.SyntaxKind.PlusPlusToken ||
7975
8321
  expr.operator === ts.SyntaxKind.MinusMinusToken)) {
7976
8322
  if (ts.isPropertyAccessExpression(expr.operand) || ts.isElementAccessExpression(expr.operand)) {
8323
+ fenceDatePrototypeWrite(lowerer, expr.operand);
7977
8324
  // Statement and value positions share ToNumeric and reference order.
7978
8325
  // Namespace/expando globals retain their direct binding path below.
7979
8326
  const binding = ts.isPropertyAccessExpression(expr.operand)
@@ -8193,6 +8540,45 @@ export function lowerDestructuringAssign(lowerer, target, init, blame, loc) {
8193
8540
  const parts = destructuringAssignInto(lowerer, target, init, null, blame, loc);
8194
8541
  return { kind: "block", body: parts.stmts, loc };
8195
8542
  }
8543
+ /** An object pattern whose first element has a default and a static key
8544
+ * (`{ a = 1 }`, `{ a: b = 1 }`): V8 reads that key without checking the
8545
+ * source first, so a null or undefined source throws the read's TypeError. */
8546
+ function firstReadsWithDefault(pattern) {
8547
+ const first = pattern.elements.nodes[0];
8548
+ return (first !== undefined &&
8549
+ first.dotDotDotToken === undefined &&
8550
+ first.initializer !== undefined &&
8551
+ !(first.propertyName !== undefined && ts.isComputedPropertyName(first.propertyName)));
8552
+ }
8553
+ /** The read of the first key of a pattern that `firstReadsWithDefault`
8554
+ * accepts, over a dyn source: on null or undefined it throws the read's
8555
+ * TypeError, as V8 does. Null when the key has no static name. */
8556
+ function firstKeyRead(lowerer, pattern, source, loc) {
8557
+ const { firstProp } = firstPatternProp(lowerer, pattern);
8558
+ if (firstProp === undefined)
8559
+ return null;
8560
+ return {
8561
+ kind: "dynKeyGet",
8562
+ key: { kind: "strLit", value: firstProp, type: STRING, loc },
8563
+ value: source(),
8564
+ type: DYN,
8565
+ loc,
8566
+ };
8567
+ }
8568
+ /** The first property V8 names in an object pattern's destructuring
8569
+ * TypeError ("Cannot destructure property 'a' of ..."): an identifier,
8570
+ * string or numeric first key. A computed first key, a rest element or
8571
+ * an empty pattern takes the bare (source-only) form. */
8572
+ function firstPatternProp(lowerer, pattern) {
8573
+ const first = pattern.elements.nodes[0];
8574
+ const firstKey = first === undefined || first.dotDotDotToken !== undefined
8575
+ ? undefined
8576
+ : (first.propertyName ?? first.name);
8577
+ const firstProp = firstKey === undefined || ts.isComputedPropertyName(firstKey)
8578
+ ? undefined
8579
+ : (patternKeyNameOf(lowerer, firstKey) ?? undefined);
8580
+ return firstProp !== undefined ? { firstProp } : {};
8581
+ }
8196
8582
  /** V8's spelling of a destructuring RHS in its TypeError message
8197
8583
  * ("Cannot destructure 'a' as it is undefined.") — plain identifiers
8198
8584
  * spell their name (parens unwrap), `this`, property chains and
@@ -8341,8 +8727,8 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
8341
8727
  ts.isBinaryExpression(rhsInner) &&
8342
8728
  rhsInner.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
8343
8729
  (ts.isObjectLiteralExpression(rhsInner.left) || ts.isArrayLiteralExpression(rhsInner.left));
8344
- if (!checkedByInner) {
8345
- const spelling = rhs === null ? null : destrSpellingOf(rhs);
8730
+ if (!checkedByInner && rhs !== null) {
8731
+ const spelling = destrSpellingOf(rhs);
8346
8732
  if (spelling === null) {
8347
8733
  lowerer.unsupported("SC1031", blame, "destructuring assignment from a checked-dynamic source whose expression spelling is unsupported (use a variable, ordinary property chain, or ordinary call)");
8348
8734
  }
@@ -8373,20 +8759,57 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
8373
8759
  }
8374
8760
  for (const prop of target.properties.nodes) {
8375
8761
  const piece = destructAssignPiece(lowerer, prop);
8376
- const read = {
8762
+ const propLoc = locOf(prop);
8763
+ let read = {
8377
8764
  kind: "dynKeyGet",
8378
- key: { kind: "strLit", value: piece.field, type: STRING, loc: locOf(prop) },
8765
+ key: { kind: "strLit", value: piece.field, type: STRING, loc: propLoc },
8379
8766
  value: tmpRef(),
8380
8767
  type: DYN,
8381
- loc: locOf(prop),
8768
+ loc: propLoc,
8382
8769
  };
8770
+ if (piece.dflt !== undefined) {
8771
+ // `{ x = 1 }` / `{ x: y = 1 }`: the default fires on the undefined
8772
+ // read and is evaluated lazily, exactly the declaration path's
8773
+ // checked-dynamic default.
8774
+ const readTmp = lowerer.declareHiddenLocal("%destr", DYN);
8775
+ out.push({ kind: "varDecl", localId: readTmp.id, init: read, loc: propLoc });
8776
+ const readRef = { kind: "varRef", localId: readTmp.id, type: DYN, loc: propLoc };
8777
+ read = {
8778
+ kind: "ternary",
8779
+ cond: { kind: "dynTest", test: "undefined", value: readRef, type: BOOL, loc: propLoc },
8780
+ then: lowerer.coerceInto(piece.dflt, lowerer.lowerExpr(piece.dflt), DYN),
8781
+ else_: readRef,
8782
+ type: DYN,
8783
+ loc: propLoc,
8784
+ };
8785
+ }
8383
8786
  out.push({
8384
8787
  kind: "assign",
8385
8788
  localId: piece.target.id,
8386
8789
  value: lowerer.coerceInto(prop, read, piece.target.type),
8387
- loc: locOf(prop),
8790
+ loc: propLoc,
8388
8791
  });
8389
8792
  }
8793
+ if (rhs === null && target.properties.nodes.length === 0) {
8794
+ // A pattern with no reads still owes the source's own coercion, and a
8795
+ // PRE-LOWERED source (`for ({} of …)`) has no source text: V8 reads
8796
+ // the value instead of spelling it ("Cannot read properties of null").
8797
+ for (const unit of ["null", "undefined"]) {
8798
+ out.push({
8799
+ kind: "if",
8800
+ cond: { kind: "dynTest", test: unit, value: tmpRef(), type: BOOL, loc },
8801
+ then: [
8802
+ {
8803
+ kind: "exprStmt",
8804
+ expr: nodeThrowExpr(1, "", `Cannot read properties of ${unit}`, VOID, loc),
8805
+ loc,
8806
+ },
8807
+ ],
8808
+ else_: null,
8809
+ loc,
8810
+ });
8811
+ }
8812
+ }
8390
8813
  return { stmts: out, value };
8391
8814
  }
8392
8815
  if (target.properties.nodes.length === 0) {
@@ -8860,10 +9283,11 @@ function lowerAssignTargetInto(lowerer, out, targetNode, blame, dflt, valueOf) {
8860
9283
  function destructAssignPiece(lowerer, prop) {
8861
9284
  let fieldName;
8862
9285
  let bindTo;
9286
+ let dflt;
8863
9287
  if (ts.isShorthandPropertyAssignment(prop)) {
8864
- if (prop.objectAssignmentInitializer) {
8865
- lowerer.unsupported("SC1031", prop, "destructuring assignment with defaults (assign, then apply the default)");
8866
- }
9288
+ // `{ x = 1 }`: the shorthand's default (the checker's name resolution
9289
+ // still answers the outer binding through the shorthand).
9290
+ dflt = prop.objectAssignmentInitializer;
8867
9291
  fieldName = prop.name.text;
8868
9292
  bindTo = prop.name;
8869
9293
  }
@@ -8874,7 +9298,12 @@ function destructAssignPiece(lowerer, prop) {
8874
9298
  lowerer.unsupported("SC1031", prop, "destructuring assignment with computed keys that do not fold to one property name");
8875
9299
  }
8876
9300
  fieldName = folded ?? "";
9301
+ // `{ x: y = 1 }`: a defaulted target, the AssignmentPattern spelling.
8877
9302
  bindTo = prop.initializer;
9303
+ if (ts.isBinaryExpression(bindTo) && bindTo.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
9304
+ dflt = bindTo.right;
9305
+ bindTo = bindTo.left;
9306
+ }
8878
9307
  }
8879
9308
  else {
8880
9309
  lowerer.unsupported("SC1031", prop, "destructuring assignment with rest or spread properties");
@@ -8895,7 +9324,7 @@ function destructAssignPiece(lowerer, prop) {
8895
9324
  if (!target) {
8896
9325
  lowerer.rejectUnresolved(bindTo, `assignment to '${bindTo.text}' (not a writable local or module global)`);
8897
9326
  }
8898
- return { field: fieldName, target };
9327
+ return { field: fieldName, target, ...(dflt !== undefined ? { dflt } : {}) };
8899
9328
  }
8900
9329
  /** The ARRAY half of destructuring assignment: element assigns from a
8901
9330
  * tuple/array/checked-dynamic source pushed into `out` (see
@@ -11174,7 +11603,55 @@ function lowerForIn(lowerer, stmt) {
11174
11603
  receiver = lowerer.coerceToExpected(receiver, DYN);
11175
11604
  }
11176
11605
  }
11606
+ return lowerForInReceiver(lowerer, stmt, labels, receiver);
11607
+ }
11608
+ /** for-in over the lowered `receiver` of `stmt`. */
11609
+ function lowerForInReceiver(lowerer, stmt, labels, receiver) {
11610
+ const loc = locOf(stmt);
11177
11611
  const recvT = receiver.type;
11612
+ // A receiver that may be null or undefined: for-in visits nothing for
11613
+ // either, and walks a present value as its own type. The receiver is
11614
+ // evaluated once.
11615
+ if (recvT.kind === "union") {
11616
+ const arms = lowerer.unions.get(recvT.unionId)?.arms ?? [];
11617
+ const present = arms.filter((arm) => arm.kind !== "undefinedT" && arm.kind !== "nullT");
11618
+ if (present.length === 1 && present.length < arms.length) {
11619
+ const arm = present[0];
11620
+ const tag = lowerer.armTag(recvT.unionId, arm);
11621
+ const recv = lowerer.declareHiddenLocal("%innullable", recvT);
11622
+ const ref = varRef(recv.id, recvT, loc);
11623
+ const narrowed = {
11624
+ kind: "unionNarrow",
11625
+ unionId: recvT.unionId,
11626
+ tag,
11627
+ value: ref,
11628
+ type: arm,
11629
+ loc,
11630
+ };
11631
+ return {
11632
+ kind: "block",
11633
+ body: [
11634
+ { kind: "varDecl", localId: recv.id, init: receiver, loc },
11635
+ {
11636
+ kind: "if",
11637
+ cond: {
11638
+ kind: "unionIsTag",
11639
+ unionId: recvT.unionId,
11640
+ tag,
11641
+ negated: false,
11642
+ value: ref,
11643
+ type: BOOL,
11644
+ loc,
11645
+ },
11646
+ then: [lowerForInReceiver(lowerer, stmt, labels, narrowed)],
11647
+ else_: null,
11648
+ loc,
11649
+ },
11650
+ ],
11651
+ loc,
11652
+ };
11653
+ }
11654
+ }
11178
11655
  if (recvT.kind === "dyn") {
11179
11656
  const recv = lowerer.declareHiddenLocal("%indyn", DYN);
11180
11657
  const ref = { kind: "varRef", localId: recv.id, type: DYN, loc };