@scriptc/compiler 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1201) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +972 -245
  2. package/ambient/scriptc-overrides.d.ts +5 -1
  3. package/ambient/scriptc.d.ts +22 -2
  4. package/dist/backend/build-cache.d.ts +4 -0
  5. package/dist/backend/build-cache.js +16 -2
  6. package/dist/backend/build-cache.js.map +1 -1
  7. package/dist/backend/cycle-analysis.js +17 -5
  8. package/dist/backend/cycle-analysis.js.map +1 -1
  9. package/dist/backend/cycle-analysis.test.js +50 -11
  10. package/dist/backend/cycle-analysis.test.js.map +1 -1
  11. package/dist/backend/debug-symbols.js.map +1 -1
  12. package/dist/backend/executable-features.js +3 -1
  13. package/dist/backend/executable-features.js.map +1 -1
  14. package/dist/backend/external-c.d.ts +13 -6
  15. package/dist/backend/external-c.js +15 -3
  16. package/dist/backend/external-c.js.map +1 -1
  17. package/dist/backend/ffi-callbacks.js +6 -9
  18. package/dist/backend/ffi-callbacks.js.map +1 -1
  19. package/dist/backend/library-identity-markers.js.map +1 -1
  20. package/dist/backend/library-pack.d.ts +1 -1
  21. package/dist/backend/library-pack.js +81 -24
  22. package/dist/backend/library-pack.js.map +1 -1
  23. package/dist/backend/link-plan-core.d.ts +2 -0
  24. package/dist/backend/link-plan-core.js +10 -2
  25. package/dist/backend/link-plan-core.js.map +1 -1
  26. package/dist/backend/link-plan.d.ts +2 -1
  27. package/dist/backend/link-plan.js +7 -5
  28. package/dist/backend/link-plan.js.map +1 -1
  29. package/dist/backend/linker.d.ts +1 -1
  30. package/dist/backend/linker.js +42 -23
  31. package/dist/backend/linker.js.map +1 -1
  32. package/dist/backend/literals.js +5 -4
  33. package/dist/backend/literals.js.map +1 -1
  34. package/dist/backend/literals.test.js +30 -5
  35. package/dist/backend/literals.test.js.map +1 -1
  36. package/dist/backend/llvm/blocks.test.js +5 -2
  37. package/dist/backend/llvm/blocks.test.js.map +1 -1
  38. package/dist/backend/llvm/borrowed-inputs.js.map +1 -1
  39. package/dist/backend/llvm/borrowed-receivers.js +43 -19
  40. package/dist/backend/llvm/borrowed-receivers.js.map +1 -1
  41. package/dist/backend/llvm/byte-numbers.js +38 -5
  42. package/dist/backend/llvm/byte-numbers.js.map +1 -1
  43. package/dist/backend/llvm/byte-windows.d.ts +31 -0
  44. package/dist/backend/llvm/byte-windows.js +334 -0
  45. package/dist/backend/llvm/byte-windows.js.map +1 -0
  46. package/dist/backend/llvm/byte-windows.test.d.ts +1 -0
  47. package/dist/backend/llvm/byte-windows.test.js +244 -0
  48. package/dist/backend/llvm/byte-windows.test.js.map +1 -0
  49. package/dist/backend/llvm/bytes-bounds.js +73 -22
  50. package/dist/backend/llvm/bytes-bounds.js.map +1 -1
  51. package/dist/backend/llvm/call-lifetimes.d.ts +5 -2
  52. package/dist/backend/llvm/call-lifetimes.js +72 -19
  53. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  54. package/dist/backend/llvm/call-lifetimes.test.js +159 -28
  55. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  56. package/dist/backend/llvm/checked-value-lifetimes.d.ts +4 -0
  57. package/dist/backend/llvm/checked-value-lifetimes.js +14 -4
  58. package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
  59. package/dist/backend/llvm/classes.d.ts +14 -1
  60. package/dist/backend/llvm/classes.js +94 -19
  61. package/dist/backend/llvm/classes.js.map +1 -1
  62. package/dist/backend/llvm/classes.test.d.ts +1 -0
  63. package/dist/backend/llvm/classes.test.js +99 -0
  64. package/dist/backend/llvm/classes.test.js.map +1 -0
  65. package/dist/backend/llvm/common.js +4 -1
  66. package/dist/backend/llvm/common.js.map +1 -1
  67. package/dist/backend/llvm/constant-callbacks.d.ts +11 -0
  68. package/dist/backend/llvm/constant-callbacks.js +213 -0
  69. package/dist/backend/llvm/constant-callbacks.js.map +1 -0
  70. package/dist/backend/llvm/constant-callbacks.test.d.ts +1 -0
  71. package/dist/backend/llvm/constant-callbacks.test.js +124 -0
  72. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -0
  73. package/dist/backend/llvm/counted-loops.js +10 -3
  74. package/dist/backend/llvm/counted-loops.js.map +1 -1
  75. package/dist/backend/llvm/debug-info.js +33 -13
  76. package/dist/backend/llvm/debug-info.js.map +1 -1
  77. package/dist/backend/llvm/debug-info.test.js +28 -6
  78. package/dist/backend/llvm/debug-info.test.js.map +1 -1
  79. package/dist/backend/llvm/dyn.d.ts +1 -1
  80. package/dist/backend/llvm/dyn.js +75 -56
  81. package/dist/backend/llvm/dyn.js.map +1 -1
  82. package/dist/backend/llvm/emitter.d.ts +28 -3
  83. package/dist/backend/llvm/emitter.js +506 -145
  84. package/dist/backend/llvm/emitter.js.map +1 -1
  85. package/dist/backend/llvm/emitter.test.js +247 -50
  86. package/dist/backend/llvm/emitter.test.js.map +1 -1
  87. package/dist/backend/llvm/expr-async.js +25 -6
  88. package/dist/backend/llvm/expr-async.js.map +1 -1
  89. package/dist/backend/llvm/expr-bytes.js +24 -4
  90. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  91. package/dist/backend/llvm/expr-callbacks.js +10 -4
  92. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  93. package/dist/backend/llvm/expr-calls.js +110 -31
  94. package/dist/backend/llvm/expr-calls.js.map +1 -1
  95. package/dist/backend/llvm/expr-containers.d.ts +2 -0
  96. package/dist/backend/llvm/expr-containers.js +112 -41
  97. package/dist/backend/llvm/expr-containers.js.map +1 -1
  98. package/dist/backend/llvm/expr-control.js +1 -3
  99. package/dist/backend/llvm/expr-control.js.map +1 -1
  100. package/dist/backend/llvm/expr-dispatch.js +3 -1
  101. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  102. package/dist/backend/llvm/expr-dynamic.js +55 -7
  103. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  104. package/dist/backend/llvm/expr-island.js +26 -6
  105. package/dist/backend/llvm/expr-island.js.map +1 -1
  106. package/dist/backend/llvm/expr-primitives.js +95 -19
  107. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  108. package/dist/backend/llvm/expr-primitives.test.js +44 -2
  109. package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
  110. package/dist/backend/llvm/expr-records.js +10 -9
  111. package/dist/backend/llvm/expr-records.js.map +1 -1
  112. package/dist/backend/llvm/expr-stream-bridges.js +44 -26
  113. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  114. package/dist/backend/llvm/expr-stream-bridges.test.js +51 -14
  115. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
  116. package/dist/backend/llvm/expr-stream-callbacks.js +34 -14
  117. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  118. package/dist/backend/llvm/integer-remainder.d.ts +7 -0
  119. package/dist/backend/llvm/integer-remainder.js +26 -0
  120. package/dist/backend/llvm/integer-remainder.js.map +1 -0
  121. package/dist/backend/llvm/integer-values.js +15 -4
  122. package/dist/backend/llvm/integer-values.js.map +1 -1
  123. package/dist/backend/llvm/integer-views.js +23 -7
  124. package/dist/backend/llvm/integer-views.js.map +1 -1
  125. package/dist/backend/llvm/integer-views.test.js +42 -7
  126. package/dist/backend/llvm/integer-views.test.js.map +1 -1
  127. package/dist/backend/llvm/layouts.js +1 -1
  128. package/dist/backend/llvm/layouts.js.map +1 -1
  129. package/dist/backend/llvm/lib-abi.js +20 -4
  130. package/dist/backend/llvm/lib-abi.js.map +1 -1
  131. package/dist/backend/llvm/lib-connect.js +7 -1
  132. package/dist/backend/llvm/lib-connect.js.map +1 -1
  133. package/dist/backend/llvm/lib-datagram.js +35 -10
  134. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  135. package/dist/backend/llvm/lib-dispatch.js +42 -38
  136. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  137. package/dist/backend/llvm/lib-filesystem.js +33 -18
  138. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  139. package/dist/backend/llvm/lib-http2.js +60 -15
  140. package/dist/backend/llvm/lib-http2.js.map +1 -1
  141. package/dist/backend/llvm/lib-lookup.js +12 -5
  142. package/dist/backend/llvm/lib-lookup.js.map +1 -1
  143. package/dist/backend/llvm/lib-network.js +97 -31
  144. package/dist/backend/llvm/lib-network.js.map +1 -1
  145. package/dist/backend/llvm/lib-process.js +57 -14
  146. package/dist/backend/llvm/lib-process.js.map +1 -1
  147. package/dist/backend/llvm/lib-shared.js +122 -31
  148. package/dist/backend/llvm/lib-shared.js.map +1 -1
  149. package/dist/backend/llvm/lib-stream.js +33 -14
  150. package/dist/backend/llvm/lib-stream.js.map +1 -1
  151. package/dist/backend/llvm/lib-test.js +21 -7
  152. package/dist/backend/llvm/lib-test.js.map +1 -1
  153. package/dist/backend/llvm/lib-tls.js +69 -20
  154. package/dist/backend/llvm/lib-tls.js.map +1 -1
  155. package/dist/backend/llvm/local-array-reads.d.ts +9 -2
  156. package/dist/backend/llvm/local-array-reads.js +176 -89
  157. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  158. package/dist/backend/llvm/local-array-reads.test.js +394 -62
  159. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  160. package/dist/backend/llvm/local-union-storage.d.ts +25 -0
  161. package/dist/backend/llvm/local-union-storage.js +109 -0
  162. package/dist/backend/llvm/local-union-storage.js.map +1 -0
  163. package/dist/backend/llvm/local-union-storage.test.d.ts +1 -0
  164. package/dist/backend/llvm/local-union-storage.test.js +210 -0
  165. package/dist/backend/llvm/local-union-storage.test.js.map +1 -0
  166. package/dist/backend/llvm/loop-array-borrows.d.ts +11 -0
  167. package/dist/backend/llvm/loop-array-borrows.js +70 -0
  168. package/dist/backend/llvm/loop-array-borrows.js.map +1 -0
  169. package/dist/backend/llvm/loop-array-borrows.test.d.ts +1 -0
  170. package/dist/backend/llvm/loop-array-borrows.test.js +145 -0
  171. package/dist/backend/llvm/loop-array-borrows.test.js.map +1 -0
  172. package/dist/backend/llvm/map-read-lifetimes.d.ts +11 -2
  173. package/dist/backend/llvm/map-read-lifetimes.js +64 -19
  174. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  175. package/dist/backend/llvm/map-read-lifetimes.test.js +89 -17
  176. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
  177. package/dist/backend/llvm/reference-effects.d.ts +5 -3
  178. package/dist/backend/llvm/reference-effects.js +74 -36
  179. package/dist/backend/llvm/reference-effects.js.map +1 -1
  180. package/dist/backend/llvm/reference-effects.test.js +92 -9
  181. package/dist/backend/llvm/reference-effects.test.js.map +1 -1
  182. package/dist/backend/llvm/shapes.d.ts +4 -1
  183. package/dist/backend/llvm/shapes.js +82 -24
  184. package/dist/backend/llvm/shapes.js.map +1 -1
  185. package/dist/backend/llvm/shapes.test.js +3 -1
  186. package/dist/backend/llvm/shapes.test.js.map +1 -1
  187. package/dist/backend/llvm/split-loops.d.ts +48 -0
  188. package/dist/backend/llvm/split-loops.js +183 -0
  189. package/dist/backend/llvm/split-loops.js.map +1 -0
  190. package/dist/backend/llvm/split.js +4 -11
  191. package/dist/backend/llvm/split.js.map +1 -1
  192. package/dist/backend/llvm/split.test.js +80 -8
  193. package/dist/backend/llvm/split.test.js.map +1 -1
  194. package/dist/backend/llvm/stack-callbacks.d.ts +14 -0
  195. package/dist/backend/llvm/stack-callbacks.js +73 -0
  196. package/dist/backend/llvm/stack-callbacks.js.map +1 -0
  197. package/dist/backend/llvm/stack-captures.d.ts +25 -0
  198. package/dist/backend/llvm/stack-captures.js +150 -0
  199. package/dist/backend/llvm/stack-captures.js.map +1 -0
  200. package/dist/backend/llvm/stack-unions.js +14 -5
  201. package/dist/backend/llvm/stack-unions.js.map +1 -1
  202. package/dist/backend/llvm/stack-unions.test.js +151 -32
  203. package/dist/backend/llvm/stack-unions.test.js.map +1 -1
  204. package/dist/backend/llvm/string-construction.js.map +1 -1
  205. package/dist/backend/llvm/string-construction.test.js +32 -7
  206. package/dist/backend/llvm/string-construction.test.js.map +1 -1
  207. package/dist/backend/llvm/string-lifetimes.js +14 -8
  208. package/dist/backend/llvm/string-lifetimes.js.map +1 -1
  209. package/dist/backend/llvm/string-lifetimes.test.js +119 -29
  210. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  211. package/dist/backend/llvm/string-slices.d.ts +20 -0
  212. package/dist/backend/llvm/string-slices.js +87 -0
  213. package/dist/backend/llvm/string-slices.js.map +1 -0
  214. package/dist/backend/llvm/string-slices.test.d.ts +1 -0
  215. package/dist/backend/llvm/string-slices.test.js +98 -0
  216. package/dist/backend/llvm/string-slices.test.js.map +1 -0
  217. package/dist/backend/llvm/switch-dispatch.d.ts +9 -0
  218. package/dist/backend/llvm/switch-dispatch.js +114 -0
  219. package/dist/backend/llvm/switch-dispatch.js.map +1 -0
  220. package/dist/backend/llvm/switch-dispatch.test.d.ts +1 -0
  221. package/dist/backend/llvm/switch-dispatch.test.js +83 -0
  222. package/dist/backend/llvm/switch-dispatch.test.js.map +1 -0
  223. package/dist/backend/llvm/unsupported.js.map +1 -1
  224. package/dist/backend/llvm/walkers.d.ts +4 -14
  225. package/dist/backend/llvm/walkers.js +58 -313
  226. package/dist/backend/llvm/walkers.js.map +1 -1
  227. package/dist/backend/mangle.js +9 -3
  228. package/dist/backend/mangle.js.map +1 -1
  229. package/dist/backend/may-throw.js +18 -8
  230. package/dist/backend/may-throw.js.map +1 -1
  231. package/dist/backend/may-throw.test.js +119 -23
  232. package/dist/backend/may-throw.test.js.map +1 -1
  233. package/dist/backend/native/artifact-stamps.d.ts +39 -0
  234. package/dist/backend/native/artifact-stamps.js +371 -0
  235. package/dist/backend/native/artifact-stamps.js.map +1 -0
  236. package/dist/backend/native/cache-warm.d.ts +24 -0
  237. package/dist/backend/native/cache-warm.js +80 -0
  238. package/dist/backend/native/cache-warm.js.map +1 -0
  239. package/dist/backend/native/compiler-fingerprint.d.ts +19 -0
  240. package/dist/backend/native/compiler-fingerprint.js +357 -0
  241. package/dist/backend/native/compiler-fingerprint.js.map +1 -0
  242. package/dist/backend/native/contracts.d.ts +316 -0
  243. package/dist/backend/native/contracts.js +2 -0
  244. package/dist/backend/native/contracts.js.map +1 -0
  245. package/dist/backend/native/dependency-files.d.ts +5 -0
  246. package/dist/backend/native/dependency-files.js +83 -0
  247. package/dist/backend/native/dependency-files.js.map +1 -0
  248. package/dist/backend/native/driver.d.ts +50 -0
  249. package/dist/backend/native/driver.js +294 -0
  250. package/dist/backend/native/driver.js.map +1 -0
  251. package/dist/backend/native/executable.d.ts +18 -0
  252. package/dist/backend/native/executable.js +1275 -0
  253. package/dist/backend/native/executable.js.map +1 -0
  254. package/dist/backend/native/library.d.ts +2 -0
  255. package/dist/backend/native/library.js +614 -0
  256. package/dist/backend/native/library.js.map +1 -0
  257. package/dist/backend/native/linker-fingerprint.d.ts +8 -0
  258. package/dist/backend/native/linker-fingerprint.js +174 -0
  259. package/dist/backend/native/linker-fingerprint.js.map +1 -0
  260. package/dist/backend/native/object-merge.d.ts +2 -0
  261. package/dist/backend/native/object-merge.js +154 -0
  262. package/dist/backend/native/object-merge.js.map +1 -0
  263. package/dist/backend/native/process.d.ts +17 -0
  264. package/dist/backend/native/process.js +42 -0
  265. package/dist/backend/native/process.js.map +1 -0
  266. package/dist/backend/native/program-shards.d.ts +21 -0
  267. package/dist/backend/native/program-shards.js +99 -0
  268. package/dist/backend/native/program-shards.js.map +1 -0
  269. package/dist/backend/native/runtime-inputs.d.ts +12 -0
  270. package/dist/backend/native/runtime-inputs.js +165 -0
  271. package/dist/backend/native/runtime-inputs.js.map +1 -0
  272. package/dist/backend/native/runtime-inputs.test.d.ts +1 -0
  273. package/dist/backend/native/runtime-inputs.test.js +64 -0
  274. package/dist/backend/native/runtime-inputs.test.js.map +1 -0
  275. package/dist/backend/native/runtime-objects.d.ts +16 -0
  276. package/dist/backend/native/runtime-objects.js +122 -0
  277. package/dist/backend/native/runtime-objects.js.map +1 -0
  278. package/dist/backend/native/session.d.ts +12 -0
  279. package/dist/backend/native/session.js +31 -0
  280. package/dist/backend/native/session.js.map +1 -0
  281. package/dist/backend/native/tool-identity.d.ts +37 -0
  282. package/dist/backend/native/tool-identity.js +310 -0
  283. package/dist/backend/native/tool-identity.js.map +1 -0
  284. package/dist/backend/native/trace-paths.d.ts +12 -0
  285. package/dist/backend/native/trace-paths.js +73 -0
  286. package/dist/backend/native/trace-paths.js.map +1 -0
  287. package/dist/backend/native/vendor.d.ts +1 -0
  288. package/dist/backend/native/vendor.js +12 -0
  289. package/dist/backend/native/vendor.js.map +1 -0
  290. package/dist/backend/native-codegen-core.d.ts +6 -0
  291. package/dist/backend/native-codegen-core.js +23 -1
  292. package/dist/backend/native-codegen-core.js.map +1 -1
  293. package/dist/backend/native-codegen.d.ts +5 -1
  294. package/dist/backend/native-codegen.js +52 -25
  295. package/dist/backend/native-codegen.js.map +1 -1
  296. package/dist/backend/native-codegen.test.js +59 -11
  297. package/dist/backend/native-codegen.test.js.map +1 -1
  298. package/dist/backend/native-link-info-core.d.ts +1 -0
  299. package/dist/backend/native-link-info-core.js +9 -5
  300. package/dist/backend/native-link-info-core.js.map +1 -1
  301. package/dist/backend/native-link-info.js +14 -5
  302. package/dist/backend/native-link-info.js.map +1 -1
  303. package/dist/backend/native-link-info.test.js +58 -13
  304. package/dist/backend/native-link-info.test.js.map +1 -1
  305. package/dist/backend/native-toolchain.d.ts +17 -450
  306. package/dist/backend/native-toolchain.js +17 -3971
  307. package/dist/backend/native-toolchain.js.map +1 -1
  308. package/dist/backend/native-toolchain.test.js +103 -72
  309. package/dist/backend/native-toolchain.test.js.map +1 -1
  310. package/dist/backend/native-tools.d.ts +3 -1
  311. package/dist/backend/native-tools.js +30 -9
  312. package/dist/backend/native-tools.js.map +1 -1
  313. package/dist/backend/object-localize.js +17 -14
  314. package/dist/backend/object-localize.js.map +1 -1
  315. package/dist/backend/object-localize.test.js +59 -12
  316. package/dist/backend/object-localize.test.js.map +1 -1
  317. package/dist/backend/runtime-abi.d.ts +2 -2
  318. package/dist/backend/runtime-abi.js +2 -2
  319. package/dist/backend/runtime-pack-core.d.ts +1 -0
  320. package/dist/backend/runtime-pack-core.js +104 -50
  321. package/dist/backend/runtime-pack-core.js.map +1 -1
  322. package/dist/backend/runtime-pack-native.js +5 -3
  323. package/dist/backend/runtime-pack-native.js.map +1 -1
  324. package/dist/backend/runtime-pack-targets.test.js +126 -17
  325. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  326. package/dist/backend/runtime-pack.d.ts +1 -1
  327. package/dist/backend/runtime-pack.js +11 -12
  328. package/dist/backend/runtime-pack.js.map +1 -1
  329. package/dist/backend/runtime-pack.test.js +51 -25
  330. package/dist/backend/runtime-pack.test.js.map +1 -1
  331. package/dist/backend/source-locations.js.map +1 -1
  332. package/dist/backend/source-locations.test.js +7 -2
  333. package/dist/backend/source-locations.test.js.map +1 -1
  334. package/dist/backend/target-diagnostics.js +44 -14
  335. package/dist/backend/target-diagnostics.js.map +1 -1
  336. package/dist/backend/target-diagnostics.test.js +93 -20
  337. package/dist/backend/target-diagnostics.test.js.map +1 -1
  338. package/dist/backend/targets.js +230 -86
  339. package/dist/backend/targets.js.map +1 -1
  340. package/dist/backend/targets.test.js +32 -18
  341. package/dist/backend/targets.test.js.map +1 -1
  342. package/dist/backend/toolchain-environment.js +5 -1
  343. package/dist/backend/toolchain-environment.js.map +1 -1
  344. package/dist/backend/vendor-archives.d.ts +2 -2
  345. package/dist/backend/vendor-archives.js +84 -35
  346. package/dist/backend/vendor-archives.js.map +1 -1
  347. package/dist/backend/vendor-inputs.js +13 -1
  348. package/dist/backend/vendor-inputs.js.map +1 -1
  349. package/dist/backend/warm-cache.d.ts +1 -1
  350. package/dist/backend/warm-cache.js +33 -9
  351. package/dist/backend/warm-cache.js.map +1 -1
  352. package/dist/cli/command.js +39 -9
  353. package/dist/cli/command.js.map +1 -1
  354. package/dist/cli/output-options.js +14 -4
  355. package/dist/cli/output-options.js.map +1 -1
  356. package/dist/cli/paths.js.map +1 -1
  357. package/dist/cli/wasi-runner.js.map +1 -1
  358. package/dist/compat/fetch-profile.js +36 -35
  359. package/dist/compat/fetch-profile.js.map +1 -1
  360. package/dist/coverage/report.js +16 -17
  361. package/dist/coverage/report.js.map +1 -1
  362. package/dist/coverage/surface-manifest.js +112 -26
  363. package/dist/coverage/surface-manifest.js.map +1 -1
  364. package/dist/diagnostics/diagnostic.js +55 -16
  365. package/dist/diagnostics/diagnostic.js.map +1 -1
  366. package/dist/executable/executable-cache.d.ts +2 -1
  367. package/dist/executable/executable-cache.js +79 -48
  368. package/dist/executable/executable-cache.js.map +1 -1
  369. package/dist/executable/executable-cache.test.js +90 -26
  370. package/dist/executable/executable-cache.test.js.map +1 -1
  371. package/dist/executable/prepare.js +2 -2
  372. package/dist/executable/prepare.js.map +1 -1
  373. package/dist/ffi/ffi-manifest.js +78 -20
  374. package/dist/ffi/ffi-manifest.js.map +1 -1
  375. package/dist/ffi/ffi-manifest.test.js +96 -16
  376. package/dist/ffi/ffi-manifest.test.js.map +1 -1
  377. package/dist/format-integer.js.map +1 -1
  378. package/dist/frontend/analysis.js +12 -2
  379. package/dist/frontend/analysis.js.map +1 -1
  380. package/dist/frontend/arguments-usage.js.map +1 -1
  381. package/dist/frontend/binding-source.js +9 -3
  382. package/dist/frontend/binding-source.js.map +1 -1
  383. package/dist/frontend/builtin-modules.js +46 -2
  384. package/dist/frontend/builtin-modules.js.map +1 -1
  385. package/dist/frontend/cjs-resolve.js +40 -17
  386. package/dist/frontend/cjs-resolve.js.map +1 -1
  387. package/dist/frontend/cjs-syntax.js +31 -10
  388. package/dist/frontend/cjs-syntax.js.map +1 -1
  389. package/dist/frontend/comptime-node.test.js +10 -11
  390. package/dist/frontend/comptime-node.test.js.map +1 -1
  391. package/dist/frontend/dts-paths.js +7 -3
  392. package/dist/frontend/dts-paths.js.map +1 -1
  393. package/dist/frontend/fork-target.d.ts +5 -0
  394. package/dist/frontend/fork-target.js +55 -18
  395. package/dist/frontend/fork-target.js.map +1 -1
  396. package/dist/frontend/fork-target.test.d.ts +1 -0
  397. package/dist/frontend/fork-target.test.js +59 -0
  398. package/dist/frontend/fork-target.test.js.map +1 -0
  399. package/dist/frontend/function-completion.js +11 -6
  400. package/dist/frontend/function-completion.js.map +1 -1
  401. package/dist/frontend/helper-tokens.js +53 -6
  402. package/dist/frontend/helper-tokens.js.map +1 -1
  403. package/dist/frontend/helper-tokens.test.js +18 -2
  404. package/dist/frontend/helper-tokens.test.js.map +1 -1
  405. package/dist/frontend/inferred-js-diagnostics.js +32 -12
  406. package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
  407. package/dist/frontend/inferred-js-diagnostics.test.js +11 -15
  408. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
  409. package/dist/frontend/input-tracker.js +11 -11
  410. package/dist/frontend/input-tracker.js.map +1 -1
  411. package/dist/frontend/input-tracker.test.js +4 -1
  412. package/dist/frontend/input-tracker.test.js.map +1 -1
  413. package/dist/frontend/lib-contract.js +38 -9
  414. package/dist/frontend/lib-contract.js.map +1 -1
  415. package/dist/frontend/literal-values.js.map +1 -1
  416. package/dist/frontend/literal-values.test.js +28 -8
  417. package/dist/frontend/literal-values.test.js.map +1 -1
  418. package/dist/frontend/lowering/abstract-equality.js +53 -10
  419. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  420. package/dist/frontend/lowering/array-indexed-mutation.d.ts +1 -1
  421. package/dist/frontend/lowering/array-indexed-mutation.js +108 -106
  422. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
  423. package/dist/frontend/lowering/array-values.js +37 -14
  424. package/dist/frontend/lowering/array-values.js.map +1 -1
  425. package/dist/frontend/lowering/binding-analysis.d.ts +50 -0
  426. package/dist/frontend/lowering/binding-analysis.js +376 -0
  427. package/dist/frontend/lowering/binding-analysis.js.map +1 -0
  428. package/dist/frontend/lowering/builtin-calls.d.ts +9 -0
  429. package/dist/frontend/lowering/builtin-calls.js +60 -0
  430. package/dist/frontend/lowering/builtin-calls.js.map +1 -0
  431. package/dist/frontend/lowering/builtins/arguments.d.ts +43 -0
  432. package/dist/frontend/lowering/builtins/arguments.js +247 -0
  433. package/dist/frontend/lowering/builtins/arguments.js.map +1 -0
  434. package/dist/frontend/lowering/builtins/async-context.d.ts +52 -0
  435. package/dist/frontend/lowering/builtins/async-context.js +436 -0
  436. package/dist/frontend/lowering/builtins/async-context.js.map +1 -0
  437. package/dist/frontend/lowering/builtins/atomics.d.ts +6 -0
  438. package/dist/frontend/lowering/builtins/atomics.js +82 -0
  439. package/dist/frontend/lowering/builtins/atomics.js.map +1 -0
  440. package/dist/frontend/lowering/builtins/callable-aliases.d.ts +13 -0
  441. package/dist/frontend/lowering/builtins/callable-aliases.js +87 -0
  442. package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -0
  443. package/dist/frontend/lowering/builtins/child-process-async.d.ts +18 -0
  444. package/dist/frontend/lowering/builtins/child-process-async.js +245 -0
  445. package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -0
  446. package/dist/frontend/lowering/builtins/child-process-methods.d.ts +21 -0
  447. package/dist/frontend/lowering/builtins/child-process-methods.js +362 -0
  448. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -0
  449. package/dist/frontend/lowering/builtins/child-process-sync.d.ts +4 -0
  450. package/dist/frontend/lowering/builtins/child-process-sync.js +639 -0
  451. package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -0
  452. package/dist/frontend/lowering/builtins/child-process.d.ts +55 -0
  453. package/dist/frontend/lowering/builtins/child-process.js +669 -0
  454. package/dist/frontend/lowering/builtins/child-process.js.map +1 -0
  455. package/dist/frontend/lowering/builtins/compression.d.ts +7 -0
  456. package/dist/frontend/lowering/builtins/compression.js +115 -0
  457. package/dist/frontend/lowering/builtins/compression.js.map +1 -0
  458. package/dist/frontend/lowering/builtins/console.d.ts +10 -0
  459. package/dist/frontend/lowering/builtins/console.js +38 -0
  460. package/dist/frontend/lowering/builtins/console.js.map +1 -0
  461. package/dist/frontend/lowering/builtins/constants.d.ts +24 -0
  462. package/dist/frontend/lowering/builtins/constants.js +141 -0
  463. package/dist/frontend/lowering/builtins/constants.js.map +1 -0
  464. package/dist/frontend/lowering/builtins/crypto.d.ts +22 -0
  465. package/dist/frontend/lowering/builtins/crypto.js +517 -0
  466. package/dist/frontend/lowering/builtins/crypto.js.map +1 -0
  467. package/dist/frontend/lowering/builtins/dates.d.ts +7 -0
  468. package/dist/frontend/lowering/builtins/dates.js +101 -0
  469. package/dist/frontend/lowering/builtins/dates.js.map +1 -0
  470. package/dist/frontend/lowering/builtins/environment.d.ts +34 -0
  471. package/dist/frontend/lowering/builtins/environment.js +95 -0
  472. package/dist/frontend/lowering/builtins/environment.js.map +1 -0
  473. package/dist/frontend/lowering/builtins/errors.d.ts +14 -0
  474. package/dist/frontend/lowering/builtins/errors.js +83 -0
  475. package/dist/frontend/lowering/builtins/errors.js.map +1 -0
  476. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +35 -0
  477. package/dist/frontend/lowering/builtins/filesystem-calls.js +725 -0
  478. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -0
  479. package/dist/frontend/lowering/builtins/filesystem.d.ts +108 -0
  480. package/dist/frontend/lowering/builtins/filesystem.js +1061 -0
  481. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -0
  482. package/dist/frontend/lowering/builtins/ipc.d.ts +8 -0
  483. package/dist/frontend/lowering/builtins/ipc.js +76 -0
  484. package/dist/frontend/lowering/builtins/ipc.js.map +1 -0
  485. package/dist/frontend/lowering/builtins/json.d.ts +12 -0
  486. package/dist/frontend/lowering/builtins/json.js +387 -0
  487. package/dist/frontend/lowering/builtins/json.js.map +1 -0
  488. package/dist/frontend/lowering/builtins/module-bindings.d.ts +85 -0
  489. package/dist/frontend/lowering/builtins/module-bindings.js +346 -0
  490. package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -0
  491. package/dist/frontend/lowering/builtins/module-calls.d.ts +8 -0
  492. package/dist/frontend/lowering/builtins/module-calls.js +308 -0
  493. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -0
  494. package/dist/frontend/lowering/builtins/module-resolution.d.ts +38 -0
  495. package/dist/frontend/lowering/builtins/module-resolution.js +344 -0
  496. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -0
  497. package/dist/frontend/lowering/builtins/numbers.d.ts +15 -0
  498. package/dist/frontend/lowering/builtins/numbers.js +124 -0
  499. package/dist/frontend/lowering/builtins/numbers.js.map +1 -0
  500. package/dist/frontend/lowering/builtins/operating-system.d.ts +13 -0
  501. package/dist/frontend/lowering/builtins/operating-system.js +148 -0
  502. package/dist/frontend/lowering/builtins/operating-system.js.map +1 -0
  503. package/dist/frontend/lowering/builtins/performance.d.ts +13 -0
  504. package/dist/frontend/lowering/builtins/performance.js +100 -0
  505. package/dist/frontend/lowering/builtins/performance.js.map +1 -0
  506. package/dist/frontend/lowering/builtins/process.d.ts +50 -0
  507. package/dist/frontend/lowering/builtins/process.js +1138 -0
  508. package/dist/frontend/lowering/builtins/process.js.map +1 -0
  509. package/dist/frontend/lowering/builtins/promises.d.ts +14 -0
  510. package/dist/frontend/lowering/builtins/promises.js +356 -0
  511. package/dist/frontend/lowering/builtins/promises.js.map +1 -0
  512. package/dist/frontend/lowering/builtins/properties.d.ts +11 -0
  513. package/dist/frontend/lowering/builtins/properties.js +186 -0
  514. package/dist/frontend/lowering/builtins/properties.js.map +1 -0
  515. package/dist/frontend/lowering/builtins/querystring.d.ts +19 -0
  516. package/dist/frontend/lowering/builtins/querystring.js +150 -0
  517. package/dist/frontend/lowering/builtins/querystring.js.map +1 -0
  518. package/dist/frontend/lowering/builtins/readline.d.ts +13 -0
  519. package/dist/frontend/lowering/builtins/readline.js +138 -0
  520. package/dist/frontend/lowering/builtins/readline.js.map +1 -0
  521. package/dist/frontend/lowering/builtins/receiver-types.d.ts +5 -0
  522. package/dist/frontend/lowering/builtins/receiver-types.js +15 -0
  523. package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -0
  524. package/dist/frontend/lowering/builtins/reflection.d.ts +13 -0
  525. package/dist/frontend/lowering/builtins/reflection.js +95 -0
  526. package/dist/frontend/lowering/builtins/reflection.js.map +1 -0
  527. package/dist/frontend/lowering/builtins/strings.d.ts +14 -0
  528. package/dist/frontend/lowering/builtins/strings.js +121 -0
  529. package/dist/frontend/lowering/builtins/strings.js.map +1 -0
  530. package/dist/frontend/lowering/builtins/text-codecs.d.ts +29 -0
  531. package/dist/frontend/lowering/builtins/text-codecs.js +590 -0
  532. package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -0
  533. package/dist/frontend/lowering/builtins/timers.d.ts +22 -0
  534. package/dist/frontend/lowering/builtins/timers.js +180 -0
  535. package/dist/frontend/lowering/builtins/timers.js.map +1 -0
  536. package/dist/frontend/lowering/builtins/url.d.ts +37 -0
  537. package/dist/frontend/lowering/builtins/url.js +596 -0
  538. package/dist/frontend/lowering/builtins/url.js.map +1 -0
  539. package/dist/frontend/lowering/builtins/util-types.d.ts +7 -0
  540. package/dist/frontend/lowering/builtins/util-types.js +31 -0
  541. package/dist/frontend/lowering/builtins/util-types.js.map +1 -0
  542. package/dist/frontend/lowering/builtins/workers.d.ts +5 -0
  543. package/dist/frontend/lowering/builtins/workers.js +65 -0
  544. package/dist/frontend/lowering/builtins/workers.js.map +1 -0
  545. package/dist/frontend/lowering/call-arguments.d.ts +72 -0
  546. package/dist/frontend/lowering/call-arguments.js +618 -0
  547. package/dist/frontend/lowering/call-arguments.js.map +1 -0
  548. package/dist/frontend/lowering/call-signatures.d.ts +115 -0
  549. package/dist/frontend/lowering/call-signatures.js +719 -0
  550. package/dist/frontend/lowering/call-signatures.js.map +1 -0
  551. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  552. package/dist/frontend/lowering/checked-iterable-spread.js +53 -10
  553. package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -1
  554. package/dist/frontend/lowering/checked-promise-all.js +41 -9
  555. package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
  556. package/dist/frontend/lowering/class-assertions.d.ts +7 -0
  557. package/dist/frontend/lowering/class-assertions.js +96 -0
  558. package/dist/frontend/lowering/class-assertions.js.map +1 -0
  559. package/dist/frontend/lowering/class-callbacks.d.ts +1 -1
  560. package/dist/frontend/lowering/class-callbacks.js +130 -27
  561. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  562. package/dist/frontend/lowering/class-construction.d.ts +1 -1
  563. package/dist/frontend/lowering/class-construction.js +247 -50
  564. package/dist/frontend/lowering/class-construction.js.map +1 -1
  565. package/dist/frontend/lowering/class-descriptors.js +109 -29
  566. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  567. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +6 -1
  568. package/dist/frontend/lowering/class-dynamic-dispatch.js +2471 -465
  569. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  570. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +284 -44
  571. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  572. package/dist/frontend/lowering/class-instance-constructor.js +17 -5
  573. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  574. package/dist/frontend/lowering/class-method-values.js +199 -51
  575. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  576. package/dist/frontend/lowering/class-protocols.d.ts +17 -0
  577. package/dist/frontend/lowering/class-protocols.js +126 -0
  578. package/dist/frontend/lowering/class-protocols.js.map +1 -0
  579. package/dist/frontend/lowering/class-prototypes.js +345 -86
  580. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  581. package/dist/frontend/lowering/class-runtime-statics.d.ts +1 -1
  582. package/dist/frontend/lowering/class-runtime-statics.js +80 -17
  583. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  584. package/dist/frontend/lowering/class-static-data.js +76 -16
  585. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  586. package/dist/frontend/lowering/coercions/builders.d.ts +13 -0
  587. package/dist/frontend/lowering/coercions/builders.js +77 -0
  588. package/dist/frontend/lowering/coercions/builders.js.map +1 -0
  589. package/dist/frontend/lowering/coercions/function-adapters.d.ts +58 -0
  590. package/dist/frontend/lowering/coercions/function-adapters.js +430 -0
  591. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -0
  592. package/dist/frontend/lowering/coercions/island.d.ts +37 -0
  593. package/dist/frontend/lowering/coercions/island.js +350 -0
  594. package/dist/frontend/lowering/coercions/island.js.map +1 -0
  595. package/dist/frontend/lowering/coercions/state.d.ts +14 -0
  596. package/dist/frontend/lowering/coercions/state.js +16 -0
  597. package/dist/frontend/lowering/coercions/state.js.map +1 -0
  598. package/dist/frontend/lowering/coercions/structural-plans.d.ts +40 -0
  599. package/dist/frontend/lowering/coercions/structural-plans.js +447 -0
  600. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -0
  601. package/dist/frontend/lowering/coercions/structural.d.ts +63 -0
  602. package/dist/frontend/lowering/coercions/structural.js +616 -0
  603. package/dist/frontend/lowering/coercions/structural.js.map +1 -0
  604. package/dist/frontend/lowering/coercions/unions.d.ts +65 -0
  605. package/dist/frontend/lowering/coercions/unions.js +318 -0
  606. package/dist/frontend/lowering/coercions/unions.js.map +1 -0
  607. package/dist/frontend/lowering/collection-ingestion.js +355 -72
  608. package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
  609. package/dist/frontend/lowering/containers/array-callbacks.d.ts +88 -0
  610. package/dist/frontend/lowering/containers/array-callbacks.js +1611 -0
  611. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -0
  612. package/dist/frontend/lowering/containers/array-construction.d.ts +42 -0
  613. package/dist/frontend/lowering/containers/array-construction.js +1044 -0
  614. package/dist/frontend/lowering/containers/array-construction.js.map +1 -0
  615. package/dist/frontend/lowering/containers/array-iteration.d.ts +16 -0
  616. package/dist/frontend/lowering/containers/array-iteration.js +95 -0
  617. package/dist/frontend/lowering/containers/array-iteration.js.map +1 -0
  618. package/dist/frontend/lowering/containers/array-methods.d.ts +27 -0
  619. package/dist/frontend/lowering/containers/array-methods.js +1854 -0
  620. package/dist/frontend/lowering/containers/array-methods.js.map +1 -0
  621. package/dist/frontend/lowering/containers/bytes.d.ts +17 -17
  622. package/dist/frontend/lowering/containers/bytes.js +430 -138
  623. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  624. package/dist/frontend/lowering/containers/callback-arguments.d.ts +26 -0
  625. package/dist/frontend/lowering/containers/callback-arguments.js +179 -0
  626. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -0
  627. package/dist/frontend/lowering/containers/collection-grouping.d.ts +19 -0
  628. package/dist/frontend/lowering/containers/collection-grouping.js +297 -0
  629. package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -0
  630. package/dist/frontend/lowering/containers/collection-methods.d.ts +57 -0
  631. package/dist/frontend/lowering/containers/collection-methods.js +1314 -0
  632. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -0
  633. package/dist/frontend/lowering/containers/dynamic-receivers.d.ts +18 -0
  634. package/dist/frontend/lowering/containers/dynamic-receivers.js +114 -0
  635. package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -0
  636. package/dist/frontend/lowering/containers/for-of.d.ts +60 -0
  637. package/dist/frontend/lowering/containers/for-of.js +643 -0
  638. package/dist/frontend/lowering/containers/for-of.js.map +1 -0
  639. package/dist/frontend/lowering/containers/indexed-objects.d.ts +132 -0
  640. package/dist/frontend/lowering/containers/indexed-objects.js +1743 -0
  641. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -0
  642. package/dist/frontend/lowering/containers/iterator-helpers.d.ts +20 -0
  643. package/dist/frontend/lowering/containers/iterator-helpers.js +809 -0
  644. package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -0
  645. package/dist/frontend/lowering/containers/string-and-regexp.js +601 -160
  646. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  647. package/dist/frontend/lowering/containers/string-replacement.js +213 -63
  648. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
  649. package/dist/frontend/lowering/crypto-tables.js +263 -64
  650. package/dist/frontend/lowering/crypto-tables.js.map +1 -1
  651. package/dist/frontend/lowering/deferred-module-initializers.js +172 -68
  652. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
  653. package/dist/frontend/lowering/deferred-module-initializers.test.js +41 -8
  654. package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -1
  655. package/dist/frontend/lowering/error-methods.js +339 -65
  656. package/dist/frontend/lowering/error-methods.js.map +1 -1
  657. package/dist/frontend/lowering/expressions/evaluation-safety.js +3 -2
  658. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
  659. package/dist/frontend/lowering/expressions/global-symbols.js +2 -1
  660. package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -1
  661. package/dist/frontend/lowering/expressions/native-proxy.js +11 -5
  662. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
  663. package/dist/frontend/lowering/expressions/nullish-assignment.js +67 -13
  664. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  665. package/dist/frontend/lowering/expressions/object-literals.js +588 -165
  666. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  667. package/dist/frontend/lowering/expressions/optional-chains.d.ts +1 -1
  668. package/dist/frontend/lowering/expressions/optional-chains.js +68 -17
  669. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  670. package/dist/frontend/lowering/expressions/union-field-write.js +45 -18
  671. package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -1
  672. package/dist/frontend/lowering/function-context.js +5 -1
  673. package/dist/frontend/lowering/function-context.js.map +1 -1
  674. package/dist/frontend/lowering/function-returns.d.ts +67 -0
  675. package/dist/frontend/lowering/function-returns.js +392 -0
  676. package/dist/frontend/lowering/function-returns.js.map +1 -0
  677. package/dist/frontend/lowering/generator-delegation.d.ts +1 -1
  678. package/dist/frontend/lowering/generator-delegation.js +171 -39
  679. package/dist/frontend/lowering/generator-delegation.js.map +1 -1
  680. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -1
  681. package/dist/frontend/lowering/generator-dynamic-dispatch.js +176 -36
  682. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  683. package/dist/frontend/lowering/generic-functions.d.ts +271 -0
  684. package/dist/frontend/lowering/generic-functions.js +1730 -0
  685. package/dist/frontend/lowering/generic-functions.js.map +1 -0
  686. package/dist/frontend/lowering/import-meta.d.ts +1 -1
  687. package/dist/frontend/lowering/import-meta.js +37 -14
  688. package/dist/frontend/lowering/import-meta.js.map +1 -1
  689. package/dist/frontend/lowering/indexed-comparison.js +6 -2
  690. package/dist/frontend/lowering/indexed-comparison.js.map +1 -1
  691. package/dist/frontend/lowering/instantiation-path.d.ts +8 -0
  692. package/dist/frontend/lowering/instantiation-path.js +10 -0
  693. package/dist/frontend/lowering/instantiation-path.js.map +1 -0
  694. package/dist/frontend/lowering/instantiation-path.test.d.ts +1 -0
  695. package/dist/frontend/lowering/instantiation-path.test.js +23 -0
  696. package/dist/frontend/lowering/instantiation-path.test.js.map +1 -0
  697. package/dist/frontend/lowering/iterator-consumption.d.ts +9 -0
  698. package/dist/frontend/lowering/iterator-consumption.js +91 -0
  699. package/dist/frontend/lowering/iterator-consumption.js.map +1 -0
  700. package/dist/frontend/lowering/lib-boundary.js +40 -17
  701. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  702. package/dist/frontend/lowering/lib-boundary.test.js +49 -11
  703. package/dist/frontend/lowering/lib-boundary.test.js.map +1 -1
  704. package/dist/frontend/lowering/lower-array-sort.d.ts +0 -19
  705. package/dist/frontend/lowering/lower-array-sort.js +331 -566
  706. package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
  707. package/dist/frontend/lowering/lower-assert.js +248 -43
  708. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  709. package/dist/frontend/lowering/lower-async-iteration.js +71 -16
  710. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  711. package/dist/frontend/lowering/lower-builtin-values.js +430 -77
  712. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  713. package/dist/frontend/lowering/lower-calls.d.ts +39 -558
  714. package/dist/frontend/lowering/lower-calls.js +2628 -5669
  715. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  716. package/dist/frontend/lowering/lower-classes.d.ts +248 -242
  717. package/dist/frontend/lowering/lower-classes.js +1820 -775
  718. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  719. package/dist/frontend/lowering/lower-comptime.d.ts +35 -35
  720. package/dist/frontend/lowering/lower-comptime.js +39 -37
  721. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  722. package/dist/frontend/lowering/lower-dgram.js +59 -31
  723. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  724. package/dist/frontend/lowering/lower-enums.js +5 -2
  725. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  726. package/dist/frontend/lowering/lower-event-emitter.js +323 -86
  727. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  728. package/dist/frontend/lowering/lower-expando.js +19 -7
  729. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  730. package/dist/frontend/lowering/lower-exprs.d.ts +194 -194
  731. package/dist/frontend/lowering/lower-exprs.js +3473 -1160
  732. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  733. package/dist/frontend/lowering/lower-functions.d.ts +23 -0
  734. package/dist/frontend/lowering/lower-functions.js +449 -0
  735. package/dist/frontend/lowering/lower-functions.js.map +1 -0
  736. package/dist/frontend/lowering/lower-generators.js +121 -32
  737. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  738. package/dist/frontend/lowering/lower-global-value.js +15 -4
  739. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  740. package/dist/frontend/lowering/lower-inspect.js +479 -89
  741. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  742. package/dist/frontend/lowering/lower-island.d.ts +79 -79
  743. package/dist/frontend/lowering/lower-island.js +366 -274
  744. package/dist/frontend/lowering/lower-island.js.map +1 -1
  745. package/dist/frontend/lowering/lower-island.test.js +7 -2
  746. package/dist/frontend/lowering/lower-island.test.js.map +1 -1
  747. package/dist/frontend/lowering/lower-mixins.js +17 -8
  748. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  749. package/dist/frontend/lowering/lower-modules.d.ts +95 -94
  750. package/dist/frontend/lowering/lower-modules.js +655 -329
  751. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  752. package/dist/frontend/lowering/lower-modules.test.js +91 -20
  753. package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
  754. package/dist/frontend/lowering/lower-namespaces.js +25 -8
  755. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  756. package/dist/frontend/lowering/lower-node-module.js +115 -34
  757. package/dist/frontend/lowering/lower-node-module.js.map +1 -1
  758. package/dist/frontend/lowering/lower-server.js +1210 -290
  759. package/dist/frontend/lowering/lower-server.js.map +1 -1
  760. package/dist/frontend/lowering/lower-stmts.d.ts +148 -148
  761. package/dist/frontend/lowering/lower-stmts.js +2324 -994
  762. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  763. package/dist/frontend/lowering/lower-stmts.test.js +13 -5
  764. package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
  765. package/dist/frontend/lowering/lower-stream.js +363 -91
  766. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  767. package/dist/frontend/lowering/lower-system-errors.js +30 -8
  768. package/dist/frontend/lowering/lower-system-errors.js.map +1 -1
  769. package/dist/frontend/lowering/lower-test.js +40 -13
  770. package/dist/frontend/lowering/lower-test.js.map +1 -1
  771. package/dist/frontend/lowering/lower-timers.d.ts +31 -0
  772. package/dist/frontend/lowering/lower-timers.js +336 -0
  773. package/dist/frontend/lowering/lower-timers.js.map +1 -0
  774. package/dist/frontend/lowering/lower-url.d.ts +1 -1
  775. package/dist/frontend/lowering/lower-url.js +46 -13
  776. package/dist/frontend/lowering/lower-url.js.map +1 -1
  777. package/dist/frontend/lowering/lowerer.d.ts +34 -352
  778. package/dist/frontend/lowering/lowerer.js +1074 -2712
  779. package/dist/frontend/lowering/lowerer.js.map +1 -1
  780. package/dist/frontend/lowering/lowerer.test.js +85 -17
  781. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  782. package/dist/frontend/lowering/module-namespace-elements.js +43 -8
  783. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  784. package/dist/frontend/lowering/native-ffi.d.ts +21 -1
  785. package/dist/frontend/lowering/native-ffi.js +487 -18
  786. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  787. package/dist/frontend/lowering/object-enumeration-receiver.js +55 -10
  788. package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -1
  789. package/dist/frontend/lowering/object-factory-new.d.ts +1 -1
  790. package/dist/frontend/lowering/object-factory-new.js +36 -11
  791. package/dist/frontend/lowering/object-factory-new.js.map +1 -1
  792. package/dist/frontend/lowering/optional-arguments.js +49 -20
  793. package/dist/frontend/lowering/optional-arguments.js.map +1 -1
  794. package/dist/frontend/lowering/pairs-snapshot.js +66 -14
  795. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  796. package/dist/frontend/lowering/runtime-optional-locals.js +3 -1
  797. package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -1
  798. package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -1
  799. package/dist/frontend/lowering/sanitize-class-types.js +4 -1
  800. package/dist/frontend/lowering/sanitize-class-types.js.map +1 -1
  801. package/dist/frontend/lowering/sanitize-class-types.test.js +86 -18
  802. package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -1
  803. package/dist/frontend/lowering/split-consumers.d.ts +7 -0
  804. package/dist/frontend/lowering/split-consumers.js +64 -0
  805. package/dist/frontend/lowering/split-consumers.js.map +1 -0
  806. package/dist/frontend/lowering/static-this.js +13 -6
  807. package/dist/frontend/lowering/static-this.js.map +1 -1
  808. package/dist/frontend/lowering/string-index.js +32 -10
  809. package/dist/frontend/lowering/string-index.js.map +1 -1
  810. package/dist/frontend/lowering/surfaces.d.ts +45 -46
  811. package/dist/frontend/lowering/surfaces.js +1129 -256
  812. package/dist/frontend/lowering/surfaces.js.map +1 -1
  813. package/dist/frontend/lowering/symbol-fields.js +40 -15
  814. package/dist/frontend/lowering/symbol-fields.js.map +1 -1
  815. package/dist/frontend/lowering/symbol-methods.js.map +1 -1
  816. package/dist/frontend/lowering/text-decoder-encoding.js +236 -24
  817. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
  818. package/dist/frontend/lowering/text-decoder-encoding.test.js +84 -12
  819. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -1
  820. package/dist/frontend/lowering/union-narrow.js +59 -16
  821. package/dist/frontend/lowering/union-narrow.js.map +1 -1
  822. package/dist/frontend/lowering/union-narrow.test.js +24 -7
  823. package/dist/frontend/lowering/union-narrow.test.js.map +1 -1
  824. package/dist/frontend/lowering/union-retag.js +155 -40
  825. package/dist/frontend/lowering/union-retag.js.map +1 -1
  826. package/dist/frontend/lowering/union-retag.test.js +131 -33
  827. package/dist/frontend/lowering/union-retag.test.js.map +1 -1
  828. package/dist/frontend/lowering/unregistered-class-types.js.map +1 -1
  829. package/dist/frontend/lowering/unregistered-class-types.test.js +34 -8
  830. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
  831. package/dist/frontend/module-source-candidates.d.ts +10 -0
  832. package/dist/frontend/module-source-candidates.js +40 -0
  833. package/dist/frontend/module-source-candidates.js.map +1 -0
  834. package/dist/frontend/module-source-candidates.test.d.ts +1 -0
  835. package/dist/frontend/module-source-candidates.test.js +53 -0
  836. package/dist/frontend/module-source-candidates.test.js.map +1 -0
  837. package/dist/frontend/module-syntax.js +21 -8
  838. package/dist/frontend/module-syntax.js.map +1 -1
  839. package/dist/frontend/module-syntax.test.js +37 -13
  840. package/dist/frontend/module-syntax.test.js.map +1 -1
  841. package/dist/frontend/npm-fetch-analysis.js +13 -4
  842. package/dist/frontend/npm-fetch-analysis.js.map +1 -1
  843. package/dist/frontend/npm-fetch-analysis.test.js +33 -10
  844. package/dist/frontend/npm-fetch-analysis.test.js.map +1 -1
  845. package/dist/frontend/npm-fetch-node.js.map +1 -1
  846. package/dist/frontend/npm-fetch-syntax.js +4 -9
  847. package/dist/frontend/npm-fetch-syntax.js.map +1 -1
  848. package/dist/frontend/npm-node.js +3 -1
  849. package/dist/frontend/npm-node.js.map +1 -1
  850. package/dist/frontend/npm-static-bundled-cjs.js +88 -29
  851. package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
  852. package/dist/frontend/npm-static-bundled-cjs.test.js +29 -10
  853. package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -1
  854. package/dist/frontend/npm-static-declaration-syntax.js +148 -56
  855. package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
  856. package/dist/frontend/npm-static-declarations.d.ts +1 -1
  857. package/dist/frontend/npm-static-declarations.js.map +1 -1
  858. package/dist/frontend/npm-static-declarations.test.js +33 -7
  859. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  860. package/dist/frontend/npm-static-prune.js +26 -12
  861. package/dist/frontend/npm-static-prune.js.map +1 -1
  862. package/dist/frontend/npm-static-prune.test.js +17 -3
  863. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  864. package/dist/frontend/npm-static-rewrite-host.js +2 -3
  865. package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
  866. package/dist/frontend/npm-static-rewrite-syntax.js +64 -21
  867. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  868. package/dist/frontend/npm-static-rewrite.js.map +1 -1
  869. package/dist/frontend/npm-static-subtyping.js +9 -4
  870. package/dist/frontend/npm-static-subtyping.js.map +1 -1
  871. package/dist/frontend/npm-static-subtyping.test.js +30 -6
  872. package/dist/frontend/npm-static-subtyping.test.js.map +1 -1
  873. package/dist/frontend/npm-static.js +15 -4
  874. package/dist/frontend/npm-static.js.map +1 -1
  875. package/dist/frontend/npm.js +122 -36
  876. package/dist/frontend/npm.js.map +1 -1
  877. package/dist/frontend/npm.test.js +30 -10
  878. package/dist/frontend/npm.test.js.map +1 -1
  879. package/dist/frontend/pipeline-native.js.map +1 -1
  880. package/dist/frontend/pipeline.js +25 -8
  881. package/dist/frontend/pipeline.js.map +1 -1
  882. package/dist/frontend/pipeline.test.js +21 -7
  883. package/dist/frontend/pipeline.test.js.map +1 -1
  884. package/dist/frontend/program-analysis.d.ts +2 -0
  885. package/dist/frontend/program-analysis.js +2 -0
  886. package/dist/frontend/program-analysis.js.map +1 -1
  887. package/dist/frontend/program-node.js +5 -3
  888. package/dist/frontend/program-node.js.map +1 -1
  889. package/dist/frontend/program.d.ts +2 -2
  890. package/dist/frontend/program.js +248 -127
  891. package/dist/frontend/program.js.map +1 -1
  892. package/dist/frontend/program.test.js +27 -27
  893. package/dist/frontend/program.test.js.map +1 -1
  894. package/dist/frontend/provenance-core.js +8 -4
  895. package/dist/frontend/provenance-core.js.map +1 -1
  896. package/dist/frontend/provenance-registry.js +1 -4
  897. package/dist/frontend/provenance-registry.js.map +1 -1
  898. package/dist/frontend/resolve.js +32 -20
  899. package/dist/frontend/resolve.js.map +1 -1
  900. package/dist/frontend/resolve.test.js +1 -1
  901. package/dist/frontend/resolve.test.js.map +1 -1
  902. package/dist/frontend/runtime-resolve.js +13 -4
  903. package/dist/frontend/runtime-resolve.js.map +1 -1
  904. package/dist/frontend/runtime-resolve.test.js +25 -9
  905. package/dist/frontend/runtime-resolve.test.js.map +1 -1
  906. package/dist/frontend/services-node.js +6 -2
  907. package/dist/frontend/services-node.js.map +1 -1
  908. package/dist/frontend/services-node.test.js +18 -6
  909. package/dist/frontend/services-node.test.js.map +1 -1
  910. package/dist/frontend/services.js +8 -4
  911. package/dist/frontend/services.js.map +1 -1
  912. package/dist/frontend/services.test.js +6 -2
  913. package/dist/frontend/services.test.js.map +1 -1
  914. package/dist/frontend/ts7/api.js +12 -4
  915. package/dist/frontend/ts7/api.js.map +1 -1
  916. package/dist/frontend/ts7/ast-bytes.js +10 -3
  917. package/dist/frontend/ts7/ast-bytes.js.map +1 -1
  918. package/dist/frontend/ts7/ast-bytes.test.js +23 -4
  919. package/dist/frontend/ts7/ast-bytes.test.js.map +1 -1
  920. package/dist/frontend/ts7/ast-guards.test.js +14 -5
  921. package/dist/frontend/ts7/ast-guards.test.js.map +1 -1
  922. package/dist/frontend/ts7/ast-node.d.ts +6 -1
  923. package/dist/frontend/ts7/ast-node.js +490 -172
  924. package/dist/frontend/ts7/ast-node.js.map +1 -1
  925. package/dist/frontend/ts7/ast-node.test.js +150 -36
  926. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  927. package/dist/frontend/ts7/ast-text.js +13 -3
  928. package/dist/frontend/ts7/ast-text.js.map +1 -1
  929. package/dist/frontend/ts7/ast-text.test.js.map +1 -1
  930. package/dist/frontend/ts7/ast-types.js.map +1 -1
  931. package/dist/frontend/ts7/ast-wire.d.ts +5 -1
  932. package/dist/frontend/ts7/ast-wire.js +83 -20
  933. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  934. package/dist/frontend/ts7/ast-wire.test.js +53 -8
  935. package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
  936. package/dist/frontend/ts7/ast.d.ts +2 -1
  937. package/dist/frontend/ts7/ast.js +53 -30
  938. package/dist/frontend/ts7/ast.js.map +1 -1
  939. package/dist/frontend/ts7/census-check.js +1 -1
  940. package/dist/frontend/ts7/census-check.js.map +1 -1
  941. package/dist/frontend/ts7/checker-cache.js.map +1 -1
  942. package/dist/frontend/ts7/checker.d.ts +8 -2
  943. package/dist/frontend/ts7/checker.js +46 -8
  944. package/dist/frontend/ts7/checker.js.map +1 -1
  945. package/dist/frontend/ts7/checker.test.js +96 -17
  946. package/dist/frontend/ts7/checker.test.js.map +1 -1
  947. package/dist/frontend/ts7/enums.test.js +9 -4
  948. package/dist/frontend/ts7/enums.test.js.map +1 -1
  949. package/dist/frontend/ts7/native-api.js.map +1 -1
  950. package/dist/frontend/ts7/native-host.js.map +1 -1
  951. package/dist/frontend/ts7/native-process.js +9 -3
  952. package/dist/frontend/ts7/native-process.js.map +1 -1
  953. package/dist/frontend/ts7/program-adapter.js +1 -1
  954. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  955. package/dist/frontend/ts7/program-host.d.ts +7 -0
  956. package/dist/frontend/ts7/program-host.js +33 -6
  957. package/dist/frontend/ts7/program-host.js.map +1 -1
  958. package/dist/frontend/ts7/program-host.test.js +72 -11
  959. package/dist/frontend/ts7/program-host.test.js.map +1 -1
  960. package/dist/frontend/ts7/rpc-api.js +3 -1
  961. package/dist/frontend/ts7/rpc-api.js.map +1 -1
  962. package/dist/frontend/ts7/rpc-client.js +15 -5
  963. package/dist/frontend/ts7/rpc-client.js.map +1 -1
  964. package/dist/frontend/ts7/rpc-client.test.js +26 -8
  965. package/dist/frontend/ts7/rpc-client.test.js.map +1 -1
  966. package/dist/frontend/ts7/rpc-filesystem.js.map +1 -1
  967. package/dist/frontend/ts7/rpc-filesystem.test.js +43 -10
  968. package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -1
  969. package/dist/frontend/ts7/rpc-process.js +16 -6
  970. package/dist/frontend/ts7/rpc-process.js.map +1 -1
  971. package/dist/frontend/ts7/rpc-process.test.js.map +1 -1
  972. package/dist/frontend/ts7/rpc-wire.d.ts +1 -0
  973. package/dist/frontend/ts7/rpc-wire.js +41 -14
  974. package/dist/frontend/ts7/rpc-wire.js.map +1 -1
  975. package/dist/frontend/ts7/rpc-wire.test.js +36 -6
  976. package/dist/frontend/ts7/rpc-wire.test.js.map +1 -1
  977. package/dist/frontend/ts7/semantic-checker.js +209 -68
  978. package/dist/frontend/ts7/semantic-checker.js.map +1 -1
  979. package/dist/frontend/ts7/semantic-checker.test.js +29 -14
  980. package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
  981. package/dist/frontend/ts7/semantic-json.js +7 -1
  982. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  983. package/dist/frontend/ts7/semantic-json.test.js +17 -3
  984. package/dist/frontend/ts7/semantic-json.test.js.map +1 -1
  985. package/dist/frontend/ts7/semantic-model.js +147 -51
  986. package/dist/frontend/ts7/semantic-model.js.map +1 -1
  987. package/dist/frontend/ts7/semantic-model.test.js +72 -19
  988. package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
  989. package/dist/frontend/ts7/semantic-types.d.ts +2 -2
  990. package/dist/frontend/ts7/session-cache.js +10 -3
  991. package/dist/frontend/ts7/session-cache.js.map +1 -1
  992. package/dist/frontend/ts7/session-cache.test.js +13 -4
  993. package/dist/frontend/ts7/session-cache.test.js.map +1 -1
  994. package/dist/frontend/ts7/session-path.js +25 -10
  995. package/dist/frontend/ts7/session-path.js.map +1 -1
  996. package/dist/frontend/ts7/session-path.test.js +47 -4
  997. package/dist/frontend/ts7/session-path.test.js.map +1 -1
  998. package/dist/frontend/ts7/session-timing.js +22 -3
  999. package/dist/frontend/ts7/session-timing.js.map +1 -1
  1000. package/dist/frontend/ts7/session-timing.test.js +12 -3
  1001. package/dist/frontend/ts7/session-timing.test.js.map +1 -1
  1002. package/dist/frontend/ts7/session.d.ts +1 -0
  1003. package/dist/frontend/ts7/session.js +109 -35
  1004. package/dist/frontend/ts7/session.js.map +1 -1
  1005. package/dist/frontend/ts7/session.test.js +69 -15
  1006. package/dist/frontend/ts7/session.test.js.map +1 -1
  1007. package/dist/frontend/ts7/source-parser.js +17 -6
  1008. package/dist/frontend/ts7/source-parser.js.map +1 -1
  1009. package/dist/frontend/ts7/source-parser.test.js +32 -9
  1010. package/dist/frontend/ts7/source-parser.test.js.map +1 -1
  1011. package/dist/frontend/tsc-codes.js +56 -11
  1012. package/dist/frontend/tsc-codes.js.map +1 -1
  1013. package/dist/frontend/tsc-codes.test.d.ts +1 -0
  1014. package/dist/frontend/tsc-codes.test.js +16 -0
  1015. package/dist/frontend/tsc-codes.test.js.map +1 -0
  1016. package/dist/frontend/type-mapper.d.ts +3 -0
  1017. package/dist/frontend/type-mapper.js +589 -206
  1018. package/dist/frontend/type-mapper.js.map +1 -1
  1019. package/dist/frontend/type-mapper.test.js +108 -33
  1020. package/dist/frontend/type-mapper.test.js.map +1 -1
  1021. package/dist/frontend/union-discriminants.js +8 -2
  1022. package/dist/frontend/union-discriminants.js.map +1 -1
  1023. package/dist/frontend/union-discriminants.test.js +77 -20
  1024. package/dist/frontend/union-discriminants.test.js.map +1 -1
  1025. package/dist/frontend/worker-target.d.ts +6 -0
  1026. package/dist/frontend/worker-target.js +108 -0
  1027. package/dist/frontend/worker-target.js.map +1 -0
  1028. package/dist/frontend/worker-target.test.d.ts +1 -0
  1029. package/dist/frontend/worker-target.test.js +71 -0
  1030. package/dist/frontend/worker-target.test.js.map +1 -0
  1031. package/dist/index.d.ts +9 -8
  1032. package/dist/index.js +174 -88
  1033. package/dist/index.js.map +1 -1
  1034. package/dist/ir/analysis.js +95 -38
  1035. package/dist/ir/analysis.js.map +1 -1
  1036. package/dist/ir/analysis.test.js +91 -15
  1037. package/dist/ir/analysis.test.js.map +1 -1
  1038. package/dist/ir/api.d.ts +4 -0
  1039. package/dist/ir/api.js +6 -0
  1040. package/dist/ir/api.js.map +1 -0
  1041. package/dist/ir/build.d.ts +7 -0
  1042. package/dist/ir/build.js +27 -1
  1043. package/dist/ir/build.js.map +1 -1
  1044. package/dist/ir/builtin-effects.d.ts +9 -0
  1045. package/dist/ir/builtin-effects.js +643 -0
  1046. package/dist/ir/builtin-effects.js.map +1 -0
  1047. package/dist/ir/builtin-signatures.d.ts +15 -0
  1048. package/dist/ir/builtin-signatures.js +3397 -0
  1049. package/dist/ir/builtin-signatures.js.map +1 -0
  1050. package/dist/ir/byte-numbers.js +67 -16
  1051. package/dist/ir/byte-numbers.js.map +1 -1
  1052. package/dist/ir/byte-numbers.test.js +17 -4
  1053. package/dist/ir/byte-numbers.test.js.map +1 -1
  1054. package/dist/ir/constant-tables.js +13 -5
  1055. package/dist/ir/constant-tables.js.map +1 -1
  1056. package/dist/ir/constant-tables.test.js +47 -7
  1057. package/dist/ir/constant-tables.test.js.map +1 -1
  1058. package/dist/ir/control-flow.js +2 -1
  1059. package/dist/ir/control-flow.js.map +1 -1
  1060. package/dist/ir/control-flow.test.js +35 -11
  1061. package/dist/ir/control-flow.test.js.map +1 -1
  1062. package/dist/ir/initializer-bindings.d.ts +9 -0
  1063. package/dist/ir/initializer-bindings.js +115 -0
  1064. package/dist/ir/initializer-bindings.js.map +1 -0
  1065. package/dist/ir/initializer-bindings.test.d.ts +1 -0
  1066. package/dist/ir/initializer-bindings.test.js +118 -0
  1067. package/dist/ir/initializer-bindings.test.js.map +1 -0
  1068. package/dist/ir/integer-loop-facts.d.ts +12 -0
  1069. package/dist/ir/integer-loop-facts.js +137 -0
  1070. package/dist/ir/integer-loop-facts.js.map +1 -0
  1071. package/dist/ir/integer-loops.js +85 -30
  1072. package/dist/ir/integer-loops.js.map +1 -1
  1073. package/dist/ir/integer-loops.test.js +76 -13
  1074. package/dist/ir/integer-loops.test.js.map +1 -1
  1075. package/dist/ir/integer-ranges.js +93 -21
  1076. package/dist/ir/integer-ranges.js.map +1 -1
  1077. package/dist/ir/integer-ranges.test.js +199 -21
  1078. package/dist/ir/integer-ranges.test.js.map +1 -1
  1079. package/dist/ir/intrinsic-signatures.d.ts +20 -0
  1080. package/dist/ir/intrinsic-signatures.js +57 -0
  1081. package/dist/ir/intrinsic-signatures.js.map +1 -0
  1082. package/dist/ir/ir.d.ts +15 -2160
  1083. package/dist/ir/ir.js +160 -1396
  1084. package/dist/ir/ir.js.map +1 -1
  1085. package/dist/ir/ir.test.js +98 -77
  1086. package/dist/ir/ir.test.js.map +1 -1
  1087. package/dist/ir/numeric-call-specialization.d.ts +8 -0
  1088. package/dist/ir/numeric-call-specialization.js +198 -0
  1089. package/dist/ir/numeric-call-specialization.js.map +1 -0
  1090. package/dist/ir/runtime-features.d.ts +221 -0
  1091. package/dist/ir/runtime-features.js +552 -0
  1092. package/dist/ir/runtime-features.js.map +1 -0
  1093. package/dist/ir/runtime-features.test.d.ts +1 -0
  1094. package/dist/ir/runtime-features.test.js +98 -0
  1095. package/dist/ir/runtime-features.test.js.map +1 -0
  1096. package/dist/ir/scalar-records.js +130 -40
  1097. package/dist/ir/scalar-records.js.map +1 -1
  1098. package/dist/ir/scalar-records.test.js +146 -27
  1099. package/dist/ir/scalar-records.test.js.map +1 -1
  1100. package/dist/ir/serialize.d.ts +1 -1
  1101. package/dist/ir/serialize.js +7 -5
  1102. package/dist/ir/serialize.js.map +1 -1
  1103. package/dist/ir/serialize.test.js +44 -9
  1104. package/dist/ir/serialize.test.js.map +1 -1
  1105. package/dist/ir/traverse.js +156 -43
  1106. package/dist/ir/traverse.js.map +1 -1
  1107. package/dist/ir/traverse.test.js +99 -24
  1108. package/dist/ir/traverse.test.js.map +1 -1
  1109. package/dist/ir/validate.d.ts +1 -31
  1110. package/dist/ir/validate.js +869 -1910
  1111. package/dist/ir/validate.js.map +1 -1
  1112. package/dist/ir/validate.test.js +697 -114
  1113. package/dist/ir/validate.test.js.map +1 -1
  1114. package/dist/library/cache-primitives.js +9 -10
  1115. package/dist/library/cache-primitives.js.map +1 -1
  1116. package/dist/library/cache-reset.test.js +2 -1
  1117. package/dist/library/cache-reset.test.js.map +1 -1
  1118. package/dist/library/compiler-self-identity.js +11 -5
  1119. package/dist/library/compiler-self-identity.js.map +1 -1
  1120. package/dist/library/compiler-self-identity.test.js +10 -3
  1121. package/dist/library/compiler-self-identity.test.js.map +1 -1
  1122. package/dist/library/fence-eval.js +24 -7
  1123. package/dist/library/fence-eval.js.map +1 -1
  1124. package/dist/library/fence-eval.test.js +31 -7
  1125. package/dist/library/fence-eval.test.js.map +1 -1
  1126. package/dist/library/int-infer.js +199 -59
  1127. package/dist/library/int-infer.js.map +1 -1
  1128. package/dist/library/int-infer.test.js +137 -61
  1129. package/dist/library/int-infer.test.js.map +1 -1
  1130. package/dist/library/ir-policy.d.ts +27 -0
  1131. package/dist/library/ir-policy.js +234 -0
  1132. package/dist/library/ir-policy.js.map +1 -0
  1133. package/dist/library/library-cache.js +40 -17
  1134. package/dist/library/library-cache.js.map +1 -1
  1135. package/dist/library/library-cache.test.js +29 -18
  1136. package/dist/library/library-cache.test.js.map +1 -1
  1137. package/dist/library/library-profile.js +68 -13
  1138. package/dist/library/library-profile.js.map +1 -1
  1139. package/dist/library/prepare.js +48 -20
  1140. package/dist/library/prepare.js.map +1 -1
  1141. package/dist/library/semantic-source.js +16 -14
  1142. package/dist/library/semantic-source.js.map +1 -1
  1143. package/dist/library/semantic-source.test.js +9 -14
  1144. package/dist/library/semantic-source.test.js.map +1 -1
  1145. package/dist/library/sidecar-validate.js +53 -12
  1146. package/dist/library/sidecar-validate.js.map +1 -1
  1147. package/dist/library/sidecar.js +85 -24
  1148. package/dist/library/sidecar.js.map +1 -1
  1149. package/dist/library/trap-teaching.js +11 -2
  1150. package/dist/library/trap-teaching.js.map +1 -1
  1151. package/dist/native/cache.js +10 -4
  1152. package/dist/native/cache.js.map +1 -1
  1153. package/dist/native/cli.js +34 -9
  1154. package/dist/native/cli.js.map +1 -1
  1155. package/dist/native/compiler.js +191 -54
  1156. package/dist/native/compiler.js.map +1 -1
  1157. package/dist/native/compiler.test.js +134 -33
  1158. package/dist/native/compiler.test.js.map +1 -1
  1159. package/dist/native/comptime.js +23 -7
  1160. package/dist/native/comptime.js.map +1 -1
  1161. package/dist/native/comptime.test.js +26 -6
  1162. package/dist/native/comptime.test.js.map +1 -1
  1163. package/dist/native/executable-cache.js +77 -27
  1164. package/dist/native/executable-cache.js.map +1 -1
  1165. package/dist/native/executable-cache.test.js +41 -6
  1166. package/dist/native/executable-cache.test.js.map +1 -1
  1167. package/dist/native/file-identity.js +9 -2
  1168. package/dist/native/file-identity.js.map +1 -1
  1169. package/dist/native/file-identity.test.js.map +1 -1
  1170. package/dist/native/library.js +50 -12
  1171. package/dist/native/library.js.map +1 -1
  1172. package/dist/native/prepare.js +121 -34
  1173. package/dist/native/prepare.js.map +1 -1
  1174. package/dist/native/prepare.test.js +22 -6
  1175. package/dist/native/prepare.test.js.map +1 -1
  1176. package/dist/native/runtime-typescript.js +24 -11
  1177. package/dist/native/runtime-typescript.js.map +1 -1
  1178. package/dist/native/runtime-typescript.test.js.map +1 -1
  1179. package/dist/native/sanitizer.js +71 -18
  1180. package/dist/native/sanitizer.js.map +1 -1
  1181. package/dist/native/sanitizer.test.js +78 -20
  1182. package/dist/native/sanitizer.test.js.map +1 -1
  1183. package/dist/native/task.js.map +1 -1
  1184. package/dist/native/task.test.js +7 -2
  1185. package/dist/native/task.test.js.map +1 -1
  1186. package/dist/native/toolchain.js +68 -26
  1187. package/dist/native/toolchain.js.map +1 -1
  1188. package/dist/native/toolchain.test.js +59 -20
  1189. package/dist/native/toolchain.test.js.map +1 -1
  1190. package/dist/startup-cache.d.ts +1 -1
  1191. package/dist/startup-cache.js +1 -1
  1192. package/dist/startup-cache.js.map +1 -1
  1193. package/dist/timing.js.map +1 -1
  1194. package/package.json +20 -20
  1195. package/surface-manifest.json +30 -2
  1196. package/dist/frontend/lowering/lower-builtins.d.ts +0 -601
  1197. package/dist/frontend/lowering/lower-builtins.js +0 -8986
  1198. package/dist/frontend/lowering/lower-builtins.js.map +0 -1
  1199. package/dist/frontend/lowering/lower-containers.d.ts +0 -382
  1200. package/dist/frontend/lowering/lower-containers.js +0 -7344
  1201. package/dist/frontend/lowering/lower-containers.js.map +0 -1
@@ -1,3 +1,4 @@
1
+ import { dynUndefinedExpr, nodeThrowExpr } from "../../ir/build.js";
1
2
  import { InternalCompilerError } from "../../errors.js";
2
3
  /* Class lowering: shape collection over the single-inheritance graph
3
4
  * (fields, methods, accessors, overrides), constructor/member lowering with
@@ -5,23 +6,32 @@ import { InternalCompilerError } from "../../errors.js";
5
6
  * accessor access, upcasts, `new` expressions, and the builtin Error
6
7
  * hierarchy registration. */
7
8
  import * as ts from "../ts7/adapter.js";
8
- import { BOOL, DATE_T, DYN, F64, bytesOf, JSVAL, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, UNDEFINED_T, VOID, arrayOf, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, typeEquals } from "../../ir/ir.js";
9
- import { MAX_GENERIC_INSTANCES, appendImplicitUndefinedReturn, bodyReadsArguments, generatorMeta, genericCallInstance, hasExplicitJsDocReturn, implicitAnyParamSymbolsOf, implicitCallInstance, implicitMonoFile, omittedArgFor } from "./lower-calls.js";
10
- import { isGenericCallableMemberType, jsOpenObjectType, typeKey, withUnitArm } from "../type-mapper.js";
11
- import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, isNodeTypesPath, locOf } from "../program.js";
12
- import { PoisonError, dynFallbackType, dynUndefinedExpr, newFnCtx, nodeThrowExpr, own } from "./lowerer.js";
13
- import { lowerArrayConstructor, lowerMapSeedNew, lowerObjectConstructor, lowerSetSeedNew } from "./lower-containers.js";
9
+ import { BOOL, DATE_T, DYN, F64, bytesOf, JSVAL, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, UNDEFINED_T, VOID, arrayOf, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, typeEquals, } from "../../ir/ir.js";
10
+ import { genericCallInstance, implicitAnyParamSymbolsOf, implicitCallInstance, implicitMonoFile, } from "./generic-functions.js";
11
+ import { extendInstantiationPath, MAX_INSTANTIATION_RECURSION, } from "./instantiation-path.js";
12
+ import { appendImplicitUndefinedReturn, hasExplicitJsDocReturn } from "./function-returns.js";
13
+ import { bodyReadsArguments } from "../arguments-usage.js";
14
+ import { generatorMeta } from "./call-signatures.js";
15
+ import { omittedArgFor } from "./call-arguments.js";
16
+ import { isGenericCallableMemberType, jsOpenObjectType, typeKey, withUnitArm, } from "../type-mapper.js";
17
+ import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, isNodeTypesPath, locOf, } from "../program.js";
18
+ import { PoisonError, dynFallbackType, newFnCtx, own } from "./lowerer.js";
19
+ import { lowerArrayConstructor } from "./containers/array-construction.js";
20
+ import { lowerMapSeedNew, lowerSetSeedNew } from "./containers/collection-methods.js";
21
+ import { lowerObjectConstructor } from "./containers/indexed-objects.js";
14
22
  import { bufEncoding } from "./containers/bytes.js";
15
23
  import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
16
- import { lowerSearchParamsNew, lowerTextCodecNew } from "./lower-builtins.js";
17
- import { requiresDynamicPackageDiag, unsupportedDiag } from "../../diagnostics/diagnostic.js";
18
- import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape } from "./lower-stream.js";
19
- import { emitOverrideShapeReason, emitSpecSuperForward, emitterRooted, lowerEmitterSuperCall } from "./lower-event-emitter.js";
24
+ import { lowerSearchParamsNew } from "./builtins/url.js";
25
+ import { lowerTextCodecNew } from "./builtins/text-codecs.js";
26
+ import { lowerWorkerNew } from "./builtins/workers.js";
27
+ import { requiresDynamicPackageDiag, unsupportedDiag, } from "../../diagnostics/diagnostic.js";
28
+ import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape, } from "./lower-stream.js";
29
+ import { emitOverrideShapeReason, emitSpecSuperForward, emitterRooted, lowerEmitterSuperCall, } from "./lower-event-emitter.js";
20
30
  import { declSymbolOf } from "./lower-modules.js";
21
- import { classSymbolKeyOf, classSymbolKeyOfSymbol, symbolFieldDisplayName } from "./symbol-fields.js";
31
+ import { classSymbolKeyOf, classSymbolKeyOfSymbol, symbolFieldDisplayName, } from "./symbol-fields.js";
22
32
  import { builtinFenceHintOf } from "./surfaces.js";
23
33
  import { lowerHttpAgentNew, lowerHttpServerNew } from "./lower-server.js";
24
- import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead } from "./lower-namespaces.js";
34
+ import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead, } from "./lower-namespaces.js";
25
35
  import { mixinResultBindingClassOf } from "./lower-mixins.js";
26
36
  import { hasLexicalPrivateReference, hasStaticThis, rejectStaticThis } from "./static-this.js";
27
37
  import { lowerUrlNew } from "./lower-url.js";
@@ -68,7 +78,9 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
68
78
  visiting.add(expression);
69
79
  if (ts.isParenthesizedExpression(expression))
70
80
  return storedClassValueType(lowerer, expression.expression, visiting);
71
- if (ts.isClassExpression(expression) && !functionLocalClass(expression) && !lowerer.collectingExprClasses.has(expression)) {
81
+ if (ts.isClassExpression(expression) &&
82
+ !functionLocalClass(expression) &&
83
+ !lowerer.collectingExprClasses.has(expression)) {
72
84
  const info = lowerer.lowerClassExpressionInfo(expression);
73
85
  return { kind: "classval", className: info.def.name };
74
86
  }
@@ -87,7 +99,12 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
87
99
  if (stored?.type.kind === "classval" && lowerer.classes.has(stored.type.className))
88
100
  return stored.type;
89
101
  const symbol = lowerer.resolveValueSymbol(expression);
90
- const declaration = symbol && lowerer.checker.declarationsOf(symbol).find((decl) => ts.isVariableDeclaration(decl) && decl.initializer && (ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
102
+ const declaration = symbol &&
103
+ lowerer.checker
104
+ .declarationsOf(symbol)
105
+ .find((decl) => ts.isVariableDeclaration(decl) &&
106
+ decl.initializer &&
107
+ (ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
91
108
  if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
92
109
  const value = storedClassValueType(lowerer, declaration.initializer, visiting);
93
110
  if (value?.kind === "classval")
@@ -100,7 +117,9 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
100
117
  for (const signature of lowerer.checker.getConstructSignatures(type)) {
101
118
  const constructor = lowerer.checker.signatureDeclaration(signature);
102
119
  const declaration = constructor && ts.isConstructorDeclaration(constructor) ? constructor.parent : undefined;
103
- if (declaration && ts.isClassExpression(declaration) && !functionLocalClass(declaration) &&
120
+ if (declaration &&
121
+ ts.isClassExpression(declaration) &&
122
+ !functionLocalClass(declaration) &&
104
123
  !lowerer.collectingExprClasses.has(declaration)) {
105
124
  const info = lowerer.lowerClassExpressionInfo(declaration);
106
125
  return { kind: "classval", className: info.def.name };
@@ -134,7 +153,12 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
134
153
  }
135
154
  if (ts.isIdentifier(callee)) {
136
155
  const symbol = lowerer.resolveValueSymbol(callee);
137
- const declaration = symbol && lowerer.checker.declarationsOf(symbol).find((decl) => ts.isVariableDeclaration(decl) && decl.initializer && (ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
156
+ const declaration = symbol &&
157
+ lowerer.checker
158
+ .declarationsOf(symbol)
159
+ .find((decl) => ts.isVariableDeclaration(decl) &&
160
+ decl.initializer &&
161
+ (ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
138
162
  if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
139
163
  callee = declaration.initializer;
140
164
  continue;
@@ -142,13 +166,18 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
142
166
  }
143
167
  break;
144
168
  }
145
- if ((ts.isArrowFunction(callee) || ts.isFunctionExpression(callee)) && isJsSourceFile(callee.getSourceFile()) &&
146
- !callee.typeParameters?.length && !lowerer.preparingClassFactories.has(callee)) {
169
+ if ((ts.isArrowFunction(callee) || ts.isFunctionExpression(callee)) &&
170
+ isJsSourceFile(callee.getSourceFile()) &&
171
+ !callee.typeParameters?.length &&
172
+ !lowerer.preparingClassFactories.has(callee)) {
147
173
  const signature = lowerer.checker.getSignatureFromDeclaration(callee);
148
174
  let result = signature && lowerer.checker.getReturnTypeOfSignature(signature);
149
175
  for (let i = 1; result && i < calls; i++) {
150
176
  const signatures = lowerer.checker.getCallSignatures(result);
151
- result = signatures.length === 1 ? lowerer.checker.getReturnTypeOfSignature(signatures[0]) : undefined;
177
+ result =
178
+ signatures.length === 1
179
+ ? lowerer.checker.getReturnTypeOfSignature(signatures[0])
180
+ : undefined;
152
181
  }
153
182
  if (result && lowerer.checker.getConstructSignatures(result).length > 0) {
154
183
  const returned = (value) => {
@@ -158,7 +187,9 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
158
187
  return type.kind === "classval" ? type : null;
159
188
  };
160
189
  const home = callee.parent;
161
- const generic = ts.isVariableDeclaration(home) && ts.isIdentifier(home.name) ? lowerer.genericFnOf(home.name) : null;
190
+ const generic = ts.isVariableDeclaration(home) && ts.isIdentifier(home.name)
191
+ ? lowerer.genericFnOf(home.name)
192
+ : null;
162
193
  if (generic?.implicitParams && ts.isVariableDeclaration(home) && ts.isIdentifier(home.name)) {
163
194
  const factory = lowerer.lowerGenericFnValue(home.name, generic);
164
195
  const type = returned(factory);
@@ -202,10 +233,15 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
202
233
  break;
203
234
  }
204
235
  }
205
- if (!factory || !isJsSourceFile(factory.getSourceFile()) || factory.typeParameters?.length ||
206
- !ts.isVariableDeclaration(factory.parent) || factory.parent.initializer !== factory ||
207
- !ts.isVariableDeclarationList(factory.parent.parent) || !(factory.parent.parent.flags & ts.NodeFlags.Const) ||
208
- !ts.isVariableStatement(factory.parent.parent.parent) || !ts.isSourceFile(factory.parent.parent.parent.parent) ||
236
+ if (!factory ||
237
+ !isJsSourceFile(factory.getSourceFile()) ||
238
+ factory.typeParameters?.length ||
239
+ !ts.isVariableDeclaration(factory.parent) ||
240
+ factory.parent.initializer !== factory ||
241
+ !ts.isVariableDeclarationList(factory.parent.parent) ||
242
+ !(factory.parent.parent.flags & ts.NodeFlags.Const) ||
243
+ !ts.isVariableStatement(factory.parent.parent.parent) ||
244
+ !ts.isSourceFile(factory.parent.parent.parent.parent) ||
209
245
  lowerer.preparingClassFactories.has(factory))
210
246
  continue;
211
247
  if (!lowerer.preparedClassFactories.has(factory)) {
@@ -229,10 +265,10 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
229
265
  return mapped;
230
266
  }
231
267
  /** The KEY symbol behind a LATE-BOUND (`__@name@id`) property: resolved
232
- * from the argument of the element-access assignment that declared it
233
- * (`this[kLimit] = v` — the declaration list holds the BinaryExpression
234
- * or the ElementAccessExpression itself). Null when no declaration has
235
- * that shape (well-known-symbol members like `[Symbol.iterator]`). */
268
+ * from the argument of the element-access assignment that declared it
269
+ * (`this[kLimit] = v` — the declaration list holds the BinaryExpression
270
+ * or the ElementAccessExpression itself). Null when no declaration has
271
+ * that shape (well-known-symbol members like `[Symbol.iterator]`). */
236
272
  function lateBoundKeySymOf(lowerer, p) {
237
273
  for (const d of lowerer.checker.declarationsOf(p)) {
238
274
  const access = ts.isBinaryExpression(d) && ts.isElementAccessExpression(d.left)
@@ -249,20 +285,20 @@ function lateBoundKeySymOf(lowerer, p) {
249
285
  return null;
250
286
  }
251
287
  /** Symbol-slot RETURN refinement (5.9.3 ABI parity): tsgo synthesizes no
252
- * late-bound property for a JS class's `this[k] = v` declaration (the
253
- * finding-5 family), so an unannotated method whose returns read a
254
- * declared symbol-keyed slot infers `any` — the checked-dynamic
255
- * fallback would box a value whose static type the class layout already
256
- * knows (5.9.3 inferred it through the late-bound property; runtime
257
- * output was identical either way, but the method ABI carried a dyn
258
- * box). Recovered here from the layout itself, under a shape that
259
- * cannot mis-type: an unannotated, non-async, non-generator JS method
260
- * whose LAST top-level statement is a return (no fall-through
261
- * `undefined` completion), where EVERY return statement (nested
262
- * functions excluded — they return elsewhere) returns `this[k]` with a
263
- * statically-resolved key declared in symbolFields, and all the slots
264
- * agree on one IR type. Null when the shape doesn't hold — the value
265
- * stays checked-dynamic exactly as before. */
288
+ * late-bound property for a JS class's `this[k] = v` declaration (the
289
+ * finding-5 family), so an unannotated method whose returns read a
290
+ * declared symbol-keyed slot infers `any` — the checked-dynamic
291
+ * fallback would box a value whose static type the class layout already
292
+ * knows (5.9.3 inferred it through the late-bound property; runtime
293
+ * output was identical either way, but the method ABI carried a dyn
294
+ * box). Recovered here from the layout itself, under a shape that
295
+ * cannot mis-type: an unannotated, non-async, non-generator JS method
296
+ * whose LAST top-level statement is a return (no fall-through
297
+ * `undefined` completion), where EVERY return statement (nested
298
+ * functions excluded — they return elsewhere) returns `this[k]` with a
299
+ * statically-resolved key declared in symbolFields, and all the slots
300
+ * agree on one IR type. Null when the shape doesn't hold — the value
301
+ * stays checked-dynamic exactly as before. */
266
302
  function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
267
303
  if (symbolFields.size === 0)
268
304
  return null;
@@ -308,12 +344,12 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
308
344
  return out;
309
345
  }
310
346
  /** The builtin Error hierarchy
311
- * as eagerly-registered ClassInfos: mapType names them the moment a lib
312
- * Error type appears, so the infos must exist before any lowering. They
313
- * are runtime-provided — no decl, no lowerable bodies; `new`/super()/
314
- * toString reach them through dedicated error.* libCall lowerings, and
315
- * user classes extend them like any base (the emitted subclass struct
316
- * embeds ScrError's prefix). */
347
+ * as eagerly-registered ClassInfos: mapType names them the moment a lib
348
+ * Error type appears, so the infos must exist before any lowering. They
349
+ * are runtime-provided — no decl, no lowerable bodies; `new`/super()/
350
+ * toString reach them through dedicated error.* libCall lowerings, and
351
+ * user classes extend them like any base (the emitted subclass struct
352
+ * embeds ScrError's prefix). */
317
353
  export function registerBuiltinErrorClasses(lowerer) {
318
354
  const loc = { file: "<builtin>", start: 0, end: 0 };
319
355
  for (const [irName, rec] of RUNTIME_ERROR_CLASSES) {
@@ -363,7 +399,10 @@ export function registerBuiltinErrorClasses(lowerer) {
363
399
  ctor: null,
364
400
  // Inherited constructors forward both raw arguments. The runtime
365
401
  // applies the undefined message default and InstallErrorCause.
366
- ctorParams: [{ type: DYN, mode: "omittable" }, { type: DYN, mode: "omittable" }],
402
+ ctorParams: [
403
+ { type: DYN, mode: "omittable" },
404
+ { type: DYN, mode: "omittable" },
405
+ ],
367
406
  base,
368
407
  subclasses: [],
369
408
  throwingSetters: [],
@@ -375,14 +414,14 @@ export function registerBuiltinErrorClasses(lowerer) {
375
414
  }
376
415
  }
377
416
  /** The runtime-provided node:events EventEmitter as an eagerly-registered
378
- * ClassInfo (the error-hierarchy story): mapType names `%EventEmitter`
379
- * the moment an emitter type appears, so the info must exist before any
380
- * lowering. No decl, no lowerable bodies — `new`/super() reach it
381
- * through emitter.* libCalls, the method surface lowers through
382
- * lower-event-emitter.ts, and user classes extend it like any base (the
383
- * emitted subclass struct embeds ScrEmitter's registry/name prefix —
384
- * carried by the BACKEND, not by IR fields, so the fields list stays
385
- * empty and subclass field layout starts right after the prefix). */
417
+ * ClassInfo (the error-hierarchy story): mapType names `%EventEmitter`
418
+ * the moment an emitter type appears, so the info must exist before any
419
+ * lowering. No decl, no lowerable bodies — `new`/super() reach it
420
+ * through emitter.* libCalls, the method surface lowers through
421
+ * lower-event-emitter.ts, and user classes extend it like any base (the
422
+ * emitted subclass struct embeds ScrEmitter's registry/name prefix —
423
+ * carried by the BACKEND, not by IR fields, so the fields list stays
424
+ * empty and subclass field layout starts right after the prefix). */
386
425
  export function registerBuiltinEmitterClass(lowerer) {
387
426
  const loc = { file: "<builtin>", start: 0, end: 0 };
388
427
  const info = {
@@ -404,13 +443,13 @@ export function registerBuiltinEmitterClass(lowerer) {
404
443
  lowerer.classes.set(RUNTIME_EMITTER_CLASS, info);
405
444
  }
406
445
  /** The runtime-provided node:stream classes as eagerly-registered
407
- * ClassInfos (the emitter story): mapType names `%Readable` et al the
408
- * moment a stream type appears, so the infos must exist before any
409
- * lowering. Each roots at the emitter through its base chain, so the
410
- * EventEmitter method surface, upcasts, and instanceof intervals apply
411
- * unchanged; the stream method/property surface lowers through
412
- * lower-stream.ts. No decl, no lowerable bodies, empty field lists —
413
- * every instance is runtime-allocated (user `extends` is fenced). */
446
+ * ClassInfos (the emitter story): mapType names `%Readable` et al the
447
+ * moment a stream type appears, so the infos must exist before any
448
+ * lowering. Each roots at the emitter through its base chain, so the
449
+ * EventEmitter method surface, upcasts, and instanceof intervals apply
450
+ * unchanged; the stream method/property surface lowers through
451
+ * lower-stream.ts. No decl, no lowerable bodies, empty field lists —
452
+ * every instance is runtime-allocated (user `extends` is fenced). */
414
453
  export function registerBuiltinStreamClasses(lowerer) {
415
454
  const loc = { file: "<builtin>", start: 0, end: 0 };
416
455
  for (const [irName, rec] of RUNTIME_STREAM_CLASSES) {
@@ -437,12 +476,12 @@ export function registerBuiltinStreamClasses(lowerer) {
437
476
  }
438
477
  }
439
478
  /** The stream ClassInfo a VALUE symbol refers to (`new Readable(...)`,
440
- * `x instanceof Writable`) — any import spelling resolves to the
441
- * ambient class. Provenance: a stdlib-file CLASS declaration inside the
442
- * "stream" ambient module, EXCLUDING @types/node's (whose stream.Readable
443
- * also types child stdio — under @types/node the childStream mapping
444
- * keeps priority and the static stream classes stand down; the shipped
445
- * fallback declarations are the supported surface). */
479
+ * `x instanceof Writable`) — any import spelling resolves to the
480
+ * ambient class. Provenance: a stdlib-file CLASS declaration inside the
481
+ * "stream" ambient module, EXCLUDING @types/node's (whose stream.Readable
482
+ * also types child stdio — under @types/node the childStream mapping
483
+ * keeps priority and the static stream classes stand down; the shipped
484
+ * fallback declarations are the supported surface). */
446
485
  export function builtinStreamInfoOf(lowerer, symbol) {
447
486
  if (!symbol)
448
487
  return null;
@@ -454,7 +493,8 @@ export function builtinStreamInfoOf(lowerer, symbol) {
454
493
  // alias plumbing (streamClassAliasDecl — both declaration walks
455
494
  // skip it).
456
495
  const decl = lowerer.checker.valueDeclarationOf(symbol);
457
- if (decl && ts.isVariableDeclaration(decl) &&
496
+ if (decl &&
497
+ ts.isVariableDeclaration(decl) &&
458
498
  (ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 &&
459
499
  decl.initializer !== undefined &&
460
500
  ts.isPropertyAccessExpression(decl.initializer) &&
@@ -495,8 +535,12 @@ export function builtinStreamInfoOf(lowerer, symbol) {
495
535
  function jsFieldInitializerType(lowerer, type, expression) {
496
536
  if (ts.isIdentifier(expression)) {
497
537
  const symbol = lowerer.checker.getSymbolAtLocation(expression);
498
- if (symbol && lowerer.checker.declarationsOf(symbol).some((decl) => ts.isParameter(decl) && (ts.isConstructorDeclaration(decl.parent) ||
499
- (lowerer.typeOf(expression).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)))
538
+ if (symbol &&
539
+ lowerer.checker
540
+ .declarationsOf(symbol)
541
+ .some((decl) => ts.isParameter(decl) &&
542
+ (ts.isConstructorDeclaration(decl.parent) ||
543
+ (lowerer.typeOf(expression).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)))
500
544
  return DYN;
501
545
  }
502
546
  if (type.kind === "array" || type.kind === "record")
@@ -507,17 +551,25 @@ function jsFieldInitializerType(lowerer, type, expression) {
507
551
  if (type.kind === "f64" && isJsSourceFile(expression.getSourceFile())) {
508
552
  const assignment = expression.parent;
509
553
  const left = ts.isBinaryExpression(assignment) ? assignment.left : null;
510
- const field = left && ts.isPropertyAccessExpression(left) && left.expression.kind === ts.SyntaxKind.ThisKeyword ? left.name.text : null;
554
+ const field = left &&
555
+ ts.isPropertyAccessExpression(left) &&
556
+ left.expression.kind === ts.SyntaxKind.ThisKeyword
557
+ ? left.name.text
558
+ : null;
511
559
  let owner = expression.parent;
512
560
  while (owner && !ts.isClassDeclaration(owner) && !ts.isClassExpression(owner))
513
561
  owner = owner.parent;
514
562
  if (field && owner) {
515
563
  let acceptsUnchecked = false;
516
564
  const scan = (node) => {
517
- if (acceptsUnchecked || node !== owner && (ts.isClassDeclaration(node) || ts.isClassExpression(node)))
565
+ if (acceptsUnchecked ||
566
+ (node !== owner && (ts.isClassDeclaration(node) || ts.isClassExpression(node))))
518
567
  return;
519
- if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
520
- ts.isPropertyAccessExpression(node.left) && node.left.expression.kind === ts.SyntaxKind.ThisKeyword && node.left.name.text === field) {
568
+ if (ts.isBinaryExpression(node) &&
569
+ node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
570
+ ts.isPropertyAccessExpression(node.left) &&
571
+ node.left.expression.kind === ts.SyntaxKind.ThisKeyword &&
572
+ node.left.name.text === field) {
521
573
  let rhs = node.right;
522
574
  while (ts.isParenthesizedExpression(rhs))
523
575
  rhs = rhs.expression;
@@ -538,14 +590,17 @@ function jsFieldInitializerType(lowerer, type, expression) {
538
590
  let prototypeArgument = false;
539
591
  for (const argument of node.arguments)
540
592
  ts.walkPreorder(argument, (part) => {
541
- if (!ts.isPropertyAccessExpression(part) || part.expression.kind !== ts.SyntaxKind.ThisKeyword)
593
+ if (!ts.isPropertyAccessExpression(part) ||
594
+ part.expression.kind !== ts.SyntaxKind.ThisKeyword)
542
595
  return;
543
596
  const symbol = lowerer.checker.getSymbolAtLocation(part.name);
544
- if (symbol && lowerer.checker.declarationsOf(symbol).some((decl) => {
545
- const member = ts.isBinaryExpression(decl) ? decl.left : decl;
546
- return ts.isPropertyAccessExpression(member) && ts.isPropertyAccessExpression(member.expression) &&
547
- member.expression.name.text === "prototype";
548
- }))
597
+ if (symbol &&
598
+ lowerer.checker.declarationsOf(symbol).some((decl) => {
599
+ const member = ts.isBinaryExpression(decl) ? decl.left : decl;
600
+ return (ts.isPropertyAccessExpression(member) &&
601
+ ts.isPropertyAccessExpression(member.expression) &&
602
+ member.expression.name.text === "prototype");
603
+ }))
549
604
  prototypeArgument = true;
550
605
  // JS checkers can synthesize a property declaration for prototype
551
606
  // assignments. Keep the source ownership proof when that happens.
@@ -555,12 +610,17 @@ function jsFieldInitializerType(lowerer, type, expression) {
555
610
  if (owner && (ts.isClassDeclaration(owner) || ts.isClassExpression(owner)) && owner.name) {
556
611
  const className = owner.name.text;
557
612
  for (const statement of owner.getSourceFile().statements) {
558
- if (!ts.isExpressionStatement(statement) || !ts.isBinaryExpression(statement.expression))
613
+ if (!ts.isExpressionStatement(statement) ||
614
+ !ts.isBinaryExpression(statement.expression))
559
615
  continue;
560
616
  const left = statement.expression.left;
561
- if (statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(left) &&
562
- left.name.text === part.name.text && ts.isPropertyAccessExpression(left.expression) && left.expression.name.text === "prototype" &&
563
- ts.isIdentifier(left.expression.expression) && left.expression.expression.text === className)
617
+ if (statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
618
+ ts.isPropertyAccessExpression(left) &&
619
+ left.name.text === part.name.text &&
620
+ ts.isPropertyAccessExpression(left.expression) &&
621
+ left.expression.name.text === "prototype" &&
622
+ ts.isIdentifier(left.expression.expression) &&
623
+ left.expression.expression.text === className)
564
624
  prototypeArgument = true;
565
625
  }
566
626
  }
@@ -572,7 +632,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
572
632
  }
573
633
  if (ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {
574
634
  const ret = lowerer.declaredReturnType(node, node);
575
- const arms = type.kind === "union" ? lowerer.unions.get(type.unionId)?.arms ?? [] : [type];
635
+ const arms = type.kind === "union" ? (lowerer.unions.get(type.unionId)?.arms ?? []) : [type];
576
636
  // Inferred arithmetic may return a checked Number or BigInt. Preserve
577
637
  // the callable when its native return ABI differs from the checker slot.
578
638
  if (arms.some((arm) => arm.kind === "func" && !typeEquals(arm.ret, ret)))
@@ -581,13 +641,22 @@ function jsFieldInitializerType(lowerer, type, expression) {
581
641
  if (node.kind === ts.SyntaxKind.NullKeyword)
582
642
  return withUnitArm(type, "nullT", lowerer.unions) ?? type;
583
643
  const inferred = lowerer.typeOf(node);
584
- const scalar = (inferred.flags & ts.TypeFlags.BooleanLike) !== 0 ? "bool"
585
- : (inferred.flags & ts.TypeFlags.NumberLike) !== 0 ? "f64"
586
- : (inferred.flags & ts.TypeFlags.StringLike) !== 0 ? "string"
587
- : (inferred.flags & ts.TypeFlags.BigIntLike) !== 0 ? "bigint"
588
- : (inferred.flags & ts.TypeFlags.ESSymbolLike) !== 0 ? "symbol" : null;
589
- if (scalar && type.kind !== "dyn" && type.kind !== scalar &&
590
- !(type.kind === "union" && lowerer.unions.get(type.unionId)?.arms.some((arm) => arm.kind === scalar)))
644
+ const scalar = (inferred.flags & ts.TypeFlags.BooleanLike) !== 0
645
+ ? "bool"
646
+ : (inferred.flags & ts.TypeFlags.NumberLike) !== 0
647
+ ? "f64"
648
+ : (inferred.flags & ts.TypeFlags.StringLike) !== 0
649
+ ? "string"
650
+ : (inferred.flags & ts.TypeFlags.BigIntLike) !== 0
651
+ ? "bigint"
652
+ : (inferred.flags & ts.TypeFlags.ESSymbolLike) !== 0
653
+ ? "symbol"
654
+ : null;
655
+ if (scalar &&
656
+ type.kind !== "dyn" &&
657
+ type.kind !== scalar &&
658
+ !(type.kind === "union" &&
659
+ lowerer.unions.get(type.unionId)?.arms.some((arm) => arm.kind === scalar)))
591
660
  return DYN;
592
661
  for (const arm of inferred.isUnionType() ? ts.constituentTypes(inferred) : [inferred]) {
593
662
  if ((arm.flags & ts.TypeFlags.Undefined) !== 0)
@@ -618,7 +687,10 @@ function inheritedJsFieldType(lowerer, decl, name, type) {
618
687
  return type;
619
688
  }
620
689
  function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
621
- if (!isJsSourceFile(member.getSourceFile()) || member.type || member.asteriskToken || hasExplicitJsDocReturn(member))
690
+ if (!isJsSourceFile(member.getSourceFile()) ||
691
+ member.type ||
692
+ member.asteriskToken ||
693
+ hasExplicitJsDocReturn(member))
622
694
  return false;
623
695
  const widened = (expression) => {
624
696
  if (ts.isParenthesizedExpression(expression))
@@ -627,22 +699,38 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
627
699
  return widened(expression.whenTrue) || widened(expression.whenFalse);
628
700
  if (ts.isCallExpression(expression)) {
629
701
  const callee = expression.expression;
630
- const symbol = ts.isPropertyAccessExpression(callee) ? lowerer.checker.getSymbolAtLocation(callee.name)
631
- : ts.isElementAccessExpression(callee) ? lowerer.checker.getPropertyOfType(lowerer.typeOf(callee.expression), lowerer.foldedStringKeyOf(callee.argumentExpression) ?? "")
702
+ const symbol = ts.isPropertyAccessExpression(callee)
703
+ ? lowerer.checker.getSymbolAtLocation(callee.name)
704
+ : ts.isElementAccessExpression(callee)
705
+ ? lowerer.checker.getPropertyOfType(lowerer.typeOf(callee.expression), lowerer.foldedStringKeyOf(callee.argumentExpression) ?? "")
632
706
  : undefined;
633
- if (symbol && lowerer.checker.declarationsOf(symbol).some((declaration) => ts.isMethodDeclaration(declaration) && lowerer.checkedVirtualJsMethods.has(declaration)))
707
+ if (symbol &&
708
+ lowerer.checker
709
+ .declarationsOf(symbol)
710
+ .some((declaration) => ts.isMethodDeclaration(declaration) &&
711
+ lowerer.checkedVirtualJsMethods.has(declaration)))
634
712
  return true;
635
713
  }
636
- const name = ts.isPropertyAccessExpression(expression) ? expression.name.text
637
- : ts.isElementAccessExpression(expression) ? lowerer.foldedStringKeyOf(expression.argumentExpression) : null;
714
+ const name = ts.isPropertyAccessExpression(expression)
715
+ ? expression.name.text
716
+ : ts.isElementAccessExpression(expression)
717
+ ? lowerer.foldedStringKeyOf(expression.argumentExpression)
718
+ : null;
638
719
  if (ts.isPropertyAccessExpression(expression)) {
639
720
  const symbol = lowerer.checker.getSymbolAtLocation(expression.name);
640
- if (symbol && lowerer.checker.declarationsOf(symbol).some((declaration) => (ts.isGetAccessorDeclaration(declaration) || ts.isSetAccessorDeclaration(declaration)) && lowerer.checkedVirtualJsAccessors.has(declaration)))
721
+ if (symbol &&
722
+ lowerer.checker
723
+ .declarationsOf(symbol)
724
+ .some((declaration) => (ts.isGetAccessorDeclaration(declaration) ||
725
+ ts.isSetAccessorDeclaration(declaration)) &&
726
+ lowerer.checkedVirtualJsAccessors.has(declaration)))
641
727
  return true;
642
728
  }
643
- if (name !== null && (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression)) &&
729
+ if (name !== null &&
730
+ (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression)) &&
644
731
  expression.expression.kind === ts.SyntaxKind.ThisKeyword) {
645
- return fields.get(name)?.kind === "dyn" || inheritedJsFieldType(lowerer, decl, name, ret).kind === "dyn";
732
+ return (fields.get(name)?.kind === "dyn" ||
733
+ inheritedJsFieldType(lowerer, decl, name, ret).kind === "dyn");
646
734
  }
647
735
  return false;
648
736
  };
@@ -659,10 +747,10 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
659
747
  return result;
660
748
  }
661
749
  /** The undefined-armed union of a JS class property's inferred type — the
662
- * honest slot for a field first assigned outside the constructor's top
663
- * level (undefined until the write runs, Node-exact). Null when the
664
- * inference is unmappable or an arm-less kind that cannot join a union
665
- * (genResultRecord's list, including scalar-backed Date values). */
750
+ * honest slot for a field first assigned outside the constructor's top
751
+ * level (undefined until the write runs, Node-exact). Null when the
752
+ * inference is unmappable or an arm-less kind that cannot join a union
753
+ * (genResultRecord's list, including scalar-backed Date values). */
666
754
  function undefArmedFieldType(lowerer, p) {
667
755
  const t = lowerer.checker.getTypeOfSymbol(p);
668
756
  const site = lowerer.checker.declarationsOf(p)[0];
@@ -673,7 +761,9 @@ function undefArmedFieldType(lowerer, p) {
673
761
  return null;
674
762
  for (const declaration of lowerer.checker.declarationsOf(p)) {
675
763
  const assignment = ts.isBinaryExpression(declaration) ? declaration : declaration.parent;
676
- if (assignment && ts.isBinaryExpression(assignment) && assignment.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
764
+ if (assignment &&
765
+ ts.isBinaryExpression(assignment) &&
766
+ assignment.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
677
767
  mapped = jsFieldInitializerType(lowerer, mapped, assignment.right);
678
768
  }
679
769
  }
@@ -683,8 +773,11 @@ function undefArmedFieldType(lowerer, p) {
683
773
  const byKey = new Map();
684
774
  const arms = mapped.kind === "union" ? (lowerer.unions.get(mapped.unionId)?.arms ?? []) : [mapped];
685
775
  for (const a of arms) {
686
- if (a.kind === "map" || a.kind === "regex" || a.kind === "date" ||
687
- a.kind === "jsval" || a.kind === "generator") {
776
+ if (a.kind === "map" ||
777
+ a.kind === "regex" ||
778
+ a.kind === "date" ||
779
+ a.kind === "jsval" ||
780
+ a.kind === "generator") {
688
781
  return null;
689
782
  }
690
783
  byKey.set(typeKey(a), a);
@@ -694,10 +787,10 @@ function undefArmedFieldType(lowerer, p) {
694
787
  return { kind: "union", unionId: lowerer.unions.intern(sorted) };
695
788
  }
696
789
  /** The emitter ClassInfo a VALUE symbol refers to (`new EventEmitter`,
697
- * `extends EventEmitter`, `x instanceof EventEmitter`) — any import
698
- * spelling (named/default/namespace member, CJS require) resolves to
699
- * the ambient class. Provenance-checked like the error classes: only a
700
- * stdlib-file declaration inside the "events" ambient module counts. */
790
+ * `extends EventEmitter`, `x instanceof EventEmitter`) — any import
791
+ * spelling (named/default/namespace member, CJS require) resolves to
792
+ * the ambient class. Provenance-checked like the error classes: only a
793
+ * stdlib-file declaration inside the "events" ambient module counts. */
701
794
  export function builtinEmitterInfoOf(lowerer, symbol) {
702
795
  if (!symbol)
703
796
  return null;
@@ -709,7 +802,8 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
709
802
  // itself is alias plumbing (builtinMemberRequireDecl — both
710
803
  // declaration walks skip it).
711
804
  const decl = lowerer.checker.valueDeclarationOf(symbol);
712
- if (decl !== undefined && ts.isVariableDeclaration(decl) &&
805
+ if (decl !== undefined &&
806
+ ts.isVariableDeclaration(decl) &&
713
807
  (ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 &&
714
808
  decl.initializer !== undefined &&
715
809
  ts.isPropertyAccessExpression(decl.initializer) &&
@@ -737,9 +831,9 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
737
831
  return declared ? (lowerer.classes.get(RUNTIME_EMITTER_CLASS) ?? null) : null;
738
832
  }
739
833
  /** The builtin error ClassInfo a VALUE symbol refers to (`new Error`,
740
- * `extends TypeError`, `x instanceof RangeError`), or null. Provenance-
741
- * checked: only the standard library's declarations count — a user's own
742
- * `class Error` resolves through classBySymbol instead. */
834
+ * `extends TypeError`, `x instanceof RangeError`), or null. Provenance-
835
+ * checked: only the standard library's declarations count — a user's own
836
+ * `class Error` resolves through classBySymbol instead. */
743
837
  export function builtinErrorInfoOf(lowerer, symbol) {
744
838
  if (!symbol || !lowerer.isStdlibSymbol(symbol))
745
839
  return null;
@@ -753,22 +847,34 @@ export function builtinErrorInfoOf(lowerer, symbol) {
753
847
  * members with these names are fenced (collectClassShapeInner) and calls
754
848
  * to them on emitter-rooted receivers lower through lower-event-emitter.ts. */
755
849
  export const EMITTER_API_MEMBERS = new Set([
756
- "on", "addListener", "once", "prependListener", "prependOnceListener",
757
- "off", "removeListener", "removeAllListeners", "emit", "listenerCount",
758
- "listeners", "rawListeners", "eventNames", "setMaxListeners", "getMaxListeners",
850
+ "on",
851
+ "addListener",
852
+ "once",
853
+ "prependListener",
854
+ "prependOnceListener",
855
+ "off",
856
+ "removeListener",
857
+ "removeAllListeners",
858
+ "emit",
859
+ "listenerCount",
860
+ "listeners",
861
+ "rawListeners",
862
+ "eventNames",
863
+ "setMaxListeners",
864
+ "getMaxListeners",
759
865
  ]);
760
866
  /** The decorators of a class-like or member node (they live in
761
- * `modifiers` since TS 4.8). */
867
+ * `modifiers` since TS 4.8). */
762
868
  export function decoratorNodesOf(n) {
763
869
  return (n.modifiers ?? []).filter((m) => m.kind === ts.SyntaxKind.Decorator);
764
870
  }
765
871
  /** The AMBIENT name a decorator expression's evaluation throws on, or
766
- * null. Node erases ambient declarations (`declare let dec: any`,
767
- * `declare const instance: T`, `declare function dec<T>(t: T): T`), so
768
- * reading the name is a ReferenceError. Factory spellings ride along —
769
- * `@dec(...)` evaluates the CALLEE before any argument — and property
770
- * chains throw at their ROOT (`@instance.decorate` reads `instance`
771
- * first). */
872
+ * null. Node erases ambient declarations (`declare let dec: any`,
873
+ * `declare const instance: T`, `declare function dec<T>(t: T): T`), so
874
+ * reading the name is a ReferenceError. Factory spellings ride along —
875
+ * `@dec(...)` evaluates the CALLEE before any argument — and property
876
+ * chains throw at their ROOT (`@instance.decorate` reads `instance`
877
+ * first). */
772
878
  function ambientDecoratorThrowNameOf(lowerer, dExpr) {
773
879
  let e = dExpr;
774
880
  while (ts.isParenthesizedExpression(e))
@@ -785,16 +891,16 @@ function ambientDecoratorThrowNameOf(lowerer, dExpr) {
785
891
  return null;
786
892
  }
787
893
  /** The guaranteed decoration THROW of a decorated class, or null. Walks
788
- * the class definition's evaluation-order items — class decorators
789
- * (source order), the heritage expression, then per member in body
790
- * order its decorators and computed key (the verified TC39/tsc-downlevel
791
- * order) — and answers the first AMBIENT decorator name, provided every
792
- * item BEFORE it is provably effect-free and non-throwing: bare
793
- * identifier decorators over defined values (a pure read), an absent /
794
- * `null` / bare-identifier heritage, literal or bare-identifier
795
- * computed keys. Anything richer (factory calls over defined values,
796
- * property-access reads, computed-key calls) stops the proof — the
797
- * named fences answer instead. */
894
+ * the class definition's evaluation-order items — class decorators
895
+ * (source order), the heritage expression, then per member in body
896
+ * order its decorators and computed key (the verified TC39/tsc-downlevel
897
+ * order) — and answers the first AMBIENT decorator name, provided every
898
+ * item BEFORE it is provably effect-free and non-throwing: bare
899
+ * identifier decorators over defined values (a pure read), an absent /
900
+ * `null` / bare-identifier heritage, literal or bare-identifier
901
+ * computed keys. Anything richer (factory calls over defined values,
902
+ * property-access reads, computed-key calls) stops the proof — the
903
+ * named fences answer instead. */
798
904
  export function guaranteedDecorationThrow(lowerer, decl) {
799
905
  const stripParens = (e) => {
800
906
  let x = e;
@@ -819,8 +925,7 @@ export function guaranteedDecorationThrow(lowerer, decl) {
819
925
  if (v !== "effectFree")
820
926
  return v;
821
927
  }
822
- const heritage = decl.heritageClauses
823
- ?.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword)
928
+ const heritage = decl.heritageClauses?.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword)
824
929
  ?.types[0];
825
930
  if (heritage) {
826
931
  const h = stripParens(heritage.expression);
@@ -846,7 +951,36 @@ export function guaranteedDecorationThrow(lowerer, decl) {
846
951
  return null;
847
952
  }
848
953
  export function collectClassShape(lowerer, decl) {
849
- const symbol = lowerer.collectDeferring(() => declSymbolOf(lowerer, decl), () => lowerer.collectClassShapeInner(decl));
954
+ if (lowerer.classes.has(lowerer.classNamer(decl)) ||
955
+ lowerer.collectingClassDeclarations.has(decl))
956
+ return;
957
+ lowerer.collectingClassDeclarations.add(decl);
958
+ try {
959
+ collectClassShapeDeferring(lowerer, decl);
960
+ }
961
+ finally {
962
+ lowerer.collectingClassDeclarations.delete(decl);
963
+ }
964
+ }
965
+ function collectClassShapeDeferring(lowerer, decl) {
966
+ const symbol = lowerer.collectDeferring(() => declSymbolOf(lowerer, decl), () => {
967
+ // A forward type reference can demand this class before collection
968
+ // reaches its earlier base declaration. Collect that dependency first;
969
+ // a later same-file base remains subject to the runtime order boundary.
970
+ const heritage = decl.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
971
+ const reference = heritage && ts.isPropertyAccessExpression(heritage) ? heritage.name : heritage;
972
+ const baseSymbol = reference && ts.isIdentifier(reference) ? lowerer.resolveValueSymbol(reference) : undefined;
973
+ const baseDeclaration = baseSymbol
974
+ ? lowerer.checker.declarationsOf(baseSymbol).find(ts.isClassDeclaration)
975
+ : undefined;
976
+ if (baseDeclaration &&
977
+ !lowerer.isStdlibSymbol(baseSymbol ?? undefined) &&
978
+ !baseDeclaration.getSourceFile().isDeclarationFile &&
979
+ (baseDeclaration.getSourceFile() !== decl.getSourceFile() ||
980
+ baseDeclaration.getStart() < decl.getStart()))
981
+ lowerer.collectClassShape(baseDeclaration);
982
+ lowerer.collectClassShapeInner(decl);
983
+ });
850
984
  // Typed receivers and module retention know the class only by its
851
985
  // qualified IR name — index the deferral under it too.
852
986
  if (symbol)
@@ -898,7 +1032,9 @@ export function collectClassShape(lowerer, decl) {
898
1032
  }
899
1033
  }
900
1034
  function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
901
- if (!ts.isNewExpression(initializer) || (initializer.arguments?.length ?? 0) !== 0 || !ts.isIdentifier(initializer.expression))
1035
+ if (!ts.isNewExpression(initializer) ||
1036
+ (initializer.arguments?.length ?? 0) !== 0 ||
1037
+ !ts.isIdentifier(initializer.expression))
902
1038
  return null;
903
1039
  const collection = initializer.expression.text;
904
1040
  if (collection !== "Map" && collection !== "Set")
@@ -912,7 +1048,11 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
912
1048
  const mappedArgument = (argument) => {
913
1049
  const type = lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(argument));
914
1050
  const mapped = lowerer.mapTypeOf(type);
915
- if (!mapped || mapped.kind === "dyn" || mapped.kind === "jsval" || mapped.kind === "void" || isUnitType(mapped))
1051
+ if (!mapped ||
1052
+ mapped.kind === "dyn" ||
1053
+ mapped.kind === "jsval" ||
1054
+ mapped.kind === "void" ||
1055
+ isUnitType(mapped))
916
1056
  return null;
917
1057
  return mapped;
918
1058
  };
@@ -927,19 +1067,27 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
927
1067
  receiver.name.text !== field) {
928
1068
  return undefined;
929
1069
  }
930
- if (collection === "Map" && node.expression.name.text === "set" && node.arguments.length === 2) {
1070
+ if (collection === "Map" &&
1071
+ node.expression.name.text === "set" &&
1072
+ node.arguments.length === 2) {
931
1073
  const key = mappedArgument(node.arguments[0]);
932
1074
  const value = mappedArgument(node.arguments[1]);
933
- if (key !== null && value !== null && isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined) && isSupportedMapValue(value)) {
1075
+ if (key !== null &&
1076
+ value !== null &&
1077
+ isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined) &&
1078
+ isSupportedMapValue(value)) {
934
1079
  mapKeys.push(key);
935
1080
  mapValues.push(value);
936
1081
  }
937
1082
  }
938
1083
  if (collection === "Set" &&
939
- (node.expression.name.text === "add" || node.expression.name.text === "has" || node.expression.name.text === "delete") &&
1084
+ (node.expression.name.text === "add" ||
1085
+ node.expression.name.text === "has" ||
1086
+ node.expression.name.text === "delete") &&
940
1087
  node.arguments.length === 1) {
941
1088
  const element = mappedArgument(node.arguments[0]);
942
- if (element !== null && isSupportedSetElem(element, element.kind === "union" ? lowerer.unions.get(element.unionId)?.arms : undefined))
1089
+ if (element !== null &&
1090
+ isSupportedSetElem(element, element.kind === "union" ? lowerer.unions.get(element.unionId)?.arms : undefined))
943
1091
  setElements.push(element);
944
1092
  }
945
1093
  return undefined;
@@ -1008,8 +1156,10 @@ mixin) {
1008
1156
  // The guaranteed-throw SHELL: declarations only (expressions
1009
1157
  // lower their throw at the expression — lowerClassExpression),
1010
1158
  // never instantiations/mixins (they share a family declaration).
1011
- if (inst === undefined && mixin === undefined &&
1012
- ts.isClassDeclaration(decl) && decl.typeParameters === undefined) {
1159
+ if (inst === undefined &&
1160
+ mixin === undefined &&
1161
+ ts.isClassDeclaration(decl) &&
1162
+ decl.typeParameters === undefined) {
1013
1163
  const thrown = guaranteedDecorationThrow(lowerer, decl);
1014
1164
  if (thrown) {
1015
1165
  const className = lowerer.classNamer(decl);
@@ -1055,9 +1205,9 @@ mixin) {
1055
1205
  : ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)
1056
1206
  ? "accessor decorators"
1057
1207
  : ts.isPropertyDeclaration(member)
1058
- ? (member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)
1208
+ ? member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)
1059
1209
  ? "auto-accessor decorators"
1060
- : "field decorators")
1210
+ : "field decorators"
1061
1211
  : "member decorators";
1062
1212
  lowerer.unsupported("SC1090", dec, `${kind} (the standard context object and member replacement have no static lowering — class decorators and provably-throwing ambient decorations compile)`);
1063
1213
  }
@@ -1093,60 +1243,48 @@ mixin) {
1093
1243
  lowerer.unsupported("SC1090", decl, "generic class expressions");
1094
1244
  }
1095
1245
  const className = inst ? inst.name : mixin ? mixin.name : lowerer.classNamer(decl); // program-wide qualified name
1096
- // Single inheritance: `extends` of a class declared in the program.
1097
- // tsc guarantees the base is declared before the derived class (its
1098
- // use-before-declaration error), and collection runs in module order,
1099
- // so the base's ClassInfo already exists here. An INSTANTIATION's
1100
- // base is its family (whose base is the declared one) — the heritage
1101
- // clause resolved when the family collected.
1246
+ // Collection follows module order for runtime heritage. Ordinary
1247
+ // instances use the family as their storage base; generic heritage
1248
+ // resolves a concrete base under each instance's type bindings.
1102
1249
  const computedBase = lowerer.computedClassBases.get(lowerer.classNamer(decl));
1103
- let base = inst ? inst.family : mixin ? mixin.base : computedBase?.classInfo ?? null;
1250
+ let base = inst
1251
+ ? inst.family
1252
+ : mixin
1253
+ ? mixin.base
1254
+ : (computedBase?.classInfo ?? null);
1255
+ let genericBase;
1104
1256
  let callableBase;
1105
1257
  let factoryBaseExpression;
1106
1258
  const adoptCallableBase = (expression) => {
1107
1259
  if (familyMode || inst || mixin)
1108
1260
  return false;
1109
1261
  if (lowerer.computedCallableBases.has(decl)) {
1110
- callableBase = { expression, constructorId: `%g.${className}.base`, prototypeId: `%g.${className}.basePrototype` };
1262
+ callableBase = {
1263
+ expression,
1264
+ constructorId: `%g.${className}.base`,
1265
+ prototypeId: `%g.${className}.basePrototype`,
1266
+ };
1111
1267
  return true;
1112
1268
  }
1113
1269
  const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(expression));
1114
1270
  const source = signatures.length === 1 ? lowerer.checker.signatureDeclaration(signatures[0]) : undefined;
1115
- if (!source || !isJsSourceFile(source.getSourceFile()) ||
1271
+ if (!source ||
1272
+ !isJsSourceFile(source.getSourceFile()) ||
1116
1273
  !(ts.isFunctionDeclaration(source) || ts.isFunctionExpression(source)))
1117
1274
  return false;
1118
- callableBase = { expression, constructorId: `%g.${className}.base`, prototypeId: `%g.${className}.basePrototype` };
1275
+ callableBase = {
1276
+ expression,
1277
+ constructorId: `%g.${className}.base`,
1278
+ prototypeId: `%g.${className}.basePrototype`,
1279
+ };
1119
1280
  return true;
1120
1281
  };
1121
- // A family whose `extends` clause mentions its OWN type parameters
1122
- // (`class D<T> extends Box<T>`) would need a different base per
1123
- // instantiation — no single family interval can sit above all of
1124
- // them. Named fence at the declaration.
1125
- if (familyMode && decl.heritageClauses !== undefined) {
1126
- const tpSyms = new Set();
1127
- for (const tp of decl.typeParameters) {
1128
- const s = lowerer.checker.getSymbolAtLocation(tp.name);
1129
- if (s)
1130
- tpSyms.add(s);
1131
- }
1132
- for (const clause of decl.heritageClauses) {
1133
- if (clause.token !== ts.SyntaxKind.ExtendsKeyword)
1134
- continue;
1135
- for (const t of clause.types) {
1136
- let mentions = false;
1137
- ts.walkPreorder(t, (n) => {
1138
- const s = ts.isIdentifier(n) ? lowerer.checker.getSymbolAtLocation(n) : undefined;
1139
- if (s && tpSyms.has(s)) {
1140
- mentions = true;
1141
- return "stop";
1142
- }
1143
- return undefined;
1144
- });
1145
- if (mentions) {
1146
- lowerer.unsupported("SC1090", t, "generic classes whose 'extends' clause mentions their own type parameters (each instantiation would need a different base)");
1147
- }
1148
- }
1149
- }
1282
+ const ownGenericBase = inst?.family.genericBase;
1283
+ if (inst && ownGenericBase) {
1284
+ const mapped = lowerer.mapTypeOf(lowerer.checker.getTypeAtLocation(ownGenericBase));
1285
+ base = mapped?.kind === "object" ? (lowerer.classes.get(mapped.className) ?? null) : null;
1286
+ if (!base || base.generic)
1287
+ lowerer.unsupported("SC1090", ownGenericBase, "a generic base whose type arguments have no concrete layout");
1150
1288
  }
1151
1289
  for (const clause of inst || mixin || computedBase ? [] : (decl.heritageClauses ?? [])) {
1152
1290
  // `implements` is pure type-world: tsc checked the conformance and
@@ -1156,6 +1294,22 @@ mixin) {
1156
1294
  if (clause.token === ts.SyntaxKind.ImplementsKeyword)
1157
1295
  continue;
1158
1296
  const t = clause.types[0];
1297
+ if (familyMode && t) {
1298
+ const reference = ts.isPropertyAccessExpression(t.expression)
1299
+ ? t.expression.name
1300
+ : t.expression;
1301
+ const symbol = ts.isIdentifier(reference)
1302
+ ? lowerer.resolveValueSymbol(reference)
1303
+ : undefined;
1304
+ const familyBase = symbol ? lowerer.classBySymbol.get(symbol) : undefined;
1305
+ if (familyBase?.generic) {
1306
+ if (symbol && ts.isPropertyAccessExpression(t.expression))
1307
+ fenceEarlyNsMemberRef(lowerer, t.expression, symbol);
1308
+ base = familyBase;
1309
+ genericBase = t;
1310
+ continue;
1311
+ }
1312
+ }
1159
1313
  // `extends events.EventEmitter` — the namespace-member spelling of
1160
1314
  // the ambient emitter base resolves like the named import.
1161
1315
  if (t && ts.isPropertyAccessExpression(t.expression) && ts.isIdentifier(t.expression.name)) {
@@ -1163,8 +1317,10 @@ mixin) {
1163
1317
  const resolved = memberSym && memberSym.flags & ts.SymbolFlags.Alias
1164
1318
  ? lowerer.checker.getAliasedSymbol(memberSym)
1165
1319
  : memberSym;
1166
- const globalError = !t.expression.questionDotToken && lowerer.isStdlibGlobal(t.expression.expression, "globalThis")
1167
- ? lowerer.builtinErrorInfoOf(resolved) : null;
1320
+ const globalError = !t.expression.questionDotToken &&
1321
+ lowerer.isStdlibGlobal(t.expression.expression, "globalThis")
1322
+ ? lowerer.builtinErrorInfoOf(resolved)
1323
+ : null;
1168
1324
  if (globalError && globalError.def.name !== "%DOMException") {
1169
1325
  if (t.typeArguments)
1170
1326
  lowerer.unsupported("SC1090", t, "extending generic classes");
@@ -1231,8 +1387,7 @@ mixin) {
1231
1387
  const rebinds = memberSym !== undefined &&
1232
1388
  lowerer.checker
1233
1389
  .declarationsOf(memberSym)
1234
- .filter((d) => ts.isBinaryExpression(d) &&
1235
- d.operatorToken.kind === ts.SyntaxKind.EqualsToken).length > 1;
1390
+ .filter((d) => ts.isBinaryExpression(d) && d.operatorToken.kind === ts.SyntaxKind.EqualsToken).length > 1;
1236
1391
  if (rebinds) {
1237
1392
  lowerer.unsupported("SC1090", t, `extending the reassigned property '${t.expression.getText()}' (the runtime base is whichever assignment ran last — bind the class exactly once)`);
1238
1393
  }
@@ -1295,8 +1450,10 @@ mixin) {
1295
1450
  if (lowerer.builtinErrorInfoOf(symbol)?.def.name === "%DOMException") {
1296
1451
  lowerer.unsupported("SC1090", t, "extending DOMException (its runtime layout carries hidden slots a subclass would overlap — extend Error and set name/code yourself)");
1297
1452
  }
1298
- const named = (symbol && lowerer.classBySymbol.get(symbol)) ?? lowerer.builtinErrorInfoOf(symbol) ??
1299
- lowerer.builtinEmitterInfoOf(symbol) ?? builtinStreamInfoOf(lowerer, symbol) ??
1453
+ const named = (symbol && lowerer.classBySymbol.get(symbol)) ??
1454
+ lowerer.builtinErrorInfoOf(symbol) ??
1455
+ lowerer.builtinEmitterInfoOf(symbol) ??
1456
+ builtinStreamInfoOf(lowerer, symbol) ??
1300
1457
  // A const BINDING holding exactly one class (`const B = Animal`,
1301
1458
  // `const B = class {…}`): the base is that class — extends
1302
1459
  // through the alias is the declaration story (a general class
@@ -1314,7 +1471,8 @@ mixin) {
1314
1471
  (() => {
1315
1472
  const stored = storedClassValueType(lowerer, t.expression);
1316
1473
  return stored?.kind === "classval" ? lowerer.classes.get(stored.className) : null;
1317
- })() ?? null;
1474
+ })() ??
1475
+ null;
1318
1476
  // `extends Box<number>` — a GENERIC program class as the base: the
1319
1477
  // base is the concrete INSTANTIATION, resolved through the heritage
1320
1478
  // type (mapType registers/reuses `Box%0`).
@@ -1397,10 +1555,16 @@ mixin) {
1397
1555
  const runtimePrototypeMembers = [];
1398
1556
  // Public JS accessors need live constructor descriptors, including
1399
1557
  // receiver-sensitive getters and setters inherited by subclasses.
1400
- const checkedStatics = isJsSourceFile(decl.getSourceFile()) && (base && hasRuntimeStatics(base) || decl.members.some((member) => ts.isAccessor(member) && !ts.isPrivateIdentifier(member.name) &&
1401
- member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) &&
1402
- !decl.members.some((member) => member.name && ts.isPrivateIdentifier(member.name) &&
1403
- ts.getModifiers(member)?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
1558
+ const checkedStatics = isJsSourceFile(decl.getSourceFile()) &&
1559
+ ((base && hasRuntimeStatics(base)) ||
1560
+ decl.members.some((member) => ts.isAccessor(member) &&
1561
+ !ts.isPrivateIdentifier(member.name) &&
1562
+ member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) &&
1563
+ !decl.members.some((member) => member.name &&
1564
+ ts.isPrivateIdentifier(member.name) &&
1565
+ ts
1566
+ .getModifiers(member)
1567
+ ?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
1404
1568
  // GENERIC methods (own type parameters), instance and static: only
1405
1569
  // the SYNTAX is checked here — parameter/return types mention the
1406
1570
  // type parameters and cannot map yet; bodies lower per call-site
@@ -1436,7 +1600,9 @@ mixin) {
1436
1600
  typeParams.push(sym);
1437
1601
  }
1438
1602
  for (const param of fnNode.parameters) {
1439
- if (!ts.isIdentifier(param.name) && !ts.isObjectBindingPattern(param.name) && !ts.isArrayBindingPattern(param.name)) {
1603
+ if (!ts.isIdentifier(param.name) &&
1604
+ !ts.isObjectBindingPattern(param.name) &&
1605
+ !ts.isArrayBindingPattern(param.name)) {
1440
1606
  lowerer.unsupported("SC1031", param);
1441
1607
  }
1442
1608
  }
@@ -1449,16 +1615,23 @@ mixin) {
1449
1615
  });
1450
1616
  };
1451
1617
  for (const member of decl.members) {
1452
- if ((functionLocalClass(decl) || checkedStatics) && isJsSourceFile(decl.getSourceFile()) &&
1453
- (ts.isClassStaticBlockDeclaration(member) || ts.getModifiers(member)?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) {
1618
+ if ((functionLocalClass(decl) || checkedStatics) &&
1619
+ isJsSourceFile(decl.getSourceFile()) &&
1620
+ (ts.isClassStaticBlockDeclaration(member) ||
1621
+ ts
1622
+ .getModifiers(member)
1623
+ ?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) {
1454
1624
  runtimeStatics.push(member);
1455
1625
  continue;
1456
1626
  }
1457
- if (functionLocalClass(decl) && isJsSourceFile(decl.getSourceFile()) &&
1458
- (ts.isMethodDeclaration(member) || ts.isAccessor(member)) && member.body &&
1627
+ if (functionLocalClass(decl) &&
1628
+ isJsSourceFile(decl.getSourceFile()) &&
1629
+ (ts.isMethodDeclaration(member) || ts.isAccessor(member)) &&
1630
+ member.body &&
1459
1631
  !ts.isPrivateIdentifier(member.name)) {
1460
1632
  runtimePrototypeMembers.push(member);
1461
- if (ts.isComputedPropertyName(member.name) && classMemberNameOf(lowerer, member.name) === null)
1633
+ if (ts.isComputedPropertyName(member.name) &&
1634
+ classMemberNameOf(lowerer, member.name) === null)
1462
1635
  continue;
1463
1636
  }
1464
1637
  if (ts.isClassStaticBlockDeclaration(member)) {
@@ -1507,15 +1680,20 @@ mixin) {
1507
1680
  (ts.isIdentifier(member.name) || ts.isPrivateIdentifier(member.name)) &&
1508
1681
  member.initializer &&
1509
1682
  member.postfixToken?.kind !== ts.SyntaxKind.QuestionToken) {
1510
- const initializerSymbol = ts.isIdentifier(member.initializer) ? lowerer.resolveValueSymbol(member.initializer) : null;
1683
+ const initializerSymbol = ts.isIdentifier(member.initializer)
1684
+ ? lowerer.resolveValueSymbol(member.initializer)
1685
+ : null;
1511
1686
  // Enum namespace aliases are erased; member reads fold through the checker.
1512
1687
  if (initializerSymbol && (initializerSymbol.flags & ts.SymbolFlags.Enum) !== 0)
1513
1688
  continue;
1514
1689
  const type = lowerer.irTypeOf(member.name);
1515
1690
  if (type.kind === "void")
1516
1691
  lowerer.badType(member.name, lowerer.typeOf(member.name));
1517
- if (type.kind === "dyn" && !isJsSourceFile(member.getSourceFile()) &&
1518
- (member.type !== undefined || (lowerer.typeOf(member.name).flags & ts.TypeFlags.Any) === 0)) {
1692
+ if (type.kind === "dyn" &&
1693
+ !isJsSourceFile(member.getSourceFile()) &&
1694
+ !lowerer.classImplementedProtocol(lowerer.typeOf(member.name)) &&
1695
+ (member.type !== undefined ||
1696
+ (lowerer.typeOf(member.name).flags & ts.TypeFlags.Any) === 0)) {
1519
1697
  lowerer.unsupported("SC1090", member.name, "'unknown'-typed static fields");
1520
1698
  }
1521
1699
  staticFields.push({
@@ -1538,14 +1716,19 @@ mixin) {
1538
1716
  lowerer.badType(member.name, lowerer.typeOf(member.name));
1539
1717
  }
1540
1718
  staticMethods.set(member.name.text, { params: shapes, ret: ft.ret, member });
1541
- if (implicitMonoFile(decl.getSourceFile()) && !functionLocalClass(decl) &&
1542
- inst === undefined && decl.typeParameters === undefined) {
1719
+ if (implicitMonoFile(decl.getSourceFile()) &&
1720
+ !functionLocalClass(decl) &&
1721
+ inst === undefined &&
1722
+ decl.typeParameters === undefined) {
1543
1723
  const implicit = implicitAnyParamSymbolsOf(lowerer, member, true);
1544
1724
  if (implicit)
1545
1725
  genericStatics.set(member.name.text, {
1546
- decl: member, baseName: member.name.text,
1726
+ decl: member,
1727
+ baseName: member.name.text,
1547
1728
  qualifiedName: `%${className}.static:${member.name.text}%implicit`,
1548
- typeParams: [], instances: new Map(), implicitParams: implicit,
1729
+ typeParams: [],
1730
+ instances: new Map(),
1731
+ implicitParams: implicit,
1549
1732
  });
1550
1733
  }
1551
1734
  }
@@ -1577,11 +1760,18 @@ mixin) {
1577
1760
  // (every named member kind stores a PropertyName there).
1578
1761
  const memberName = member.name;
1579
1762
  if (errorRooted && memberName && classMemberNameOf(lowerer, memberName) === "cause") {
1580
- if (ts.isPropertyDeclaration(member) && !member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
1763
+ if (ts.isPropertyDeclaration(member) &&
1764
+ !member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
1581
1765
  if (!isJsSourceFile(member.getSourceFile()))
1582
1766
  lowerer.unsupported("SC1090", memberName, "redeclaring Error.cause (pass the cause in the Error constructor options)");
1583
- fieldOrder.push({ name: "cause", type: DYN, initializer: member.initializer,
1584
- ...(member.initializer ? {} : { undefinedInitializer: locOf(member) }), redeclared: true, errorCause: true });
1767
+ fieldOrder.push({
1768
+ name: "cause",
1769
+ type: DYN,
1770
+ initializer: member.initializer,
1771
+ ...(member.initializer ? {} : { undefinedInitializer: locOf(member) }),
1772
+ redeclared: true,
1773
+ errorCause: true,
1774
+ });
1585
1775
  continue;
1586
1776
  }
1587
1777
  lowerer.unsupported("SC1090", memberName, "Error.cause accessors");
@@ -1619,7 +1809,8 @@ mixin) {
1619
1809
  // keep the fence for emit too: the runtime stream machinery emits
1620
1810
  // 'data'/'end'/... internally, which could never route through
1621
1811
  // the override.
1622
- if (memberName && ts.isIdentifier(memberName) &&
1812
+ if (memberName &&
1813
+ ts.isIdentifier(memberName) &&
1623
1814
  EMITTER_API_MEMBERS.has(memberName.text) &&
1624
1815
  (() => {
1625
1816
  for (let c = base; c; c = c.base)
@@ -1633,7 +1824,10 @@ mixin) {
1633
1824
  return true;
1634
1825
  return false;
1635
1826
  })();
1636
- if (memberName.text === "emit" && !streamRooted && !inst && !mixin &&
1827
+ if (memberName.text === "emit" &&
1828
+ !streamRooted &&
1829
+ !inst &&
1830
+ !mixin &&
1637
1831
  ts.isMethodDeclaration(member) &&
1638
1832
  !member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
1639
1833
  const reason = emitOverrideShapeReason(lowerer, member);
@@ -1698,20 +1892,39 @@ mixin) {
1698
1892
  // get/set pair — declare the field and accessors explicitly.
1699
1893
  lowerer.unsupported("SC1090", member, "auto-accessor fields ('accessor x')");
1700
1894
  }
1701
- if (ts.isComputedPropertyName(member.name) || ts.isStringLiteralLike(member.name) || ts.isNumericLiteral(member.name)) {
1702
- const symbolKey = ts.isComputedPropertyName(member.name) ? classSymbolKeyOf(lowerer, member.name.expression) : null;
1703
- const stringKey = ts.isComputedPropertyName(member.name) ? lowerer.foldedStringKeyOf(member.name.expression)
1704
- : ts.isNumericLiteral(member.name) ? String(Number(member.name.text)) : member.name.text;
1895
+ if (ts.isComputedPropertyName(member.name) ||
1896
+ ts.isStringLiteralLike(member.name) ||
1897
+ ts.isNumericLiteral(member.name)) {
1898
+ const symbolKey = ts.isComputedPropertyName(member.name)
1899
+ ? classSymbolKeyOf(lowerer, member.name.expression)
1900
+ : null;
1901
+ const stringKey = ts.isComputedPropertyName(member.name)
1902
+ ? lowerer.foldedStringKeyOf(member.name.expression)
1903
+ : ts.isNumericLiteral(member.name)
1904
+ ? String(Number(member.name.text))
1905
+ : member.name.text;
1705
1906
  const fieldName = symbolKey?.fieldName ?? stringKey;
1706
- if (fieldName === null || (!member.initializer && !isJsSourceFile(member.getSourceFile()))) {
1907
+ if (fieldName === null ||
1908
+ (!member.initializer && !isJsSourceFile(member.getSourceFile()))) {
1707
1909
  lowerer.unsupported("SC1090", member, "computed class fields without an initializer and a stable string, number, or module-level literal Symbol()/Symbol.for() key");
1708
1910
  }
1709
1911
  const declared = lowerer.typeOf(member);
1710
- const inferred = member.type || !member.initializer ? declared : lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(member.initializer));
1711
- const mapped = member.initializer ? lowerer.mapTypeOf(inferred) ?? dynFallbackType(lowerer, member, inferred) : DYN;
1912
+ const inferred = member.type || !member.initializer
1913
+ ? declared
1914
+ : lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(member.initializer));
1915
+ const mapped = member.initializer
1916
+ ? (lowerer.mapTypeOf(inferred) ?? dynFallbackType(lowerer, member, inferred))
1917
+ : DYN;
1712
1918
  let type = mapped?.kind === "record" && isJsSourceFile(member.getSourceFile()) && !member.type
1713
- ? DYN : mapped ? jsOpenObjectType(member, mapped, lowerer.shapes, lowerer.unions) : null;
1714
- if (!type || type.kind === "void" || (type.kind === "dyn" && !isJsSourceFile(member.getSourceFile())))
1919
+ ? DYN
1920
+ : mapped
1921
+ ? jsOpenObjectType(member, mapped, lowerer.shapes, lowerer.unions)
1922
+ : null;
1923
+ if (!type ||
1924
+ type.kind === "void" ||
1925
+ (type.kind === "dyn" &&
1926
+ !isJsSourceFile(member.getSourceFile()) &&
1927
+ !lowerer.classImplementedProtocol(inferred)))
1715
1928
  lowerer.badType(member, inferred);
1716
1929
  if (isJsSourceFile(member.getSourceFile())) {
1717
1930
  type = inheritedJsFieldType(lowerer, decl, fieldName, type);
@@ -1729,11 +1942,22 @@ mixin) {
1729
1942
  if (!typeEquals(previous, type)) {
1730
1943
  lowerer.unsupported("SC1090", member.name, "redeclaring computed fields at a different type");
1731
1944
  }
1732
- fieldOrder.push({ name: fieldName, type, initializer: member.initializer, ...(undefinedInitializer ? { undefinedInitializer } : {}), redeclared: true });
1945
+ fieldOrder.push({
1946
+ name: fieldName,
1947
+ type,
1948
+ initializer: member.initializer,
1949
+ ...(undefinedInitializer ? { undefinedInitializer } : {}),
1950
+ redeclared: true,
1951
+ });
1733
1952
  }
1734
1953
  else {
1735
1954
  fields.set(fieldName, type);
1736
- fieldOrder.push({ name: fieldName, type, initializer: member.initializer, ...(undefinedInitializer ? { undefinedInitializer } : {}) });
1955
+ fieldOrder.push({
1956
+ name: fieldName,
1957
+ type,
1958
+ initializer: member.initializer,
1959
+ ...(undefinedInitializer ? { undefinedInitializer } : {}),
1960
+ });
1737
1961
  }
1738
1962
  if (symbolKey)
1739
1963
  symbolFields.set(symbolKey.identity, fieldName);
@@ -1788,20 +2012,28 @@ mixin) {
1788
2012
  if (isJsSourceFile(member.getSourceFile()) && !member.initializer) {
1789
2013
  const constructor = decl.members.find((part) => ts.isConstructorDeclaration(part) && !!part.body);
1790
2014
  for (const statement of constructor?.body?.statements ?? []) {
1791
- if (!ts.isExpressionStatement(statement) || !ts.isBinaryExpression(statement.expression) ||
2015
+ if (!ts.isExpressionStatement(statement) ||
2016
+ !ts.isBinaryExpression(statement.expression) ||
1792
2017
  statement.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
1793
2018
  continue;
1794
2019
  const left = statement.expression.left;
1795
- if (!ts.isPropertyAccessExpression(left) || left.expression.kind !== ts.SyntaxKind.ThisKeyword || left.name.text !== member.name.text)
2020
+ if (!ts.isPropertyAccessExpression(left) ||
2021
+ left.expression.kind !== ts.SyntaxKind.ThisKeyword ||
2022
+ left.name.text !== member.name.text)
1796
2023
  continue;
1797
- type = statement.expression.right.kind === ts.SyntaxKind.NullKeyword ? DYN : jsFieldInitializerType(lowerer, type, statement.expression.right);
2024
+ type =
2025
+ statement.expression.right.kind === ts.SyntaxKind.NullKeyword
2026
+ ? DYN
2027
+ : jsFieldInitializerType(lowerer, type, statement.expression.right);
1798
2028
  }
1799
2029
  }
1800
2030
  // Unannotated JavaScript callback slots retain the original
1801
2031
  // callable and its receiver instead of adapting its signature.
1802
- if (isJsSourceFile(member.getSourceFile()) && !member.type &&
2032
+ if (isJsSourceFile(member.getSourceFile()) &&
2033
+ !member.type &&
1803
2034
  !/@type\b/.test(member.getSourceFile().text.slice(member.pos, member.getStart())) &&
1804
- (type.kind === "func" || type.kind === "record") && lowerer.dynConvertible(type))
2035
+ (type.kind === "func" || type.kind === "record") &&
2036
+ lowerer.dynConvertible(type))
1805
2037
  type = DYN;
1806
2038
  // JS permits reads before a constructor's first assignment even
1807
2039
  // when its inferred field type omits undefined.
@@ -1820,7 +2052,9 @@ mixin) {
1820
2052
  // Bundled JS declares fields without annotations before assigning
1821
2053
  // them in the constructor. Use the same native checked-dynamic
1822
2054
  // storage as implicit constructor-assigned JS fields.
1823
- if (type.kind === "dyn" && !isJsSourceFile(member.getSourceFile())) {
2055
+ if (type.kind === "dyn" &&
2056
+ !isJsSourceFile(member.getSourceFile()) &&
2057
+ !lowerer.classImplementedProtocol(lowerer.typeOf(member.name))) {
1824
2058
  lowerer.unsupported("SC1090", member.name, "'unknown'-typed class fields");
1825
2059
  }
1826
2060
  const undefinedInitializer = type.kind === "dyn" && !member.initializer ? locOf(member) : undefined;
@@ -1838,7 +2072,13 @@ mixin) {
1838
2072
  // Other bare or type-changing redeclarations keep the fence.
1839
2073
  const baseType = fields.get(member.name.text);
1840
2074
  if ((member.initializer || type.kind === "dyn") && typeEquals(type, baseType)) {
1841
- fieldOrder.push({ name: member.name.text, type, initializer: member.initializer, ...(undefinedInitializer ? { undefinedInitializer } : {}), redeclared: true });
2075
+ fieldOrder.push({
2076
+ name: member.name.text,
2077
+ type,
2078
+ initializer: member.initializer,
2079
+ ...(undefinedInitializer ? { undefinedInitializer } : {}),
2080
+ redeclared: true,
2081
+ });
1842
2082
  continue;
1843
2083
  }
1844
2084
  lowerer.unsupported("SC1090", member.name, member.initializer
@@ -1862,8 +2102,10 @@ mixin) {
1862
2102
  // list checked against the constructor after the member loop
1863
2103
  // (the constructor may be declared later in the class body).
1864
2104
  const admitsUndefined = (type.kind === "union" &&
1865
- (lowerer.unions.get(type.unionId)?.arms.some((a) => a.kind === "undefinedT") ?? false)) ||
1866
- type.kind === "jsval" || type.kind === "dyn";
2105
+ (lowerer.unions.get(type.unionId)?.arms.some((a) => a.kind === "undefinedT") ??
2106
+ false)) ||
2107
+ type.kind === "jsval" ||
2108
+ type.kind === "dyn";
1867
2109
  if (!member.initializer && !admitsUndefined) {
1868
2110
  const opts = lowerer.program.getCompilerOptions();
1869
2111
  const spi = opts.strictPropertyInitialization ?? opts.strict ?? false;
@@ -1883,7 +2125,12 @@ mixin) {
1883
2125
  }
1884
2126
  }
1885
2127
  fields.set(member.name.text, type);
1886
- fieldOrder.push({ name: member.name.text, type, initializer: member.initializer, ...(undefinedInitializer ? { undefinedInitializer } : {}) });
2128
+ fieldOrder.push({
2129
+ name: member.name.text,
2130
+ type,
2131
+ initializer: member.initializer,
2132
+ ...(undefinedInitializer ? { undefinedInitializer } : {}),
2133
+ });
1887
2134
  }
1888
2135
  else if (ts.isConstructorDeclaration(member)) {
1889
2136
  // A body-less constructor is an OVERLOAD SIGNATURE: type-world,
@@ -1935,7 +2182,7 @@ mixin) {
1935
2182
  if (type.kind === "void")
1936
2183
  lowerer.badType(p.name, lowerer.typeOf(p.name));
1937
2184
  // The class-field dyn rule verbatim (KEEP NARROW).
1938
- if (type.kind === "dyn") {
2185
+ if (type.kind === "dyn" && !lowerer.classImplementedProtocol(lowerer.typeOf(p))) {
1939
2186
  lowerer.unsupported("SC1090", p.name, "'unknown'-typed class fields");
1940
2187
  }
1941
2188
  // `override x` (and any same-named inherited member) would
@@ -2027,15 +2274,18 @@ mixin) {
2027
2274
  // signature carries bindable untyped params collects like a
2028
2275
  // GENERIC method — into genericMethods, no vtable slot, one
2029
2276
  // instance per call-site type tuple (the untyped params ARE the
2030
- // type parameters; see lower-calls' implicit section). DECLINES
2277
+ // type parameters; see generic-functions.ts). DECLINES
2031
2278
  // (falls through to the normal all-dyn ABI) wherever the two
2032
2279
  // dispatch worlds could meet: an inherited declaration of the
2033
2280
  // name (the override stays on the vtable), a shadowed field, or
2034
2281
  // a generic-class instantiation's member.
2035
- if (implicitMonoFile(decl.getSourceFile()) && !functionLocalClass(decl) &&
2282
+ if (implicitMonoFile(decl.getSourceFile()) &&
2283
+ !functionLocalClass(decl) &&
2036
2284
  ts.isIdentifier(member.name) &&
2037
- !lowerer.virtualJsMethods.has(member) && !lowerer.prototypeMethodAccesses.has(member.name.text) &&
2038
- inst === undefined && decl.typeParameters === undefined &&
2285
+ !lowerer.virtualJsMethods.has(member) &&
2286
+ !lowerer.prototypeMethodAccesses.has(member.name.text) &&
2287
+ inst === undefined &&
2288
+ decl.typeParameters === undefined &&
2039
2289
  !fields.has(member.name.text) &&
2040
2290
  !lowerer.findMethodOn(base, member.name.text) &&
2041
2291
  !findGenericMethodOn(lowerer, base, member.name.text)) {
@@ -2069,9 +2319,13 @@ mixin) {
2069
2319
  }
2070
2320
  // JS inference may retain only a symbol sentinel while a method
2071
2321
  // also returns values from an untyped mutable field or local.
2072
- if (isJsSourceFile(member.getSourceFile()) && !member.type && !hasExplicitJsDocReturn(member) && ft.ret.kind === "symbol")
2322
+ if (isJsSourceFile(member.getSourceFile()) &&
2323
+ !member.type &&
2324
+ !hasExplicitJsDocReturn(member) &&
2325
+ ft.ret.kind === "symbol")
2073
2326
  ft.ret = DYN;
2074
- if (isJsSourceFile(member.getSourceFile()) && lowerer.prototypeMethodAccesses.has(mName) &&
2327
+ if (isJsSourceFile(member.getSourceFile()) &&
2328
+ lowerer.prototypeMethodAccesses.has(mName) &&
2075
2329
  !lowerer.findMethodOn(base, mName)?.declarer.def.runtime &&
2076
2330
  shapes.every((p) => p.mode === "required" || p.mode === "omittable")) {
2077
2331
  for (const shape of shapes) {
@@ -2087,7 +2341,8 @@ mixin) {
2087
2341
  // argument slots in the base before constructing its vtable; shorter
2088
2342
  // bodies ignore them and omitted call arguments become undefined.
2089
2343
  const virtualArity = lowerer.virtualJsMethodArity.get(member) ?? shapes.length;
2090
- if (virtualArity > shapes.length && !bodyReadsArguments(member) &&
2344
+ if (virtualArity > shapes.length &&
2345
+ !bodyReadsArguments(member) &&
2091
2346
  shapes.every((p) => p.type.kind === "dyn" && (p.mode === "required" || p.mode === "omittable"))) {
2092
2347
  while (shapes.length < virtualArity)
2093
2348
  shapes.push({ type: DYN, mode: "omittable" });
@@ -2121,13 +2376,18 @@ mixin) {
2121
2376
  // An unannotated JS override can return a checked value into
2122
2377
  // the inherited native ABI, just as its untyped parameters do.
2123
2378
  // Body lowering inserts the conversion at each return.
2124
- if (!member.type && ft.ret.kind === "dyn" && overridden.sig.ret.kind !== "dyn" &&
2125
- !overridden.sig.async && !overridden.sig.gen)
2379
+ if (!member.type &&
2380
+ ft.ret.kind === "dyn" &&
2381
+ overridden.sig.ret.kind !== "dyn" &&
2382
+ !overridden.sig.async &&
2383
+ !overridden.sig.gen)
2126
2384
  ft.ret = overridden.sig.ret;
2127
2385
  // Fluent overrides return the same native receiver. Keep the
2128
2386
  // inherited return ABI and upcast `this` when lowering returns.
2129
- if (overridden.sig.ret.kind === "object" && base &&
2130
- (base.def.name === overridden.sig.ret.className || lowerer.isSubclassOf(base.def.name, overridden.sig.ret.className)) &&
2387
+ if (overridden.sig.ret.kind === "object" &&
2388
+ base &&
2389
+ (base.def.name === overridden.sig.ret.className ||
2390
+ lowerer.isSubclassOf(base.def.name, overridden.sig.ret.className)) &&
2131
2391
  returnsOnlyThis(member))
2132
2392
  ft.ret = overridden.sig.ret;
2133
2393
  // An unannotated JS parameter can use the base's typed ABI.
@@ -2136,8 +2396,13 @@ mixin) {
2136
2396
  for (let i = 0; i < shapes.length; i++) {
2137
2397
  const parameter = member.parameters[i];
2138
2398
  const inherited = overridden.sig.params[i];
2139
- if (parameter && inherited && !parameter.type && !parameter.initializer && !parameter.dotDotDotToken &&
2140
- shapes[i].type.kind === "dyn" && inherited.type.kind !== "dyn" &&
2399
+ if (parameter &&
2400
+ inherited &&
2401
+ !parameter.type &&
2402
+ !parameter.initializer &&
2403
+ !parameter.dotDotDotToken &&
2404
+ shapes[i].type.kind === "dyn" &&
2405
+ inherited.type.kind !== "dyn" &&
2141
2406
  (inherited.mode === "required" || inherited.mode === "omittable")) {
2142
2407
  shapes[i] = { ...inherited };
2143
2408
  }
@@ -2147,12 +2412,18 @@ mixin) {
2147
2412
  // checked-value ABI slots as unused parameters, and let shorter
2148
2413
  // calls fill them with undefined. Typed tails and rest/arguments
2149
2414
  // readers keep the exact-signature fence.
2150
- if (overridden && isJsSourceFile(member.getSourceFile()) &&
2415
+ if (overridden &&
2416
+ isJsSourceFile(member.getSourceFile()) &&
2151
2417
  shapes.length < overridden.sig.params.length &&
2152
2418
  !bodyReadsArguments(member) &&
2153
- shapes.every((p, i) => (p.mode === "required" || p.mode === "omittable") && typeEquals(p.type, overridden.sig.params[i].type)) &&
2154
- overridden.sig.params.slice(shapes.length).every((p) => p.type.kind === "dyn" && (p.mode === "required" || p.mode === "omittable"))) {
2155
- shapes.push(...overridden.sig.params.slice(shapes.length).map((p) => ({ type: p.type, mode: "omittable" })));
2419
+ shapes.every((p, i) => (p.mode === "required" || p.mode === "omittable") &&
2420
+ typeEquals(p.type, overridden.sig.params[i].type)) &&
2421
+ overridden.sig.params
2422
+ .slice(shapes.length)
2423
+ .every((p) => p.type.kind === "dyn" && (p.mode === "required" || p.mode === "omittable"))) {
2424
+ shapes.push(...overridden.sig.params
2425
+ .slice(shapes.length)
2426
+ .map((p) => ({ type: p.type, mode: "omittable" })));
2156
2427
  }
2157
2428
  if (overridden &&
2158
2429
  member.asteriskToken === undefined &&
@@ -2160,7 +2431,8 @@ mixin) {
2160
2431
  !overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) ||
2161
2432
  !typeEquals(overridden.sig.ret, ft.ret))) {
2162
2433
  const fencedJsOverride = isJsSourceFile(member.getSourceFile()) &&
2163
- overridden.declarer.decl !== null && isJsSourceFile(overridden.declarer.decl.getSourceFile()) &&
2434
+ overridden.declarer.decl !== null &&
2435
+ isJsSourceFile(overridden.declarer.decl.getSourceFile()) &&
2164
2436
  overridden.sig.gen === undefined;
2165
2437
  if (fencedJsOverride) {
2166
2438
  // A dormant JS method must not poison the whole class. Keep
@@ -2171,8 +2443,11 @@ mixin) {
2171
2443
  !member.parameters.some((parameter, index) => {
2172
2444
  if (!parameter.initializer)
2173
2445
  return false;
2174
- const baseMember = overridden.declarer.decl?.members.find((candidate) => ts.isMethodDeclaration(candidate) && classMemberNameOf(lowerer, candidate.name) === mName);
2175
- const inherited = baseMember && ts.isMethodDeclaration(baseMember) ? baseMember.parameters[index]?.initializer : undefined;
2446
+ const baseMember = overridden.declarer.decl?.members.find((candidate) => ts.isMethodDeclaration(candidate) &&
2447
+ classMemberNameOf(lowerer, candidate.name) === mName);
2448
+ const inherited = baseMember && ts.isMethodDeclaration(baseMember)
2449
+ ? baseMember.parameters[index]?.initializer
2450
+ : undefined;
2176
2451
  if (!inherited)
2177
2452
  return false;
2178
2453
  const ownType = lowerer.mapTypeOf(lowerer.typeOf(parameter.initializer));
@@ -2201,7 +2476,8 @@ mixin) {
2201
2476
  else
2202
2477
  lowerer.unsupported("SC1090", member.name, message);
2203
2478
  }
2204
- if (overridden && (member.asteriskToken !== undefined || overridden.sig.gen !== undefined)) {
2479
+ if (overridden &&
2480
+ (member.asteriskToken !== undefined || overridden.sig.gen !== undefined)) {
2205
2481
  const message = `overriding the generator method '${mName}' (generator methods dispatch statically — a virtual slot cannot enter their spawn wrapper)`;
2206
2482
  if (isJsSourceFile(member.getSourceFile()))
2207
2483
  methodEntryFences.set(mName, unsupportedDiag("SC1090", locOf(member.name), message));
@@ -2223,7 +2499,9 @@ mixin) {
2223
2499
  });
2224
2500
  }
2225
2501
  else {
2226
- methods.set(mName, asyncMember ? { params: shapes, ret: ft.ret, async: true } : { params: shapes, ret: ft.ret });
2502
+ methods.set(mName, asyncMember
2503
+ ? { params: shapes, ret: ft.ret, async: true }
2504
+ : { params: shapes, ret: ft.ret });
2227
2505
  }
2228
2506
  // Overrides keep the inherited ABI exactly, so only non-override
2229
2507
  // methods may still refine once the ctor scan runs.
@@ -2262,14 +2540,19 @@ mixin) {
2262
2540
  if (!member.body && !abstractAccessor)
2263
2541
  lowerer.unsupported("SC1090", member, "bodyless accessors");
2264
2542
  const mName = `${isGet ? "get" : "set"}:${prop}`;
2265
- if (fields.has(prop) && isJsSourceFile(decl.getSourceFile()) && base?.fields.has(prop) &&
2543
+ if (fields.has(prop) &&
2544
+ isJsSourceFile(decl.getSourceFile()) &&
2545
+ base?.fields.has(prop) &&
2266
2546
  !fieldOrder.some((field) => field.name === prop)) {
2267
2547
  // JS may override an inherited data field with a prototype
2268
2548
  // accessor. Retain the base storage prefix for its constructor;
2269
2549
  // property dispatch on this subclass selects the accessor.
2270
2550
  fields.delete(prop);
2271
2551
  }
2272
- if (fields.has(prop) && !((prop === "message" || prop === "name") && base && (base.def.name === "%Error" || lowerer.isSubclassOf(base.def.name, "%Error")))) {
2552
+ if (fields.has(prop) &&
2553
+ !((prop === "message" || prop === "name") &&
2554
+ base &&
2555
+ (base.def.name === "%Error" || lowerer.isSubclassOf(base.def.name, "%Error")))) {
2273
2556
  // tsc rejects field/accessor mixing (TS2610/2611); defensive.
2274
2557
  lowerer.unsupported("SC1090", member.name, "accessors sharing a name with a field");
2275
2558
  }
@@ -2333,7 +2616,11 @@ mixin) {
2333
2616
  if (paramProps.length > 0) {
2334
2617
  for (const pp of paramProps)
2335
2618
  fields.set(pp.name, pp.type);
2336
- fieldOrder.unshift(...paramProps.map((pp) => ({ name: pp.name, type: pp.type, initializer: undefined })));
2619
+ fieldOrder.unshift(...paramProps.map((pp) => ({
2620
+ name: pp.name,
2621
+ type: pp.type,
2622
+ initializer: undefined,
2623
+ })));
2337
2624
  }
2338
2625
  // The deferred definite-assignment check: a field on the unguarded
2339
2626
  // list passes only with an unconditional `this.x = ...` at the
@@ -2367,9 +2654,14 @@ mixin) {
2367
2654
  // extraction targets one arm); union-typed `!` fields keep the
2368
2655
  // fence.
2369
2656
  const declared = fields.get(f.name);
2370
- const armable = declared !== undefined && !isUnitType(declared) &&
2371
- declared.kind !== "union" && declared.kind !== "jsval" && declared.kind !== "dyn" &&
2372
- declared.kind !== "map" && declared.kind !== "date" && declared.kind !== "generator" &&
2657
+ const armable = declared !== undefined &&
2658
+ !isUnitType(declared) &&
2659
+ declared.kind !== "union" &&
2660
+ declared.kind !== "jsval" &&
2661
+ declared.kind !== "dyn" &&
2662
+ declared.kind !== "map" &&
2663
+ declared.kind !== "date" &&
2664
+ declared.kind !== "generator" &&
2373
2665
  declared.kind !== "void" &&
2374
2666
  declared.kind !== "caught";
2375
2667
  const armed = armable ? lowerer.withUndefinedArm(declared) : null;
@@ -2436,13 +2728,18 @@ mixin) {
2436
2728
  // forbids via strictPropertyInitialization — so they keep a named
2437
2729
  // fence instead of a silent undefined.
2438
2730
  if (isJsSourceFile(decl.getSourceFile())) {
2439
- const hasAccessor = (name) => methods.has(`get:${name}`) || methods.has(`set:${name}`) ||
2731
+ const hasAccessor = (name) => methods.has(`get:${name}`) ||
2732
+ methods.has(`set:${name}`) ||
2440
2733
  lowerer.findMethodOn(base, `get:${name}`) !== null ||
2441
2734
  lowerer.findMethodOn(base, `set:${name}`) !== null;
2442
2735
  // Named classes (declarations and self-binding expressions) resolve
2443
2736
  // by name; the nameless default-export declaration by its module's
2444
2737
  // default-export symbol.
2445
- const classSym = decl.name ? lowerer.checker.getSymbolAtLocation(decl.name) : ts.isClassDeclaration(decl) ? declSymbolOf(lowerer, decl) : undefined;
2738
+ const classSym = decl.name
2739
+ ? lowerer.checker.getSymbolAtLocation(decl.name)
2740
+ : ts.isClassDeclaration(decl)
2741
+ ? declSymbolOf(lowerer, decl)
2742
+ : undefined;
2446
2743
  const instType = classSym ? lowerer.checker.getDeclaredTypeOfSymbol(classSym) : undefined;
2447
2744
  // LATE-BOUND properties (the checker's `__@name@id` spelling —
2448
2745
  // `this[kLimit] = v` where kLimit is a unique symbol const) by
@@ -2466,7 +2763,8 @@ mixin) {
2466
2763
  stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken
2467
2764
  ? stmt.expression.left
2468
2765
  : null;
2469
- if (lhs && ts.isPropertyAccessExpression(lhs) &&
2766
+ if (lhs &&
2767
+ ts.isPropertyAccessExpression(lhs) &&
2470
2768
  lhs.expression.kind === ts.SyntaxKind.ThisKeyword) {
2471
2769
  const assign = lhs;
2472
2770
  const name = assign.name.text;
@@ -2493,7 +2791,9 @@ mixin) {
2493
2791
  // TS-annotated `unknown` fields keep their fence (KEEP NARROW
2494
2792
  // applies where an annotation could say better).
2495
2793
  let type = t ? (lowerer.mapTypeOf(t) ?? dynFallbackType(lowerer, assign, t)) : null;
2496
- if (t && (t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 && isJsSourceFile(decl.getSourceFile()))
2794
+ if (t &&
2795
+ (t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 &&
2796
+ isJsSourceFile(decl.getSourceFile()))
2497
2797
  type = DYN;
2498
2798
  if (type)
2499
2799
  type = jsOpenObjectType(assign, type, lowerer.shapes, lowerer.unions);
@@ -2540,7 +2840,8 @@ mixin) {
2540
2840
  // property type, through the same JS checked-dynamic fallback
2541
2841
  // as named fields. Keys that DON'T resolve fall through to the
2542
2842
  // late-bound fence below.
2543
- if (lhs && ts.isElementAccessExpression(lhs) &&
2843
+ if (lhs &&
2844
+ ts.isElementAccessExpression(lhs) &&
2544
2845
  lhs.expression.kind === ts.SyntaxKind.ThisKeyword) {
2545
2846
  const key = classSymbolKeyOf(lowerer, lhs.argumentExpression);
2546
2847
  const stringKey = lowerer.foldedStringKeyOf(lhs.argumentExpression);
@@ -2566,7 +2867,11 @@ mixin) {
2566
2867
  // one layout would need one printable name for two slots.
2567
2868
  lowerer.unsupported("SC1090", lhs, `distinct symbol keys sharing the printable name '${symbolFieldDisplayName(fieldName)}' in one class`);
2568
2869
  }
2569
- const propSym = key ? lateBoundByKey.get(key.sym) : instType ? lowerer.checker.getPropertyOfType(instType, fieldName) : undefined;
2870
+ const propSym = key
2871
+ ? lateBoundByKey.get(key.sym)
2872
+ : instType
2873
+ ? lowerer.checker.getPropertyOfType(instType, fieldName)
2874
+ : undefined;
2570
2875
  // tsgo does not synthesize the late-bound `__@name@id`
2571
2876
  // property for a JS `this[k] = v` declaration (the finding-5
2572
2877
  // family: no expando/late-bound synthesis in its stricter
@@ -2610,7 +2915,10 @@ mixin) {
2610
2915
  continue;
2611
2916
  if (base && (base.fields.has(p.name) || lowerer.findMethodOn(base, p.name)))
2612
2917
  continue;
2613
- const site = lowerer.checker.declarationsOf(p).find((d) => ts.isPropertyAccessExpression(d) || ts.isBinaryExpression(d) ||
2918
+ const site = lowerer.checker
2919
+ .declarationsOf(p)
2920
+ .find((d) => ts.isPropertyAccessExpression(d) ||
2921
+ ts.isBinaryExpression(d) ||
2614
2922
  ts.isElementAccessExpression(d));
2615
2923
  if (!site)
2616
2924
  continue;
@@ -2684,8 +2992,11 @@ mixin) {
2684
2992
  const ctorParams = ctor && !mixinForwarding
2685
2993
  ? lowerer.paramShapes(ctor.parameters)
2686
2994
  : (base?.ctorParams ?? (callableBase ? [{ type: DYN, mode: "dynRest" }] : []));
2687
- if (ctor && !mixinForwarding && isJsSourceFile(ctor.getSourceFile()) &&
2688
- !ctorParams.some((shape) => shape.mode === "rest" || shape.mode === "dynRest" || shape.mode === "islandRest") && bodyReadsArguments(ctor)) {
2995
+ if (ctor &&
2996
+ !mixinForwarding &&
2997
+ isJsSourceFile(ctor.getSourceFile()) &&
2998
+ !ctorParams.some((shape) => shape.mode === "rest" || shape.mode === "dynRest" || shape.mode === "islandRest") &&
2999
+ bodyReadsArguments(ctor)) {
2689
3000
  ctorParams.push({ type: DYN, mode: "arguments" });
2690
3001
  }
2691
3002
  const info = {
@@ -2708,7 +3019,9 @@ mixin) {
2708
3019
  // initializers assign the prefix slot).
2709
3020
  fields: [
2710
3021
  ...(base?.def.fields ?? []),
2711
- ...fieldOrder.filter((f) => f.redeclared !== true).map((f) => ({ name: f.name, type: f.type })),
3022
+ ...fieldOrder
3023
+ .filter((f) => f.redeclared !== true)
3024
+ .map((f) => ({ name: f.name, type: f.type })),
2712
3025
  ],
2713
3026
  ...(methods.size > 0 ? { methods: [...methods.keys()] } : {}),
2714
3027
  ...(abstractClass ? { abstract: true } : {}),
@@ -2729,6 +3042,7 @@ mixin) {
2729
3042
  ctorParams,
2730
3043
  ...(paramProps.length > 0 ? { paramProps } : {}),
2731
3044
  base,
3045
+ ...(genericBase ? { genericBase } : {}),
2732
3046
  ...(callableBase ? { callableBase } : {}),
2733
3047
  ...(factoryBaseExpression ? { factoryBaseExpression } : {}),
2734
3048
  subclasses: [],
@@ -2738,7 +3052,9 @@ mixin) {
2738
3052
  ...(staticBlocks.length > 0 ? { staticBlocks } : {}),
2739
3053
  ...(symbolFields.size > 0 ? { symbolFields } : {}),
2740
3054
  ...(symbolMethods.size > 0 ? { symbolMethods } : {}),
2741
- ...(classDecoratorNodes.length > 0 ? { classDecorators: { nodes: classDecoratorNodes } } : {}),
3055
+ ...(classDecoratorNodes.length > 0
3056
+ ? { classDecorators: { nodes: classDecoratorNodes } }
3057
+ : {}),
2742
3058
  ...(deferredInitFields.size > 0 ? { deferredInitFields } : {}),
2743
3059
  };
2744
3060
  // GENERIC members get their declaring-class backlink now that the
@@ -2756,6 +3072,7 @@ mixin) {
2756
3072
  }
2757
3073
  if (inst) {
2758
3074
  info.genericInstance = {
3075
+ path: inst.path,
2759
3076
  family: inst.family,
2760
3077
  bindings: inst.bindings,
2761
3078
  typeArgsText: inst.typeArgsText,
@@ -2793,14 +3110,29 @@ mixin) {
2793
3110
  lowerer.classes.set(className, info);
2794
3111
  if (computedBase && !functionLocalClass(decl)) {
2795
3112
  info.def.baseValueGlobal = `%g.${className}.computedBase`;
2796
- lowerer.globalsList.push({ id: info.def.baseValueGlobal, name: `${className} base`, type: computedBase.value.type, mutable: false });
3113
+ lowerer.globalsList.push({
3114
+ id: info.def.baseValueGlobal,
3115
+ name: `${className} base`,
3116
+ type: computedBase.value.type,
3117
+ mutable: false,
3118
+ });
2797
3119
  }
2798
3120
  if (factoryBaseExpression && !functionLocalClass(decl)) {
2799
3121
  info.def.baseValueGlobal = `%g.${className}.computedBase`;
2800
- lowerer.globalsList.push({ id: info.def.baseValueGlobal, name: `${className} base`, type: { kind: "classval", className: base.def.name }, mutable: false });
3122
+ lowerer.globalsList.push({
3123
+ id: info.def.baseValueGlobal,
3124
+ name: `${className} base`,
3125
+ type: { kind: "classval", className: base.def.name },
3126
+ mutable: false,
3127
+ });
2801
3128
  }
2802
3129
  if (callableBase && !functionLocalClass(decl)) {
2803
- lowerer.globalsList.push({ id: callableBase.constructorId, name: `${className} base`, type: DYN, mutable: false }, { id: callableBase.prototypeId, name: `${className} base prototype`, type: DYN, mutable: false });
3130
+ lowerer.globalsList.push({ id: callableBase.constructorId, name: `${className} base`, type: DYN, mutable: false }, {
3131
+ id: callableBase.prototypeId,
3132
+ name: `${className} base prototype`,
3133
+ type: DYN,
3134
+ mutable: false,
3135
+ });
2804
3136
  }
2805
3137
  // A NAMED class binds its name (declarations in their scope, class
2806
3138
  // expressions inside their own bodies — tsc resolves both to this
@@ -2812,29 +3144,45 @@ mixin) {
2812
3144
  // classes fence at their use sites).
2813
3145
  const classSymbol = inst || mixin
2814
3146
  ? undefined
2815
- : decl.name ? lowerer.checker.getSymbolAtLocation(decl.name) : ts.isClassDeclaration(decl) ? declSymbolOf(lowerer, decl) : undefined;
3147
+ : decl.name
3148
+ ? lowerer.checker.getSymbolAtLocation(decl.name)
3149
+ : ts.isClassDeclaration(decl)
3150
+ ? declSymbolOf(lowerer, decl)
3151
+ : undefined;
2816
3152
  if (classSymbol)
2817
3153
  lowerer.classBySymbol.set(classSymbol, info);
2818
3154
  // Static-field storage registers with the module's globals only
2819
3155
  // once the whole shape collected (a poisoned class never leaves a
2820
3156
  // half-registered global behind).
2821
3157
  for (const f of staticFields) {
2822
- lowerer.globalsList.push({ id: f.globalId, name: `${info.def.jsName ?? className}.${f.name}`, type: f.type, mutable: !f.readonly });
3158
+ lowerer.globalsList.push({
3159
+ id: f.globalId,
3160
+ name: `${info.def.jsName ?? className}.${f.name}`,
3161
+ type: f.type,
3162
+ mutable: !f.readonly,
3163
+ });
2823
3164
  }
2824
3165
  }
2825
3166
  }
2826
3167
  /** mapType's generic-class hook: the INSTANTIATION a concrete type
2827
- * reference (`Box<number>`) names — registered on first demand. The
2828
- * instance's NAME reserves its key before the shape collects, so
2829
- * self-referential layouts (`next: Box<T> | null`) re-enter here and
2830
- * take the name without recursing; a poisoned collection (a field type
2831
- * with no lowering under these bindings — the diagnostic carries the
2832
- * instantiation context) leaves the entry poisoned and the type
2833
- * unmapped, the fenced-JS-class story. Null answers (unmappable type
2834
- * arguments, the instance cap, an uncollected family) make the whole
2835
- * reference unmappable — per-site diagnostics own the fence. */
3168
+ * reference (`Box<number>`) names — registered on first demand. The
3169
+ * instance's NAME reserves its key before the shape collects, so
3170
+ * self-referential layouts (`next: Box<T> | null`) re-enter here and
3171
+ * take the name without recursing; a poisoned collection (a field type
3172
+ * with no lowering under these bindings — the diagnostic carries the
3173
+ * instantiation context) leaves the entry poisoned and the type
3174
+ * unmapped, the fenced-JS-class story. Null answers (unmappable type
3175
+ * arguments, the instance cap, an uncollected family) make the whole
3176
+ * reference unmappable — per-site diagnostics own the fence. */
2836
3177
  export function genericClassInstanceType(lowerer, decl, ref, mapArgument) {
2837
- const gci = lowerer.genericClassByDecl.get(decl);
3178
+ let gci = lowerer.genericClassByDecl.get(decl);
3179
+ if (!gci && ts.isClassDeclaration(decl)) {
3180
+ // A method signature can reference a generic class declared later in
3181
+ // the same module. Resolve its family now rather than freezing the
3182
+ // signature at the erased family layout for the rest of the build.
3183
+ lowerer.collectClassShape(decl);
3184
+ gci = lowerer.genericClassByDecl.get(decl);
3185
+ }
2838
3186
  if (!gci) {
2839
3187
  // The family never collected (a deferred/poisoned declaration): the
2840
3188
  // pre-generics answer — the class's own name, unregistered, so dead
@@ -2856,7 +3204,9 @@ export function genericClassInstanceType(lowerer, decl, ref, mapArgument) {
2856
3204
  const familyT = { kind: "object", className: gci.family.def.name };
2857
3205
  // The checker appends `this` (and outer type parameters) to
2858
3206
  // getTypeArguments — only the declaration's own count participates.
2859
- const args = lowerer.checker.getTypeArguments(ref).slice(0, gci.typeParams.length);
3207
+ const args = lowerer.checker
3208
+ .getTypeArguments(ref)
3209
+ .slice(0, gci.typeParams.length);
2860
3210
  const mapped = [];
2861
3211
  if (args.length === gci.typeParams.length) {
2862
3212
  for (const a of args) {
@@ -2889,12 +3239,12 @@ export function genericClassInstanceType(lowerer, decl, ref, mapArgument) {
2889
3239
  lowerer.noteGenericClassInstanceDemand(existing.info);
2890
3240
  return existing.poisoned ? null : { kind: "object", className: existing.name };
2891
3241
  }
2892
- // The generic-fn cap, same rationale (polymorphic recursion through
2893
- // class fields would mint instances forever). mapType has no
2894
- // diagnostic channel — the family answer keeps the site compilable
2895
- // where the OBJECT itself is never touched; touched members fence.
2896
- if (gci.instances.size >= MAX_GENERIC_INSTANCES)
2897
- return familyT;
3242
+ // Recursive class fields and queued member bodies share the function
3243
+ // demand budget. Independent uses do not limit the family size.
3244
+ const path = extendInstantiationPath(lowerer.genericInstantiationPath, decl);
3245
+ if (!path) {
3246
+ lowerer.unsupported("SC1090", decl, `unbounded generic class instantiation ('${gci.baseName}' exceeded ${MAX_INSTANTIATION_RECURSION} recursive specializations on one demand path)`);
3247
+ }
2898
3248
  const ordinal = gci.instances.size;
2899
3249
  const name = `${gci.family.def.name}%${ordinal}`;
2900
3250
  const entry = { name, info: null };
@@ -2905,10 +3255,19 @@ export function genericClassInstanceType(lowerer, decl, ref, mapArgument) {
2905
3255
  const typeArgsText = `<${rendered.length > 80 ? rendered.slice(0, 77) + "..." : rendered}>`;
2906
3256
  const prevBindings = lowerer.typeParamBindings;
2907
3257
  const prevContext = lowerer.instantiationContext;
3258
+ const previousPath = lowerer.genericInstantiationPath;
3259
+ lowerer.genericInstantiationPath = path;
2908
3260
  lowerer.typeParamBindings = bindings;
2909
3261
  lowerer.instantiationContext = `instantiating class '${gci.baseName}' with ${typeArgsText}`;
2910
3262
  try {
2911
- lowerer.collectClassShapeInner(decl, undefined, { family: gci.family, name, bindings, typeArgsText, ordinal });
3263
+ lowerer.collectClassShapeInner(decl, undefined, {
3264
+ path,
3265
+ family: gci.family,
3266
+ name,
3267
+ bindings,
3268
+ typeArgsText,
3269
+ ordinal,
3270
+ });
2912
3271
  }
2913
3272
  catch (e) {
2914
3273
  // Collection fenced under THESE bindings: the diagnostic (with the
@@ -2921,6 +3280,7 @@ export function genericClassInstanceType(lowerer, decl, ref, mapArgument) {
2921
3280
  finally {
2922
3281
  lowerer.typeParamBindings = prevBindings;
2923
3282
  lowerer.instantiationContext = prevContext;
3283
+ lowerer.genericInstantiationPath = previousPath;
2924
3284
  }
2925
3285
  const info = lowerer.classes.get(name);
2926
3286
  if (!info) {
@@ -2934,11 +3294,11 @@ export function genericClassInstanceType(lowerer, decl, ref, mapArgument) {
2934
3294
  return { kind: "object", className: name };
2935
3295
  }
2936
3296
  /** Runs a member-lowering thunk under an INSTANTIATION's type-parameter
2937
- * bindings (the generic-fn typeParamResolver mechanism) — the checker
2938
- * keeps reporting the unsubstituted `T`s inside the shared body AST.
2939
- * Coverage counts a generic class's statements once: only the FIRST
2940
- * instantiation contributes (the lowerGenericInstance rule). A no-op
2941
- * for ordinary classes. */
3297
+ * bindings (the generic-fn typeParamResolver mechanism) — the checker
3298
+ * keeps reporting the unsubstituted `T`s inside the shared body AST.
3299
+ * Coverage counts a generic class's statements once: only the FIRST
3300
+ * instantiation contributes (the lowerGenericInstance rule). A no-op
3301
+ * for ordinary classes. */
2942
3302
  function withInstanceBindings(lowerer, info, fn) {
2943
3303
  const gi = info.genericInstance;
2944
3304
  if (!gi) {
@@ -2970,6 +3330,8 @@ function withInstanceBindings(lowerer, info, fn) {
2970
3330
  const prevBindings = lowerer.typeParamBindings;
2971
3331
  const prevContext = lowerer.instantiationContext;
2972
3332
  const prevSuppress = lowerer.suppressStats;
3333
+ const previousPath = lowerer.genericInstantiationPath;
3334
+ lowerer.genericInstantiationPath = gi.path;
2973
3335
  lowerer.typeParamBindings = gi.bindings;
2974
3336
  lowerer.instantiationContext = `instantiating class '${gi.family.generic?.baseName ?? info.def.jsName ?? ""}' with ${gi.typeArgsText}`;
2975
3337
  lowerer.suppressStats = prevSuppress || gi.ordinal > 0;
@@ -2980,14 +3342,15 @@ function withInstanceBindings(lowerer, info, fn) {
2980
3342
  lowerer.typeParamBindings = prevBindings;
2981
3343
  lowerer.instantiationContext = prevContext;
2982
3344
  lowerer.suppressStats = prevSuppress;
3345
+ lowerer.genericInstantiationPath = previousPath;
2983
3346
  }
2984
3347
  }
2985
3348
  /** The `%init` statements for one class's static readonly fields AND
2986
- * static blocks, interleaved in member order — emitted at the class
2987
- * statement's source position (see lowerFileInit's merge), exactly when
2988
- * JS evaluates static initializers and blocks. Field failures poison per
2989
- * field, like fieldInitStmts; a block lowers as the block statement it
2990
- * is, so its statements poison individually inside lowerStmts. */
3349
+ * static blocks, interleaved in member order — emitted at the class
3350
+ * statement's source position (see lowerFileInit's merge), exactly when
3351
+ * JS evaluates static initializers and blocks. Field failures poison per
3352
+ * field, like fieldInitStmts; a block lowers as the block statement it
3353
+ * is, so its statements poison individually inside lowerStmts. */
2991
3354
  export function lowerStaticFieldInits(lowerer, info) {
2992
3355
  if (info.localClass)
2993
3356
  return [];
@@ -3018,41 +3381,102 @@ function lowerStaticFieldInitsInner(lowerer, info) {
3018
3381
  // initializers and static blocks (verified against Node — the
3019
3382
  // decorated result is what `this`/the class name mean inside them).
3020
3383
  const out = [...lowerClassDecoration(lowerer, info)];
3021
- const computedBase = info.decl ? lowerer.computedClassBases.get(lowerer.classNamer(info.decl)) : undefined;
3384
+ const computedBase = info.decl
3385
+ ? lowerer.computedClassBases.get(lowerer.classNamer(info.decl))
3386
+ : undefined;
3022
3387
  if (info.factoryBaseExpression && info.def.baseValueGlobal) {
3023
3388
  const loc = locOf(info.factoryBaseExpression);
3024
3389
  const type = { kind: "classval", className: info.base.def.name };
3025
- out.push({ kind: "assign", localId: info.def.baseValueGlobal, value: lowerer.lowerExprExpecting(info.factoryBaseExpression, type), loc });
3026
- out.push({ kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classInherit", args: [
3390
+ out.push({
3391
+ kind: "assign",
3392
+ localId: info.def.baseValueGlobal,
3393
+ value: lowerer.lowerExprExpecting(info.factoryBaseExpression, type),
3394
+ loc,
3395
+ });
3396
+ out.push({
3397
+ kind: "exprStmt",
3398
+ expr: {
3399
+ kind: "libCall",
3400
+ fn: "dyn.classInherit",
3401
+ args: [
3027
3402
  lowerer.coerceToExpected(classValueRef(lowerer, info, info.decl), DYN),
3028
3403
  lowerer.coerceToExpected({ kind: "varRef", localId: info.def.baseValueGlobal, type, loc }, DYN),
3029
- ], type: DYN, loc }, loc });
3404
+ ],
3405
+ type: DYN,
3406
+ loc,
3407
+ },
3408
+ loc,
3409
+ });
3030
3410
  }
3031
3411
  if (computedBase && info.def.baseValueGlobal) {
3032
3412
  const loc = computedBase.value.loc;
3033
3413
  out.push({ kind: "assign", localId: info.def.baseValueGlobal, value: computedBase.value, loc });
3034
- out.push({ kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classInherit", args: [
3414
+ out.push({
3415
+ kind: "exprStmt",
3416
+ expr: {
3417
+ kind: "libCall",
3418
+ fn: "dyn.classInherit",
3419
+ args: [
3035
3420
  lowerer.coerceToExpected(classValueRef(lowerer, info, info.decl), DYN),
3036
- lowerer.coerceToExpected({ kind: "varRef", localId: info.def.baseValueGlobal, type: computedBase.value.type, loc }, DYN),
3037
- ], type: DYN, loc }, loc });
3421
+ lowerer.coerceToExpected({
3422
+ kind: "varRef",
3423
+ localId: info.def.baseValueGlobal,
3424
+ type: computedBase.value.type,
3425
+ loc,
3426
+ }, DYN),
3427
+ ],
3428
+ type: DYN,
3429
+ loc,
3430
+ },
3431
+ loc,
3432
+ });
3038
3433
  }
3039
3434
  if (info.callableBase) {
3040
3435
  const { expression, constructorId, prototypeId } = info.callableBase;
3041
3436
  const loc = locOf(expression);
3042
- out.push({ kind: "assign", localId: constructorId, value: info.decl && lowerer.computedCallableBases.has(info.decl)
3437
+ out.push({
3438
+ kind: "assign",
3439
+ localId: constructorId,
3440
+ value: info.decl && lowerer.computedCallableBases.has(info.decl)
3043
3441
  ? lowerer.coerceToExpected(lowerer.computedCallableBases.get(info.decl), DYN)
3044
- : lowerer.lowerExprExpecting(expression, DYN), loc }, { kind: "assign", localId: prototypeId, value: { kind: "libCall", fn: "dyn.classBasePrototype",
3045
- args: [{ kind: "varRef", localId: constructorId, type: DYN, loc }], type: DYN, loc }, loc });
3442
+ : lowerer.lowerExprExpecting(expression, DYN),
3443
+ loc,
3444
+ }, {
3445
+ kind: "assign",
3446
+ localId: prototypeId,
3447
+ value: {
3448
+ kind: "libCall",
3449
+ fn: "dyn.classBasePrototype",
3450
+ args: [{ kind: "varRef", localId: constructorId, type: DYN, loc }],
3451
+ type: DYN,
3452
+ loc,
3453
+ },
3454
+ loc,
3455
+ });
3046
3456
  const prototype = classPrototypeData(lowerer, info, loc);
3047
3457
  if (prototype)
3048
3458
  out.push({ kind: "exprStmt", expr: prototype, loc });
3049
- out.push({ kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classInherit", args: [
3459
+ out.push({
3460
+ kind: "exprStmt",
3461
+ expr: {
3462
+ kind: "libCall",
3463
+ fn: "dyn.classInherit",
3464
+ args: [
3050
3465
  lowerer.coerceToExpected(classValueRef(lowerer, info, info.decl), DYN),
3051
3466
  { kind: "varRef", localId: constructorId, type: DYN, loc },
3052
- ], type: DYN, loc }, loc });
3467
+ ],
3468
+ type: DYN,
3469
+ loc,
3470
+ },
3471
+ loc,
3472
+ });
3053
3473
  }
3054
3474
  if (info.runtimeStatics && !info.localClass && info.decl) {
3055
- out.push({ kind: "exprStmt", expr: initializeRuntimeStatics(lowerer, info, classValueRef(lowerer, info, info.decl)), loc: locOf(info.decl) });
3475
+ out.push({
3476
+ kind: "exprStmt",
3477
+ expr: initializeRuntimeStatics(lowerer, info, classValueRef(lowerer, info, info.decl)),
3478
+ loc: locOf(info.decl),
3479
+ });
3056
3480
  }
3057
3481
  const items = [
3058
3482
  ...info.staticFields.map((f) => ({ pos: f.initializer.getStart(), kind: "field", f })),
@@ -3072,11 +3496,24 @@ function lowerStaticFieldInitsInner(lowerer, info) {
3072
3496
  try {
3073
3497
  const previousThis = lowerer.ctx.thisLocal;
3074
3498
  const receiver = f.initializer.kind === ts.SyntaxKind.ThisKeyword || hasStaticThis(f.initializer)
3075
- ? lowerer.declareHiddenLocal("%staticThis", { kind: "classval", className: info.def.name }) : null;
3499
+ ? lowerer.declareHiddenLocal("%staticThis", {
3500
+ kind: "classval",
3501
+ className: info.def.name,
3502
+ })
3503
+ : null;
3076
3504
  if (receiver) {
3077
3505
  lowerer.noteEdge(`%${info.def.name}.constructor`);
3078
- out.push({ kind: "varDecl", localId: receiver.id, init: { kind: "classRef", className: info.def.name,
3079
- type: receiver.type, loc: locOf(f.initializer) }, loc: locOf(f.initializer) });
3506
+ out.push({
3507
+ kind: "varDecl",
3508
+ localId: receiver.id,
3509
+ init: {
3510
+ kind: "classRef",
3511
+ className: info.def.name,
3512
+ type: receiver.type,
3513
+ loc: locOf(f.initializer),
3514
+ },
3515
+ loc: locOf(f.initializer),
3516
+ });
3080
3517
  }
3081
3518
  let value;
3082
3519
  try {
@@ -3095,7 +3532,9 @@ function lowerStaticFieldInitsInner(lowerer, info) {
3095
3532
  lowerer.stats.statementsFailed++;
3096
3533
  lowerer.bumpFileStat(locOf(f.initializer).file, "failed");
3097
3534
  if (isJsSourceFile(f.initializer.getSourceFile()) && lowerer.diagSink === null) {
3098
- const fence = lowerer.deferToRuntimeFence(diagsBefore, f.initializer, { kind: "statement" });
3535
+ const fence = lowerer.deferToRuntimeFence(diagsBefore, f.initializer, {
3536
+ kind: "statement",
3537
+ });
3099
3538
  if (fence)
3100
3539
  out.push(fence);
3101
3540
  }
@@ -3104,22 +3543,22 @@ function lowerStaticFieldInitsInner(lowerer, info) {
3104
3543
  return out;
3105
3544
  }
3106
3545
  /** Post-collection analysis of a decorated class (all shapes registered —
3107
- * a decorator's return type may name a subclass declared BELOW the
3108
- * class). Classifies every class-level decorator by its checker type:
3109
- * exactly one parameter, itself a classval the decorated class legally
3110
- * flows into (the class, or a base sharing its completed constructor
3111
- * ABI — the classval widening rule), returning void/undefined (an
3112
- * effect-only decorator) or the class/a same-ABI subclass (a REPLACING
3113
- * decorator, whose result rebinds the name). Everything else is a named
3114
- * fence: the standard context parameter, structural sibling
3115
- * replacements tsc admits but the nominal classval world cannot carry,
3116
- * unions mixing the class with undefined. A replacing decorator
3117
- * registers the mutable classval global the name rebinds through, and
3118
- * fences the two shapes the value rebinding cannot keep exact —
3119
- * subclasses of the decorated class (the compiled hierarchy is fixed at
3120
- * build time; the runtime base would be the decoration result) and
3121
- * namespace-nested declarations (qualified references resolve the class
3122
- * directly, not through the rebound value). */
3546
+ * a decorator's return type may name a subclass declared BELOW the
3547
+ * class). Classifies every class-level decorator by its checker type:
3548
+ * exactly one parameter, itself a classval the decorated class legally
3549
+ * flows into (the class, or a base sharing its completed constructor
3550
+ * ABI — the classval widening rule), returning void/undefined (an
3551
+ * effect-only decorator) or the class/a same-ABI subclass (a REPLACING
3552
+ * decorator, whose result rebinds the name). Everything else is a named
3553
+ * fence: the standard context parameter, structural sibling
3554
+ * replacements tsc admits but the nominal classval world cannot carry,
3555
+ * unions mixing the class with undefined. A replacing decorator
3556
+ * registers the mutable classval global the name rebinds through, and
3557
+ * fences the two shapes the value rebinding cannot keep exact —
3558
+ * subclasses of the decorated class (the compiled hierarchy is fixed at
3559
+ * build time; the runtime base would be the decoration result) and
3560
+ * namespace-nested declarations (qualified references resolve the class
3561
+ * directly, not through the rebound value). */
3123
3562
  export function analyzeClassDecoration(lowerer, info) {
3124
3563
  const cd = info.classDecorators;
3125
3564
  if (!cd || cd.shapes !== undefined || cd.poisoned)
@@ -3237,14 +3676,14 @@ export function analyzeClassDecoration(lowerer, info) {
3237
3676
  }
3238
3677
  }
3239
3678
  /** The decoration statements of a decorated class — the %init code that
3240
- * runs at the class statement's position, BEFORE its static field
3241
- * initializers and blocks (lowerStaticFieldInits composes them; the
3242
- * lower-modules interleave places the whole bundle). Verified Node
3243
- * order: decorator expressions evaluate in SOURCE order (factories run
3244
- * here), then applications run in REVERSE member order over the class
3245
- * object, each replacing decorator's non-undefined result feeding the
3246
- * next application; the final value binds the class name (the mutable
3247
- * classval global) when any decorator can replace. */
3679
+ * runs at the class statement's position, BEFORE its static field
3680
+ * initializers and blocks (lowerStaticFieldInits composes them; the
3681
+ * lower-modules interleave places the whole bundle). Verified Node
3682
+ * order: decorator expressions evaluate in SOURCE order (factories run
3683
+ * here), then applications run in REVERSE member order over the class
3684
+ * object, each replacing decorator's non-undefined result feeding the
3685
+ * next application; the final value binds the class name (the mutable
3686
+ * classval global) when any decorator can replace. */
3248
3687
  function lowerClassDecoration(lowerer, info) {
3249
3688
  const cd = info.classDecorators;
3250
3689
  if (!cd || cd.poisoned || cd.shapes === undefined || info.decl === null)
@@ -3264,7 +3703,11 @@ function lowerClassDecoration(lowerer, info) {
3264
3703
  const d = cd.nodes[i];
3265
3704
  const shape = cd.shapes[i];
3266
3705
  if (shape.kind === "ambientThrow") {
3267
- stmts.push({ kind: "exprStmt", expr: nsUndefRead(lowerer, shape.name, d, F64), loc: locOf(d) });
3706
+ stmts.push({
3707
+ kind: "exprStmt",
3708
+ expr: nsUndefRead(lowerer, shape.name, d, F64),
3709
+ loc: locOf(d),
3710
+ });
3268
3711
  return stmts;
3269
3712
  }
3270
3713
  const value = lowerer.lowerExprExpecting(d.expression, shape.funcType);
@@ -3313,9 +3756,9 @@ function lowerClassDecoration(lowerer, info) {
3313
3756
  }
3314
3757
  }
3315
3758
  /** The nearest declaration of static member `name` at or above `info` —
3316
- * the compile-time prototype-chain walk (`D.x` reads C's global when C
3317
- * declared x and nothing between redeclares it; a redeclaration shadows
3318
- * with its OWN storage, exactly JS). */
3759
+ * the compile-time prototype-chain walk (`D.x` reads C's global when C
3760
+ * declared x and nothing between redeclares it; a redeclaration shadows
3761
+ * with its OWN storage, exactly JS). */
3319
3762
  export function findStaticOn(lowerer, info, name) {
3320
3763
  for (let c = info; c; c = c.base) {
3321
3764
  const field = c.staticFields.find((s) => s.name === name);
@@ -3328,17 +3771,17 @@ export function findStaticOn(lowerer, info, name) {
3328
3771
  return null;
3329
3772
  }
3330
3773
  /** True when some STRICT descendant of `info` redeclares static `name` —
3331
- * the through-a-VALUE devirtualization test: a classval(info) slot can
3332
- * hold any descendant, and a shadowing redeclaration means the runtime
3333
- * class decides which storage answers. */
3334
- export function staticShadowBelow(lowerer, info, name) {
3774
+ * the through-a-VALUE devirtualization test: a classval(info) slot can
3775
+ * hold any descendant, and a shadowing redeclaration means the runtime
3776
+ * class decides which storage answers. */
3777
+ export function staticShadowBelow(info, name) {
3335
3778
  return info.subclasses.some((s) => s.staticFields.some((f) => f.name === name) ||
3336
3779
  s.staticMethods?.has(name) === true ||
3337
3780
  s.genericStatics?.has(name) === true ||
3338
- staticShadowBelow(lowerer, s, name));
3781
+ staticShadowBelow(s, name));
3339
3782
  }
3340
3783
  /** The nearest GENERIC static declaration of `name` at/above `info` —
3341
- * findStaticOn's twin over the genericStatics tables. */
3784
+ * findStaticOn's twin over the genericStatics tables. */
3342
3785
  export function findGenericStaticOn(lowerer, info, name) {
3343
3786
  for (let c = info; c; c = c.base) {
3344
3787
  const gs = c.genericStatics?.get(name);
@@ -3348,8 +3791,8 @@ export function findGenericStaticOn(lowerer, info, name) {
3348
3791
  return null;
3349
3792
  }
3350
3793
  /** A static METHOD taken as a value: the zero-capture closure over its
3351
- * module function — the declared-function-as-value rule verbatim
3352
- * (interned by the backend, so `C.m === C.m` holds). */
3794
+ * module function — the declared-function-as-value rule verbatim
3795
+ * (interned by the backend, so `C.m === C.m` holds). */
3353
3796
  function staticMethodValue(lowerer, declarer, name, sig, blame, loc) {
3354
3797
  const reflected = reflectedClassStaticMethodValue(lowerer, declarer, name);
3355
3798
  if (reflected)
@@ -3366,13 +3809,13 @@ function staticMethodValue(lowerer, declarer, name, sig, blame, loc) {
3366
3809
  return { kind: "closure", fnName, captures: [], type: funcType, loc };
3367
3810
  }
3368
3811
  /** The class itself taken as a VALUE (`const X = C`, an argument, an
3369
- * array element, a class expression's result): the classRef over the
3370
- * per-class immortal class object. The construct thunk needs a thunk-
3371
- * shaped constructor, so classes whose construction is libCall-shaped —
3372
- * the runtime-provided builtins and anything inheriting a builtin
3373
- * constructor (Error/EventEmitter/stream chains complete their `new`
3374
- * by special rules) — are named fences here. The constructor edge is
3375
- * noted at every classRef: a value can always be constructed through. */
3812
+ * array element, a class expression's result): the classRef over the
3813
+ * per-class immortal class object. The construct thunk needs a thunk-
3814
+ * shaped constructor, so classes whose construction is libCall-shaped —
3815
+ * the runtime-provided builtins and anything inheriting a builtin
3816
+ * constructor (Error/EventEmitter/stream chains complete their `new`
3817
+ * by special rules) — are named fences here. The constructor edge is
3818
+ * noted at every classRef: a value can always be constructed through. */
3376
3819
  export function classValueRef(lowerer, info, blame) {
3377
3820
  const display = info.def.name.replace(/^%|^%m\d+\./, "");
3378
3821
  fenceDecorationThrows(lowerer, info, blame);
@@ -3395,9 +3838,12 @@ export function classValueRef(lowerer, info, blame) {
3395
3838
  }
3396
3839
  if (lowerer.inheritsBuiltinEmitterCtor(info) ||
3397
3840
  inheritsBuiltinStreamCtor(lowerer, info) ||
3398
- (() => { for (let c = info.base; c; c = c.base)
3399
- if (c.builtinEmitter || c.builtinStream !== undefined)
3400
- return true; return false; })()) {
3841
+ (() => {
3842
+ for (let c = info.base; c; c = c.base)
3843
+ if (c.builtinEmitter || c.builtinStream !== undefined)
3844
+ return true;
3845
+ return false;
3846
+ })()) {
3401
3847
  lowerer.unsupported("SC1090", blame, `classes extending builtin bases as values ('${display}' inherits a runtime-provided constructor)`);
3402
3848
  }
3403
3849
  lowerer.noteEdge(`%${info.def.name}.constructor`);
@@ -3409,20 +3855,22 @@ export function classValueRef(lowerer, info, blame) {
3409
3855
  };
3410
3856
  }
3411
3857
  /** Constructor-ABI equality — the classval widening rule: a classval(D)
3412
- * value may flow into a classval(C) slot only when D's completed
3413
- * constructor signature equals C's (same count, modes, and ABI types),
3414
- * which is what keeps newValue completion against C's one signature
3415
- * sound for every value legally in the slot. */
3858
+ * value may flow into a classval(C) slot only when D's completed
3859
+ * constructor signature equals C's (same count, modes, and ABI types),
3860
+ * which is what keeps newValue completion against C's one signature
3861
+ * sound for every value legally in the slot. */
3416
3862
  export function ctorAbiEquals(lowerer, sub, sup) {
3417
3863
  const a = sub.ctorParams;
3418
3864
  const b = sup.ctorParams;
3419
- return a.length === b.length && a.every((p, i) => p.mode === b[i].mode && typeEquals(p.type, b[i].type));
3865
+ return (a.length === b.length &&
3866
+ a.every((p, i) => p.mode === b[i].mode && typeEquals(p.type, b[i].type)));
3420
3867
  }
3421
3868
  /** Writable storage for an own static field named through its exact class.
3422
3869
  * Inherited writes create a new subclass property in JS, so they must not
3423
3870
  * update the declaring class's global. */
3424
3871
  export function staticFieldWriteTarget(lowerer, access) {
3425
- if (access.questionDotToken || (!ts.isIdentifier(access.expression) && access.expression.kind !== ts.SyntaxKind.ThisKeyword))
3872
+ if (access.questionDotToken ||
3873
+ (!ts.isIdentifier(access.expression) && access.expression.kind !== ts.SyntaxKind.ThisKeyword))
3426
3874
  return null;
3427
3875
  const info = lowerer.exactClassOfReceiver(access.expression);
3428
3876
  if (!info)
@@ -3439,20 +3887,23 @@ export function staticFieldWriteTarget(lowerer, access) {
3439
3887
  return { id: found.field.globalId, type: found.field.type };
3440
3888
  }
3441
3889
  /** `C.x` where C is a class declared in the program and x a static
3442
- * member of its chain: field reads are the module global, static
3443
- * methods become interned closures, and `.name` folds to the class's
3444
- * compile-time name. Null for everything else — unresolved members
3445
- * fall through to the ordinary chain so the static fence or the
3446
- * generic member rejection names the site. */
3890
+ * member of its chain: field reads are the module global, static
3891
+ * methods become interned closures, and `.name` folds to the class's
3892
+ * compile-time name. Null for everything else — unresolved members
3893
+ * fall through to the ordinary chain so the static fence or the
3894
+ * generic member rejection names the site. */
3447
3895
  export function lowerStaticFieldRead(lowerer, expr) {
3448
3896
  if (expr.name.text === "prototype")
3449
3897
  return null;
3450
3898
  if (expr.questionDotToken)
3451
3899
  return null;
3452
- if (!ts.isIdentifier(expr.expression) && expr.expression.kind !== ts.SyntaxKind.ThisKeyword &&
3900
+ if (!ts.isIdentifier(expr.expression) &&
3901
+ expr.expression.kind !== ts.SyntaxKind.ThisKeyword &&
3453
3902
  exactClassOfReceiver(lowerer, expr.expression) === null)
3454
3903
  return null;
3455
- const symbol = ts.isIdentifier(expr.expression) ? lowerer.resolveValueSymbol(expr.expression) : null;
3904
+ const symbol = ts.isIdentifier(expr.expression)
3905
+ ? lowerer.resolveValueSymbol(expr.expression)
3906
+ : null;
3456
3907
  const info = (symbol ? lowerer.classBySymbol.get(symbol) : undefined) ??
3457
3908
  // A require binding over `module.exports = class {…}` (the alias
3458
3909
  // lands on the expression's own symbol): resolve/collect on demand,
@@ -3473,8 +3924,13 @@ export function lowerStaticFieldRead(lowerer, expr) {
3473
3924
  const loc = locOf(expr);
3474
3925
  const found = findStaticOn(lowerer, info, expr.name.text);
3475
3926
  if (hasRuntimeStatics(info) && !found?.field)
3476
- return { kind: "dynKeyGet", value: lowerer.coerceToExpected(classValueRef(lowerer, info, expr.expression), DYN),
3477
- key: { kind: "strLit", value: expr.name.text, type: STRING, loc }, type: DYN, loc };
3927
+ return {
3928
+ kind: "dynKeyGet",
3929
+ value: lowerer.coerceToExpected(classValueRef(lowerer, info, expr.expression), DYN),
3930
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
3931
+ type: DYN,
3932
+ loc,
3933
+ };
3478
3934
  // A #private static resolves only through the DECLARING class's own
3479
3935
  // name: in JS the brand lives on that one constructor object, so
3480
3936
  // `D.#s` (a subclass receiver) throws Node's TypeError instead of
@@ -3503,25 +3959,38 @@ export function lowerStaticFieldRead(lowerer, expr) {
3503
3959
  return { kind: "strLit", value: info.def.jsName, type: STRING, loc };
3504
3960
  }
3505
3961
  if (info.callableBase)
3506
- return { kind: "dynKeyGet", value: lowerer.coerceToExpected(classValueRef(lowerer, info, expr.expression), DYN),
3507
- key: { kind: "strLit", value: expr.name.text, type: STRING, loc }, type: DYN, loc };
3962
+ return {
3963
+ kind: "dynKeyGet",
3964
+ value: lowerer.coerceToExpected(classValueRef(lowerer, info, expr.expression), DYN),
3965
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
3966
+ type: DYN,
3967
+ loc,
3968
+ };
3508
3969
  const data = classStaticDataFor(lowerer, info, expr.name.text, loc);
3509
3970
  if (data) {
3510
- const value = { kind: "dynKeyGet", value: data, key: { kind: "strLit", value: expr.name.text, type: STRING, loc }, type: DYN, loc };
3971
+ const value = {
3972
+ kind: "dynKeyGet",
3973
+ value: data,
3974
+ key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
3975
+ type: DYN,
3976
+ loc,
3977
+ };
3511
3978
  // JavaScript often assigns public statics after the class declaration.
3512
3979
  // Their storage stays mutable and checked, while reads retain the
3513
3980
  // checker's concrete type instead of losing the method receiver.
3514
- const type = isJsSourceFile(expr.getSourceFile()) ? null : lowerer.mapTypeOf(lowerer.typeOf(expr));
3981
+ const type = isJsSourceFile(expr.getSourceFile())
3982
+ ? null
3983
+ : lowerer.mapTypeOf(lowerer.typeOf(expr));
3515
3984
  return type ? lowerer.coerceToExpected(value, type) : value;
3516
3985
  }
3517
3986
  return null;
3518
3987
  }
3519
3988
  /** NamedEvaluation's answer for a class expression's `.name`: its own
3520
- * declared name, else the binding name when the expression is the
3521
- * direct initializer of a variable declaration / the RHS of a simple
3522
- * assignment / an object-literal property value / a default parameter —
3523
- * "" everywhere else (array elements, call arguments). Verified against
3524
- * Node for each shape. */
3989
+ * declared name, else the binding name when the expression is the
3990
+ * direct initializer of a variable declaration / the RHS of a simple
3991
+ * assignment / an object-literal property value / a default parameter —
3992
+ * "" everywhere else (array elements, call arguments). Verified against
3993
+ * Node for each shape. */
3525
3994
  function namedEvaluationName(expr) {
3526
3995
  if (expr.name)
3527
3996
  return expr.name.text;
@@ -3530,7 +3999,9 @@ function namedEvaluationName(expr) {
3530
3999
  p = p.parent;
3531
4000
  if (ts.isVariableDeclaration(p) && ts.isIdentifier(p.name) && p.initializer !== undefined)
3532
4001
  return p.name.text;
3533
- if (ts.isBinaryExpression(p) && p.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isIdentifier(p.left))
4002
+ if (ts.isBinaryExpression(p) &&
4003
+ p.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
4004
+ ts.isIdentifier(p.left))
3534
4005
  return p.left.text;
3535
4006
  if (ts.isPropertyAssignment(p) && ts.isIdentifier(p.name))
3536
4007
  return p.name.text;
@@ -3567,19 +4038,28 @@ export function lowerClassExpressionInfo(lowerer, expr) {
3567
4038
  if (local && expr.members.some((member) => member.name && ts.isPrivateIdentifier(member.name))) {
3568
4039
  lowerer.unsupported("SC1090", expr, "function-local classes with private brands");
3569
4040
  }
3570
- if (local && (expr.typeParameters?.length ||
3571
- decoratorNodesOf(expr).length || expr.members.some((member) => decoratorNodesOf(member).length ||
3572
- (!isJsSourceFile(expr.getSourceFile()) && (ts.isClassStaticBlockDeclaration(member) ||
3573
- ts.getModifiers(member)?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) ||
3574
- (ts.isMethodDeclaration(member) && member.typeParameters?.length)))) {
4041
+ if (local &&
4042
+ (expr.typeParameters?.length ||
4043
+ decoratorNodesOf(expr).length ||
4044
+ expr.members.some((member) => decoratorNodesOf(member).length ||
4045
+ (!isJsSourceFile(expr.getSourceFile()) &&
4046
+ (ts.isClassStaticBlockDeclaration(member) ||
4047
+ ts
4048
+ .getModifiers(member)
4049
+ ?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) ||
4050
+ (ts.isMethodDeclaration(member) && member.typeParameters?.length)))) {
3575
4051
  lowerer.unsupported("SC1090", expr, "function-local classes with statics, decorators, or generic members");
3576
4052
  }
3577
4053
  lowerer.collectingExprClasses.add(expr);
3578
4054
  try {
3579
- if (local && lowerer.fnStack.length > 0 && !lowerer.computedClassBases.has(lowerer.classNamer(expr))) {
4055
+ if (local &&
4056
+ lowerer.fnStack.length > 0 &&
4057
+ !lowerer.computedClassBases.has(lowerer.classNamer(expr))) {
3580
4058
  const heritage = expr.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
3581
- if (heritage && (ts.isCallExpression(heritage) ||
3582
- ts.isIdentifier(heritage) && (lowerer.peekLocal(heritage) ?? lowerer.globalOf(heritage)) != null)) {
4059
+ if (heritage &&
4060
+ (ts.isCallExpression(heritage) ||
4061
+ (ts.isIdentifier(heritage) &&
4062
+ (lowerer.peekLocal(heritage) ?? lowerer.globalOf(heritage)) != null))) {
3583
4063
  let value = lowerer.lowerExpr(heritage);
3584
4064
  const known = value.type.kind === "dyn" ? storedClassValueType(lowerer, heritage) : null;
3585
4065
  if (known?.kind === "classval")
@@ -3601,7 +4081,10 @@ export function lowerClassExpressionInfo(lowerer, expr) {
3601
4081
  throw new PoisonError(); // collection poisoned and reported
3602
4082
  if (local) {
3603
4083
  info.def.localCaptures = [];
3604
- info.def.fields.push({ name: `%classEnvironment:${info.def.name}`, type: { kind: "classval", className: info.def.name } });
4084
+ info.def.fields.push({
4085
+ name: `%classEnvironment:${info.def.name}`,
4086
+ type: { kind: "classval", className: info.def.name },
4087
+ });
3605
4088
  info.localClass = { context: null, bodies: new Map(), captureSources: [], ready: false };
3606
4089
  if (info.base?.localClass) {
3607
4090
  const baseExpression = expr.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
@@ -3619,10 +4102,17 @@ export function lowerClassExpressionInfo(lowerer, expr) {
3619
4102
  // drains it), which is JS's order for whole-initializer positions.
3620
4103
  // Anything subtler (multi-declarator statements, arguments evaluated
3621
4104
  // after other side effects) is a named fence, never a reordering.
3622
- if (!local && (info.callableBase || info.def.baseValueGlobal || info.runtimeStatics || info.staticFields.length > 0 || (info.staticBlocks?.length ?? 0) > 0)) {
4105
+ if (!local &&
4106
+ (info.callableBase ||
4107
+ info.def.baseValueGlobal ||
4108
+ info.runtimeStatics ||
4109
+ info.staticFields.length > 0 ||
4110
+ (info.staticBlocks?.length ?? 0) > 0)) {
3623
4111
  let holder = expr.parent;
3624
- while (ts.isParenthesizedExpression(holder) || ts.isClassExpression(holder) ||
3625
- ts.isHeritageClause(holder) || ts.isExpressionWithTypeArguments(holder)) {
4112
+ while (ts.isParenthesizedExpression(holder) ||
4113
+ ts.isClassExpression(holder) ||
4114
+ ts.isHeritageClause(holder) ||
4115
+ ts.isExpressionWithTypeArguments(holder)) {
3626
4116
  holder = holder.parent;
3627
4117
  }
3628
4118
  const wholeInit = (ts.isVariableDeclaration(holder) &&
@@ -3643,13 +4133,13 @@ export function lowerClassExpressionInfo(lowerer, expr) {
3643
4133
  return info;
3644
4134
  }
3645
4135
  /** `class {…}` in expression position: a class definition bound to no
3646
- * statement — once the static side is a value, the expression IS the
3647
- * definition plus a classRef over it. A DECORATED class expression
3648
- * whose decoration provably throws (the ambient-decorator shape) never
3649
- * mints a class at all: evaluating the expression IS the
3650
- * ReferenceError, so it lowers to exactly that read — every evaluation
3651
- * throws identically, which is why the once-evaluated restriction and
3652
- * the member fences don't apply. */
4136
+ * statement — once the static side is a value, the expression IS the
4137
+ * definition plus a classRef over it. A DECORATED class expression
4138
+ * whose decoration provably throws (the ambient-decorator shape) never
4139
+ * mints a class at all: evaluating the expression IS the
4140
+ * ReferenceError, so it lowers to exactly that read — every evaluation
4141
+ * throws identically, which is why the once-evaluated restriction and
4142
+ * the member fences don't apply. */
3653
4143
  export function lowerClassExpression(lowerer, expr) {
3654
4144
  if (decoratorNodesOf(expr).length > 0 ||
3655
4145
  expr.members.some((m) => decoratorNodesOf(m).length > 0)) {
@@ -3664,8 +4154,13 @@ export function lowerClassExpression(lowerer, expr) {
3664
4154
  }
3665
4155
  }
3666
4156
  const info = lowerClassExpressionInfo(lowerer, expr);
3667
- if (!info.localClass && !info.expressionInitializationEmitted &&
3668
- (info.callableBase || info.def.baseValueGlobal || info.runtimeStatics || info.staticFields.length > 0 || (info.staticBlocks?.length ?? 0) > 0)) {
4157
+ if (!info.localClass &&
4158
+ !info.expressionInitializationEmitted &&
4159
+ (info.callableBase ||
4160
+ info.def.baseValueGlobal ||
4161
+ info.runtimeStatics ||
4162
+ info.staticFields.length > 0 ||
4163
+ (info.staticBlocks?.length ?? 0) > 0)) {
3669
4164
  info.expressionInitializationEmitted = true;
3670
4165
  lowerer.pendingClassExprInits.push(...lowerer.lowerStaticFieldInits(info));
3671
4166
  }
@@ -3681,7 +4176,11 @@ export function lowerClassExpression(lowerer, expr) {
3681
4176
  info.localClass.captureSources = context.captureSources;
3682
4177
  if (info.localClass.baseExpression && info.base) {
3683
4178
  info.def.localBaseCapture = info.def.localCaptures.length;
3684
- info.def.localCaptures.push({ localId: "%base", name: "base", type: { kind: "classval", className: info.base.def.name } });
4179
+ info.def.localCaptures.push({
4180
+ localId: "%base",
4181
+ name: "base",
4182
+ type: { kind: "classval", className: info.base.def.name },
4183
+ });
3685
4184
  }
3686
4185
  info.localClass.ready = true;
3687
4186
  lowerer.onExprClassCollected?.(info);
@@ -3701,18 +4200,47 @@ export function lowerClassExpression(lowerer, expr) {
3701
4200
  const clsRef = { kind: "varRef", localId: clsLocal.id, type: value.type, loc };
3702
4201
  const boxed = { kind: "dynFrom", value: clsRef, type: DYN, loc };
3703
4202
  info.localPrototypeData = true;
3704
- return initializeRuntimeStatics(lowerer, info, { kind: "seqExpr", stmts: [
4203
+ return initializeRuntimeStatics(lowerer, info, {
4204
+ kind: "seqExpr",
4205
+ stmts: [
3705
4206
  { kind: "varDecl", localId: baseLocal.id, init: base, loc },
3706
- { kind: "varDecl", localId: clsLocal.id, init: { ...value, captures: info.localClass.captureSources }, loc },
3707
- { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classInherit", args: [boxed, baseRef], type: DYN, loc }, loc },
3708
- { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classPrototype", args: [boxed,
4207
+ {
4208
+ kind: "varDecl",
4209
+ localId: clsLocal.id,
4210
+ init: { ...value, captures: info.localClass.captureSources },
4211
+ loc,
4212
+ },
4213
+ {
4214
+ kind: "exprStmt",
4215
+ expr: { kind: "libCall", fn: "dyn.classInherit", args: [boxed, baseRef], type: DYN, loc },
4216
+ loc,
4217
+ },
4218
+ {
4219
+ kind: "exprStmt",
4220
+ expr: {
4221
+ kind: "libCall",
4222
+ fn: "dyn.classPrototype",
4223
+ args: [
4224
+ boxed,
3709
4225
  { kind: "libCall", fn: "dyn.classBasePrototype", args: [baseRef], type: DYN, loc },
3710
- ], type: DYN, loc }, loc },
3711
- ], result: clsRef, type: value.type, loc });
4226
+ ],
4227
+ type: DYN,
4228
+ loc,
4229
+ },
4230
+ loc,
4231
+ },
4232
+ ],
4233
+ result: clsRef,
4234
+ type: value.type,
4235
+ loc,
4236
+ });
3712
4237
  }
3713
4238
  if (info.localClass?.baseExpression && info.base && value.kind === "classRef") {
3714
4239
  const loc = locOf(expr);
3715
- const base = lowerer.lowerExprExpecting(info.localClass.baseExpression, { kind: "classval", className: info.base.def.name });
4240
+ const base = lowerer.lowerExprExpecting(info.localClass.baseExpression, {
4241
+ kind: "classval",
4242
+ className: info.base.def.name,
4243
+ });
3716
4244
  const baseLocal = lowerer.declareHiddenLocal("%classBase", base.type);
3717
4245
  baseLocal.boxed = true;
3718
4246
  const clsLocal = lowerer.declareHiddenLocal("%classValue", value.type);
@@ -3720,26 +4248,57 @@ export function lowerClassExpression(lowerer, expr) {
3720
4248
  const clsRef = { kind: "varRef", localId: clsLocal.id, type: value.type, loc };
3721
4249
  const basePrototype = classPrototypeData(lowerer, info.base, loc, baseRef);
3722
4250
  info.localPrototypeData = true;
3723
- return initializeRuntimeStatics(lowerer, info, { kind: "seqExpr", stmts: [
4251
+ return initializeRuntimeStatics(lowerer, info, {
4252
+ kind: "seqExpr",
4253
+ stmts: [
3724
4254
  { kind: "varDecl", localId: baseLocal.id, init: base, loc },
3725
- { kind: "varDecl", localId: clsLocal.id, init: { ...value, captures: [...info.localClass.captureSources, baseLocal.id] }, loc },
3726
- { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classInherit", args: [
3727
- { kind: "dynFrom", value: clsRef, type: DYN, loc }, { kind: "dynFrom", value: baseRef, type: DYN, loc },
3728
- ], type: DYN, loc }, loc },
3729
- { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classPrototype", args: [
3730
- { kind: "dynFrom", value: clsRef, type: DYN, loc }, basePrototype,
3731
- ], type: DYN, loc }, loc },
3732
- ], result: clsRef, type: value.type, loc });
3733
- }
3734
- return info.localClass ? initializeRuntimeStatics(lowerer, info, value.kind === "classRef"
3735
- ? { ...value, captures: info.localClass.captureSources } : value) : value;
4255
+ {
4256
+ kind: "varDecl",
4257
+ localId: clsLocal.id,
4258
+ init: { ...value, captures: [...info.localClass.captureSources, baseLocal.id] },
4259
+ loc,
4260
+ },
4261
+ {
4262
+ kind: "exprStmt",
4263
+ expr: {
4264
+ kind: "libCall",
4265
+ fn: "dyn.classInherit",
4266
+ args: [
4267
+ { kind: "dynFrom", value: clsRef, type: DYN, loc },
4268
+ { kind: "dynFrom", value: baseRef, type: DYN, loc },
4269
+ ],
4270
+ type: DYN,
4271
+ loc,
4272
+ },
4273
+ loc,
4274
+ },
4275
+ {
4276
+ kind: "exprStmt",
4277
+ expr: {
4278
+ kind: "libCall",
4279
+ fn: "dyn.classPrototype",
4280
+ args: [{ kind: "dynFrom", value: clsRef, type: DYN, loc }, basePrototype],
4281
+ type: DYN,
4282
+ loc,
4283
+ },
4284
+ loc,
4285
+ },
4286
+ ],
4287
+ result: clsRef,
4288
+ type: value.type,
4289
+ loc,
4290
+ });
4291
+ }
4292
+ return info.localClass
4293
+ ? initializeRuntimeStatics(lowerer, info, value.kind === "classRef" ? { ...value, captures: info.localClass.captureSources } : value)
4294
+ : value;
3736
4295
  }
3737
4296
  /** The EXACT class a receiver expression is statically known to BE (not
3738
- * merely be typed by): the class name itself, or a `const` binding
3739
- * whose initializer is a class expression / class name. Such receivers
3740
- * can never hold a subclass at runtime, so static WRITES through them
3741
- * hit the declaring class's storage exactly (the shadowing hazards of
3742
- * general class values don't arise). Null for everything else. */
4297
+ * merely be typed by): the class name itself, or a `const` binding
4298
+ * whose initializer is a class expression / class name. Such receivers
4299
+ * can never hold a subclass at runtime, so static WRITES through them
4300
+ * hit the declaring class's storage exactly (the shadowing hazards of
4301
+ * general class values don't arise). Null for everything else. */
3743
4302
  export function exactClassOfReceiver(lowerer, expr) {
3744
4303
  if (ts.isPropertyAccessExpression(expr) && !expr.questionDotToken) {
3745
4304
  const member = nsMemberIdentOf(lowerer, expr);
@@ -3750,7 +4309,9 @@ export function exactClassOfReceiver(lowerer, expr) {
3750
4309
  // receiver specialization; ordinary instance this remains an object.
3751
4310
  if (expr.kind === ts.SyntaxKind.ThisKeyword) {
3752
4311
  const receiver = lowerer.resolveThis();
3753
- return receiver?.type.kind === "classval" ? lowerer.classes.get(receiver.type.className) ?? null : null;
4312
+ return receiver?.type.kind === "classval"
4313
+ ? (lowerer.classes.get(receiver.type.className) ?? null)
4314
+ : null;
3754
4315
  }
3755
4316
  if (!ts.isIdentifier(expr))
3756
4317
  return null;
@@ -3765,7 +4326,9 @@ export function exactClassOfReceiver(lowerer, expr) {
3765
4326
  if (direct)
3766
4327
  return direct.classDecorators?.valueGlobalId !== undefined ? null : direct;
3767
4328
  const decl = lowerer.checker.valueDeclarationOf(symbol);
3768
- if (!decl || !ts.isVariableDeclaration(decl) || decl.initializer === undefined ||
4329
+ if (!decl ||
4330
+ !ts.isVariableDeclaration(decl) ||
4331
+ decl.initializer === undefined ||
3769
4332
  !ts.isVariableDeclarationList(decl.parent) ||
3770
4333
  (decl.parent.flags & ts.NodeFlags.Const) === 0) {
3771
4334
  return null;
@@ -3785,20 +4348,20 @@ export function exactClassOfReceiver(lowerer, expr) {
3785
4348
  return null;
3786
4349
  }
3787
4350
  /** The class a PROPERTY-ASSIGNMENT binding pins — the salsa/CJS
3788
- * declaration forms of a class expression: `Common.I = class {…}`
3789
- * (expando members of a plain object), `exports.I = class {…}` /
3790
- * `module.exports.I = class {…}` (CJS member exports), and
3791
- * `module.exports = class {…}` (the whole-export replacement, whose
3792
- * export symbol requirer bindings alias to). The symbol arrives in two
3793
- * shapes — an ALIAS resolving to the class expression's own symbol
3794
- * (valueDeclaration IS the ts.ClassExpression), or the expando property
3795
- * symbol whose declarations are the assignment BinaryExpressions — and
3796
- * both pin the class exactly when ONE top-level assignment declares it:
3797
- * a reassigned property is a dynamic binding (the runtime class is
3798
- * whichever assignment ran last), so it answers null and the caller's
3799
- * fence names it. Collection is on demand and idempotent
3800
- * (lowerClassExpressionInfo), so resolution order between files and
3801
- * passes never matters. */
4351
+ * declaration forms of a class expression: `Common.I = class {…}`
4352
+ * (expando members of a plain object), `exports.I = class {…}` /
4353
+ * `module.exports.I = class {…}` (CJS member exports), and
4354
+ * `module.exports = class {…}` (the whole-export replacement, whose
4355
+ * export symbol requirer bindings alias to). The symbol arrives in two
4356
+ * shapes — an ALIAS resolving to the class expression's own symbol
4357
+ * (valueDeclaration IS the ts.ClassExpression), or the expando property
4358
+ * symbol whose declarations are the assignment BinaryExpressions — and
4359
+ * both pin the class exactly when ONE top-level assignment declares it:
4360
+ * a reassigned property is a dynamic binding (the runtime class is
4361
+ * whichever assignment ran last), so it answers null and the caller's
4362
+ * fence names it. Collection is on demand and idempotent
4363
+ * (lowerClassExpressionInfo), so resolution order between files and
4364
+ * passes never matters. */
3802
4365
  export function propertyAssignedClassInfoOf(lowerer, symbol) {
3803
4366
  if (!symbol)
3804
4367
  return null;
@@ -3840,22 +4403,25 @@ export function propertyAssignedClassInfoOf(lowerer, symbol) {
3840
4403
  return info;
3841
4404
  }
3842
4405
  /** The top-level `… = <this class expression>` assignment a class
3843
- * expression is the (paren-unwrapped) RHS of, or null. */
4406
+ * expression is the (paren-unwrapped) RHS of, or null. */
3844
4407
  function enclosingTopLevelClassAssignment(expr) {
3845
4408
  let value = expr;
3846
4409
  while (ts.isParenthesizedExpression(value.parent))
3847
4410
  value = value.parent;
3848
4411
  const p = value.parent;
3849
- if (!ts.isBinaryExpression(p) || p.operatorToken.kind !== ts.SyntaxKind.EqualsToken ||
3850
- p.right !== value || !ts.isExpressionStatement(p.parent) || !ts.isSourceFile(p.parent.parent)) {
4412
+ if (!ts.isBinaryExpression(p) ||
4413
+ p.operatorToken.kind !== ts.SyntaxKind.EqualsToken ||
4414
+ p.right !== value ||
4415
+ !ts.isExpressionStatement(p.parent) ||
4416
+ !ts.isSourceFile(p.parent.parent)) {
3851
4417
  return null;
3852
4418
  }
3853
4419
  return p;
3854
4420
  }
3855
4421
  /** How many top-level statements of the file assign the same target as
3856
- * `assign` (textual LHS match — `module.exports`, `exports.I`,
3857
- * `Common.I`): a second assignment makes the binding dynamic, so
3858
- * callers refuse to pin the first one's class. */
4422
+ * `assign` (textual LHS match — `module.exports`, `exports.I`,
4423
+ * `Common.I`): a second assignment makes the binding dynamic, so
4424
+ * callers refuse to pin the first one's class. */
3859
4425
  function countAssignmentsTo(assign) {
3860
4426
  const sf = assign.getSourceFile();
3861
4427
  // `exports.I` and `module.exports.I` are the SAME binding in Node
@@ -3871,7 +4437,8 @@ function countAssignmentsTo(assign) {
3871
4437
  if (!ts.isExpressionStatement(stmt))
3872
4438
  continue;
3873
4439
  const e = stmt.expression;
3874
- if (ts.isBinaryExpression(e) && e.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
4440
+ if (ts.isBinaryExpression(e) &&
4441
+ e.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
3875
4442
  canon(e.left) === target) {
3876
4443
  n++;
3877
4444
  }
@@ -3879,14 +4446,14 @@ function countAssignmentsTo(assign) {
3879
4446
  return n;
3880
4447
  }
3881
4448
  /** `C.m(args)` / `X.m(args)` — static method calls, on the class name
3882
- * directly or through a class VALUE. Resolution walks the chain
3883
- * (nearest declarer, the compile-time prototype chain); through a
3884
- * VALUE the call devirtualizes exactly when no strict descendant
3885
- * redeclares the member (values never leave the static class's
3886
- * subtree). A func-typed static FIELD in call position reads the
3887
- * global and calls through the value. Null when the receiver isn't a
3888
- * class name/value or the member doesn't resolve (the fences name the
3889
- * site downstream). */
4449
+ * directly or through a class VALUE. Resolution walks the chain
4450
+ * (nearest declarer, the compile-time prototype chain); through a
4451
+ * VALUE the call devirtualizes exactly when no strict descendant
4452
+ * redeclares the member (values never leave the static class's
4453
+ * subtree). A func-typed static FIELD in call position reads the
4454
+ * global and calls through the value. Null when the receiver isn't a
4455
+ * class name/value or the member doesn't resolve (the fences name the
4456
+ * site downstream). */
3890
4457
  export function lowerStaticMethodCall(lowerer, call, access) {
3891
4458
  if (access.questionDotToken)
3892
4459
  return null;
@@ -3896,11 +4463,25 @@ export function lowerStaticMethodCall(lowerer, call, access) {
3896
4463
  if (info)
3897
4464
  return staticCallOn(lowerer, call, access, info, false);
3898
4465
  }
4466
+ // Namespace exports are immutable bindings to the same declaration as
4467
+ // named imports. Resolve them before asking for a constructor-value ABI:
4468
+ // a generic family has statics but no single constructor signature.
4469
+ if (ts.isPropertyAccessExpression(access.expression) && !access.expression.questionDotToken) {
4470
+ const member = nsMemberIdentOf(lowerer, access.expression);
4471
+ const symbol = member ? lowerer.resolveValueSymbol(member) : null;
4472
+ const info = symbol ? lowerer.classBySymbol.get(symbol) : undefined;
4473
+ if (info && info.classDecorators?.valueGlobalId === undefined) {
4474
+ if (symbol)
4475
+ fenceEarlyNsMemberRef(lowerer, access.expression, symbol);
4476
+ return staticCallOn(lowerer, call, access, info, false);
4477
+ }
4478
+ }
3899
4479
  // `module.exports.describe()` in a module whose whole export IS a
3900
4480
  // class expression: the receiver is exactly that class (the kept
3901
4481
  // export assignment pins it) — the direct-name rules apply.
3902
4482
  if (!ts.isIdentifier(access.expression)) {
3903
- if (!isModuleExportsAccess(access.expression) || !isCjsJsFile(access.getSourceFile(), lowerer.program)) {
4483
+ if (!isModuleExportsAccess(access.expression) ||
4484
+ !isCjsJsFile(access.getSourceFile(), lowerer.program)) {
3904
4485
  let receiverType = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
3905
4486
  if (receiverType?.kind !== "classval" && isJsSourceFile(call.getSourceFile())) {
3906
4487
  const receiver = tryLowerExpression(lowerer, access.expression);
@@ -3919,8 +4500,13 @@ export function lowerStaticMethodCall(lowerer, call, access) {
3919
4500
  // A typed checker projection cannot turn a replaced field into a call
3920
4501
  // to the class that originally occupied it.
3921
4502
  const receiver = lowerer.lowerExprExpecting(access.expression, receiverType);
3922
- return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: receiver, loc: locOf(access.expression) }],
3923
- result, type: result.type, loc: locOf(call) };
4503
+ return {
4504
+ kind: "seqExpr",
4505
+ stmts: [{ kind: "exprStmt", expr: receiver, loc: locOf(access.expression) }],
4506
+ result,
4507
+ type: result.type,
4508
+ loc: locOf(call),
4509
+ };
3924
4510
  }
3925
4511
  const whole = cjsClassExprWholeExportOf(access.getSourceFile());
3926
4512
  if (!whole)
@@ -3949,31 +4535,42 @@ export function lowerStaticMethodCall(lowerer, call, access) {
3949
4535
  return staticCallOn(lowerer, call, access, info, throughValue);
3950
4536
  }
3951
4537
  /** True when a class-VALUE receiver can only hold `info`'s own class
3952
- * object at runtime: the receiver provably IS the class
3953
- * (exactClassOfReceiver — the name, or a const bound to the class
3954
- * expression / class name), or `info` is a LEAF class, so no strict
3955
- * descendant exists to flow into the slot (the static-write path's
3956
- * rule — a rebindable decorated name rides this arm, since replacement
3957
- * decorators fence any class with subclasses before minting the
3958
- * rebindable global). Exactly then a #private static access through
3959
- * the value always carries the declaring class's brand — Node's
3960
- * TypeError cannot arise. */
4538
+ * object at runtime: the receiver provably IS the class
4539
+ * (exactClassOfReceiver — the name, or a const bound to the class
4540
+ * expression / class name), or `info` is a LEAF class, so no strict
4541
+ * descendant exists to flow into the slot (the static-write path's
4542
+ * rule — a rebindable decorated name rides this arm, since replacement
4543
+ * decorators fence any class with subclasses before minting the
4544
+ * rebindable global). Exactly then a #private static access through
4545
+ * the value always carries the declaring class's brand — Node's
4546
+ * TypeError cannot arise. */
3961
4547
  function classValueIsExactlyOwn(lowerer, recv, info) {
3962
4548
  return exactClassOfReceiver(lowerer, recv) === info || info.subclasses.length === 0;
3963
4549
  }
3964
4550
  function staticCallOn(lowerer, call, access, info, throughValue) {
3965
4551
  const loc = locOf(call);
3966
- if (hasRuntimeStatics(info) && !findStaticOn(lowerer, info, access.name.text)?.field || info.callableBase && !findStaticOn(lowerer, info, access.name.text) && !findGenericStaticOn(lowerer, info, access.name.text))
3967
- return { kind: "dynInvoke", recv: lowerer.lowerExprExpecting(access.expression, DYN),
3968
- method: access.name.text, calleeName: access.name.text,
3969
- args: call.arguments.map((argument) => lowerer.lowerExprExpecting(argument, DYN)), type: DYN, loc };
4552
+ if ((hasRuntimeStatics(info) && !findStaticOn(lowerer, info, access.name.text)?.field) ||
4553
+ (info.callableBase &&
4554
+ !findStaticOn(lowerer, info, access.name.text) &&
4555
+ !findGenericStaticOn(lowerer, info, access.name.text)))
4556
+ return {
4557
+ kind: "dynInvoke",
4558
+ recv: lowerer.lowerExprExpecting(access.expression, DYN),
4559
+ method: access.name.text,
4560
+ calleeName: access.name.text,
4561
+ args: call.arguments.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
4562
+ type: DYN,
4563
+ loc,
4564
+ };
3970
4565
  // #private statics: through-a-VALUE receiver the call devirtualizes
3971
4566
  // exactly when the value can only BE the declaring class
3972
4567
  // (classValueIsExactlyOwn — a slot that could hold a descendant at
3973
4568
  // runtime fences, since only the declaring class object carries the
3974
4569
  // brand in JS), and the direct spelling resolves only on the
3975
4570
  // declaring class itself — `D.#s` is Node's TypeError.
3976
- if (access.name.text.startsWith("#") && throughValue && !classValueIsExactlyOwn(lowerer, access.expression, info)) {
4571
+ if (access.name.text.startsWith("#") &&
4572
+ throughValue &&
4573
+ !classValueIsExactlyOwn(lowerer, access.expression, info)) {
3977
4574
  lowerer.unsupported("SC1090", call, `calling the private static '${access.name.text}' through a class value (JS brands the declaring class object alone — call it through the class's own name)`);
3978
4575
  }
3979
4576
  const found = findStaticOn(lowerer, info, access.name.text);
@@ -3987,14 +4584,14 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
3987
4584
  const gfound = findGenericStaticOn(lowerer, info, access.name.text);
3988
4585
  if (!gfound)
3989
4586
  return null;
3990
- if (throughValue && staticShadowBelow(lowerer, info, access.name.text)) {
4587
+ if (throughValue && staticShadowBelow(info, access.name.text)) {
3991
4588
  lowerer.unsupported("SC1090", call, `calling the static member '${access.name.text}' through a class value (a subclass of '${info.def.name.replace(/^%|^%m\d+\./, "")}' redeclares it, so the runtime class decides which declaration answers)`);
3992
4589
  }
3993
4590
  const instance = genericCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, gfound.info, info, throughValue));
3994
4591
  const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
3995
4592
  return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
3996
4593
  }
3997
- if (throughValue && staticShadowBelow(lowerer, info, access.name.text)) {
4594
+ if (throughValue && staticShadowBelow(info, access.name.text)) {
3998
4595
  lowerer.unsupported("SC1090", call, `calling the static member '${access.name.text}' through a class value (a subclass of '${info.def.name.replace(/^%|^%m\d+\./, "")}' redeclares it, so the runtime class decides which declaration answers)`);
3999
4596
  }
4000
4597
  const specialized = findGenericStaticOn(lowerer, info, access.name.text);
@@ -4008,7 +4605,12 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
4008
4605
  // call through the value (the ctor-assigned-callback pattern).
4009
4606
  if (found.field.type.kind !== "func")
4010
4607
  return null;
4011
- const callee = { kind: "varRef", localId: found.field.globalId, type: found.field.type, loc };
4608
+ const callee = {
4609
+ kind: "varRef",
4610
+ localId: found.field.globalId,
4611
+ type: found.field.type,
4612
+ loc,
4613
+ };
4012
4614
  const params = found.field.type.params;
4013
4615
  const args = call.arguments.map((a, i) => lowerer.lowerExprExpecting(a, params[i]));
4014
4616
  for (let i = args.length; i < params.length; i++) {
@@ -4018,17 +4620,32 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
4018
4620
  }
4019
4621
  args.push(absent);
4020
4622
  }
4021
- return { kind: "callValue", callee, receiver: lowerer.lowerExprExpecting(access.expression, DYN), args, type: found.field.type.ret, loc };
4623
+ return {
4624
+ kind: "callValue",
4625
+ callee,
4626
+ receiver: lowerer.lowerExprExpecting(access.expression, DYN),
4627
+ args,
4628
+ type: found.field.type.ret,
4629
+ loc,
4630
+ };
4022
4631
  }
4023
4632
  if (found.method.member.body && hasStaticThis(found.method.member)) {
4024
- const generic = found.method.receiverInfo ??= {
4025
- decl: found.method.member, baseName: access.name.text,
4633
+ const generic = (found.method.receiverInfo ??= {
4634
+ decl: found.method.member,
4635
+ baseName: access.name.text,
4026
4636
  qualifiedName: `%${found.declarer.def.name}.static:${access.name.text}`,
4027
- typeParams: [], instances: new Map(), member: { cls: found.declarer, kind: "static" },
4028
- };
4637
+ typeParams: [],
4638
+ instances: new Map(),
4639
+ member: { cls: found.declarer, kind: "static" },
4640
+ });
4029
4641
  const instance = genericCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, generic, info, throughValue));
4030
- return { kind: "call", callee: instance.name,
4031
- args: lowerer.completeArgs(call.arguments, instance.params, loc, call), type: instance.returnType, loc };
4642
+ return {
4643
+ kind: "call",
4644
+ callee: instance.name,
4645
+ args: lowerer.completeArgs(call.arguments, instance.params, loc, call),
4646
+ type: instance.returnType,
4647
+ loc,
4648
+ };
4032
4649
  }
4033
4650
  const fnName = `%${found.declarer.def.name}.static:${access.name.text}`;
4034
4651
  lowerer.noteEdge(fnName);
@@ -4047,22 +4664,27 @@ function staticMethodForReceiver(lowerer, access, method, receiver, throughValue
4047
4664
  if (throughValue && !classValueIsExactlyOwn(lowerer, access.expression, receiver)) {
4048
4665
  lowerer.unsupported("SC1090", access, "receiver-dependent static methods through a polymorphic class value");
4049
4666
  }
4050
- const instances = method.receiverSpecializations ??= new Map();
4667
+ const instances = (method.receiverSpecializations ??= new Map());
4051
4668
  let specialized = instances.get(receiver.def.name);
4052
4669
  if (!specialized) {
4053
- specialized = { ...method, qualifiedName: `${method.qualifiedName}%on.${receiver.def.name}`,
4054
- instances: new Map(), staticReceiver: receiver, receiverSpecializations: new Map() };
4670
+ specialized = {
4671
+ ...method,
4672
+ qualifiedName: `${method.qualifiedName}%on.${receiver.def.name}`,
4673
+ instances: new Map(),
4674
+ staticReceiver: receiver,
4675
+ receiverSpecializations: new Map(),
4676
+ };
4055
4677
  instances.set(receiver.def.name, specialized);
4056
4678
  }
4057
4679
  return specialized;
4058
4680
  }
4059
4681
  /** Static member access through a class VALUE (`X.m` where X is
4060
- * classval-typed): devirtualized — the member resolves against the
4061
- * static class's chain, exact when no strict descendant redeclares it
4062
- * (values in the slot never leave the subtree). `X.name` is the one
4063
- * genuinely dynamic member: the class.name libCall reads the runtime
4064
- * class object's stored name. Null when the receiver isn't a class
4065
- * value or the member doesn't resolve. */
4682
+ * classval-typed): devirtualized — the member resolves against the
4683
+ * static class's chain, exact when no strict descendant redeclares it
4684
+ * (values in the slot never leave the subtree). `X.name` is the one
4685
+ * genuinely dynamic member: the class.name libCall reads the runtime
4686
+ * class object's stored name. Null when the receiver isn't a class
4687
+ * value or the member doesn't resolve. */
4066
4688
  export function lowerClassValueProperty(lowerer, expr) {
4067
4689
  if (expr.questionDotToken)
4068
4690
  return null;
@@ -4072,9 +4694,16 @@ export function lowerClassValueProperty(lowerer, expr) {
4072
4694
  const loc = locOf(expr);
4073
4695
  const member = expr.name.text;
4074
4696
  const info = lowerer.classes.get(recvT.className);
4075
- if (info && (hasRuntimeStatics(info) && !findStaticOn(lowerer, info, member)?.field || info.callableBase && !findStaticOn(lowerer, info, member)))
4076
- return { kind: "dynKeyGet", value: lowerer.lowerExprExpecting(expr.expression, DYN),
4077
- key: { kind: "strLit", value: member, type: STRING, loc }, type: DYN, loc };
4697
+ if (info &&
4698
+ ((hasRuntimeStatics(info) && !findStaticOn(lowerer, info, member)?.field) ||
4699
+ (info.callableBase && !findStaticOn(lowerer, info, member))))
4700
+ return {
4701
+ kind: "dynKeyGet",
4702
+ value: lowerer.lowerExprExpecting(expr.expression, DYN),
4703
+ key: { kind: "strLit", value: member, type: STRING, loc },
4704
+ type: DYN,
4705
+ loc,
4706
+ };
4078
4707
  // `X.name` reads the RUNTIME class object's stored name — the one
4079
4708
  // genuinely dynamic member. It CONSUMES the receiver (no evaluation
4080
4709
  // is discarded), so any receiver expression is fine here.
@@ -4119,7 +4748,7 @@ export function lowerClassValueProperty(lowerer, expr) {
4119
4748
  lowerer.unsupported("SC1090", expr, `reading the private static '${member}' through the subclass '${info.def.name.replace(/^%|^%m\d+\./, "")}' (JS brands the declaring class object alone — Node throws a TypeError here; spell the declaring class's name)`);
4120
4749
  }
4121
4750
  }
4122
- if (staticShadowBelow(lowerer, info, member)) {
4751
+ if (staticShadowBelow(info, member)) {
4123
4752
  lowerer.unsupported("SC1090", expr, `reading the static member '${member}' through a class value (a subclass of '${info.def.name.replace(/^%|^%m\d+\./, "")}' redeclares it, so the runtime class decides which declaration answers)`);
4124
4753
  }
4125
4754
  if (found.field !== undefined) {
@@ -4128,18 +4757,21 @@ export function lowerClassValueProperty(lowerer, expr) {
4128
4757
  return staticMethodValue(lowerer, found.declarer, member, found.method, expr, loc);
4129
4758
  }
4130
4759
  /** An abstract method's signature — lambdaSignature minus the body check
4131
- * (an abstract declaration IS exactly a signature; tsc rejects the
4132
- * async/generator/generic-with-body combinations before this runs, and
4133
- * the generic case fences at the caller). */
4760
+ * (an abstract declaration IS exactly a signature; tsc rejects the
4761
+ * async/generator/generic-with-body combinations before this runs, and
4762
+ * the generic case fences at the caller). */
4134
4763
  function abstractMemberSignature(lowerer, member) {
4135
4764
  for (const param of member.parameters) {
4136
4765
  if (!ts.isIdentifier(param.name))
4137
4766
  lowerer.unsupported("SC1031", param);
4138
4767
  }
4139
- return { shapes: lowerer.paramShapes(member.parameters), ret: lowerer.declaredReturnType(member, member.name) };
4768
+ return {
4769
+ shapes: lowerer.paramShapes(member.parameters),
4770
+ ret: lowerer.declaredReturnType(member, member.name),
4771
+ };
4140
4772
  }
4141
4773
  /** The nearest declaration of `name` at or above `info` — the method a
4142
- * receiver of that static class runs when nothing below overrides it. */
4774
+ * receiver of that static class runs when nothing below overrides it. */
4143
4775
  export function findMethodOn(lowerer, info, name) {
4144
4776
  for (let c = info; c; c = c.base) {
4145
4777
  const sig = c.methods.get(name);
@@ -4150,15 +4782,21 @@ export function findMethodOn(lowerer, info, name) {
4150
4782
  }
4151
4783
  /** True when `sub` is a STRICT descendant of `sup` in the class graph. */
4152
4784
  export function isSubclassOf(lowerer, sub, sup) {
4153
- for (let c = lowerer.classes.get(sub)?.base ?? null; c; c = c.base) {
4154
- if (c.def.name === sup)
4785
+ if (sub === sup)
4786
+ return false;
4787
+ for (let c = lowerer.classes.get(sub); c; c = c.base ?? undefined) {
4788
+ if (c.def.name === sup && c.def.name !== sub)
4155
4789
  return true;
4790
+ for (let family = c.genericInstance?.family; family; family = family.base ?? undefined) {
4791
+ if (family.def.name === sup)
4792
+ return true;
4793
+ }
4156
4794
  }
4157
4795
  return false;
4158
4796
  }
4159
4797
  /** In an extends-hierarchy (as base or derived): the class carries a
4160
- * vtable and participates in dynamic instanceof; standalone classes keep
4161
- * their exact pre-inheritance layout and behavior. */
4798
+ * vtable and participates in dynamic instanceof; standalone classes keep
4799
+ * their exact pre-inheritance layout and behavior. */
4162
4800
  export function inHierarchy(lowerer, info) {
4163
4801
  // The runtime emitter class is ALWAYS a hierarchy member: ScrEmitter
4164
4802
  // carries its vtable word whether or not the program subclasses it
@@ -4166,10 +4804,10 @@ export function inHierarchy(lowerer, info) {
4166
4804
  return info.base !== null || info.subclasses.length > 0 || info.builtinEmitter === true;
4167
4805
  }
4168
4806
  /** True when some STRICT descendant of `info` declares `name` with a BODY
4169
- * — the whole-program devirtualization test: a call through this static
4170
- * class can reach a distinct implementation, so it must dispatch
4171
- * dynamically. Abstract re-declarations don't count (they carry no
4172
- * implementation; the concrete ones below them do, via the recursion). */
4807
+ * — the whole-program devirtualization test: a call through this static
4808
+ * class can reach a distinct implementation, so it must dispatch
4809
+ * dynamically. Abstract re-declarations don't count (they carry no
4810
+ * implementation; the concrete ones below them do, via the recursion). */
4173
4811
  export function overrideBelow(lowerer, info, name) {
4174
4812
  return info.subclasses.some((s) => {
4175
4813
  const m = s.methods.get(name);
@@ -4177,7 +4815,7 @@ export function overrideBelow(lowerer, info, name) {
4177
4815
  });
4178
4816
  }
4179
4817
  /** The nearest GENERIC-method declaration of `name` at/above `info` —
4180
- * findMethodOn's twin over the genericMethods tables. */
4818
+ * findMethodOn's twin over the genericMethods tables. */
4181
4819
  export function findGenericMethodOn(lowerer, info, name) {
4182
4820
  for (let c = info; c; c = c.base) {
4183
4821
  const gm = c.genericMethods?.get(name);
@@ -4187,11 +4825,11 @@ export function findGenericMethodOn(lowerer, info, name) {
4187
4825
  return null;
4188
4826
  }
4189
4827
  /** True when some STRICT descendant of `info` re-declares the generic
4190
- * method `name` — overrideBelow's twin: generic methods have no vtable
4191
- * slot, so a call that could reach an override compiles only when the
4192
- * receiver's runtime class is statically exact. */
4193
- export function genericOverrideBelow(lowerer, info, name) {
4194
- return info.subclasses.some((s) => s.genericMethods?.has(name) === true || genericOverrideBelow(lowerer, s, name));
4828
+ * method `name` — overrideBelow's twin: generic methods have no vtable
4829
+ * slot, so a call that could reach an override compiles only when the
4830
+ * receiver's runtime class is statically exact. */
4831
+ export function genericOverrideBelow(info, name) {
4832
+ return info.subclasses.some((s) => s.genericMethods?.has(name) === true || genericOverrideBelow(s, name));
4195
4833
  }
4196
4834
  /** Discover inherited data writes before any base storage ABI is chosen.
4197
4835
  * The checker does not widen a base field for assignments in JS subclasses. */
@@ -4200,7 +4838,8 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
4200
4838
  if (!isJsSourceFile(file))
4201
4839
  continue;
4202
4840
  ts.walkPreorder(file, (node) => {
4203
- if ((!ts.isClassDeclaration(node) && !ts.isClassExpression(node)) || !node.heritageClauses?.length)
4841
+ if ((!ts.isClassDeclaration(node) && !ts.isClassExpression(node)) ||
4842
+ !node.heritageClauses?.length)
4204
4843
  return;
4205
4844
  const writes = new Map();
4206
4845
  const addWrite = (name, expression) => {
@@ -4211,14 +4850,17 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
4211
4850
  writes.set(name, [expression]);
4212
4851
  };
4213
4852
  const scan = (part) => {
4214
- if (ts.isClassDeclaration(part) || ts.isClassExpression(part) ||
4215
- ts.isFunctionLike(part) && !ts.isArrowFunction(part))
4853
+ if (ts.isClassDeclaration(part) ||
4854
+ ts.isClassExpression(part) ||
4855
+ (ts.isFunctionLike(part) && !ts.isArrowFunction(part)))
4216
4856
  return;
4217
4857
  if (ts.isBinaryExpression(part) && part.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
4218
4858
  const left = part.left;
4219
- if (ts.isPropertyAccessExpression(left) && left.expression.kind === ts.SyntaxKind.ThisKeyword)
4859
+ if (ts.isPropertyAccessExpression(left) &&
4860
+ left.expression.kind === ts.SyntaxKind.ThisKeyword)
4220
4861
  addWrite(left.name.text, part.right);
4221
- else if (ts.isElementAccessExpression(left) && left.expression.kind === ts.SyntaxKind.ThisKeyword) {
4862
+ else if (ts.isElementAccessExpression(left) &&
4863
+ left.expression.kind === ts.SyntaxKind.ThisKeyword) {
4222
4864
  const name = lowerer.foldedStringKeyOf(left.argumentExpression);
4223
4865
  if (name !== null)
4224
4866
  addWrite(name, part.right);
@@ -4230,12 +4872,16 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
4230
4872
  if (member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))
4231
4873
  continue;
4232
4874
  if (ts.isPropertyDeclaration(member) && member.initializer) {
4233
- const name = ts.isPrivateIdentifier(member.name) ? null : classMemberNameOf(lowerer, member.name);
4875
+ const name = ts.isPrivateIdentifier(member.name)
4876
+ ? null
4877
+ : classMemberNameOf(lowerer, member.name);
4234
4878
  if (name !== null)
4235
4879
  addWrite(name, member.initializer);
4236
4880
  scan(member.initializer);
4237
4881
  }
4238
- if (ts.isConstructorDeclaration(member) || ts.isMethodDeclaration(member) || ts.isAccessor(member)) {
4882
+ if (ts.isConstructorDeclaration(member) ||
4883
+ ts.isMethodDeclaration(member) ||
4884
+ ts.isAccessor(member)) {
4239
4885
  if (member.body)
4240
4886
  scan(member.body);
4241
4887
  }
@@ -4259,11 +4905,13 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
4259
4905
  let owner = declaration.parent;
4260
4906
  while (owner && !ts.isClassDeclaration(owner) && !ts.isClassExpression(owner))
4261
4907
  owner = owner.parent;
4262
- if (!owner || (!ts.isClassDeclaration(owner) && !ts.isClassExpression(owner)) || !isJsSourceFile(owner.getSourceFile()))
4908
+ if (!owner ||
4909
+ (!ts.isClassDeclaration(owner) && !ts.isClassExpression(owner)) ||
4910
+ !isJsSourceFile(owner.getSourceFile()))
4263
4911
  continue;
4264
4912
  let fields = lowerer.inheritedJsFieldWrites.get(owner);
4265
4913
  if (!fields)
4266
- lowerer.inheritedJsFieldWrites.set(owner, fields = new Map());
4914
+ lowerer.inheritedJsFieldWrites.set(owner, (fields = new Map()));
4267
4915
  const existing = fields.get(name);
4268
4916
  if (existing)
4269
4917
  existing.push(...expressions);
@@ -4292,24 +4940,35 @@ export function collectVirtualJsMethods(lowerer, files) {
4292
4940
  ts.walkPreorder(file, (node) => {
4293
4941
  if (!ts.isPropertyAccessExpression(node) && !ts.isElementAccessExpression(node))
4294
4942
  return;
4295
- const name = ts.isPropertyAccessExpression(node) ? node.name.text
4296
- : ts.isStringLiteralLike(node.argumentExpression) ? node.argumentExpression.text : null;
4943
+ const name = ts.isPropertyAccessExpression(node)
4944
+ ? node.name.text
4945
+ : ts.isStringLiteralLike(node.argumentExpression)
4946
+ ? node.argumentExpression.text
4947
+ : null;
4297
4948
  if (name === null)
4298
4949
  return;
4299
4950
  const prototype = ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "prototype";
4300
- const assigned = ts.isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken;
4301
- const symbol = !assigned ? undefined : ts.isPropertyAccessExpression(node)
4302
- ? lowerer.checker.getSymbolAtLocation(node.name)
4303
- : lowerer.checker.getPropertyOfType(lowerer.typeOf(node.expression), name);
4304
- if (prototype || symbol && lowerer.checker.declarationsOf(symbol).some(ts.isMethodDeclaration)) {
4951
+ const assigned = ts.isBinaryExpression(node.parent) &&
4952
+ node.parent.left === node &&
4953
+ node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken;
4954
+ const symbol = !assigned
4955
+ ? undefined
4956
+ : ts.isPropertyAccessExpression(node)
4957
+ ? lowerer.checker.getSymbolAtLocation(node.name)
4958
+ : lowerer.checker.getPropertyOfType(lowerer.typeOf(node.expression), name);
4959
+ if (prototype ||
4960
+ (symbol && lowerer.checker.declarationsOf(symbol).some(ts.isMethodDeclaration))) {
4305
4961
  lowerer.prototypeMethodAccesses.set(name, node);
4306
4962
  }
4307
4963
  });
4308
4964
  const visit = (node) => {
4309
4965
  if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
4310
- const accessors = node.members.filter((member) => (ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) && ts.isIdentifier(member.name) &&
4966
+ const accessors = node.members.filter((member) => (ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) &&
4967
+ ts.isIdentifier(member.name) &&
4311
4968
  !member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
4312
- if (node.heritageClauses?.length && accessors.length && isJsSourceFile(node.getSourceFile())) {
4969
+ if (node.heritageClauses?.length &&
4970
+ accessors.length &&
4971
+ isJsSourceFile(node.getSourceFile())) {
4313
4972
  const symbol = lowerer.typeOf(node).getSymbol();
4314
4973
  const instance = symbol ? lowerer.checker.getDeclaredTypeOfSymbol(symbol) : null;
4315
4974
  const seen = new Set();
@@ -4324,12 +4983,15 @@ export function collectVirtualJsMethods(lowerer, files) {
4324
4983
  continue;
4325
4984
  const property = lowerer.checker.getPropertyOfType(base, member.name.text);
4326
4985
  for (const declaration of property ? lowerer.checker.declarationsOf(property) : []) {
4327
- if ((ts.isGetAccessorDeclaration(declaration) || ts.isSetAccessorDeclaration(declaration)) && isJsSourceFile(declaration.getSourceFile())) {
4986
+ if ((ts.isGetAccessorDeclaration(declaration) ||
4987
+ ts.isSetAccessorDeclaration(declaration)) &&
4988
+ isJsSourceFile(declaration.getSourceFile())) {
4328
4989
  lowerer.checkedVirtualJsAccessors.add(declaration);
4329
4990
  lowerer.checkedVirtualJsAccessors.add(member);
4330
4991
  for (const twin of node.members)
4331
4992
  if ((ts.isGetAccessorDeclaration(twin) || ts.isSetAccessorDeclaration(twin)) &&
4332
- ts.isIdentifier(twin.name) && twin.name.text === member.name.text)
4993
+ ts.isIdentifier(twin.name) &&
4994
+ twin.name.text === member.name.text)
4333
4995
  lowerer.checkedVirtualJsAccessors.add(twin);
4334
4996
  }
4335
4997
  }
@@ -4340,7 +5002,8 @@ export function collectVirtualJsMethods(lowerer, files) {
4340
5002
  if (instance)
4341
5003
  markAccessors(instance);
4342
5004
  }
4343
- const members = node.members.filter((member) => ts.isMethodDeclaration(member) && ts.isIdentifier(member.name) &&
5005
+ const members = node.members.filter((member) => ts.isMethodDeclaration(member) &&
5006
+ ts.isIdentifier(member.name) &&
4344
5007
  !member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
4345
5008
  if (node.heritageClauses?.length && members.length > 0) {
4346
5009
  const symbol = lowerer.typeOf(node).getSymbol();
@@ -4357,14 +5020,18 @@ export function collectVirtualJsMethods(lowerer, files) {
4357
5020
  continue;
4358
5021
  const property = lowerer.checker.getPropertyOfType(base, member.name.text);
4359
5022
  for (const declaration of property ? lowerer.checker.declarationsOf(property) : []) {
4360
- if (ts.isMethodDeclaration(declaration) && isJsSourceFile(declaration.getSourceFile())) {
5023
+ if (ts.isMethodDeclaration(declaration) &&
5024
+ isJsSourceFile(declaration.getSourceFile())) {
4361
5025
  lowerer.virtualJsMethods.add(declaration);
4362
- if (isJsSourceFile(member.getSourceFile()) && !member.typeParameters &&
4363
- !member.asteriskToken && !member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
5026
+ if (isJsSourceFile(member.getSourceFile()) &&
5027
+ !member.typeParameters &&
5028
+ !member.asteriskToken &&
5029
+ !member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
4364
5030
  !bodyReadsArguments(member) &&
4365
5031
  member.parameters.every((p) => !p.dotDotDotToken)) {
4366
5032
  lowerer.virtualJsMethodArity.set(declaration, Math.max(lowerer.virtualJsMethodArity.get(declaration) ?? 0, member.parameters.length));
4367
- const checked = !declaration.typeParameters && !declaration.asteriskToken &&
5033
+ const checked = !declaration.typeParameters &&
5034
+ !declaration.asteriskToken &&
4368
5035
  !declaration.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
4369
5036
  !bodyReadsArguments(declaration) &&
4370
5037
  [...member.parameters, ...declaration.parameters].every((p) => !p.dotDotDotToken);
@@ -4401,7 +5068,8 @@ export function collectVirtualJsMethods(lowerer, files) {
4401
5068
  while (changed) {
4402
5069
  changed = false;
4403
5070
  for (const [base, derived] of families) {
4404
- if (!lowerer.checkedVirtualJsValueReturns.has(base) && !lowerer.checkedVirtualJsValueReturns.has(derived))
5071
+ if (!lowerer.checkedVirtualJsValueReturns.has(base) &&
5072
+ !lowerer.checkedVirtualJsValueReturns.has(derived))
4405
5073
  continue;
4406
5074
  for (const member of [base, derived])
4407
5075
  if (!lowerer.checkedVirtualJsValueReturns.has(member)) {
@@ -4412,11 +5080,11 @@ export function collectVirtualJsMethods(lowerer, files) {
4412
5080
  }
4413
5081
  }
4414
5082
  /** The receiver's EXACT runtime class, when the expression proves it: a
4415
- * `new C(...)` expression directly, or a const binding initialized with
4416
- * one (the binding can never be reassigned to a subclass instance).
4417
- * The class is read off the mapped INITIALIZER type — a `const b: Base =
4418
- * new D()` receiver is exactly D, not its annotation. Distinct from
4419
- * exactClassOfReceiver, which answers for CLASS-VALUE receivers. */
5083
+ * `new C(...)` expression directly, or a const binding initialized with
5084
+ * one (the binding can never be reassigned to a subclass instance).
5085
+ * The class is read off the mapped INITIALIZER type — a `const b: Base =
5086
+ * new D()` receiver is exactly D, not its annotation. Distinct from
5087
+ * exactClassOfReceiver, which answers for CLASS-VALUE receivers. */
4420
5088
  export function exactInstanceClassOf(lowerer, expr) {
4421
5089
  let e = expr;
4422
5090
  while (ts.isParenthesizedExpression(e))
@@ -4434,7 +5102,9 @@ export function exactInstanceClassOf(lowerer, expr) {
4434
5102
  return null;
4435
5103
  const symbol = lowerer.resolveValueSymbol(e);
4436
5104
  const decl = symbol ? lowerer.checker.valueDeclarationOf(symbol) : undefined;
4437
- if (!decl || !ts.isVariableDeclaration(decl) || decl.initializer === undefined ||
5105
+ if (!decl ||
5106
+ !ts.isVariableDeclaration(decl) ||
5107
+ decl.initializer === undefined ||
4438
5108
  !ts.isVariableDeclarationList(decl.parent) ||
4439
5109
  (decl.parent.flags & ts.NodeFlags.Const) === 0) {
4440
5110
  return null;
@@ -4445,19 +5115,19 @@ export function exactInstanceClassOf(lowerer, expr) {
4445
5115
  return classOfNew(init);
4446
5116
  }
4447
5117
  /** `const r: Repo = new MemRepo()` where EVERY member of the annotation's
4448
- * checker type is a generic-callable method (`interface Repo { get<T>(id:
4449
- * string): T }`): the record shape maps EMPTY — generic members are
4450
- * excluded (no closure slot can hold a generic function) — so the
4451
- * copy-reshape width coercion would DROP the exact class the method
4452
- * calls monomorphize against, and in JS the binding IS the instance (no
4453
- * copy exists). The binding keeps the initializer's class
4454
- * representation instead: generic-method calls resolve like class-typed
4455
- * receivers (exactInstanceClassOf reads the same const+new discipline),
4456
- * and uses that want the empty record width-coerce at the use site.
4457
- * Const + direct `new` only — a reassignable binding or a produced
4458
- * value keeps today's record story and its fences. */
5118
+ * checker type is a generic-callable method (`interface Repo { get<T>(id:
5119
+ * string): T }`): the record shape maps EMPTY — generic members are
5120
+ * excluded (no closure slot can hold a generic function) — so the
5121
+ * copy-reshape width coercion would DROP the exact class the method
5122
+ * calls monomorphize against, and in JS the binding IS the instance (no
5123
+ * copy exists). The binding keeps the initializer's class
5124
+ * representation instead: generic-method calls resolve like class-typed
5125
+ * receivers (exactInstanceClassOf reads the same const+new discipline),
5126
+ * and uses that want the empty record width-coerce at the use site.
5127
+ * Const + direct `new` only — a reassignable binding or a produced
5128
+ * value keeps today's record story and its fences. */
4459
5129
  export function genericIfaceBindingKeepsClass(lowerer, decl, declaredType) {
4460
- if (declaredType.kind !== "record")
5130
+ if (declaredType.kind !== "record" && declaredType.kind !== "dyn")
4461
5131
  return false;
4462
5132
  if (!ts.isIdentifier(decl.name) || decl.initializer === undefined || decl.type === undefined)
4463
5133
  return false;
@@ -4468,27 +5138,30 @@ export function genericIfaceBindingKeepsClass(lowerer, decl, declaredType) {
4468
5138
  init = init.expression;
4469
5139
  if (!ts.isNewExpression(init))
4470
5140
  return false;
4471
- const shape = lowerer.shapes.get(declaredType.shapeId);
4472
- if (!shape || shape.fields.length > 0 || shape.indexValue !== undefined || shape.tuple === true)
4473
- return false;
4474
5141
  const annT = lowerer.typeOf(decl.name);
4475
5142
  const props = lowerer.checker.getPropertiesOfType(annT);
4476
5143
  if (props.length === 0)
4477
5144
  return false;
5145
+ if (declaredType.kind === "dyn")
5146
+ return (lowerer.classImplementedProtocol(annT) &&
5147
+ props.some((property) => isGenericCallableMemberType(lowerer.checker.getTypeOfSymbol(property), lowerer.checker)));
5148
+ const shape = lowerer.shapes.get(declaredType.shapeId);
5149
+ if (!shape || shape.fields.length > 0 || shape.indexValue !== undefined || shape.tuple === true)
5150
+ return false;
4478
5151
  return props.every((p) => isGenericCallableMemberType(lowerer.checker.getTypeOfSymbol(p), lowerer.checker));
4479
5152
  }
4480
5153
  /** `recv.m<T>(args)` — a GENERIC method call, dispatched STATICALLY: the
4481
- * checker's resolved signature (type arguments substituted, inferred or
4482
- * explicit) keys one instantiation of the nearest declarer's body, and
4483
- * the call is a direct `call` of `%C.m%n` over the (up/down)cast
4484
- * receiver. No per-instantiation vtable slots exist, so a receiver whose
4485
- * runtime class could OVERRIDE the method (genericOverrideBelow) must be
4486
- * statically exact (exactInstanceClassOf) — the override set then
4487
- * resolves at compile time — or fences by name. */
5154
+ * checker's resolved signature (type arguments substituted, inferred or
5155
+ * explicit) keys one instantiation of the nearest declarer's body, and
5156
+ * the call is a direct `call` of `%C.m%n` over the (up/down)cast
5157
+ * receiver. No per-instantiation vtable slots exist, so a receiver whose
5158
+ * runtime class could OVERRIDE the method (genericOverrideBelow) must be
5159
+ * statically exact (exactInstanceClassOf) — the override set then
5160
+ * resolves at compile time — or fences by name. */
4488
5161
  export function lowerClassGenericMethodCall(lowerer, call, access, recvInfo, found, recvIr) {
4489
5162
  const name = access.name.text;
4490
5163
  let { declarer, info } = found;
4491
- if (genericOverrideBelow(lowerer, recvInfo, name)) {
5164
+ if (genericOverrideBelow(recvInfo, name)) {
4492
5165
  const exact = exactInstanceClassOf(lowerer, access.expression);
4493
5166
  const refound = exact ? findGenericMethodOn(lowerer, exact, name) : null;
4494
5167
  if (!refound) {
@@ -4509,14 +5182,26 @@ export function lowerClassGenericMethodCall(lowerer, call, access, recvInfo, fou
4509
5182
  // path; the EXACT path can land below it (a base-typed const provably
4510
5183
  // holding the subclass) — that direction is the checker-grade downcast
4511
5184
  // (the exactness proof is static, stronger than an instanceof guard).
4512
- const thisArg = receiver.type.kind === "object" && isSubclassOf(lowerer, declarer.def.name, receiver.type.className)
4513
- ? { kind: "downcast", value: receiver, type: { kind: "object", className: declarer.def.name }, loc }
5185
+ const thisArg = receiver.type.kind === "object" &&
5186
+ isSubclassOf(lowerer, declarer.def.name, receiver.type.className)
5187
+ ? {
5188
+ kind: "downcast",
5189
+ value: receiver,
5190
+ type: { kind: "object", className: declarer.def.name },
5191
+ loc,
5192
+ }
4514
5193
  : upcastTo(lowerer, receiver, declarer.def.name);
4515
5194
  const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
4516
- return { kind: "call", callee: instance.name, args: [thisArg, ...args], type: instance.returnType, loc };
5195
+ return {
5196
+ kind: "call",
5197
+ callee: instance.name,
5198
+ args: [thisArg, ...args],
5199
+ type: instance.returnType,
5200
+ loc,
5201
+ };
4517
5202
  }
4518
5203
  /** Wraps a derived-class expression in an upcast when the target base
4519
- * class differs (a no-op reinterpret at runtime; keeps IR types exact). */
5204
+ * class differs (a no-op reinterpret at runtime; keeps IR types exact). */
4520
5205
  export function upcastTo(lowerer, expr, className) {
4521
5206
  if (expr.type.kind === "object" && expr.type.className !== className) {
4522
5207
  return { kind: "upcast", value: expr, type: { kind: "object", className }, loc: expr.loc };
@@ -4524,12 +5209,12 @@ export function upcastTo(lowerer, expr, className) {
4524
5209
  return expr;
4525
5210
  }
4526
5211
  /** Constructor and methods become module functions `%C.name` whose first
4527
- * param is `this`. Field initializers run in declaration order at the top
4528
- * of a base class's constructor; a derived class's run right after its
4529
- * super() call returns (tsc/JS initialization order). Reachability gates
4530
- * each member independently: an unreached method body never lowers and
4531
- * never emits (pinned by the corpus), while every override a reachable
4532
- * virtualCall can dispatch to was marked by the discovery pass. */
5212
+ * param is `this`. Field initializers run in declaration order at the top
5213
+ * of a base class's constructor; a derived class's run right after its
5214
+ * super() call returns (tsc/JS initialization order). Reachability gates
5215
+ * each member independently: an unreached method body never lowers and
5216
+ * never emits (pinned by the corpus), while every override a reachable
5217
+ * virtualCall can dispatch to was marked by the discovery pass. */
4533
5218
  /** True when a MIXIN class's constructor is the pure forwarding shape:
4534
5219
  * exactly one rest parameter, `super(...args)` as the first statement,
4535
5220
  * and no other reference to the parameter — the one rest-constructor
@@ -4563,7 +5248,9 @@ function mixinForwardingCtor(lowerer, ctor) {
4563
5248
  ts.walkPreorder(ctor.body, (n) => {
4564
5249
  if (n === spreadIdent)
4565
5250
  return undefined;
4566
- if (ts.isIdentifier(n) && n.text === paramName.text && lowerer.checker.getSymbolAtLocation(n) === paramSym) {
5251
+ if (ts.isIdentifier(n) &&
5252
+ n.text === paramName.text &&
5253
+ lowerer.checker.getSymbolAtLocation(n) === paramSym) {
4567
5254
  extraRef = true;
4568
5255
  return "stop";
4569
5256
  }
@@ -4585,7 +5272,9 @@ export function lowerClassMembers(lowerer, info) {
4585
5272
  // demand-driven like generic-fn instances, not reachability units:
4586
5273
  // they are never registered as units, so wantBody's name-keyed gate
4587
5274
  // cannot apply — every member of a demanded instantiation lowers.
4588
- const always = info.genericInstance !== undefined || info.mixinInstance !== undefined || info.localClass !== undefined;
5275
+ const always = info.genericInstance !== undefined ||
5276
+ info.mixinInstance !== undefined ||
5277
+ info.localClass !== undefined;
4589
5278
  // A FAMILY has no constructor function at all (nothing constructs it;
4590
5279
  // construction resolves to instantiations) and declares no instance
4591
5280
  // members — only its statics lower below.
@@ -4603,10 +5292,19 @@ export function lowerClassMembers(lowerer, info) {
4603
5292
  if (!(e instanceof PoisonError))
4604
5293
  throw e;
4605
5294
  if (info.decl && isJsSourceFile(info.decl.getSourceFile())) {
4606
- const types = [{ kind: "object", className }, ...info.ctorParams.map((param) => param.type)];
5295
+ const types = [
5296
+ { kind: "object", className },
5297
+ ...info.ctorParams.map((param) => param.type),
5298
+ ];
4607
5299
  const fallback = lowerer.deferToRuntimeFence(diagsBefore, info.ctor ?? info.decl, {
4608
- kind: "function", name: `%${className}.constructor`, returnType: VOID,
4609
- params: types.map((type, index) => ({ localId: `p.${index}`, name: index === 0 ? "this" : `p${index}`, type })),
5300
+ kind: "function",
5301
+ name: `%${className}.constructor`,
5302
+ returnType: VOID,
5303
+ params: types.map((type, index) => ({
5304
+ localId: `p.${index}`,
5305
+ name: index === 0 ? "this" : `p${index}`,
5306
+ type,
5307
+ })),
4610
5308
  });
4611
5309
  if (fallback)
4612
5310
  out.push(fallback);
@@ -4641,9 +5339,9 @@ export function lowerClassMembers(lowerer, info) {
4641
5339
  return out;
4642
5340
  }
4643
5341
  /** The constructor function `%C.constructor`. Synthesized when absent: a
4644
- * base class runs just its field initializers; a derived class inherits
4645
- * the base's signature — forward every param to super(), then run own
4646
- * field initializers. */
5342
+ * base class runs just its field initializers; a derived class inherits
5343
+ * the base's signature — forward every param to super(), then run own
5344
+ * field initializers. */
4647
5345
  export function lowerClassCtor(lowerer, info) {
4648
5346
  const cached = info.localClass?.bodies.get(`%${info.def.name}.constructor`);
4649
5347
  if (cached)
@@ -4656,11 +5354,16 @@ function classCaptureParams(info, context) {
4656
5354
  const environment = info.localClass.context;
4657
5355
  if (!environment)
4658
5356
  throw new InternalCompilerError("local class lowered outside its lexical environment");
4659
- return { classCaptures: (context.captures ?? []).map((capture, index) => {
5357
+ return {
5358
+ classCaptures: (context.captures ?? []).map((capture, index) => {
4660
5359
  if (!capture)
4661
5360
  throw new InternalCompilerError("missing local class capture");
4662
- return { ...capture, slot: environment.captures.findIndex((entry) => entry.localId === context.captureSources[index]) };
4663
- }) };
5361
+ return {
5362
+ ...capture,
5363
+ slot: environment.captures.findIndex((entry) => entry.localId === context.captureSources[index]),
5364
+ };
5365
+ }),
5366
+ };
4664
5367
  }
4665
5368
  function lowerClassCtorInner(lowerer, info) {
4666
5369
  const className = info.def.name;
@@ -4683,7 +5386,12 @@ function lowerClassCtorInner(lowerer, info) {
4683
5386
  // unchanged, and the remaining statements lower normally.
4684
5387
  const loc = locOf(info.ctor);
4685
5388
  const forward = info.ctorParams.map((shape, i) => {
4686
- const local = { id: `arg${i}.0`, name: `arg${i}`, type: shape.type, mutable: false };
5389
+ const local = {
5390
+ id: `arg${i}.0`,
5391
+ name: `arg${i}`,
5392
+ type: shape.type,
5393
+ mutable: false,
5394
+ };
4687
5395
  lowerer.ctx.locals.push(local);
4688
5396
  params.push({ localId: local.id, name: local.name, type: shape.type });
4689
5397
  return { kind: "varRef", localId: local.id, type: shape.type, loc };
@@ -4724,7 +5432,12 @@ function lowerClassCtorInner(lowerer, info) {
4724
5432
  // apply in the base constructor's own prologue, never twice).
4725
5433
  const loc = locOf(info.decl);
4726
5434
  const superArgs = info.ctorParams.map((shape, i) => {
4727
- const local = { id: `arg${i}.0`, name: `arg${i}`, type: shape.type, mutable: false };
5435
+ const local = {
5436
+ id: `arg${i}.0`,
5437
+ name: `arg${i}`,
5438
+ type: shape.type,
5439
+ mutable: false,
5440
+ };
4728
5441
  lowerer.ctx.locals.push(local);
4729
5442
  params.push({ localId: local.id, name: local.name, type: shape.type });
4730
5443
  return { kind: "varRef", localId: local.id, type: shape.type, loc };
@@ -4758,14 +5471,14 @@ function lowerClassCtorInner(lowerer, info) {
4758
5471
  }
4759
5472
  }
4760
5473
  /** The lowered method-map name of a class member: identifier text, a
4761
- * COMPUTED name that folds to one compile-time string
4762
- * (foldedStringKeyOf — the object-literal computed-key machinery
4763
- * applied to method positions; tsc late-bound the member under exactly
4764
- * that name), or a reserved `sym:*` slot for the well-known symbols the
4765
- * compiler consumes as language protocols (iterator and explicit
4766
- * resource management). These names are unspellable as user identifiers,
4767
- * like the accessor `get:x` convention. Null for genuinely
4768
- * runtime-keyed names — the computed-member fences stay. */
5474
+ * COMPUTED name that folds to one compile-time string
5475
+ * (foldedStringKeyOf — the object-literal computed-key machinery
5476
+ * applied to method positions; tsc late-bound the member under exactly
5477
+ * that name), or a reserved `sym:*` slot for the well-known symbols the
5478
+ * compiler consumes as language protocols (iterator and explicit
5479
+ * resource management). These names are unspellable as user identifiers,
5480
+ * like the accessor `get:x` convention. Null for genuinely
5481
+ * runtime-keyed names — the computed-member fences stay. */
4769
5482
  export function classMemberNameOf(lowerer, name) {
4770
5483
  if (ts.isIdentifier(name))
4771
5484
  return name.text;
@@ -4791,7 +5504,8 @@ export function classMemberNameOf(lowerer, name) {
4791
5504
  return `sym:${member}`;
4792
5505
  }
4793
5506
  }
4794
- return classSymbolKeyOf(lowerer, name.expression)?.fieldName ?? lowerer.foldedStringKeyOf(name.expression);
5507
+ return (classSymbolKeyOf(lowerer, name.expression)?.fieldName ??
5508
+ lowerer.foldedStringKeyOf(name.expression));
4795
5509
  }
4796
5510
  export function classIteratorOf(lowerer, t) {
4797
5511
  if (t.kind !== "object")
@@ -4825,10 +5539,16 @@ export function classIteratorOf(lowerer, t) {
4825
5539
  const done = shape.fields.find((f) => f.name === "done");
4826
5540
  if (done && done.type.kind !== "bool")
4827
5541
  return null;
4828
- return { className: t.className, iterT, resultT, valueT: value.type, hasDone: done !== undefined };
5542
+ return {
5543
+ className: t.className,
5544
+ iterT,
5545
+ resultT,
5546
+ valueT: value.type,
5547
+ hasDone: done !== undefined,
5548
+ };
4829
5549
  }
4830
5550
  /** The `it.next()` step of a class iterator as an ordinary (possibly
4831
- * virtual) method call. */
5551
+ * virtual) method call. */
4832
5552
  export function classIteratorNextCall(lowerer, cit, itRef, loc) {
4833
5553
  return accessorCall(lowerer, cit.iterT.className, "next", itRef, [], cit.resultT, loc);
4834
5554
  }
@@ -4837,14 +5557,14 @@ export function classIteratorOpenCall(lowerer, cit, recv, loc) {
4837
5557
  return accessorCall(lowerer, cit.className, "sym:iterator", recv, [], cit.iterT, loc);
4838
5558
  }
4839
5559
  /** `[...new C]` / `f(...new C)` over a CLASS ITERABLE: the eager drain —
4840
- * an interned `%iter.drain.<n>(recv)` lifted function running the
4841
- * whole protocol into a fresh element array (a doneless iterator loops
4842
- * forever, exactly Node's spread of an infinite iterator). `elemT`
4843
- * (default: the iterator's own value type) is the DESTINATION element —
4844
- * a spread into a union-element literal (`[...numbers, ...symbols]` as
4845
- * `(number | symbol)[]`) pushes each value wrapped into its arm. Null
4846
- * when the value isn't a recognized class iterable or the element
4847
- * doesn't coerce — spread fences stay. */
5560
+ * an interned `%iter.drain.<n>(recv)` lifted function running the
5561
+ * whole protocol into a fresh element array (a doneless iterator loops
5562
+ * forever, exactly Node's spread of an infinite iterator). `elemT`
5563
+ * (default: the iterator's own value type) is the DESTINATION element —
5564
+ * a spread into a union-element literal (`[...numbers, ...symbols]` as
5565
+ * `(number | symbol)[]`) pushes each value wrapped into its arm. Null
5566
+ * when the value isn't a recognized class iterable or the element
5567
+ * doesn't coerce — spread fences stay. */
4848
5568
  export function classIteratorDrainCall(lowerer, src, loc, elemT) {
4849
5569
  const cit = classIteratorOf(lowerer, src.type);
4850
5570
  if (!cit)
@@ -4867,14 +5587,33 @@ export function classIteratorDrainCall(lowerer, src, loc, elemT) {
4867
5587
  const itRef = { kind: "varRef", localId: "it.0", type: cit.iterT, loc };
4868
5588
  const outRef = { kind: "varRef", localId: "out.0", type: outT, loc };
4869
5589
  const resRef = { kind: "varRef", localId: "res.0", type: cit.resultT, loc };
4870
- const valueRead = { kind: "recordGet", obj: resRef, shapeId: cit.resultT.shapeId, field: "value", type: cit.valueT, loc };
5590
+ const valueRead = {
5591
+ kind: "recordGet",
5592
+ obj: resRef,
5593
+ shapeId: cit.resultT.shapeId,
5594
+ field: "value",
5595
+ type: cit.valueT,
5596
+ loc,
5597
+ };
4871
5598
  const loop = [
4872
- { kind: "varDecl", localId: "res.0", init: classIteratorNextCall(lowerer, cit, itRef, loc), loc },
5599
+ {
5600
+ kind: "varDecl",
5601
+ localId: "res.0",
5602
+ init: classIteratorNextCall(lowerer, cit, itRef, loc),
5603
+ loc,
5604
+ },
4873
5605
  ...(cit.hasDone
4874
5606
  ? [
4875
5607
  {
4876
5608
  kind: "if",
4877
- cond: { kind: "recordGet", obj: resRef, shapeId: cit.resultT.shapeId, field: "done", type: BOOL, loc },
5609
+ cond: {
5610
+ kind: "recordGet",
5611
+ obj: resRef,
5612
+ shapeId: cit.resultT.shapeId,
5613
+ field: "done",
5614
+ type: BOOL,
5615
+ loc,
5616
+ },
4878
5617
  then: [{ kind: "return", value: outRef, loc }],
4879
5618
  else_: null,
4880
5619
  loc,
@@ -4905,8 +5644,18 @@ export function classIteratorDrainCall(lowerer, src, loc, elemT) {
4905
5644
  { id: "res.0", name: "res", type: cit.resultT, mutable: true },
4906
5645
  ],
4907
5646
  body: [
4908
- { kind: "varDecl", localId: "out.0", init: { kind: "arrayLit", elems: [], type: outT, loc }, loc },
4909
- { kind: "varDecl", localId: "it.0", init: classIteratorOpenCall(lowerer, cit, recvRef, loc), loc },
5647
+ {
5648
+ kind: "varDecl",
5649
+ localId: "out.0",
5650
+ init: { kind: "arrayLit", elems: [], type: outT, loc },
5651
+ loc,
5652
+ },
5653
+ {
5654
+ kind: "varDecl",
5655
+ localId: "it.0",
5656
+ init: classIteratorOpenCall(lowerer, cit, recvRef, loc),
5657
+ loc,
5658
+ },
4910
5659
  {
4911
5660
  kind: "while",
4912
5661
  cond: { kind: "boolLit", value: true, type: BOOL, loc },
@@ -4917,7 +5666,12 @@ export function classIteratorDrainCall(lowerer, src, loc, elemT) {
4917
5666
  // all-paths-return rule (the retag-helper convention).
4918
5667
  {
4919
5668
  kind: "throw",
4920
- value: { kind: "strLit", value: "scriptc: internal error: iterator drain fell through", type: STRING, loc },
5669
+ value: {
5670
+ kind: "strLit",
5671
+ value: "scriptc: internal error: iterator drain fell through",
5672
+ type: STRING,
5673
+ loc,
5674
+ },
4921
5675
  loc,
4922
5676
  },
4923
5677
  ],
@@ -4927,8 +5681,8 @@ export function classIteratorDrainCall(lowerer, src, loc, elemT) {
4927
5681
  return { kind: "call", callee: name, args: [src], type: outT, loc };
4928
5682
  }
4929
5683
  /** The tail of a class iterable's protocol from an already-open ITERATOR
4930
- * object (`var [a, ...rest] = new C` — the rest element drains whatever
4931
- * next() still yields): the drain loop keyed by the iterator class. */
5684
+ * object (`var [a, ...rest] = new C` — the rest element drains whatever
5685
+ * next() still yields): the drain loop keyed by the iterator class. */
4932
5686
  export function classIteratorRestDrainCall(lowerer, cit, itVal, loc) {
4933
5687
  const outT = arrayOf(cit.valueT);
4934
5688
  const key = `it:${cit.iterT.className}`;
@@ -4940,12 +5694,24 @@ export function classIteratorRestDrainCall(lowerer, cit, itVal, loc) {
4940
5694
  const outRef = { kind: "varRef", localId: "out.0", type: outT, loc };
4941
5695
  const resRef = { kind: "varRef", localId: "res.0", type: cit.resultT, loc };
4942
5696
  const loop = [
4943
- { kind: "varDecl", localId: "res.0", init: classIteratorNextCall(lowerer, cit, itRef, loc), loc },
5697
+ {
5698
+ kind: "varDecl",
5699
+ localId: "res.0",
5700
+ init: classIteratorNextCall(lowerer, cit, itRef, loc),
5701
+ loc,
5702
+ },
4944
5703
  ...(cit.hasDone
4945
5704
  ? [
4946
5705
  {
4947
5706
  kind: "if",
4948
- cond: { kind: "recordGet", obj: resRef, shapeId: cit.resultT.shapeId, field: "done", type: BOOL, loc },
5707
+ cond: {
5708
+ kind: "recordGet",
5709
+ obj: resRef,
5710
+ shapeId: cit.resultT.shapeId,
5711
+ field: "done",
5712
+ type: BOOL,
5713
+ loc,
5714
+ },
4949
5715
  then: [{ kind: "return", value: outRef, loc }],
4950
5716
  else_: null,
4951
5717
  loc,
@@ -4958,7 +5724,16 @@ export function classIteratorRestDrainCall(lowerer, cit, itVal, loc) {
4958
5724
  kind: "arrIntrinsic",
4959
5725
  method: "push",
4960
5726
  receiver: outRef,
4961
- args: [{ kind: "recordGet", obj: resRef, shapeId: cit.resultT.shapeId, field: "value", type: cit.valueT, loc }],
5727
+ args: [
5728
+ {
5729
+ kind: "recordGet",
5730
+ obj: resRef,
5731
+ shapeId: cit.resultT.shapeId,
5732
+ field: "value",
5733
+ type: cit.valueT,
5734
+ loc,
5735
+ },
5736
+ ],
4962
5737
  type: F64,
4963
5738
  loc,
4964
5739
  },
@@ -4975,11 +5750,21 @@ export function classIteratorRestDrainCall(lowerer, cit, itVal, loc) {
4975
5750
  { id: "res.0", name: "res", type: cit.resultT, mutable: true },
4976
5751
  ],
4977
5752
  body: [
4978
- { kind: "varDecl", localId: "out.0", init: { kind: "arrayLit", elems: [], type: outT, loc }, loc },
5753
+ {
5754
+ kind: "varDecl",
5755
+ localId: "out.0",
5756
+ init: { kind: "arrayLit", elems: [], type: outT, loc },
5757
+ loc,
5758
+ },
4979
5759
  { kind: "while", cond: { kind: "boolLit", value: true, type: BOOL, loc }, body: loop, loc },
4980
5760
  {
4981
5761
  kind: "throw",
4982
- value: { kind: "strLit", value: "scriptc: internal error: iterator drain fell through", type: STRING, loc },
5762
+ value: {
5763
+ kind: "strLit",
5764
+ value: "scriptc: internal error: iterator drain fell through",
5765
+ type: STRING,
5766
+ loc,
5767
+ },
4983
5768
  loc,
4984
5769
  },
4985
5770
  ],
@@ -4989,12 +5774,14 @@ export function classIteratorRestDrainCall(lowerer, cit, itVal, loc) {
4989
5774
  return { kind: "call", callee: name, args: [itVal], type: outT, loc };
4990
5775
  }
4991
5776
  /** One method or accessor body as its module function `%C.name`
4992
- * (accessors are methods with property syntax: "get:x"/"set:x" entries —
4993
- * see collectClassShape). */
5777
+ * (accessors are methods with property syntax: "get:x"/"set:x" entries —
5778
+ * see collectClassShape). */
4994
5779
  export function lowerClassMethodMember(lowerer, info, fnLike) {
4995
5780
  if (info.localClass?.ready) {
4996
5781
  const member = classMemberNameOf(lowerer, fnLike.name);
4997
- const name = ts.isMethodDeclaration(fnLike) ? member : `${ts.isGetAccessor(fnLike) ? "get" : "set"}:${member}`;
5782
+ const name = ts.isMethodDeclaration(fnLike)
5783
+ ? member
5784
+ : `${ts.isGetAccessor(fnLike) ? "get" : "set"}:${member}`;
4998
5785
  return info.localClass.bodies.get(`%${info.def.name}.${name}`) ?? null;
4999
5786
  }
5000
5787
  return withInstanceBindings(lowerer, info, () => lowerClassMethodMemberInner(lowerer, info, fnLike));
@@ -5088,12 +5875,12 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
5088
5875
  }
5089
5876
  }
5090
5877
  /** One static method body as its module function `%C.static:m` — an
5091
- * ordinary function with NO `this` param. `this` and `super` inside
5092
- * name the RECEIVER class in JS (dynamic — `F.who()` sees F even when
5093
- * who() is declared on E), which has no static story here: both are
5094
- * named fences, with arrow functions transparent (they inherit the
5095
- * method's `this`) and this-binding function forms opaque — the static-
5096
- * block rule verbatim. */
5878
+ * ordinary function with NO `this` param. `this` and `super` inside
5879
+ * name the RECEIVER class in JS (dynamic — `F.who()` sees F even when
5880
+ * who() is declared on E), which has no static story here: both are
5881
+ * named fences, with arrow functions transparent (they inherit the
5882
+ * method's `this`) and this-binding function forms opaque — the static-
5883
+ * block rule verbatim. */
5097
5884
  export function lowerStaticMethod(lowerer, info, name) {
5098
5885
  const entry = info.staticMethods?.get(name);
5099
5886
  if (!entry?.member.body)
@@ -5109,7 +5896,9 @@ export function lowerStaticMethod(lowerer, info, name) {
5109
5896
  const genCh = isGenerator && entry.ret.kind === "generator" ? generatorMeta(lowerer, entry.ret) : null;
5110
5897
  const bodyReturn = genCh !== null
5111
5898
  ? lowerer.genBodyReturnType(entry.ret)
5112
- : isAsync && entry.ret.kind === "promise" ? entry.ret.inner : entry.ret;
5899
+ : isAsync && entry.ret.kind === "promise"
5900
+ ? entry.ret.inner
5901
+ : entry.ret;
5113
5902
  const fnCtx = newFnCtx(false, null, null, bodyReturn);
5114
5903
  fnCtx.isAsync = isAsync;
5115
5904
  if (genCh !== null)
@@ -5153,10 +5942,10 @@ export function lowerStaticMethod(lowerer, info, name) {
5153
5942
  }
5154
5943
  }
5155
5944
  /** A synthesized throwing setter: a getter-only override shadows the
5156
- * inherited pair (JS), so a base-typed write dispatches HERE and must
5157
- * throw exactly like Node's TypeError — a real instance (a typed catch's
5158
- * `e instanceof TypeError` matches), catchable, exit 1 uncaught (message
5159
- * text is compiler-worded; stdout and exit code are the contract). */
5945
+ * inherited pair (JS), so a base-typed write dispatches HERE and must
5946
+ * throw exactly like Node's TypeError — a real instance (a typed catch's
5947
+ * `e instanceof TypeError` matches), catchable, exit 1 uncaught (message
5948
+ * text is compiler-worded; stdout and exit code are the contract). */
5160
5949
  export function throwingSetterFn(lowerer, info, prop) {
5161
5950
  const className = info.def.name;
5162
5951
  const thisType = { kind: "object", className };
@@ -5195,27 +5984,38 @@ export function throwingSetterFn(lowerer, info, prop) {
5195
5984
  };
5196
5985
  }
5197
5986
  /** The base a constructor chain actually CALLS into: generic FAMILIES are
5198
- * never constructed (no `%<family>.constructor` exists), so an
5199
- * instantiation's construction-relevant base is the family's own base —
5200
- * null when the generic class extends nothing, exactly the source's
5201
- * story (tsc forbids super() there). Ordinary classes answer their base
5202
- * unchanged. */
5987
+ * never constructed (no `%<family>.constructor` exists), so an
5988
+ * instantiation's construction-relevant base is the family's own base —
5989
+ * null when the generic class extends nothing, exactly the source's
5990
+ * story (tsc forbids super() there). Ordinary classes answer their base
5991
+ * unchanged. */
5203
5992
  function superBaseOf(info) {
5204
5993
  const b = info.base;
5205
5994
  return b?.generic ? b.base : b;
5206
5995
  }
5207
5996
  /** The class's OWN field initializers as fieldSet statements (declaration
5208
- * order) — a base constructor's prologue, a derived constructor's
5209
- * super()-return continuation. */
5997
+ * order) — a base constructor's prologue, a derived constructor's
5998
+ * super()-return continuation. */
5210
5999
  export function fieldInitStmts(lowerer, info, thisLocal) {
5211
6000
  const out = [];
5212
6001
  const thisType = { kind: "object", className: info.def.name };
5213
6002
  for (const f of info.fieldOrder) {
5214
6003
  if (f.errorCause) {
5215
6004
  const loc = f.initializer ? locOf(f.initializer) : f.undefinedInitializer;
5216
- const value = f.initializer ? lowerer.lowerExprExpecting(f.initializer, DYN) : dynUndefinedExpr(loc);
5217
- out.push({ kind: "exprStmt", expr: { kind: "libCall", fn: "error.defineCause",
5218
- args: [{ kind: "varRef", localId: thisLocal.id, type: thisType, loc }, value], type: VOID, loc }, loc });
6005
+ const value = f.initializer
6006
+ ? lowerer.lowerExprExpecting(f.initializer, DYN)
6007
+ : dynUndefinedExpr(loc);
6008
+ out.push({
6009
+ kind: "exprStmt",
6010
+ expr: {
6011
+ kind: "libCall",
6012
+ fn: "error.defineCause",
6013
+ args: [{ kind: "varRef", localId: thisLocal.id, type: thisType, loc }, value],
6014
+ type: VOID,
6015
+ loc,
6016
+ },
6017
+ loc,
6018
+ });
5219
6019
  continue;
5220
6020
  }
5221
6021
  if (f.undefinedInitializer) {
@@ -5251,7 +6051,9 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
5251
6051
  lowerer.stats.statementsFailed++;
5252
6052
  lowerer.bumpFileStat(locOf(f.initializer).file, "failed");
5253
6053
  if (isJsSourceFile(f.initializer.getSourceFile()) && lowerer.diagSink === null) {
5254
- const fence = lowerer.deferToRuntimeFence(diagsBefore, f.initializer, { kind: "statement" });
6054
+ const fence = lowerer.deferToRuntimeFence(diagsBefore, f.initializer, {
6055
+ kind: "statement",
6056
+ });
5255
6057
  if (fence)
5256
6058
  out.push(fence);
5257
6059
  }
@@ -5260,14 +6062,14 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
5260
6062
  return out;
5261
6063
  }
5262
6064
  /** PARAMETER-PROPERTY assignments (`this.x = x`, synthesized): run AFTER
5263
- * the field initializers — Node's transform defines the fields at the
5264
- * top of the class body (undefined until assigned) and injects the
5265
- * assignments at the start of the constructor body, i.e. after super()
5266
- * and after the (native) field initializers ran (probed: a field
5267
- * initializer reading `this.x` sees undefined; the body sees the value).
5268
- * Each assignment reads the parameter's BODY local (defaults already
5269
- * applied by the declareParams prologue), whose type the collection made
5270
- * the field's type — slot-exact by construction. */
6065
+ * the field initializers — Node's transform defines the fields at the
6066
+ * top of the class body (undefined until assigned) and injects the
6067
+ * assignments at the start of the constructor body, i.e. after super()
6068
+ * and after the (native) field initializers ran (probed: a field
6069
+ * initializer reading `this.x` sees undefined; the body sees the value).
6070
+ * Each assignment reads the parameter's BODY local (defaults already
6071
+ * applied by the declareParams prologue), whose type the collection made
6072
+ * the field's type — slot-exact by construction. */
5271
6073
  function paramPropInitStmts(lowerer, info, thisLocal) {
5272
6074
  const out = [];
5273
6075
  const thisType = { kind: "object", className: info.def.name };
@@ -5291,8 +6093,8 @@ function paramPropInitStmts(lowerer, info, thisLocal) {
5291
6093
  return out;
5292
6094
  }
5293
6095
  /** Super statements initialize the base and then the derived fields on
5294
- * whichever control-flow path executes. Repeated calls are explicitly
5295
- * refused until native layouts can allocate a second receiver. */
6096
+ * whichever control-flow path executes. Repeated calls are explicitly
6097
+ * refused until native layouts can allocate a second receiver. */
5296
6098
  export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
5297
6099
  let superSeen = false;
5298
6100
  const initialized = lowerer.declareHiddenLocal("%superInitialized", BOOL);
@@ -5306,11 +6108,30 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
5306
6108
  lowerer.unsupported("SC1090", superCall, "super() in an expression position");
5307
6109
  superSeen = true;
5308
6110
  const loc = locOf(superCall);
5309
- const statements = [{ kind: "if", cond: { kind: "varRef", localId: initialized.id, type: BOOL, loc }, then: [{ kind: "exprStmt", expr: nodeThrowExpr(0, "SC2020", "repeated super() calls require a fresh receiver and are not supported yet", DYN, loc), loc }], else_: null, loc }];
6111
+ const statements = [
6112
+ {
6113
+ kind: "if",
6114
+ cond: { kind: "varRef", localId: initialized.id, type: BOOL, loc },
6115
+ then: [
6116
+ {
6117
+ kind: "exprStmt",
6118
+ expr: nodeThrowExpr(0, "SC2020", "repeated super() calls require a fresh receiver and are not supported yet", DYN, loc),
6119
+ loc,
6120
+ },
6121
+ ],
6122
+ else_: null,
6123
+ loc,
6124
+ },
6125
+ ];
5310
6126
  if (info.callableBase) {
5311
6127
  if (superCall.arguments.some(ts.isSpreadElement))
5312
6128
  lowerer.unsupported("SC1090", superCall, "spreading explicit super arguments into an ordinary constructor");
5313
- const pack = { kind: "dynArrLit", elems: superCall.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), type: DYN, loc };
6129
+ const pack = {
6130
+ kind: "dynArrLit",
6131
+ elems: superCall.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
6132
+ type: DYN,
6133
+ loc,
6134
+ };
5314
6135
  statements.push(lowerer.superCallStmt(info, thisLocal, [pack], loc));
5315
6136
  }
5316
6137
  else {
@@ -5321,19 +6142,33 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
5321
6142
  statements.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments, thisLocal, loc, superCall));
5322
6143
  }
5323
6144
  else {
5324
- const surplusSpread = forward === undefined && !base.builtinError && !base.builtinEmitter &&
5325
- base.ctorParams.length === 0 && superCall.arguments.some(ts.isSpreadElement);
6145
+ const surplusSpread = forward === undefined &&
6146
+ !base.builtinError &&
6147
+ !base.builtinEmitter &&
6148
+ base.ctorParams.length === 0 &&
6149
+ superCall.arguments.some(ts.isSpreadElement);
5326
6150
  if (surplusSpread) {
5327
6151
  const evaluated = lowerer.completeArgs(superCall.arguments, [{ mode: "dynRest", type: DYN }], loc, superCall);
5328
6152
  for (const value of evaluated)
5329
6153
  statements.push({ kind: "exprStmt", expr: value, loc });
5330
6154
  }
5331
- const surplus = forward === undefined && !base.builtinError && !base.builtinEmitter &&
6155
+ const surplus = forward === undefined &&
6156
+ !base.builtinError &&
6157
+ !base.builtinEmitter &&
5332
6158
  !base.ctorParams.some((param) => param.mode === "rest" || param.mode === "dynRest" || param.mode === "islandRest") &&
5333
- !superCall.arguments.some(ts.isSpreadElement) && superCall.arguments.length > base.ctorParams.length;
5334
- let args = surplusSpread ? [] : forward !== undefined ? forward : base.builtinError
5335
- ? lowerer.errorConstructorArgs(superCall.arguments, loc, superCall) : base.builtinEmitter ? []
5336
- : lowerer.completeArgs(surplus ? superCall.arguments.slice(0, base.ctorParams.length) : superCall.arguments, base.ctorParams, loc, superCall);
6159
+ !superCall.arguments.some(ts.isSpreadElement) &&
6160
+ superCall.arguments.length > base.ctorParams.length;
6161
+ let args = surplusSpread
6162
+ ? []
6163
+ : forward !== undefined
6164
+ ? forward
6165
+ : base.builtinError
6166
+ ? lowerer.errorConstructorArgs(superCall.arguments, loc, superCall)
6167
+ : base.builtinEmitter
6168
+ ? []
6169
+ : lowerer.completeArgs(surplus
6170
+ ? superCall.arguments.slice(0, base.ctorParams.length)
6171
+ : superCall.arguments, base.ctorParams, loc, superCall);
5337
6172
  if (surplus) {
5338
6173
  args = args.map((arg) => {
5339
6174
  const local = lowerer.declareHiddenLocal("%superArgument", arg.type);
@@ -5341,13 +6176,22 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
5341
6176
  return { kind: "varRef", localId: local.id, type: arg.type, loc };
5342
6177
  });
5343
6178
  for (const argument of superCall.arguments.slice(base.ctorParams.length)) {
5344
- statements.push({ kind: "exprStmt", expr: lowerer.lowerExpr(argument), loc: locOf(argument) });
6179
+ statements.push({
6180
+ kind: "exprStmt",
6181
+ expr: lowerer.lowerExpr(argument),
6182
+ loc: locOf(argument),
6183
+ });
5345
6184
  }
5346
6185
  }
5347
6186
  statements.push(lowerer.superCallStmt(info, thisLocal, args, loc));
5348
6187
  }
5349
6188
  }
5350
- statements.push({ kind: "assign", localId: initialized.id, value: { kind: "boolLit", value: true, type: BOOL, loc }, loc });
6189
+ statements.push({
6190
+ kind: "assign",
6191
+ localId: initialized.id,
6192
+ value: { kind: "boolLit", value: true, type: BOOL, loc },
6193
+ loc,
6194
+ });
5351
6195
  delete context.superInitialized;
5352
6196
  try {
5353
6197
  statements.push(...lowerer.fieldInitStmts(info, thisLocal), ...paramPropInitStmts(lowerer, info, thisLocal));
@@ -5356,16 +6200,52 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
5356
6200
  context.superInitialized = initialized;
5357
6201
  }
5358
6202
  const result = { kind: "varRef", localId: thisLocal.id, type: thisLocal.type, loc };
5359
- return { kind: "seqExpr", stmts: statements.map((statement) => statement.kind === "runtimeFence"
5360
- ? { kind: "exprStmt", expr: nodeThrowExpr(0, statement.code, statement.message, DYN, statement.loc), loc: statement.loc }
5361
- : statement), result, type: result.type, loc };
6203
+ return {
6204
+ kind: "seqExpr",
6205
+ stmts: statements.map((statement) => statement.kind === "runtimeFence"
6206
+ ? {
6207
+ kind: "exprStmt",
6208
+ expr: nodeThrowExpr(0, statement.code, statement.message, DYN, statement.loc),
6209
+ loc: statement.loc,
6210
+ }
6211
+ : statement),
6212
+ result,
6213
+ type: result.type,
6214
+ loc,
6215
+ };
5362
6216
  };
5363
6217
  try {
5364
6218
  const result = lowerer.lowerStmts(info.ctor.body.statements);
5365
- result.push({ kind: "if", cond: { kind: "unary", op: "!", operand: { kind: "varRef", localId: initialized.id, type: BOOL, loc: locOf(info.ctor) }, type: BOOL, loc: locOf(info.ctor) }, then: [{ kind: "exprStmt", expr: nodeThrowExpr(5, "", "Must call super constructor in derived class before accessing 'this' or returning from derived constructor", DYN, locOf(info.ctor)), loc: locOf(info.ctor) }], else_: null, loc: locOf(info.ctor) });
6219
+ result.push({
6220
+ kind: "if",
6221
+ cond: {
6222
+ kind: "unary",
6223
+ op: "!",
6224
+ operand: { kind: "varRef", localId: initialized.id, type: BOOL, loc: locOf(info.ctor) },
6225
+ type: BOOL,
6226
+ loc: locOf(info.ctor),
6227
+ },
6228
+ then: [
6229
+ {
6230
+ kind: "exprStmt",
6231
+ expr: nodeThrowExpr(5, "", "Must call super constructor in derived class before accessing 'this' or returning from derived constructor", DYN, locOf(info.ctor)),
6232
+ loc: locOf(info.ctor),
6233
+ },
6234
+ ],
6235
+ else_: null,
6236
+ loc: locOf(info.ctor),
6237
+ });
5366
6238
  if (!superSeen)
5367
6239
  lowerer.pushDiag(unsupportedDiag("SC1090", locOf(info.ctor), "derived constructors without a lowered super() call"));
5368
- return [{ kind: "varDecl", localId: initialized.id, init: { kind: "boolLit", value: false, type: BOOL, loc: locOf(info.ctor) }, loc: locOf(info.ctor) }, ...result];
6240
+ return [
6241
+ {
6242
+ kind: "varDecl",
6243
+ localId: initialized.id,
6244
+ init: { kind: "boolLit", value: false, type: BOOL, loc: locOf(info.ctor) },
6245
+ loc: locOf(info.ctor),
6246
+ },
6247
+ ...result,
6248
+ ];
5369
6249
  }
5370
6250
  finally {
5371
6251
  if (previous)
@@ -5379,8 +6259,8 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
5379
6259
  }
5380
6260
  }
5381
6261
  /** `super(args)` → direct call of the base constructor with the SAME
5382
- * `this` (upcast; retained by the varRef read — the callee owns and
5383
- * releases its param per the universal convention). */
6262
+ * `this` (upcast; retained by the varRef read — the callee owns and
6263
+ * releases its param per the universal convention). */
5384
6264
  export function superCallStmt(lowerer, info, thisLocal, args, loc) {
5385
6265
  const base = superBaseOf(info);
5386
6266
  const thisRef = {
@@ -5391,12 +6271,41 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
5391
6271
  };
5392
6272
  if (info.callableBase)
5393
6273
  return {
5394
- kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classSuper",
5395
- args: [info.localClass ? { kind: "libCall", fn: "dyn.getPrototype", args: [
5396
- { kind: "dynFrom", value: { kind: "fieldGet", obj: thisRef, className: info.def.name,
5397
- field: `%classEnvironment:${info.def.name}`, type: { kind: "classval", className: info.def.name }, loc }, type: DYN, loc },
5398
- ], type: DYN, loc } : { kind: "varRef", localId: info.callableBase.constructorId, type: DYN, loc },
5399
- lowerer.coerceToExpected(thisRef, DYN), args[0]], type: VOID, loc }, loc,
6274
+ kind: "exprStmt",
6275
+ expr: {
6276
+ kind: "libCall",
6277
+ fn: "dyn.classSuper",
6278
+ args: [
6279
+ info.localClass
6280
+ ? {
6281
+ kind: "libCall",
6282
+ fn: "dyn.getPrototype",
6283
+ args: [
6284
+ {
6285
+ kind: "dynFrom",
6286
+ value: {
6287
+ kind: "fieldGet",
6288
+ obj: thisRef,
6289
+ className: info.def.name,
6290
+ field: `%classEnvironment:${info.def.name}`,
6291
+ type: { kind: "classval", className: info.def.name },
6292
+ loc,
6293
+ },
6294
+ type: DYN,
6295
+ loc,
6296
+ },
6297
+ ],
6298
+ type: DYN,
6299
+ loc,
6300
+ }
6301
+ : { kind: "varRef", localId: info.callableBase.constructorId, type: DYN, loc },
6302
+ lowerer.coerceToExpected(thisRef, DYN),
6303
+ args[0],
6304
+ ],
6305
+ type: VOID,
6306
+ loc,
6307
+ },
6308
+ loc,
5400
6309
  };
5401
6310
  if (base.builtinError) {
5402
6311
  // super(message) into the runtime-provided Error constructor: stamps
@@ -5453,8 +6362,8 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
5453
6362
  };
5454
6363
  }
5455
6364
  /** `super.method(args)`: the base chain's implementation, called
5456
- * DIRECTLY over this method's own `this` (upcast to the declarer) —
5457
- * super dispatch is static in JS too, never through the dynamic class. */
6365
+ * DIRECTLY over this method's own `this` (upcast to the declarer) —
6366
+ * super dispatch is static in JS too, never through the dynamic class. */
5458
6367
  export function lowerSuperMethodCall(lowerer, call, access) {
5459
6368
  const cls = lowerer.currentClass;
5460
6369
  if (!cls?.base) {
@@ -5516,15 +6425,33 @@ export function lowerSuperMethodCall(lowerer, call, access) {
5516
6425
  if (lowerer.prototypeMethodAccesses.has(access.name.text)) {
5517
6426
  const prototype = classPrototypeData(lowerer, cls.base, loc);
5518
6427
  if (prototype) {
5519
- const callee = { kind: "dynKeyGet", value: prototype,
5520
- key: { kind: "strLit", value: access.name.text, type: STRING, loc }, type: DYN, loc };
5521
- const value = { kind: "dynCall", callee, receiver: lowerer.coerceToExpected(thisRef, DYN),
5522
- calleeName: access.getText(), args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), type: DYN, loc };
6428
+ const callee = {
6429
+ kind: "dynKeyGet",
6430
+ value: prototype,
6431
+ key: { kind: "strLit", value: access.name.text, type: STRING, loc },
6432
+ type: DYN,
6433
+ loc,
6434
+ };
6435
+ const value = {
6436
+ kind: "dynCall",
6437
+ callee,
6438
+ receiver: lowerer.coerceToExpected(thisRef, DYN),
6439
+ calleeName: access.getText(),
6440
+ args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
6441
+ type: DYN,
6442
+ loc,
6443
+ };
5523
6444
  return found.sig.ret.kind === "void" ? value : lowerer.coerceToExpected(value, found.sig.ret);
5524
6445
  }
5525
6446
  }
5526
6447
  if (found.declarer.builtinError) {
5527
- return { kind: "libCall", fn: "error.toString", args: [lowerer.upcastTo(thisRef, "%Error")], type: STRING, loc };
6448
+ return {
6449
+ kind: "libCall",
6450
+ fn: "error.toString",
6451
+ args: [lowerer.upcastTo(thisRef, "%Error")],
6452
+ type: STRING,
6453
+ loc,
6454
+ };
5528
6455
  }
5529
6456
  lowerer.noteEdge(`%${found.declarer.def.name}.${access.name.text}`);
5530
6457
  const args = lowerer.completeArgs(call.arguments, found.sig.params, loc, call);
@@ -5537,7 +6464,7 @@ export function lowerSuperMethodCall(lowerer, call, access) {
5537
6464
  };
5538
6465
  }
5539
6466
  /** The `this` reference for super accessor reads/writes, with the shared
5540
- * validity checks (derived-class body, resolvable this). */
6467
+ * validity checks (derived-class body, resolvable this). */
5541
6468
  export function superThisRef(lowerer, access) {
5542
6469
  const cls = lowerer.currentClass;
5543
6470
  if (!cls?.base) {
@@ -5553,8 +6480,8 @@ export function superThisRef(lowerer, access) {
5553
6480
  };
5554
6481
  }
5555
6482
  /** `super.x` read: a DIRECT call of the base chain's getter over this
5556
- * method's own `this` (upcast to the declarer) — like super.method(),
5557
- * never through the vtable. */
6483
+ * method's own `this` (upcast to the declarer) — like super.method(),
6484
+ * never through the vtable. */
5558
6485
  export function lowerSuperAccessorRead(lowerer, access) {
5559
6486
  const { thisRef, base } = lowerer.superThisRef(access);
5560
6487
  const name = access.name.text;
@@ -5578,7 +6505,7 @@ export function lowerSuperAccessorRead(lowerer, access) {
5578
6505
  };
5579
6506
  }
5580
6507
  /** `super.x = v`: a DIRECT call of the base chain's setter (same
5581
- * static-dispatch rule as every super member access). */
6508
+ * static-dispatch rule as every super member access). */
5582
6509
  export function lowerSuperAccessorWrite(lowerer, access, rhs, loc) {
5583
6510
  const { thisRef, base } = lowerer.superThisRef(access);
5584
6511
  const name = access.name.text;
@@ -5605,9 +6532,9 @@ export function lowerSuperAccessorWrite(lowerer, access, rhs, loc) {
5605
6532
  };
5606
6533
  }
5607
6534
  /** True when `info`'s EFFECTIVE constructor — its own, or the one
5608
- * inherited through ctor-less bases — is a builtin error class's. Such
5609
- * classes construct with the error argument rule, and their synthesized
5610
- * constructors forward both checked-dynamic values to error.ctorOptions. */
6535
+ * inherited through ctor-less bases — is a builtin error class's. Such
6536
+ * classes construct with the error argument rule, and their synthesized
6537
+ * constructors forward both checked-dynamic values to error.ctorOptions. */
5611
6538
  export function inheritsBuiltinErrorCtor(lowerer, info) {
5612
6539
  for (let c = info; c; c = c.base) {
5613
6540
  if (c.builtinError)
@@ -5618,7 +6545,7 @@ export function inheritsBuiltinErrorCtor(lowerer, info) {
5618
6545
  return false;
5619
6546
  }
5620
6547
  /** The EventEmitter twin: a ctor-less chain into the emitter base
5621
- * inherits `new C()` — zero arguments (the options bag fences). */
6548
+ * inherits `new C()` — zero arguments (the options bag fences). */
5622
6549
  export function inheritsBuiltinEmitterCtor(lowerer, info) {
5623
6550
  for (let c = info; c; c = c.base) {
5624
6551
  if (c.builtinStream)
@@ -5631,10 +6558,10 @@ export function inheritsBuiltinEmitterCtor(lowerer, info) {
5631
6558
  return false;
5632
6559
  }
5633
6560
  /** The stream twin: a ctor-less chain into a runtime stream base
5634
- * inherits `new C()` — zero arguments (the synthesized constructor runs
5635
- * super() with default options; passing options through an inherited
5636
- * constructor would need the literal at the new-site to plumb, so it
5637
- * asks for a declared constructor instead). */
6561
+ * inherits `new C()` — zero arguments (the synthesized constructor runs
6562
+ * super() with default options; passing options through an inherited
6563
+ * constructor would need the literal at the new-site to plumb, so it
6564
+ * asks for a declared constructor instead). */
5638
6565
  function inheritsBuiltinStreamCtor(lowerer, info) {
5639
6566
  for (let c = info; c; c = c.base) {
5640
6567
  if (c.builtinStream)
@@ -5708,8 +6635,13 @@ function lowerProgramClassNew(lowerer, expr, declaredInfo, loc) {
5708
6635
  : lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
5709
6636
  for (let current = info; current; current = current.base) {
5710
6637
  if (current.def.baseValueGlobal)
5711
- return { kind: "newValue", callee: classValueRef(lowerer, info, expr),
5712
- args, type: { kind: "object", className: info.def.name }, loc };
6638
+ return {
6639
+ kind: "newValue",
6640
+ callee: classValueRef(lowerer, info, expr),
6641
+ args,
6642
+ type: { kind: "object", className: info.def.name },
6643
+ loc,
6644
+ };
5713
6645
  }
5714
6646
  return {
5715
6647
  kind: "new",
@@ -5732,6 +6664,9 @@ function assignedThisFieldType(lowerer, expr) {
5732
6664
  }
5733
6665
  export function lowerNew(lowerer, expr) {
5734
6666
  const loc = locOf(expr);
6667
+ const worker = lowerWorkerNew(lowerer, expr);
6668
+ if (worker)
6669
+ return worker;
5735
6670
  let intlConstructor = expr.expression;
5736
6671
  if (ts.isIdentifier(intlConstructor)) {
5737
6672
  const symbol = lowerer.resolveValueSymbol(intlConstructor);
@@ -5739,7 +6674,9 @@ export function lowerNew(lowerer, expr) {
5739
6674
  if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer)
5740
6675
  intlConstructor = declaration.initializer;
5741
6676
  }
5742
- const intl = ts.isPropertyAccessExpression(intlConstructor) ? lowerer.stdlibGlobalMember(intlConstructor, "Intl") : null;
6677
+ const intl = ts.isPropertyAccessExpression(intlConstructor)
6678
+ ? lowerer.stdlibGlobalMember(intlConstructor, "Intl")
6679
+ : null;
5743
6680
  if (intl && intl !== "Segmenter")
5744
6681
  lowerer.noLowering(`new Intl.${intl}`, expr, undefined, lowerer.checker.getSymbolAtLocation(expr.expression));
5745
6682
  const instanceConstructor = lowerInstanceConstructorNew(lowerer, expr);
@@ -5750,10 +6687,16 @@ export function lowerNew(lowerer, expr) {
5750
6687
  return objectFactory;
5751
6688
  if (ts.isIdentifier(expr.expression)) {
5752
6689
  const symbol = lowerer.resolveValueSymbol(expr.expression);
5753
- const declaration = symbol && lowerer.checker.declarationsOf(symbol).find((node) => ts.isFunctionDeclaration(node) && node.body !== undefined);
6690
+ const declaration = symbol &&
6691
+ lowerer.checker
6692
+ .declarationsOf(symbol)
6693
+ .find((node) => ts.isFunctionDeclaration(node) && node.body !== undefined);
5754
6694
  if (declaration && ts.isFunctionDeclaration(declaration) && declaration.body) {
5755
6695
  const last = declaration.body.statements.at(-1);
5756
- if (last && ts.isReturnStatement(last) && last.expression && ts.isObjectLiteralExpression(last.expression)) {
6696
+ if (last &&
6697
+ ts.isReturnStatement(last) &&
6698
+ last.expression &&
6699
+ ts.isObjectLiteralExpression(last.expression)) {
5757
6700
  lowerer.unsupported("SC1090", expr, "object-returning constructors that observe this or return mixed primitive/object values");
5758
6701
  }
5759
6702
  }
@@ -5767,13 +6710,24 @@ export function lowerNew(lowerer, expr) {
5767
6710
  if (yes && no && !yes.classDecorators && !no.classDecorators) {
5768
6711
  const yesType = { kind: "object", className: yes.def.name };
5769
6712
  const noType = { kind: "object", className: no.def.name };
5770
- const type = yes === no ? yesType : { kind: "union", unionId: lowerer.unions.intern([yesType, noType].sort((a, b) => typeKey(a) < typeKey(b) ? -1 : 1)) };
5771
- return { kind: "ternary", cond: lowerer.lowerCondition(selected.condition),
6713
+ const type = yes === no
6714
+ ? yesType
6715
+ : {
6716
+ kind: "union",
6717
+ unionId: lowerer.unions.intern([yesType, noType].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1))),
6718
+ };
6719
+ return {
6720
+ kind: "ternary",
6721
+ cond: lowerer.lowerCondition(selected.condition),
5772
6722
  then: lowerer.coerceInto(expr, lowerProgramClassNew(lowerer, expr, yes, loc), type),
5773
- else_: lowerer.coerceInto(expr, lowerProgramClassNew(lowerer, expr, no, loc), type), type, loc };
6723
+ else_: lowerer.coerceInto(expr, lowerProgramClassNew(lowerer, expr, no, loc), type),
6724
+ type,
6725
+ loc,
6726
+ };
5774
6727
  }
5775
6728
  }
5776
- if (ts.isPropertyAccessExpression(expr.expression) && expr.expression.name.text === "Segmenter" &&
6729
+ if (ts.isPropertyAccessExpression(expr.expression) &&
6730
+ expr.expression.name.text === "Segmenter" &&
5777
6731
  lowerer.isStdlibGlobal(expr.expression.expression, "Intl")) {
5778
6732
  const args = expr.arguments ?? [];
5779
6733
  const undefinedArg = (arg) => (lowerer.typeOf(arg).flags & ts.TypeFlags.Undefined) !== 0;
@@ -5781,16 +6735,24 @@ export function lowerNew(lowerer, expr) {
5781
6735
  lowerer.noLowering("Intl.Segmenter locale negotiation", expr, "omit the locale or pass undefined for default Unicode grapheme segmentation");
5782
6736
  }
5783
6737
  const options = args[1];
5784
- if (options && !undefinedArg(options) &&
5785
- !(ts.isObjectLiteralExpression(options) && options.properties.every((property) => ts.isPropertyAssignment(property) &&
5786
- (ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)) && property.name.text === "granularity" &&
5787
- ts.isStringLiteral(property.initializer) && property.initializer.text === "grapheme"))) {
6738
+ if (options &&
6739
+ !undefinedArg(options) &&
6740
+ !(ts.isObjectLiteralExpression(options) &&
6741
+ options.properties.every((property) => ts.isPropertyAssignment(property) &&
6742
+ (ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)) &&
6743
+ property.name.text === "granularity" &&
6744
+ ts.isStringLiteral(property.initializer) &&
6745
+ property.initializer.text === "grapheme"))) {
5788
6746
  lowerer.noLowering("Intl.Segmenter options", options, 'the native segmenter supports default options and { granularity: "grapheme" }; word and sentence segmentation remain unsupported');
5789
6747
  }
5790
6748
  // Explicit undefined expressions can carry effects; retain argument order.
5791
6749
  const stmts = args.map((arg) => {
5792
6750
  const value = lowerer.lowerExpr(arg);
5793
- return { kind: "exprStmt", expr: value.type.kind === "void" ? value : lowerer.coerceInto(arg, value, DYN), loc: locOf(arg) };
6751
+ return {
6752
+ kind: "exprStmt",
6753
+ expr: value.type.kind === "void" ? value : lowerer.coerceInto(arg, value, DYN),
6754
+ loc: locOf(arg),
6755
+ };
5794
6756
  });
5795
6757
  const result = { kind: "libCall", fn: "intl.segmenterNew", args: [], type: DYN, loc };
5796
6758
  return stmts.length ? { kind: "seqExpr", stmts, result, type: DYN, loc } : result;
@@ -5960,8 +6922,10 @@ export function lowerNew(lowerer, expr) {
5960
6922
  if (agent)
5961
6923
  return agent;
5962
6924
  }
5963
- if (ts.isIdentifier(expr.expression) || ts.isPropertyAccessExpression(expr.expression) && ts.isIdentifier(expr.expression.name) &&
5964
- lowerer.isStdlibGlobal(expr.expression.expression, "globalThis")) {
6925
+ if (ts.isIdentifier(expr.expression) ||
6926
+ (ts.isPropertyAccessExpression(expr.expression) &&
6927
+ ts.isIdentifier(expr.expression.name) &&
6928
+ lowerer.isStdlibGlobal(expr.expression.expression, "globalThis"))) {
5965
6929
  // `import C = N.C; new C()` — the alias's own source-order guards
5966
6930
  // (a no-op for every non-import= binding).
5967
6931
  if (ts.isIdentifier(expr.expression))
@@ -6059,8 +7023,14 @@ export function lowerNew(lowerer, expr) {
6059
7023
  if (values.some((value) => value.type.kind === "dyn" || value.type.kind === "regex")) {
6060
7024
  const checked = [0, 1].map((index) => values[index]
6061
7025
  ? lowerer.coerceInto(args[index], values[index], DYN)
6062
- : { kind: "dynFrom", value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc }, type: DYN, loc });
6063
- return { kind: "libCall", fn: "regex.newChecked", args: checked, type: { kind: "regex" }, loc };
7026
+ : dynUndefinedExpr(loc));
7027
+ return {
7028
+ kind: "libCall",
7029
+ fn: "regex.newChecked",
7030
+ args: checked,
7031
+ type: { kind: "regex" },
7032
+ loc,
7033
+ };
6064
7034
  }
6065
7035
  const strArg = (a, what) => {
6066
7036
  if (!a)
@@ -6070,9 +7040,18 @@ export function lowerNew(lowerer, expr) {
6070
7040
  if (v.type.kind === "undefinedT") {
6071
7041
  if (v.kind === "unitLit")
6072
7042
  return empty;
6073
- return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: lowerer.coerceToExpected(v, DYN), loc: locOf(a) }], result: empty, type: STRING, loc };
7043
+ return {
7044
+ kind: "seqExpr",
7045
+ stmts: [{ kind: "exprStmt", expr: lowerer.coerceToExpected(v, DYN), loc: locOf(a) }],
7046
+ result: empty,
7047
+ type: STRING,
7048
+ loc,
7049
+ };
6074
7050
  }
6075
- if (v.type.kind === "union" && lowerer.unions.get(v.type.unionId)?.arms.every((arm) => arm.kind === "string" || arm.kind === "undefinedT")) {
7051
+ if (v.type.kind === "union" &&
7052
+ lowerer.unions
7053
+ .get(v.type.unionId)
7054
+ ?.arms.every((arm) => arm.kind === "string" || arm.kind === "undefinedT")) {
6076
7055
  return { kind: "nullish", left: v, right: empty, type: STRING, loc: locOf(a) };
6077
7056
  }
6078
7057
  if (v.type.kind !== "string") {
@@ -6082,7 +7061,13 @@ export function lowerNew(lowerer, expr) {
6082
7061
  };
6083
7062
  const pattern = strArg(args[0], "pattern");
6084
7063
  const flags = strArg(args[1], "flags argument");
6085
- return { kind: "libCall", fn: "regex.new", args: [pattern, flags], type: { kind: "regex" }, loc };
7064
+ return {
7065
+ kind: "libCall",
7066
+ fn: "regex.new",
7067
+ args: [pattern, flags],
7068
+ type: { kind: "regex" },
7069
+ loc,
7070
+ };
6086
7071
  }
6087
7072
  if (symbol && symbol.name === "URL" && lowerer.isStdlibSymbol(symbol)) {
6088
7073
  return lowerUrlNew(lowerer, expr);
@@ -6102,9 +7087,20 @@ export function lowerNew(lowerer, expr) {
6102
7087
  lowerer.noLowering(`new Date with ${args.length} arguments`, expr, "new Date(), new Date(milliseconds), and new Date(dateString) are supported; the local-time year/month field constructor has no lowering", symbol);
6103
7088
  }
6104
7089
  if (isJsSourceFile(expr.getSourceFile())) {
6105
- return { kind: "libCall", fn: "date.nativeNew", args: [
6106
- { kind: "dynArrLit", elems: args.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), type: DYN, loc },
6107
- ], type: DYN, loc };
7090
+ return {
7091
+ kind: "libCall",
7092
+ fn: "date.nativeNew",
7093
+ args: [
7094
+ {
7095
+ kind: "dynArrLit",
7096
+ elems: args.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
7097
+ type: DYN,
7098
+ loc,
7099
+ },
7100
+ ],
7101
+ type: DYN,
7102
+ loc,
7103
+ };
6108
7104
  }
6109
7105
  if (args.length === 0) {
6110
7106
  return { kind: "libCall", fn: "date.newNow", args: [], type: DATE_T, loc };
@@ -6146,7 +7142,9 @@ export function lowerNew(lowerer, expr) {
6146
7142
  loc,
6147
7143
  };
6148
7144
  }
6149
- if (symbol && (symbol.name === "TextDecoder" || symbol.name === "TextEncoder") && lowerer.isStdlibSymbol(symbol)) {
7145
+ if (symbol &&
7146
+ (symbol.name === "TextDecoder" || symbol.name === "TextEncoder") &&
7147
+ lowerer.isStdlibSymbol(symbol)) {
6150
7148
  return lowerTextCodecNew(lowerer, expr, symbol.name);
6151
7149
  }
6152
7150
  // `new Uint8Array(...)` / `new Uint32Array(...)` / `new
@@ -6191,7 +7189,8 @@ export function lowerNew(lowerer, expr) {
6191
7189
  }
6192
7190
  if (symbol?.name === "Map" && lowerer.isStdlibSymbol(symbol)) {
6193
7191
  const seedArg = (expr.arguments?.length ?? 0) === 1 ? expr.arguments[0] : null;
6194
- const isPairLit = (el) => ts.isArrayLiteralExpression(el) && el.elements.length === 2 &&
7192
+ const isPairLit = (el) => ts.isArrayLiteralExpression(el) &&
7193
+ el.elements.length === 2 &&
6195
7194
  !el.elements.some(ts.isSpreadElement);
6196
7195
  const entriesLit = seedArg && ts.isArrayLiteralExpression(seedArg) && seedArg.elements.every(isPairLit)
6197
7196
  ? seedArg.elements.filter(isPairLit)
@@ -6212,7 +7211,8 @@ export function lowerNew(lowerer, expr) {
6212
7211
  while (ts.isParenthesizedExpression(parent))
6213
7212
  parent = parent.parent;
6214
7213
  // `satisfies` checks a view but retains the expression's own type.
6215
- const contextualSeed = !ts.isSatisfiesExpression(parent) && (expr.typeArguments?.length ?? 0) === 0 &&
7214
+ const contextualSeed = !ts.isSatisfiesExpression(parent) &&
7215
+ (expr.typeArguments?.length ?? 0) === 0 &&
6216
7216
  (entriesLit !== null || (expr.arguments?.length ?? 0) === 0);
6217
7217
  // JavaScript's `new Map()` has no type-argument syntax: the no-arg
6218
7218
  // constructor overload pins Map<any, any> whatever the JSDoc says
@@ -6264,7 +7264,9 @@ export function lowerNew(lowerer, expr) {
6264
7264
  return { kind: "dynObjLit", type: DYN, loc };
6265
7265
  }
6266
7266
  const keyIr = targs[0] ? lowerer.mapTypeOf(targs[0]) : null;
6267
- if (targs[0] && (!keyIr || !isSupportedMapKey(keyIr, keyIr.kind === "union" ? lowerer.unions.get(keyIr.unionId)?.arms : undefined))) {
7267
+ if (targs[0] &&
7268
+ (!keyIr ||
7269
+ !isSupportedMapKey(keyIr, keyIr.kind === "union" ? lowerer.unions.get(keyIr.unionId)?.arms : undefined))) {
6268
7270
  lowerer.unsupported("SC1090", expr, `Map keys of type '${lowerer.checker.typeToString(targs[0])}' ` +
6269
7271
  `(Map keys must be numbers, strings, booleans, bigints, identity references, or supported unions)`);
6270
7272
  }
@@ -6276,19 +7278,35 @@ export function lowerNew(lowerer, expr) {
6276
7278
  lowerer.badType(expr, tsType);
6277
7279
  }
6278
7280
  // Weak containers share checked native key identities and lifetime hooks.
6279
- if ((symbol?.name === "WeakMap" || symbol?.name === "WeakSet") && lowerer.isStdlibSymbol(symbol)) {
7281
+ if ((symbol?.name === "WeakMap" || symbol?.name === "WeakSet") &&
7282
+ lowerer.isStdlibSymbol(symbol)) {
6280
7283
  const args = expr.arguments ?? [];
6281
7284
  if (args.length > 1 || args.some(ts.isSpreadElement)) {
6282
7285
  lowerer.unsupported("SC1090", expr, `${symbol.name} construction with surplus or spread arguments`);
6283
7286
  }
6284
7287
  if (lowerer.dynamic) {
6285
- const ctor = { kind: "jsOp", op: "globalGet", name: symbol.name, args: [], type: JSVAL, loc };
6286
- return { kind: "jsOp", op: "construct", args: [ctor, ...args.map((arg) => lowerer.jsvalIn(lowerer.lowerExpr(arg), arg))], type: JSVAL, loc };
7288
+ const ctor = {
7289
+ kind: "jsOp",
7290
+ op: "globalGet",
7291
+ name: symbol.name,
7292
+ args: [],
7293
+ type: JSVAL,
7294
+ loc,
7295
+ };
7296
+ return {
7297
+ kind: "jsOp",
7298
+ op: "construct",
7299
+ args: [ctor, ...args.map((arg) => lowerer.jsvalIn(lowerer.lowerExpr(arg), arg))],
7300
+ type: JSVAL,
7301
+ loc,
7302
+ };
6287
7303
  }
6288
7304
  return {
6289
- kind: "libCall", fn: symbol.name === "WeakMap" ? "weakMap.new" : "weakSet.new",
7305
+ kind: "libCall",
7306
+ fn: symbol.name === "WeakMap" ? "weakMap.new" : "weakSet.new",
6290
7307
  args: [args[0] ? lowerer.lowerExprExpecting(args[0], DYN) : dynUndefinedExpr(loc)],
6291
- type: DYN, loc,
7308
+ type: DYN,
7309
+ loc,
6292
7310
  };
6293
7311
  }
6294
7312
  // `new Set<T>()`: construct + bulk add from supported values,
@@ -6304,9 +7322,21 @@ export function lowerNew(lowerer, expr) {
6304
7322
  if (seeded)
6305
7323
  return seeded;
6306
7324
  }
6307
- if (!mapped && isJsSourceFile(expr.getSourceFile()) && (expr.arguments?.length ?? 0) <= 1 && !expr.arguments?.some(ts.isSpreadElement)) {
6308
- return { kind: "libCall", fn: "dyn.nativeSetNew", args: [expr.arguments?.[0]
6309
- ? lowerer.lowerExprExpecting(expr.arguments[0], DYN) : dynUndefinedExpr(loc)], type: DYN, loc };
7325
+ if (!mapped &&
7326
+ isJsSourceFile(expr.getSourceFile()) &&
7327
+ (expr.arguments?.length ?? 0) <= 1 &&
7328
+ !expr.arguments?.some(ts.isSpreadElement)) {
7329
+ return {
7330
+ kind: "libCall",
7331
+ fn: "dyn.nativeSetNew",
7332
+ args: [
7333
+ expr.arguments?.[0]
7334
+ ? lowerer.lowerExprExpecting(expr.arguments[0], DYN)
7335
+ : dynUndefinedExpr(loc),
7336
+ ],
7337
+ type: DYN,
7338
+ loc,
7339
+ };
6310
7340
  }
6311
7341
  // JavaScript's identity-Set idiom: `new Set([setTimeout, atob,
6312
7342
  // ...])` — the element TYPE (a union of stdlib signatures) has no
@@ -6427,7 +7457,9 @@ export function lowerNew(lowerer, expr) {
6427
7457
  lowerer.mapTypeOf(lowerer.typeOf(expr.arguments[0]))?.kind !== "string" &&
6428
7458
  lowerer.mapTypeOf(lowerer.typeOf(expr.arguments[1]))?.kind === "string") {
6429
7459
  const first = lowerer.lowerExpr(expr.arguments[0]);
6430
- if (first.kind === "unitLit" || first.type.kind === "dyn" || lowerer.dynConvertible(first.type)) {
7460
+ if (first.kind === "unitLit" ||
7461
+ first.type.kind === "dyn" ||
7462
+ lowerer.dynConvertible(first.type)) {
6431
7463
  const got = first.type.kind === "dyn" ? first : { kind: "dynFrom", value: first, type: DYN, loc };
6432
7464
  // The encoding argument still evaluates in Node before the
6433
7465
  // throw only via the ctor body's later reads — it does NOT
@@ -6435,7 +7467,13 @@ export function lowerNew(lowerer, expr) {
6435
7467
  // effect-free operands; effectful ones keep the fence.
6436
7468
  const enc = lowerer.lowerExpr(expr.arguments[1]);
6437
7469
  if (enc.kind === "strLit" || isSafeToRepeat(enc)) {
6438
- return { kind: "libCall", fn: "buffer.newStringFail", args: [got], type: bytesOf("u8"), loc };
7470
+ return {
7471
+ kind: "libCall",
7472
+ fn: "buffer.newStringFail",
7473
+ args: [got],
7474
+ type: bytesOf("u8"),
7475
+ loc,
7476
+ };
6439
7477
  }
6440
7478
  }
6441
7479
  }
@@ -6490,10 +7528,10 @@ export function lowerNew(lowerer, expr) {
6490
7528
  if (t?.kind !== "record")
6491
7529
  lowerer.badType(expr, lowerer.typeOf(expr));
6492
7530
  const key = `x509.record:${isBytes ? "bytes" : "str"}`;
6493
- let helper = lowerer.widthHelpers.get(key);
7531
+ let helper = lowerer.valueHelpers.get(key);
6494
7532
  if (!helper) {
6495
- helper = `%x509.record.${lowerer.widthHelpers.size}`;
6496
- lowerer.widthHelpers.set(key, helper);
7533
+ helper = `%x509.record.${lowerer.valueHelpers.size}`;
7534
+ lowerer.valueHelpers.set(key, helper);
6497
7535
  const dataT = data.type;
6498
7536
  const dRef = { kind: "varRef", localId: "d.0", type: dataT, loc };
6499
7537
  const field = (name, fn) => ({
@@ -6539,7 +7577,9 @@ export function lowerNew(lowerer, expr) {
6539
7577
  const calleeT = storedClassValueType(lowerer, expr.expression);
6540
7578
  if (calleeT?.kind === "classval") {
6541
7579
  let info = lowerer.classes.get(calleeT.className);
6542
- if (!info && ts.isPropertyAccessExpression(expr.expression) && ts.isIdentifier(expr.expression.name)) {
7580
+ if (!info &&
7581
+ ts.isPropertyAccessExpression(expr.expression) &&
7582
+ ts.isIdentifier(expr.expression.name)) {
6543
7583
  // A property-assigned class expression not collected yet (this
6544
7584
  // body lowers ahead of the assignment statement — hoisted
6545
7585
  // functions): collect it on demand and retry, keeping the
@@ -6590,7 +7630,8 @@ export function lowerNew(lowerer, expr) {
6590
7630
  if (calleeT?.kind === "union") {
6591
7631
  const def = lowerer.unions.get(calleeT.unionId);
6592
7632
  if (def?.arms.some((a) => a.kind === "classval")) {
6593
- if (def.arms.every((arm) => arm.kind === "classval" || isJsSourceFile(expr.getSourceFile()) && isUnitType(arm)) && lowerer.dynConvertible(calleeT)) {
7633
+ if (def.arms.every((arm) => arm.kind === "classval" || (isJsSourceFile(expr.getSourceFile()) && isUnitType(arm))) &&
7634
+ lowerer.dynConvertible(calleeT)) {
6594
7635
  const callee = lowerer.lowerExprExpecting(expr.expression, DYN);
6595
7636
  return lowerCheckedConstructor(lowerer, expr, callee);
6596
7637
  }
@@ -6621,7 +7662,10 @@ export function lowerNew(lowerer, expr) {
6621
7662
  }
6622
7663
  // Checked construction supports emitted classes and builtin typed arrays.
6623
7664
  const callee = tryLowerExpression(lowerer, expr.expression);
6624
- if (callee && (callee.type.kind === "dyn" || (callee.type.kind === "func" || callee.type.kind === "classval") && lowerer.dynConvertible(callee.type))) {
7665
+ if (callee &&
7666
+ (callee.type.kind === "dyn" ||
7667
+ ((callee.type.kind === "func" || callee.type.kind === "classval") &&
7668
+ lowerer.dynConvertible(callee.type)))) {
6625
7669
  return lowerCheckedConstructor(lowerer, expr, lowerer.coerceToExpected(callee, DYN));
6626
7670
  }
6627
7671
  lowerer.unsupported("SC1090", expr, "constructing values other than classes declared in the program");
@@ -6636,10 +7680,10 @@ function lowerCheckedConstructor(lowerer, expr, callee) {
6636
7680
  return checkedClassConstruction(lowerer, callee, args.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), loc);
6637
7681
  }
6638
7682
  /** A getter/setter invocation over an accessor target's receiver — the
6639
- * same whole-program devirtualization as method calls: a virtualCall
6640
- * when some strict subclass of the receiver's static class overrides
6641
- * this HALF of the accessor (get and set devirtualize independently),
6642
- * a direct call of the nearest declaration otherwise. */
7683
+ * same whole-program devirtualization as method calls: a virtualCall
7684
+ * when some strict subclass of the receiver's static class overrides
7685
+ * this HALF of the accessor (get and set devirtualize independently),
7686
+ * a direct call of the nearest declaration otherwise. */
6643
7687
  export function accessorCall(lowerer, className, member, obj, extraArgs, ret, loc) {
6644
7688
  const info = lowerer.classes.get(className);
6645
7689
  if (!info)
@@ -6687,7 +7731,8 @@ function genericFieldFnNodeOf(member) {
6687
7731
  while (ts.isParenthesizedExpression(init))
6688
7732
  init = init.expression;
6689
7733
  if ((ts.isArrowFunction(init) || ts.isFunctionExpression(init)) &&
6690
- init.typeParameters !== undefined && init.body !== undefined) {
7734
+ init.typeParameters !== undefined &&
7735
+ init.body !== undefined) {
6691
7736
  return init;
6692
7737
  }
6693
7738
  return null;