@scriptc/compiler 0.0.34 → 0.0.36

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 (424) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +7 -6
  2. package/dist/backend/build-cache.d.ts +44 -0
  3. package/dist/backend/build-cache.js +241 -0
  4. package/dist/backend/build-cache.js.map +1 -0
  5. package/dist/backend/{emission/emit-async.d.ts → c/async.d.ts} +21 -30
  6. package/dist/backend/{emission/emit-async.js → c/async.js} +270 -286
  7. package/dist/backend/c/async.js.map +1 -0
  8. package/dist/backend/{emission/emitter.d.ts → c/c-emitter.d.ts} +6 -23
  9. package/dist/backend/{emission/emitter.js → c/c-emitter.js} +53 -107
  10. package/dist/backend/c/c-emitter.js.map +1 -0
  11. package/dist/backend/c/exprs.d.ts +8 -0
  12. package/dist/backend/c/exprs.js +7913 -0
  13. package/dist/backend/c/exprs.js.map +1 -0
  14. package/dist/backend/{emission/emit-island.d.ts → c/island.d.ts} +5 -5
  15. package/dist/backend/{emission/emit-island.js → c/island.js} +24 -22
  16. package/dist/backend/c/island.js.map +1 -0
  17. package/dist/backend/{emission → c}/may-throw.d.ts +1 -1
  18. package/dist/backend/{emission → c}/may-throw.js +1 -1
  19. package/dist/backend/c/may-throw.js.map +1 -0
  20. package/dist/backend/{emission/emit-shapes.d.ts → c/shapes.d.ts} +19 -19
  21. package/dist/backend/{emission/emit-shapes.js → c/shapes.js} +78 -87
  22. package/dist/backend/c/shapes.js.map +1 -0
  23. package/dist/backend/{emission/emit-stmts.d.ts → c/stmts.d.ts} +12 -12
  24. package/dist/backend/{emission/emit-stmts.js → c/stmts.js} +377 -343
  25. package/dist/backend/c/stmts.js.map +1 -0
  26. package/dist/backend/{emission/emit-types.d.ts → c/types.d.ts} +1 -1
  27. package/dist/backend/{emission/emit-types.js → c/types.js} +42 -286
  28. package/dist/backend/c/types.js.map +1 -0
  29. package/dist/backend/c/types.test.js +25 -0
  30. package/dist/backend/c/types.test.js.map +1 -0
  31. package/dist/backend/{emission/emit-walkers.d.ts → c/walkers.d.ts} +19 -41
  32. package/dist/backend/{emission/emit-walkers.js → c/walkers.js} +238 -298
  33. package/dist/backend/c/walkers.js.map +1 -0
  34. package/dist/backend/ffi-callbacks.d.ts +1 -1
  35. package/dist/backend/ffi-callbacks.js +4 -3
  36. package/dist/backend/ffi-callbacks.js.map +1 -1
  37. package/dist/backend/{library-identity.d.ts → library-identity-markers.d.ts} +0 -4
  38. package/dist/backend/{library-identity.js → library-identity-markers.js} +10 -9
  39. package/dist/backend/library-identity-markers.js.map +1 -0
  40. package/dist/backend/llvm/blocks.d.ts +4 -0
  41. package/dist/backend/llvm/blocks.js +29 -0
  42. package/dist/backend/llvm/blocks.js.map +1 -1
  43. package/dist/backend/llvm/classes.d.ts +2 -19
  44. package/dist/backend/llvm/classes.js +20 -52
  45. package/dist/backend/llvm/classes.js.map +1 -1
  46. package/dist/backend/llvm/common.d.ts +4 -0
  47. package/dist/backend/llvm/common.js +27 -0
  48. package/dist/backend/llvm/common.js.map +1 -0
  49. package/dist/backend/llvm/dyn.d.ts +3 -8
  50. package/dist/backend/llvm/dyn.js +152 -224
  51. package/dist/backend/llvm/dyn.js.map +1 -1
  52. package/dist/backend/llvm/emitter.d.ts +4 -1
  53. package/dist/backend/llvm/emitter.js +514 -9981
  54. package/dist/backend/llvm/emitter.js.map +1 -1
  55. package/dist/backend/llvm/expr-async.d.ts +4 -0
  56. package/dist/backend/llvm/expr-async.js +726 -0
  57. package/dist/backend/llvm/expr-async.js.map +1 -0
  58. package/dist/backend/llvm/expr-bytes.d.ts +13 -0
  59. package/dist/backend/llvm/expr-bytes.js +456 -0
  60. package/dist/backend/llvm/expr-bytes.js.map +1 -0
  61. package/dist/backend/llvm/expr-callbacks.d.ts +22 -0
  62. package/dist/backend/llvm/expr-callbacks.js +520 -0
  63. package/dist/backend/llvm/expr-callbacks.js.map +1 -0
  64. package/dist/backend/llvm/expr-calls.d.ts +2 -0
  65. package/dist/backend/llvm/expr-calls.js +618 -0
  66. package/dist/backend/llvm/expr-calls.js.map +1 -0
  67. package/dist/backend/llvm/expr-containers.d.ts +25 -0
  68. package/dist/backend/llvm/expr-containers.js +623 -0
  69. package/dist/backend/llvm/expr-containers.js.map +1 -0
  70. package/dist/backend/llvm/expr-context.d.ts +255 -0
  71. package/dist/backend/llvm/expr-context.js +2 -0
  72. package/dist/backend/llvm/expr-context.js.map +1 -0
  73. package/dist/backend/llvm/expr-control.d.ts +2 -0
  74. package/dist/backend/llvm/expr-control.js +473 -0
  75. package/dist/backend/llvm/expr-control.js.map +1 -0
  76. package/dist/backend/llvm/expr-dispatch.d.ts +4 -0
  77. package/dist/backend/llvm/expr-dispatch.js +151 -0
  78. package/dist/backend/llvm/expr-dispatch.js.map +1 -0
  79. package/dist/backend/llvm/expr-dynamic.d.ts +2 -0
  80. package/dist/backend/llvm/expr-dynamic.js +810 -0
  81. package/dist/backend/llvm/expr-dynamic.js.map +1 -0
  82. package/dist/backend/llvm/expr-island.d.ts +15 -0
  83. package/dist/backend/llvm/expr-island.js +690 -0
  84. package/dist/backend/llvm/expr-island.js.map +1 -0
  85. package/dist/backend/llvm/expr-primitives.d.ts +6 -0
  86. package/dist/backend/llvm/expr-primitives.js +622 -0
  87. package/dist/backend/llvm/expr-primitives.js.map +1 -0
  88. package/dist/backend/llvm/expr-records.d.ts +9 -0
  89. package/dist/backend/llvm/expr-records.js +299 -0
  90. package/dist/backend/llvm/expr-records.js.map +1 -0
  91. package/dist/backend/llvm/expr-stream-bridges.d.ts +13 -0
  92. package/dist/backend/llvm/expr-stream-bridges.js +396 -0
  93. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -0
  94. package/dist/backend/llvm/expr-stream-callbacks.d.ts +12 -0
  95. package/dist/backend/llvm/expr-stream-callbacks.js +360 -0
  96. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -0
  97. package/dist/backend/llvm/lib-dispatch.d.ts +5 -0
  98. package/dist/backend/llvm/lib-dispatch.js +267 -0
  99. package/dist/backend/llvm/lib-dispatch.js.map +1 -0
  100. package/dist/backend/llvm/lib-filesystem.d.ts +6 -0
  101. package/dist/backend/llvm/lib-filesystem.js +594 -0
  102. package/dist/backend/llvm/lib-filesystem.js.map +1 -0
  103. package/dist/backend/llvm/lib-network.d.ts +2 -0
  104. package/dist/backend/llvm/lib-network.js +429 -0
  105. package/dist/backend/llvm/lib-network.js.map +1 -0
  106. package/dist/backend/llvm/lib-process.d.ts +5 -0
  107. package/dist/backend/llvm/lib-process.js +585 -0
  108. package/dist/backend/llvm/lib-process.js.map +1 -0
  109. package/dist/backend/llvm/lib-shared.d.ts +6 -0
  110. package/dist/backend/llvm/lib-shared.js +687 -0
  111. package/dist/backend/llvm/lib-shared.js.map +1 -0
  112. package/dist/backend/llvm/lib-stream.d.ts +2 -0
  113. package/dist/backend/llvm/lib-stream.js +470 -0
  114. package/dist/backend/llvm/lib-stream.js.map +1 -0
  115. package/dist/backend/llvm/shapes.d.ts +12 -2
  116. package/dist/backend/llvm/shapes.js +66 -307
  117. package/dist/backend/llvm/shapes.js.map +1 -1
  118. package/dist/backend/llvm/shapes.test.js +52 -0
  119. package/dist/backend/llvm/shapes.test.js.map +1 -0
  120. package/dist/backend/llvm/split.d.ts +43 -0
  121. package/dist/backend/llvm/split.js +227 -0
  122. package/dist/backend/llvm/split.js.map +1 -0
  123. package/dist/backend/llvm/split.test.d.ts +1 -0
  124. package/dist/backend/llvm/split.test.js +102 -0
  125. package/dist/backend/llvm/split.test.js.map +1 -0
  126. package/dist/backend/llvm/unsupported.d.ts +1 -1
  127. package/dist/backend/llvm/walkers.d.ts +2 -3
  128. package/dist/backend/llvm/walkers.js +164 -218
  129. package/dist/backend/llvm/walkers.js.map +1 -1
  130. package/dist/backend/native-codegen.d.ts +38 -0
  131. package/dist/backend/native-codegen.js +261 -0
  132. package/dist/backend/native-codegen.js.map +1 -0
  133. package/dist/backend/native-codegen.test.d.ts +1 -0
  134. package/dist/backend/native-codegen.test.js +188 -0
  135. package/dist/backend/native-codegen.test.js.map +1 -0
  136. package/dist/backend/native-link-info.d.ts +96 -0
  137. package/dist/backend/native-link-info.js +219 -0
  138. package/dist/backend/native-link-info.js.map +1 -0
  139. package/dist/backend/native-link-info.test.d.ts +1 -0
  140. package/dist/backend/native-link-info.test.js +134 -0
  141. package/dist/backend/native-link-info.test.js.map +1 -0
  142. package/dist/backend/{cc.d.ts → native-toolchain.d.ts} +139 -47
  143. package/dist/backend/{cc.js → native-toolchain.js} +1008 -910
  144. package/dist/backend/native-toolchain.js.map +1 -0
  145. package/dist/backend/native-toolchain.test.d.ts +1 -0
  146. package/dist/backend/{cc-cache.test.js → native-toolchain.test.js} +1297 -127
  147. package/dist/backend/native-toolchain.test.js.map +1 -0
  148. package/dist/backend/object-localize.js +1 -1
  149. package/dist/backend/object-localize.test.js +20 -0
  150. package/dist/backend/object-localize.test.js.map +1 -1
  151. package/dist/backend/runtime-abi.d.ts +10 -0
  152. package/dist/backend/runtime-abi.js +11 -0
  153. package/dist/backend/runtime-abi.js.map +1 -0
  154. package/dist/backend/runtime-pack.d.ts +137 -0
  155. package/dist/backend/runtime-pack.js +400 -0
  156. package/dist/backend/runtime-pack.js.map +1 -0
  157. package/dist/backend/runtime-pack.test.d.ts +1 -0
  158. package/dist/backend/runtime-pack.test.js +438 -0
  159. package/dist/backend/runtime-pack.test.js.map +1 -0
  160. package/dist/backend/targets.d.ts +30 -0
  161. package/dist/backend/targets.js +46 -0
  162. package/dist/backend/targets.js.map +1 -0
  163. package/dist/backend/targets.test.d.ts +1 -0
  164. package/dist/backend/targets.test.js +19 -0
  165. package/dist/backend/targets.test.js.map +1 -0
  166. package/dist/backend/vendor-archives.d.ts +41 -0
  167. package/dist/backend/vendor-archives.js +462 -0
  168. package/dist/backend/vendor-archives.js.map +1 -0
  169. package/dist/compat/fetch-profile.d.ts +0 -1
  170. package/dist/compat/fetch-profile.js +0 -1
  171. package/dist/compat/fetch-profile.js.map +1 -1
  172. package/dist/coverage/report.js +3 -3
  173. package/dist/coverage/report.js.map +1 -1
  174. package/dist/coverage/surface-manifest.js +25 -32
  175. package/dist/coverage/surface-manifest.js.map +1 -1
  176. package/dist/diagnostics/diagnostic.d.ts +11 -12
  177. package/dist/diagnostics/diagnostic.js +19 -17
  178. package/dist/diagnostics/diagnostic.js.map +1 -1
  179. package/dist/diagnostics/render.d.ts +1 -1
  180. package/dist/diagnostics/render.js +1 -1
  181. package/dist/diagnostics/render.js.map +1 -1
  182. package/dist/errors.d.ts +5 -0
  183. package/dist/errors.js +9 -0
  184. package/dist/errors.js.map +1 -0
  185. package/dist/executable/executable-cache.d.ts +86 -0
  186. package/dist/executable/executable-cache.js +398 -0
  187. package/dist/executable/executable-cache.js.map +1 -0
  188. package/dist/executable/executable-cache.test.d.ts +1 -0
  189. package/dist/executable/executable-cache.test.js +300 -0
  190. package/dist/executable/executable-cache.test.js.map +1 -0
  191. package/dist/ffi/{profile.d.ts → ffi-manifest.d.ts} +7 -2
  192. package/dist/ffi/{profile.js → ffi-manifest.js} +2 -1
  193. package/dist/ffi/ffi-manifest.js.map +1 -0
  194. package/dist/frontend/builtin-modules.d.ts +21 -0
  195. package/dist/frontend/builtin-modules.js +82 -0
  196. package/dist/frontend/builtin-modules.js.map +1 -0
  197. package/dist/frontend/cjs-lexer.d.ts +7 -0
  198. package/dist/frontend/cjs-lexer.js +15 -17
  199. package/dist/frontend/cjs-lexer.js.map +1 -1
  200. package/dist/frontend/dts-paths.d.ts +26 -0
  201. package/dist/frontend/dts-paths.js +41 -0
  202. package/dist/frontend/dts-paths.js.map +1 -0
  203. package/dist/frontend/input-tracker.d.ts +0 -2
  204. package/dist/frontend/input-tracker.js +1 -4
  205. package/dist/frontend/input-tracker.js.map +1 -1
  206. package/dist/frontend/lib-contract.d.ts +1 -5
  207. package/dist/frontend/lib-contract.js +1 -1
  208. package/dist/frontend/lib-contract.js.map +1 -1
  209. package/dist/frontend/lib-exports.d.ts +1 -1
  210. package/dist/frontend/lowering/call-position.d.ts +4 -0
  211. package/dist/frontend/lowering/call-position.js +7 -0
  212. package/dist/frontend/lowering/call-position.js.map +1 -0
  213. package/dist/frontend/lowering/callback-arg.d.ts +20 -0
  214. package/dist/frontend/lowering/callback-arg.js +44 -0
  215. package/dist/frontend/lowering/callback-arg.js.map +1 -0
  216. package/dist/frontend/lowering/lib-boundary.d.ts +1 -1
  217. package/dist/frontend/lowering/lib-boundary.js +34 -34
  218. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  219. package/dist/frontend/lowering/lower-assert.d.ts +3 -3
  220. package/dist/frontend/lowering/lower-assert.js +214 -241
  221. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  222. package/dist/frontend/lowering/lower-builtins.d.ts +74 -146
  223. package/dist/frontend/lowering/lower-builtins.js +1126 -1234
  224. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  225. package/dist/frontend/lowering/lower-calls.d.ts +56 -188
  226. package/dist/frontend/lowering/lower-calls.js +1409 -1494
  227. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  228. package/dist/frontend/lowering/lower-classes.d.ts +62 -125
  229. package/dist/frontend/lowering/lower-classes.js +832 -866
  230. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  231. package/dist/frontend/lowering/lower-comptime.d.ts +5 -12
  232. package/dist/frontend/lowering/lower-comptime.js +32 -31
  233. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  234. package/dist/frontend/lowering/lower-containers.d.ts +35 -135
  235. package/dist/frontend/lowering/lower-containers.js +1394 -1715
  236. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  237. package/dist/frontend/lowering/lower-dgram.d.ts +3 -7
  238. package/dist/frontend/lowering/lower-dgram.js +97 -111
  239. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  240. package/dist/frontend/lowering/lower-enums.d.ts +4 -4
  241. package/dist/frontend/lowering/lower-enums.js +30 -30
  242. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  243. package/dist/frontend/lowering/{lower-emitter.d.ts → lower-event-emitter.d.ts} +7 -18
  244. package/dist/frontend/lowering/{lower-emitter.js → lower-event-emitter.js} +172 -174
  245. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -0
  246. package/dist/frontend/lowering/lower-expando.d.ts +5 -5
  247. package/dist/frontend/lowering/lower-expando.js +40 -40
  248. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  249. package/dist/frontend/lowering/lower-exprs.d.ts +56 -264
  250. package/dist/frontend/lowering/lower-exprs.js +1644 -1704
  251. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  252. package/dist/frontend/lowering/lower-generators.d.ts +6 -6
  253. package/dist/frontend/lowering/lower-generators.js +73 -72
  254. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  255. package/dist/frontend/lowering/lower-inspect.d.ts +5 -17
  256. package/dist/frontend/lowering/lower-inspect.js +236 -238
  257. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  258. package/dist/frontend/lowering/lower-island.d.ts +34 -45
  259. package/dist/frontend/lowering/lower-island.js +440 -511
  260. package/dist/frontend/lowering/lower-island.js.map +1 -1
  261. package/dist/frontend/lowering/lower-mixins.d.ts +7 -10
  262. package/dist/frontend/lowering/lower-mixins.js +86 -86
  263. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  264. package/dist/frontend/lowering/lower-modules.d.ts +12 -18
  265. package/dist/frontend/lowering/lower-modules.js +284 -283
  266. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  267. package/dist/frontend/lowering/lower-namespaces.d.ts +23 -49
  268. package/dist/frontend/lowering/lower-namespaces.js +123 -115
  269. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  270. package/dist/frontend/lowering/lower-server.d.ts +18 -25
  271. package/dist/frontend/lowering/lower-server.js +899 -899
  272. package/dist/frontend/lowering/lower-server.js.map +1 -1
  273. package/dist/frontend/lowering/lower-stmts.d.ts +30 -149
  274. package/dist/frontend/lowering/lower-stmts.js +1176 -1229
  275. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  276. package/dist/frontend/lowering/lower-stream.d.ts +12 -12
  277. package/dist/frontend/lowering/lower-stream.js +300 -301
  278. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  279. package/dist/frontend/lowering/lower-test.d.ts +5 -5
  280. package/dist/frontend/lowering/lower-test.js +82 -82
  281. package/dist/frontend/lowering/lower-test.js.map +1 -1
  282. package/dist/frontend/lowering/lowerer.d.ts +66 -20
  283. package/dist/frontend/lowering/lowerer.js +421 -198
  284. package/dist/frontend/lowering/lowerer.js.map +1 -1
  285. package/dist/frontend/lowering/pairs-snapshot.d.ts +11 -0
  286. package/dist/frontend/lowering/pairs-snapshot.js +85 -0
  287. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -0
  288. package/dist/frontend/lowering/static-this.d.ts +6 -0
  289. package/dist/frontend/lowering/static-this.js +24 -0
  290. package/dist/frontend/lowering/static-this.js.map +1 -0
  291. package/dist/frontend/lowering/surfaces.d.ts +14 -33
  292. package/dist/frontend/lowering/surfaces.js +64 -64
  293. package/dist/frontend/lowering/surfaces.js.map +1 -1
  294. package/dist/frontend/npm-static-rewrite.js +6 -28
  295. package/dist/frontend/npm-static-rewrite.js.map +1 -1
  296. package/dist/frontend/npm-static.d.ts +0 -10
  297. package/dist/frontend/npm-static.js +4 -7
  298. package/dist/frontend/npm-static.js.map +1 -1
  299. package/dist/frontend/npm.d.ts +0 -24
  300. package/dist/frontend/npm.js +11 -85
  301. package/dist/frontend/npm.js.map +1 -1
  302. package/dist/frontend/program.d.ts +3 -1
  303. package/dist/frontend/program.js +51 -17
  304. package/dist/frontend/program.js.map +1 -1
  305. package/dist/frontend/provenance-registry.d.ts +0 -2
  306. package/dist/frontend/provenance-registry.js +0 -10
  307. package/dist/frontend/provenance-registry.js.map +1 -1
  308. package/dist/frontend/provenance.js +4 -7
  309. package/dist/frontend/provenance.js.map +1 -1
  310. package/dist/frontend/resolve.d.ts +7 -2
  311. package/dist/frontend/resolve.js +12 -17
  312. package/dist/frontend/resolve.js.map +1 -1
  313. package/dist/frontend/resolve.test.d.ts +1 -0
  314. package/dist/frontend/resolve.test.js +29 -0
  315. package/dist/frontend/resolve.test.js.map +1 -0
  316. package/dist/frontend/ts7/adapter.d.ts +2 -2
  317. package/dist/frontend/ts7/adapter.js +1 -1
  318. package/dist/frontend/ts7/adapter.js.map +1 -1
  319. package/dist/frontend/ts7/checker.d.ts +40 -2
  320. package/dist/frontend/ts7/checker.js +182 -54
  321. package/dist/frontend/ts7/checker.js.map +1 -1
  322. package/dist/frontend/ts7/enums.js +2 -1
  323. package/dist/frontend/ts7/enums.js.map +1 -1
  324. package/dist/frontend/ts7/{program.js → program-adapter.js} +7 -6
  325. package/dist/frontend/ts7/program-adapter.js.map +1 -0
  326. package/dist/frontend/ts7/world-check.d.ts +1 -3
  327. package/dist/frontend/ts7/world-check.js +3 -1
  328. package/dist/frontend/ts7/world-check.js.map +1 -1
  329. package/dist/frontend/tsc-codes.d.ts +8 -0
  330. package/dist/frontend/tsc-codes.js +109 -0
  331. package/dist/frontend/tsc-codes.js.map +1 -0
  332. package/dist/frontend/{types.d.ts → type-mapper.d.ts} +2 -25
  333. package/dist/frontend/{types.js → type-mapper.js} +31 -52
  334. package/dist/frontend/type-mapper.js.map +1 -0
  335. package/dist/frontend/workspace-registry.d.ts +26 -0
  336. package/dist/frontend/workspace-registry.js +71 -0
  337. package/dist/frontend/workspace-registry.js.map +1 -0
  338. package/dist/index.d.ts +115 -30
  339. package/dist/index.js +650 -146
  340. package/dist/index.js.map +1 -1
  341. package/dist/ir/analysis.d.ts +37 -0
  342. package/dist/ir/analysis.js +118 -0
  343. package/dist/ir/analysis.js.map +1 -0
  344. package/dist/ir/analysis.test.d.ts +1 -0
  345. package/dist/ir/analysis.test.js +21 -0
  346. package/dist/ir/analysis.test.js.map +1 -0
  347. package/dist/ir/build.d.ts +9 -0
  348. package/dist/ir/build.js +33 -0
  349. package/dist/ir/build.js.map +1 -0
  350. package/dist/ir/integer-loops.d.ts +1 -1
  351. package/dist/ir/{nodes.d.ts → ir.d.ts} +60 -26
  352. package/dist/ir/{nodes.js → ir.js} +173 -141
  353. package/dist/ir/ir.js.map +1 -0
  354. package/dist/ir/ir.test.d.ts +1 -0
  355. package/dist/ir/ir.test.js +17 -0
  356. package/dist/ir/ir.test.js.map +1 -0
  357. package/dist/ir/serialize.d.ts +1 -1
  358. package/dist/ir/serialize.js +2 -1
  359. package/dist/ir/serialize.js.map +1 -1
  360. package/dist/ir/validate.d.ts +1 -1
  361. package/dist/ir/validate.js +16 -5
  362. package/dist/ir/validate.js.map +1 -1
  363. package/dist/library/cache-primitives.d.ts +24 -0
  364. package/dist/library/cache-primitives.js +83 -0
  365. package/dist/library/cache-primitives.js.map +1 -0
  366. package/dist/library/cache-reset.test.d.ts +1 -0
  367. package/dist/library/cache-reset.test.js +47 -0
  368. package/dist/library/cache-reset.test.js.map +1 -0
  369. package/dist/library/compiler-self-identity.d.ts +23 -0
  370. package/dist/library/compiler-self-identity.js +84 -0
  371. package/dist/library/compiler-self-identity.js.map +1 -0
  372. package/dist/library/fence-eval.d.ts +3 -1
  373. package/dist/library/fence-eval.js +5 -1
  374. package/dist/library/fence-eval.js.map +1 -1
  375. package/dist/library/int-infer.d.ts +1 -36
  376. package/dist/library/int-infer.js +17 -17
  377. package/dist/library/int-infer.js.map +1 -1
  378. package/dist/library/{early-cache.d.ts → library-cache.d.ts} +1 -1
  379. package/dist/library/{early-cache.js → library-cache.js} +37 -111
  380. package/dist/library/library-cache.js.map +1 -0
  381. package/dist/library/library-cache.test.d.ts +1 -0
  382. package/dist/library/{early-cache.test.js → library-cache.test.js} +2 -2
  383. package/dist/library/library-cache.test.js.map +1 -0
  384. package/dist/library/{profile.d.ts → library-profile.d.ts} +4 -7
  385. package/dist/library/{profile.js → library-profile.js} +18 -11
  386. package/dist/library/library-profile.js.map +1 -0
  387. package/dist/library/semantic-source.js +2 -1
  388. package/dist/library/semantic-source.js.map +1 -1
  389. package/dist/library/sidecar.d.ts +5 -2
  390. package/dist/library/sidecar.js +11 -5
  391. package/dist/library/sidecar.js.map +1 -1
  392. package/dist/startup-cache.d.ts +6 -0
  393. package/dist/startup-cache.js +6 -0
  394. package/dist/startup-cache.js.map +1 -0
  395. package/package.json +7 -2
  396. package/surface-manifest.json +1 -1
  397. package/dist/backend/cc-cache.test.js.map +0 -1
  398. package/dist/backend/cc.js.map +0 -1
  399. package/dist/backend/emission/emit-async.js.map +0 -1
  400. package/dist/backend/emission/emit-exprs.d.ts +0 -13
  401. package/dist/backend/emission/emit-exprs.js +0 -7407
  402. package/dist/backend/emission/emit-exprs.js.map +0 -1
  403. package/dist/backend/emission/emit-island.js.map +0 -1
  404. package/dist/backend/emission/emit-shapes.js.map +0 -1
  405. package/dist/backend/emission/emit-stmts.js.map +0 -1
  406. package/dist/backend/emission/emit-types.js.map +0 -1
  407. package/dist/backend/emission/emit-walkers.js.map +0 -1
  408. package/dist/backend/emission/emitter.js.map +0 -1
  409. package/dist/backend/emission/may-throw.js.map +0 -1
  410. package/dist/backend/library-identity.js.map +0 -1
  411. package/dist/ffi/profile.js.map +0 -1
  412. package/dist/frontend/lowering/lower-emitter.js.map +0 -1
  413. package/dist/frontend/shared.d.ts +0 -82
  414. package/dist/frontend/shared.js +0 -308
  415. package/dist/frontend/shared.js.map +0 -1
  416. package/dist/frontend/ts7/program.js.map +0 -1
  417. package/dist/frontend/types.js.map +0 -1
  418. package/dist/ir/nodes.js.map +0 -1
  419. package/dist/library/early-cache.js.map +0 -1
  420. package/dist/library/early-cache.test.js.map +0 -1
  421. package/dist/library/profile.js.map +0 -1
  422. /package/dist/backend/{cc-cache.test.d.ts → c/types.test.d.ts} +0 -0
  423. /package/dist/{library/early-cache.test.d.ts → backend/llvm/shapes.test.d.ts} +0 -0
  424. /package/dist/frontend/ts7/{program.d.ts → program-adapter.d.ts} +0 -0
@@ -1,12 +1,13 @@
1
+ import { InternalCompilerError } from "../../errors.js";
1
2
  /* Class lowering: shape collection over the single-inheritance graph
2
3
  * (fields, methods, accessors, overrides), constructor/member lowering with
3
4
  * synthesized derived ctors and field initializers, super calls and super
4
5
  * accessor access, upcasts, `new` expressions, and the builtin Error
5
6
  * hierarchy registration. */
6
7
  import * as ts from "../ts7/adapter.js";
7
- import { BOOL, DATE_T, DYN, F64, bytesOf, JSVAL, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, UNDEFINED_T, URL_T, VOID, arrayOf, isSupportedMapKey, isUnitType, typeEquals } from "../../ir/nodes.js";
8
+ import { BOOL, DATE_T, DYN, F64, bytesOf, JSVAL, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, UNDEFINED_T, URL_T, VOID, arrayOf, isSupportedMapKey, isUnitType, typeEquals } from "../../ir/ir.js";
8
9
  import { MAX_GENERIC_INSTANCES, genericCallInstance, implicitAnyParamSymbolsOf, implicitCallInstance, implicitMonoFile, omittedArgFor } from "./lower-calls.js";
9
- import { isGenericCallableMemberType, typeKey } from "../types.js";
10
+ import { isGenericCallableMemberType, typeKey } from "../type-mapper.js";
10
11
  import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, isNodeTypesPath, locOf } from "../program.js";
11
12
  import { PoisonError, dynFallbackType, dynUndefinedExpr, newFnCtx, own } from "./lowerer.js";
12
13
  import { bufEncoding, lowerMapSeedArrayNew } from "./lower-containers.js";
@@ -14,19 +15,20 @@ import { pureReemittable } from "./lower-exprs.js";
14
15
  import { lowerSearchParamsNew } from "./lower-builtins.js";
15
16
  import { requiresDynamicPackageDiag, unsupportedDiag } from "../../diagnostics/diagnostic.js";
16
17
  import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape } from "./lower-stream.js";
17
- import { emitOverrideShapeReason, emitSpecSuperForward, emitterRooted, lowerEmitterSuperCall } from "./lower-emitter.js";
18
+ import { emitOverrideShapeReason, emitSpecSuperForward, emitterRooted, lowerEmitterSuperCall } from "./lower-event-emitter.js";
18
19
  import { declSymbolOf } from "./lower-modules.js";
19
20
  import { uniqueSymbolKeyOf } from "./lower-exprs.js";
20
21
  import { lowerHttpAgentNew, lowerHttpServerNew } from "./lower-server.js";
21
22
  import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead } from "./lower-namespaces.js";
22
23
  import { mixinResultBindingClassOf } from "./lower-mixins.js";
24
+ import { rejectStaticThis } from "./static-this.js";
23
25
  /** The KEY symbol behind a LATE-BOUND (`__@name@id`) property: resolved
24
26
  * from the argument of the element-access assignment that declared it
25
27
  * (`this[kLimit] = v` — the declaration list holds the BinaryExpression
26
28
  * or the ElementAccessExpression itself). Null when no declaration has
27
29
  * that shape (well-known-symbol members like `[Symbol.iterator]`). */
28
- function lateBoundKeySymOf(L, p) {
29
- for (const d of L.checker.declarationsOf(p)) {
30
+ function lateBoundKeySymOf(lowerer, p) {
31
+ for (const d of lowerer.checker.declarationsOf(p)) {
30
32
  const access = ts.isBinaryExpression(d) && ts.isElementAccessExpression(d.left)
31
33
  ? d.left
32
34
  : ts.isElementAccessExpression(d)
@@ -34,7 +36,7 @@ function lateBoundKeySymOf(L, p) {
34
36
  : null;
35
37
  if (!access || !ts.isIdentifier(access.argumentExpression))
36
38
  continue;
37
- const sym = L.resolveValueSymbol(access.argumentExpression);
39
+ const sym = lowerer.resolveValueSymbol(access.argumentExpression);
38
40
  if (sym)
39
41
  return sym;
40
42
  }
@@ -55,7 +57,7 @@ function lateBoundKeySymOf(L, p) {
55
57
  * statically-resolved key declared in symbolFields, and all the slots
56
58
  * agree on one IR type. Null when the shape doesn't hold — the value
57
59
  * stays checked-dynamic exactly as before. */
58
- function symbolSlotReturnType(L, fnLike, symbolFields, fields) {
60
+ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
59
61
  if (symbolFields.size === 0)
60
62
  return null;
61
63
  if (fnLike.type !== undefined || !fnLike.body)
@@ -88,7 +90,7 @@ function symbolSlotReturnType(L, fnLike, symbolFields, fields) {
88
90
  return null;
89
91
  if (e.expression.kind !== ts.SyntaxKind.ThisKeyword)
90
92
  return null;
91
- const key = uniqueSymbolKeyOf(L, e.argumentExpression);
93
+ const key = uniqueSymbolKeyOf(lowerer, e.argumentExpression);
92
94
  const fieldName = key ? symbolFields.get(key.sym) : undefined;
93
95
  const t = fieldName !== undefined ? fields.get(fieldName) : undefined;
94
96
  if (t === undefined || t.kind === "dyn")
@@ -106,10 +108,10 @@ function symbolSlotReturnType(L, fnLike, symbolFields, fields) {
106
108
  * toString reach them through dedicated error.* libCall lowerings, and
107
109
  * user classes extend them like any base (the emitted subclass struct
108
110
  * embeds ScrError's prefix). */
109
- export function registerBuiltinErrorClasses(L) {
111
+ export function registerBuiltinErrorClasses(lowerer) {
110
112
  const loc = { file: "<builtin>", start: 0, end: 0 };
111
113
  for (const [irName, rec] of RUNTIME_ERROR_CLASSES) {
112
- const base = rec.base ? (L.classes.get(rec.base) ?? null) : null;
114
+ const base = rec.base ? (lowerer.classes.get(rec.base) ?? null) : null;
113
115
  const info = {
114
116
  def: {
115
117
  name: irName,
@@ -155,7 +157,7 @@ export function registerBuiltinErrorClasses(L) {
155
157
  };
156
158
  if (base)
157
159
  base.subclasses.push(info);
158
- L.classes.set(irName, info);
160
+ lowerer.classes.set(irName, info);
159
161
  }
160
162
  }
161
163
  /** The runtime-provided node:events EventEmitter as an eagerly-registered
@@ -163,11 +165,11 @@ export function registerBuiltinErrorClasses(L) {
163
165
  * the moment an emitter type appears, so the info must exist before any
164
166
  * lowering. No decl, no lowerable bodies — `new`/super() reach it
165
167
  * through emitter.* libCalls, the method surface lowers through
166
- * lower-emitter.ts, and user classes extend it like any base (the
168
+ * lower-event-emitter.ts, and user classes extend it like any base (the
167
169
  * emitted subclass struct embeds ScrEmitter's registry/name prefix —
168
170
  * carried by the BACKEND, not by IR fields, so the fields list stays
169
171
  * empty and subclass field layout starts right after the prefix). */
170
- export function registerBuiltinEmitterClass(L) {
172
+ export function registerBuiltinEmitterClass(lowerer) {
171
173
  const loc = { file: "<builtin>", start: 0, end: 0 };
172
174
  const info = {
173
175
  def: { name: RUNTIME_EMITTER_CLASS, runtime: true, fields: [], loc },
@@ -185,7 +187,7 @@ export function registerBuiltinEmitterClass(L) {
185
187
  throwingSetters: [],
186
188
  staticFields: [],
187
189
  };
188
- L.classes.set(RUNTIME_EMITTER_CLASS, info);
190
+ lowerer.classes.set(RUNTIME_EMITTER_CLASS, info);
189
191
  }
190
192
  /** The runtime-provided node:stream classes as eagerly-registered
191
193
  * ClassInfos (the emitter story): mapType names `%Readable` et al the
@@ -195,10 +197,10 @@ export function registerBuiltinEmitterClass(L) {
195
197
  * unchanged; the stream method/property surface lowers through
196
198
  * lower-stream.ts. No decl, no lowerable bodies, empty field lists —
197
199
  * every instance is runtime-allocated (user `extends` is fenced). */
198
- export function registerBuiltinStreamClasses(L) {
200
+ export function registerBuiltinStreamClasses(lowerer) {
199
201
  const loc = { file: "<builtin>", start: 0, end: 0 };
200
202
  for (const [irName, rec] of RUNTIME_STREAM_CLASSES) {
201
- const base = L.classes.get(rec.base) ?? null;
203
+ const base = lowerer.classes.get(rec.base) ?? null;
202
204
  const info = {
203
205
  def: { name: irName, runtime: true, base: rec.base, fields: [], loc },
204
206
  fields: new Map(),
@@ -217,7 +219,7 @@ export function registerBuiltinStreamClasses(L) {
217
219
  };
218
220
  if (base)
219
221
  base.subclasses.push(info);
220
- L.classes.set(irName, info);
222
+ lowerer.classes.set(irName, info);
221
223
  }
222
224
  }
223
225
  /** The stream ClassInfo a VALUE symbol refers to (`new Readable(...)`,
@@ -227,27 +229,27 @@ export function registerBuiltinStreamClasses(L) {
227
229
  * also types child stdio — under @types/node the childStream mapping
228
230
  * keeps priority and the static stream classes stand down; the shipped
229
231
  * fallback declarations are the supported surface). */
230
- export function builtinStreamInfoOf(L, symbol) {
232
+ export function builtinStreamInfoOf(lowerer, symbol) {
231
233
  if (!symbol)
232
234
  return null;
233
- if (!L.isStdlibSymbol(symbol)) {
235
+ if (!lowerer.isStdlibSymbol(symbol)) {
234
236
  // A const ALIAS of a namespace member (`const Writable =
235
237
  // stream.Writable` — the two-step spelling; the one-step
236
238
  // require('stream').Writable rides the same walk): follow the
237
239
  // member to the stdlib class symbol. The declaration itself is
238
240
  // alias plumbing (streamClassAliasDecl — both declaration walks
239
241
  // skip it).
240
- const decl = L.checker.valueDeclarationOf(symbol);
242
+ const decl = lowerer.checker.valueDeclarationOf(symbol);
241
243
  if (decl && ts.isVariableDeclaration(decl) &&
242
244
  (ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 &&
243
245
  decl.initializer !== undefined &&
244
246
  ts.isPropertyAccessExpression(decl.initializer) &&
245
247
  !decl.initializer.questionDotToken &&
246
- L.builtinNamespaceModuleOf(decl.initializer.expression) === "stream") {
247
- const mSym = L.checker.getSymbolAtLocation(decl.initializer.name);
248
- const target = mSym && mSym.flags & ts.SymbolFlags.Alias ? L.checker.getAliasedSymbol(mSym) : mSym;
248
+ lowerer.builtinNamespaceModuleOf(decl.initializer.expression) === "stream") {
249
+ const mSym = lowerer.checker.getSymbolAtLocation(decl.initializer.name);
250
+ const target = mSym && mSym.flags & ts.SymbolFlags.Alias ? lowerer.checker.getAliasedSymbol(mSym) : mSym;
249
251
  if (target && target !== symbol)
250
- return builtinStreamInfoOf(L, target);
252
+ return builtinStreamInfoOf(lowerer, target);
251
253
  }
252
254
  return null;
253
255
  }
@@ -258,7 +260,7 @@ export function builtinStreamInfoOf(L, symbol) {
258
260
  }
259
261
  if (!irName)
260
262
  return null;
261
- const declared = L.checker.declarationsOf(symbol).some((d) => {
263
+ const declared = lowerer.checker.declarationsOf(symbol).some((d) => {
262
264
  if (!ts.isClassDeclaration(d))
263
265
  return false;
264
266
  if (isNodeTypesPath(d.getSourceFile().fileName))
@@ -272,7 +274,7 @@ export function builtinStreamInfoOf(L, symbol) {
272
274
  }
273
275
  return false;
274
276
  });
275
- return declared ? (L.classes.get(irName) ?? null) : null;
277
+ return declared ? (lowerer.classes.get(irName) ?? null) : null;
276
278
  }
277
279
  /** The undefined-armed union of a JS class property's inferred type — the
278
280
  * honest slot for a field first assigned outside the constructor's top
@@ -280,13 +282,13 @@ export function builtinStreamInfoOf(L, symbol) {
280
282
  * inference is unmappable, checked-dynamic (dyn stays out of class
281
283
  * fields — KEEP NARROW), or an arm-less kind that cannot join a union
282
284
  * (genResultRecord's list, including scalar-backed Date values). */
283
- function undefArmedFieldType(L, p) {
284
- const t = L.checker.getTypeOfSymbol(p);
285
- const mapped = L.mapTypeOf(t);
285
+ function undefArmedFieldType(lowerer, p) {
286
+ const t = lowerer.checker.getTypeOfSymbol(p);
287
+ const mapped = lowerer.mapTypeOf(t);
286
288
  if (!mapped || mapped.kind === "void" || mapped.kind === "dyn")
287
289
  return null;
288
290
  const byKey = new Map();
289
- const arms = mapped.kind === "union" ? (L.unions.get(mapped.unionId)?.arms ?? []) : [mapped];
291
+ const arms = mapped.kind === "union" ? (lowerer.unions.get(mapped.unionId)?.arms ?? []) : [mapped];
290
292
  for (const a of arms) {
291
293
  if (a.kind === "map" || a.kind === "regex" || a.kind === "date" ||
292
294
  a.kind === "jsval" || a.kind === "generator") {
@@ -296,38 +298,38 @@ function undefArmedFieldType(L, p) {
296
298
  }
297
299
  byKey.set(typeKey(UNDEFINED_T), UNDEFINED_T);
298
300
  const sorted = [...byKey.values()].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
299
- return { kind: "union", unionId: L.unions.intern(sorted) };
301
+ return { kind: "union", unionId: lowerer.unions.intern(sorted) };
300
302
  }
301
303
  /** The emitter ClassInfo a VALUE symbol refers to (`new EventEmitter`,
302
304
  * `extends EventEmitter`, `x instanceof EventEmitter`) — any import
303
305
  * spelling (named/default/namespace member, CJS require) resolves to
304
306
  * the ambient class. Provenance-checked like the error classes: only a
305
307
  * stdlib-file declaration inside the "events" ambient module counts. */
306
- export function builtinEmitterInfoOf(L, symbol) {
308
+ export function builtinEmitterInfoOf(lowerer, symbol) {
307
309
  if (!symbol)
308
310
  return null;
309
- if (!L.isStdlibSymbol(symbol)) {
311
+ if (!lowerer.isStdlibSymbol(symbol)) {
310
312
  // A const ALIAS of the emitter class member (`const EventEmitter =
311
313
  // require('node:events').EventEmitter` — commander's spelling; the
312
314
  // two-step `const EE = events.EventEmitter` rides the same walk):
313
315
  // follow the member off the module namespace. The declaration
314
316
  // itself is alias plumbing (builtinMemberRequireDecl — both
315
317
  // declaration walks skip it).
316
- const decl = L.checker.valueDeclarationOf(symbol);
318
+ const decl = lowerer.checker.valueDeclarationOf(symbol);
317
319
  if (decl !== undefined && ts.isVariableDeclaration(decl) &&
318
320
  (ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 &&
319
321
  decl.initializer !== undefined &&
320
322
  ts.isPropertyAccessExpression(decl.initializer) &&
321
323
  !decl.initializer.questionDotToken &&
322
324
  decl.initializer.name.text === "EventEmitter" &&
323
- L.builtinNamespaceModuleOf(decl.initializer.expression) === "events") {
324
- return L.classes.get(RUNTIME_EMITTER_CLASS) ?? null;
325
+ lowerer.builtinNamespaceModuleOf(decl.initializer.expression) === "events") {
326
+ return lowerer.classes.get(RUNTIME_EMITTER_CLASS) ?? null;
325
327
  }
326
328
  return null;
327
329
  }
328
330
  if (symbol.name !== "EventEmitter")
329
331
  return null;
330
- const declared = L.checker.declarationsOf(symbol).some((d) => {
332
+ const declared = lowerer.checker.declarationsOf(symbol).some((d) => {
331
333
  if (!ts.isClassDeclaration(d) && !ts.isInterfaceDeclaration(d))
332
334
  return false;
333
335
  let node = d.parent;
@@ -339,24 +341,24 @@ export function builtinEmitterInfoOf(L, symbol) {
339
341
  }
340
342
  return false;
341
343
  });
342
- return declared ? (L.classes.get(RUNTIME_EMITTER_CLASS) ?? null) : null;
344
+ return declared ? (lowerer.classes.get(RUNTIME_EMITTER_CLASS) ?? null) : null;
343
345
  }
344
346
  /** The builtin error ClassInfo a VALUE symbol refers to (`new Error`,
345
347
  * `extends TypeError`, `x instanceof RangeError`), or null. Provenance-
346
348
  * checked: only the standard library's declarations count — a user's own
347
349
  * `class Error` resolves through classBySymbol instead. */
348
- export function builtinErrorInfoOf(L, symbol) {
349
- if (!symbol || !L.isStdlibSymbol(symbol))
350
+ export function builtinErrorInfoOf(lowerer, symbol) {
351
+ if (!symbol || !lowerer.isStdlibSymbol(symbol))
350
352
  return null;
351
353
  for (const [irName, rec] of RUNTIME_ERROR_CLASSES) {
352
354
  if (rec.lib === symbol.name)
353
- return L.classes.get(irName) ?? null;
355
+ return lowerer.classes.get(irName) ?? null;
354
356
  }
355
357
  return null;
356
358
  }
357
359
  /** The instance-method surface the runtime EventEmitter owns — subclass
358
360
  * members with these names are fenced (collectClassShapeInner) and calls
359
- * to them on emitter-rooted receivers lower through lower-emitter.ts. */
361
+ * to them on emitter-rooted receivers lower through lower-event-emitter.ts. */
360
362
  export const EMITTER_API_MEMBERS = new Set([
361
363
  "on", "addListener", "once", "prependListener", "prependOnceListener",
362
364
  "off", "removeListener", "removeAllListeners", "emit", "listenerCount",
@@ -374,18 +376,18 @@ export function decoratorNodesOf(n) {
374
376
  * `@dec(...)` evaluates the CALLEE before any argument — and property
375
377
  * chains throw at their ROOT (`@instance.decorate` reads `instance`
376
378
  * first). */
377
- export function ambientDecoratorThrowNameOf(L, dExpr) {
379
+ function ambientDecoratorThrowNameOf(lowerer, dExpr) {
378
380
  let e = dExpr;
379
381
  while (ts.isParenthesizedExpression(e))
380
382
  e = e.expression;
381
383
  const target = ts.isCallExpression(e) ? e.expression : e;
382
- const root = ambientUndefVarRootOf(L, target);
384
+ const root = ambientUndefVarRootOf(lowerer, target);
383
385
  if (root)
384
386
  return root.text;
385
387
  let callee = target;
386
388
  while (ts.isParenthesizedExpression(callee))
387
389
  callee = callee.expression;
388
- if (ts.isIdentifier(callee) && ambientUndefinedFnSymbolOf(L, callee) !== null)
390
+ if (ts.isIdentifier(callee) && ambientUndefinedFnSymbolOf(lowerer, callee) !== null)
389
391
  return callee.text;
390
392
  return null;
391
393
  }
@@ -400,7 +402,7 @@ export function ambientDecoratorThrowNameOf(L, dExpr) {
400
402
  * computed keys. Anything richer (factory calls over defined values,
401
403
  * property-access reads, computed-key calls) stops the proof — the
402
404
  * named fences answer instead. */
403
- export function guaranteedDecorationThrow(L, decl) {
405
+ export function guaranteedDecorationThrow(lowerer, decl) {
404
406
  const stripParens = (e) => {
405
407
  let x = e;
406
408
  while (ts.isParenthesizedExpression(x))
@@ -408,7 +410,7 @@ export function guaranteedDecorationThrow(L, decl) {
408
410
  return x;
409
411
  };
410
412
  const decoratorVerdict = (d) => {
411
- const name = ambientDecoratorThrowNameOf(L, d.expression);
413
+ const name = ambientDecoratorThrowNameOf(lowerer, d.expression);
412
414
  if (name !== null)
413
415
  return { name, node: d };
414
416
  const e = stripParens(d.expression);
@@ -450,12 +452,12 @@ export function guaranteedDecorationThrow(L, decl) {
450
452
  }
451
453
  return null;
452
454
  }
453
- export function collectClassShape(L, decl) {
454
- const symbol = L.collectDeferring(() => declSymbolOf(L, decl), () => L.collectClassShapeInner(decl));
455
+ export function collectClassShape(lowerer, decl) {
456
+ const symbol = lowerer.collectDeferring(() => declSymbolOf(lowerer, decl), () => lowerer.collectClassShapeInner(decl));
455
457
  // Typed receivers and module retention know the class only by its
456
458
  // qualified IR name — index the deferral under it too.
457
459
  if (symbol)
458
- L.deferredClassByName.set(L.classNamer(decl), symbol);
460
+ lowerer.deferredClassByName.set(lowerer.classNamer(decl), symbol);
459
461
  // A poisoned class containing a static BLOCK or a DECORATOR must report
460
462
  // EAGERLY: deferral's premise ("an unreached broken declaration costs
461
463
  // nothing") fails here — Node runs the block (and calls the decorator)
@@ -465,13 +467,13 @@ export function collectClassShape(L, decl) {
465
467
  const hasDeclTimeCode = (n) => ts.isClassStaticBlockDeclaration(n) ||
466
468
  (n.modifiers ?? []).some((m) => m.kind === ts.SyntaxKind.Decorator);
467
469
  if (symbol && (hasDeclTimeCode(decl) || decl.members.some(hasDeclTimeCode))) {
468
- const diags = L.deferredDiags.get(symbol);
470
+ const diags = lowerer.deferredDiags.get(symbol);
469
471
  if (diags) {
470
- L.deferredDiags.delete(symbol);
471
- if (!L.alreadyFlushed.has(symbol)) {
472
- L.flushedSymbols.add(symbol);
472
+ lowerer.deferredDiags.delete(symbol);
473
+ if (!lowerer.alreadyFlushed.has(symbol)) {
474
+ lowerer.flushedSymbols.add(symbol);
473
475
  for (const d of diags)
474
- L.pushDiag(d);
476
+ lowerer.pushDiag(d);
475
477
  }
476
478
  }
477
479
  }
@@ -490,19 +492,19 @@ export function collectClassShape(L, decl) {
490
492
  ?.find((h) => h.token === ts.SyntaxKind.ExtendsKeyword)
491
493
  ?.types.map((t) => t.expression)
492
494
  .filter(ts.isIdentifier)[0];
493
- const baseSym = baseIdent ? L.resolveValueSymbol(baseIdent) : null;
494
- const baseDiags = baseSym ? L.deferredDiags.get(baseSym) : undefined;
495
+ const baseSym = baseIdent ? lowerer.resolveValueSymbol(baseIdent) : null;
496
+ const baseDiags = baseSym ? lowerer.deferredDiags.get(baseSym) : undefined;
495
497
  if (baseSym && baseDiags) {
496
- L.deferredDiags.delete(baseSym);
497
- if (!L.alreadyFlushed.has(baseSym)) {
498
- L.flushedSymbols.add(baseSym);
498
+ lowerer.deferredDiags.delete(baseSym);
499
+ if (!lowerer.alreadyFlushed.has(baseSym)) {
500
+ lowerer.flushedSymbols.add(baseSym);
499
501
  for (const d of baseDiags)
500
- L.pushDiag(d);
502
+ lowerer.pushDiag(d);
501
503
  }
502
504
  }
503
505
  }
504
506
  }
505
- export function collectClassShapeInner(L, decl, jsNameOverride, inst,
507
+ export function collectClassShapeInner(lowerer, decl, jsNameOverride, inst,
506
508
  /** MIXIN instantiation mode (lower-mixins.ts): the class inside a
507
509
  * mixin function, collected per call site — `base` is the ARGUMENT
508
510
  * class (the heritage clause names the mixin's parameter and is
@@ -515,8 +517,8 @@ mixin) {
515
517
  // nameless class DECLARATION is `export default class {}` — its
516
518
  // symbol is the module's default export (declSymbolOf) and it
517
519
  // registers under classNamer's "%anon" spelling (unique per file).
518
- if (!decl.name && ts.isClassDeclaration(decl) && declSymbolOf(L, decl) === undefined) {
519
- L.unsupported("SC1090", decl, "anonymous classes");
520
+ if (!decl.name && ts.isClassDeclaration(decl) && declSymbolOf(lowerer, decl) === undefined) {
521
+ lowerer.unsupported("SC1090", decl, "anonymous classes");
520
522
  }
521
523
  // Decorators are declaration-time CALLS (they run when the class
522
524
  // statement evaluates and may replace the declaration outright).
@@ -542,16 +544,16 @@ mixin) {
542
544
  // loaders leave `@dec` in place) — there is no runtime behavior
543
545
  // to be exact against.
544
546
  if (isJsSourceFile(decl.getSourceFile())) {
545
- L.unsupported("SC1090", (classDecoratorNodes[0] ?? decoratorNodesOf(decoratedMembers[0])[0]), "decorators in JavaScript sources (V8 has not shipped decorators — Node cannot execute this file)");
547
+ lowerer.unsupported("SC1090", (classDecoratorNodes[0] ?? decoratorNodesOf(decoratedMembers[0])[0]), "decorators in JavaScript sources (V8 has not shipped decorators — Node cannot execute this file)");
546
548
  }
547
549
  // The guaranteed-throw SHELL: declarations only (expressions
548
550
  // lower their throw at the expression — lowerClassExpression),
549
551
  // never instantiations/mixins (they share a family declaration).
550
552
  if (inst === undefined && mixin === undefined &&
551
553
  ts.isClassDeclaration(decl) && decl.typeParameters === undefined) {
552
- const thrown = guaranteedDecorationThrow(L, decl);
554
+ const thrown = guaranteedDecorationThrow(lowerer, decl);
553
555
  if (thrown) {
554
- const className = L.classNamer(decl);
556
+ const className = lowerer.classNamer(decl);
555
557
  const info = {
556
558
  def: {
557
559
  name: className,
@@ -578,12 +580,12 @@ mixin) {
578
580
  shapes: [{ kind: "ambientThrow", name: thrown.name }],
579
581
  },
580
582
  };
581
- L.classes.set(className, info);
583
+ lowerer.classes.set(className, info);
582
584
  const classSymbol = decl.name
583
- ? L.checker.getSymbolAtLocation(decl.name)
584
- : declSymbolOf(L, decl);
585
+ ? lowerer.checker.getSymbolAtLocation(decl.name)
586
+ : declSymbolOf(lowerer, decl);
585
587
  if (classSymbol)
586
- L.classBySymbol.set(classSymbol, info);
588
+ lowerer.classBySymbol.set(classSymbol, info);
587
589
  return;
588
590
  }
589
591
  }
@@ -598,7 +600,7 @@ mixin) {
598
600
  ? "auto-accessor decorators"
599
601
  : "field decorators")
600
602
  : "member decorators";
601
- L.unsupported("SC1090", dec, `${kind} (the standard context object and member replacement have no static lowering — class decorators and provably-throwing ambient decorations compile)`);
603
+ lowerer.unsupported("SC1090", dec, `${kind} (the standard context object and member replacement have no static lowering — class decorators and provably-throwing ambient decorations compile)`);
602
604
  }
603
605
  }
604
606
  if (classDecoratorNodes.length > 0) {
@@ -606,14 +608,14 @@ mixin) {
606
608
  // minted class; only once-evaluated declarations have a single
607
609
  // decoration event to lower.
608
610
  if (!ts.isClassDeclaration(decl)) {
609
- L.unsupported("SC1090", classDecoratorNodes[0], "decorators on class expressions (each evaluation decorates a distinct class)");
611
+ lowerer.unsupported("SC1090", classDecoratorNodes[0], "decorators on class expressions (each evaluation decorates a distinct class)");
610
612
  }
611
613
  // A generic class declares ONCE in JS (one decoration event over
612
614
  // the one runtime Box) but compiles per instantiation here — the
613
615
  // family object is never constructed and the instantiations were
614
616
  // never individually decorated.
615
617
  if (decl.typeParameters !== undefined) {
616
- L.unsupported("SC1090", classDecoratorNodes[0], "decorators on generic classes (JS decorates the one runtime class; the compiled family instantiates per type argument)");
618
+ lowerer.unsupported("SC1090", classDecoratorNodes[0], "decorators on generic classes (JS decorates the one runtime class; the compiled family instantiates per type argument)");
617
619
  }
618
620
  }
619
621
  }
@@ -629,9 +631,9 @@ mixin) {
629
631
  // FAMILY of classes has no once-evaluated story.
630
632
  const familyMode = decl.typeParameters !== undefined && inst === undefined;
631
633
  if (familyMode && !ts.isClassDeclaration(decl)) {
632
- L.unsupported("SC1090", decl, "generic class expressions");
634
+ lowerer.unsupported("SC1090", decl, "generic class expressions");
633
635
  }
634
- const className = inst ? inst.name : mixin ? mixin.name : L.classNamer(decl); // program-wide qualified name
636
+ const className = inst ? inst.name : mixin ? mixin.name : lowerer.classNamer(decl); // program-wide qualified name
635
637
  // Single inheritance: `extends` of a class declared in the program.
636
638
  // tsc guarantees the base is declared before the derived class (its
637
639
  // use-before-declaration error), and collection runs in module order,
@@ -646,7 +648,7 @@ mixin) {
646
648
  if (familyMode && decl.heritageClauses !== undefined) {
647
649
  const tpSyms = new Set();
648
650
  for (const tp of decl.typeParameters) {
649
- const s = L.checker.getSymbolAtLocation(tp.name);
651
+ const s = lowerer.checker.getSymbolAtLocation(tp.name);
650
652
  if (s)
651
653
  tpSyms.add(s);
652
654
  }
@@ -656,7 +658,7 @@ mixin) {
656
658
  for (const t of clause.types) {
657
659
  let mentions = false;
658
660
  ts.walkPreorder(t, (n) => {
659
- const s = ts.isIdentifier(n) ? L.checker.getSymbolAtLocation(n) : undefined;
661
+ const s = ts.isIdentifier(n) ? lowerer.checker.getSymbolAtLocation(n) : undefined;
660
662
  if (s && tpSyms.has(s)) {
661
663
  mentions = true;
662
664
  return "stop";
@@ -664,7 +666,7 @@ mixin) {
664
666
  return undefined;
665
667
  });
666
668
  if (mentions) {
667
- L.unsupported("SC1090", t, "generic classes whose 'extends' clause mentions their own type parameters (each instantiation would need a different base)");
669
+ lowerer.unsupported("SC1090", t, "generic classes whose 'extends' clause mentions their own type parameters (each instantiation would need a different base)");
668
670
  }
669
671
  }
670
672
  }
@@ -680,15 +682,15 @@ mixin) {
680
682
  // `extends events.EventEmitter` — the namespace-member spelling of
681
683
  // the ambient emitter base resolves like the named import.
682
684
  if (t && ts.isPropertyAccessExpression(t.expression) && ts.isIdentifier(t.expression.name)) {
683
- const memberSym = L.checker.getSymbolAtLocation(t.expression.name);
685
+ const memberSym = lowerer.checker.getSymbolAtLocation(t.expression.name);
684
686
  const resolved = memberSym && memberSym.flags & ts.SymbolFlags.Alias
685
- ? L.checker.getAliasedSymbol(memberSym)
687
+ ? lowerer.checker.getAliasedSymbol(memberSym)
686
688
  : memberSym;
687
- const emitterBase = L.builtinEmitterInfoOf(resolved);
688
- const streamBaseNs = builtinStreamInfoOf(L, resolved);
689
+ const emitterBase = lowerer.builtinEmitterInfoOf(resolved);
690
+ const streamBaseNs = builtinStreamInfoOf(lowerer, resolved);
689
691
  if (emitterBase || streamBaseNs) {
690
692
  if (t.typeArguments)
691
- L.unsupported("SC1090", t, "extending generic classes");
693
+ lowerer.unsupported("SC1090", t, "extending generic classes");
692
694
  base = (emitterBase ?? streamBaseNs);
693
695
  continue;
694
696
  }
@@ -697,14 +699,14 @@ mixin) {
697
699
  // (import= alias chains included), with the source-order guard
698
700
  // (the class statement evaluates at its init position; a base
699
701
  // block below it would still be uninitialized in Node).
700
- if (!t.expression.questionDotToken && nsMemberIdentOf(L, t.expression)) {
702
+ if (!t.expression.questionDotToken && nsMemberIdentOf(lowerer, t.expression)) {
701
703
  if (t.typeArguments)
702
- L.unsupported("SC1090", t, "extending generic classes");
704
+ lowerer.unsupported("SC1090", t, "extending generic classes");
703
705
  if (memberSym)
704
- fenceEarlyNsMemberRef(L, t.expression, memberSym);
705
- const nsBase = resolved ? L.classBySymbol.get(resolved) : undefined;
706
+ fenceEarlyNsMemberRef(lowerer, t.expression, memberSym);
707
+ const nsBase = resolved ? lowerer.classBySymbol.get(resolved) : undefined;
706
708
  if (!nsBase) {
707
- L.unsupported("SC1090", t, `extending the namespace member '${t.expression.name.text}' (no class lowering)`);
709
+ lowerer.unsupported("SC1090", t, `extending the namespace member '${t.expression.name.text}' (no class lowering)`);
708
710
  }
709
711
  base = nsBase;
710
712
  continue;
@@ -721,15 +723,15 @@ mixin) {
721
723
  // answers null for them) and keep the computed-expression fence:
722
724
  // the runtime base is whichever assignment ran last.
723
725
  if (!t.expression.questionDotToken) {
724
- const propBase = propertyAssignedClassInfoOf(L, memberSym);
726
+ const propBase = propertyAssignedClassInfoOf(lowerer, memberSym);
725
727
  if (propBase) {
726
728
  if (t.typeArguments)
727
- L.unsupported("SC1090", t, "extending generic classes");
729
+ lowerer.unsupported("SC1090", t, "extending generic classes");
728
730
  const baseDecl = propBase.decl;
729
731
  if (baseDecl != null &&
730
732
  baseDecl.getSourceFile() === decl.getSourceFile() &&
731
733
  baseDecl.getStart() > decl.getStart()) {
732
- L.unsupported("SC1090", t, `extending '${t.expression.getText()}' above the statement that assigns it (the property is still undefined when this class evaluates — Node throws here; assign the base first)`);
734
+ lowerer.unsupported("SC1090", t, `extending '${t.expression.getText()}' above the statement that assigns it (the property is still undefined when this class evaluates — Node throws here; assign the base first)`);
733
735
  }
734
736
  base = propBase;
735
737
  continue;
@@ -738,12 +740,12 @@ mixin) {
738
740
  // fence (the generic computed-expression one below would hide
739
741
  // what actually blocks it).
740
742
  const rebinds = memberSym !== undefined &&
741
- L.checker
743
+ lowerer.checker
742
744
  .declarationsOf(memberSym)
743
745
  .filter((d) => ts.isBinaryExpression(d) &&
744
746
  d.operatorToken.kind === ts.SyntaxKind.EqualsToken).length > 1;
745
747
  if (rebinds) {
746
- L.unsupported("SC1090", t, `extending the reassigned property '${t.expression.getText()}' (the runtime base is whichever assignment ran last — bind the class exactly once)`);
748
+ lowerer.unsupported("SC1090", t, `extending the reassigned property '${t.expression.getText()}' (the runtime base is whichever assignment ran last — bind the class exactly once)`);
747
749
  }
748
750
  }
749
751
  }
@@ -753,8 +755,8 @@ mixin) {
753
755
  // recursion order delivers exactly that).
754
756
  if (t && ts.isClassExpression(t.expression)) {
755
757
  if (t.typeArguments)
756
- L.unsupported("SC1090", t, "extending generic classes");
757
- const baseExpr = L.lowerClassExpressionInfo(t.expression);
758
+ lowerer.unsupported("SC1090", t, "extending generic classes");
759
+ const baseExpr = lowerer.lowerClassExpressionInfo(t.expression);
758
760
  base = baseExpr;
759
761
  continue;
760
762
  }
@@ -765,16 +767,16 @@ mixin) {
765
767
  // callee is NOT a mixin function keeps the computed-expression
766
768
  // fence below.
767
769
  if (t && ts.isCallExpression(t.expression) && !t.typeArguments) {
768
- const mixinBase = L.mixinCallClassInfoOf(t.expression);
770
+ const mixinBase = lowerer.mixinCallClassInfoOf(t.expression);
769
771
  if (mixinBase) {
770
772
  base = mixinBase;
771
773
  continue;
772
774
  }
773
775
  }
774
776
  if (!t || !ts.isIdentifier(t.expression)) {
775
- L.unsupported("SC1090", clause, "extending computed expressions");
777
+ lowerer.unsupported("SC1090", clause, "extending computed expressions");
776
778
  }
777
- const symbol = L.resolveValueSymbol(t.expression);
779
+ const symbol = lowerer.resolveValueSymbol(t.expression);
778
780
  // Extending a REBINDABLE decorated class (analysis already ran —
779
781
  // this collection is a class expression or a generic
780
782
  // instantiation demanded during lowering): the runtime base is
@@ -782,53 +784,53 @@ mixin) {
782
784
  // subclasses collected BEFORE analysis meet the same fence from
783
785
  // analyzeClassDecoration's subclasses check.
784
786
  {
785
- const directBase = symbol && L.classBySymbol.get(symbol);
787
+ const directBase = symbol && lowerer.classBySymbol.get(symbol);
786
788
  if (directBase && directBase.classDecorators?.valueGlobalId !== undefined) {
787
- L.unsupported("SC1090", t, `extending the decorated class '${directBase.def.jsName ?? directBase.def.name}' (its decorators may replace it — the runtime base would be the decoration result)`);
789
+ lowerer.unsupported("SC1090", t, `extending the decorated class '${directBase.def.jsName ?? directBase.def.name}' (its decorators may replace it — the runtime base would be the decoration result)`);
788
790
  }
789
791
  if (directBase)
790
- fenceDecorationThrows(L, directBase, t);
792
+ fenceDecorationThrows(lowerer, directBase, t);
791
793
  }
792
794
  // `extends DOMException`: the runtime instance carries hidden
793
795
  // slots (the legacy code, the cause) BEYOND the ScrError prefix
794
796
  // the IR fields describe — a subclass layout would overlap them.
795
- if (L.builtinErrorInfoOf(symbol)?.def.name === "%DOMException") {
796
- L.unsupported("SC1090", t, "extending DOMException (its runtime layout carries hidden slots a subclass would overlap — extend Error and set name/code yourself)");
797
+ if (lowerer.builtinErrorInfoOf(symbol)?.def.name === "%DOMException") {
798
+ lowerer.unsupported("SC1090", t, "extending DOMException (its runtime layout carries hidden slots a subclass would overlap — extend Error and set name/code yourself)");
797
799
  }
798
- const named = (symbol && L.classBySymbol.get(symbol)) ?? L.builtinErrorInfoOf(symbol) ??
799
- L.builtinEmitterInfoOf(symbol) ?? builtinStreamInfoOf(L, symbol) ??
800
+ const named = (symbol && lowerer.classBySymbol.get(symbol)) ?? lowerer.builtinErrorInfoOf(symbol) ??
801
+ lowerer.builtinEmitterInfoOf(symbol) ?? builtinStreamInfoOf(lowerer, symbol) ??
800
802
  // A const BINDING holding exactly one class (`const B = Animal`,
801
803
  // `const B = class {…}`): the base is that class — extends
802
804
  // through the alias is the declaration story (a general class
803
805
  // VALUE stays fenced: the runtime base would be dynamic).
804
- exactClassOfReceiver(L, t.expression) ??
806
+ exactClassOfReceiver(lowerer, t.expression) ??
805
807
  // A require BINDING of a class-expression whole export
806
808
  // (`const C = require('./x')` over `module.exports = class {…}`):
807
809
  // the alias resolves to the expression's own symbol — the same
808
810
  // declaration story, collected on demand.
809
- propertyAssignedClassInfoOf(L, symbol) ??
811
+ propertyAssignedClassInfoOf(lowerer, symbol) ??
810
812
  // A const BINDING of a mixin call (`const Tagged = M(Base);
811
813
  // class D extends Tagged {}`): the binding pins that call's
812
814
  // instantiation — collected on demand (lower-mixins.ts).
813
- mixinResultBindingClassOf(L, symbol) ?? null;
815
+ mixinResultBindingClassOf(lowerer, symbol) ?? null;
814
816
  // `extends Box<number>` — a GENERIC program class as the base: the
815
817
  // base is the concrete INSTANTIATION, resolved through the heritage
816
818
  // type (mapType registers/reuses `Box%0`).
817
819
  if (named?.generic) {
818
- const instT = L.checker.getTypeAtLocation(t);
819
- const mappedBase = L.mapTypeOf(instT);
820
- const instBase = mappedBase?.kind === "object" ? L.classes.get(mappedBase.className) : undefined;
820
+ const instT = lowerer.checker.getTypeAtLocation(t);
821
+ const mappedBase = lowerer.mapTypeOf(instT);
822
+ const instBase = mappedBase?.kind === "object" ? lowerer.classes.get(mappedBase.className) : undefined;
821
823
  if (!instBase || instBase.generic) {
822
- L.unsupported("SC1090", t, `extending the generic class '${t.expression.text}' without a compiled concrete instantiation (the type arguments must map — see the instantiation's own diagnostic)`);
824
+ lowerer.unsupported("SC1090", t, `extending the generic class '${t.expression.text}' without a compiled concrete instantiation (the type arguments must map — see the instantiation's own diagnostic)`);
823
825
  }
824
826
  base = instBase;
825
827
  continue;
826
828
  }
827
829
  if (t.typeArguments)
828
- L.unsupported("SC1090", t, "extending generic classes");
830
+ lowerer.unsupported("SC1090", t, "extending generic classes");
829
831
  base = named;
830
832
  if (!base) {
831
- L.unsupported("SC1090", t, `extending classes not declared in the program ('${t.expression.text}')`);
833
+ lowerer.unsupported("SC1090", t, `extending classes not declared in the program ('${t.expression.text}')`);
832
834
  }
833
835
  }
834
836
  const fields = new Map(base ? base.fields : []);
@@ -881,21 +883,21 @@ mixin) {
881
883
  ? genericFieldFnNodeOf(member)
882
884
  : member;
883
885
  if (!ts.isIdentifier(member.name) && !ts.isPrivateIdentifier(member.name)) {
884
- L.unsupported("SC1090", member, "computed generic method names");
886
+ lowerer.unsupported("SC1090", member, "computed generic method names");
885
887
  }
886
888
  if (fnNode.asteriskToken)
887
- L.unsupported("SC1071", member);
889
+ lowerer.unsupported("SC1071", member);
888
890
  const mName = member.name.text;
889
891
  const typeParams = [];
890
892
  for (const tp of fnNode.typeParameters) {
891
- const sym = L.checker.getSymbolAtLocation(tp.name);
893
+ const sym = lowerer.checker.getSymbolAtLocation(tp.name);
892
894
  if (!sym)
893
- L.unsupported("SC1090", member, "this method form");
895
+ lowerer.unsupported("SC1090", member, "this method form");
894
896
  typeParams.push(sym);
895
897
  }
896
898
  for (const param of fnNode.parameters) {
897
899
  if (!ts.isIdentifier(param.name) && !ts.isObjectBindingPattern(param.name) && !ts.isArrayBindingPattern(param.name)) {
898
- L.unsupported("SC1031", param);
900
+ lowerer.unsupported("SC1031", param);
899
901
  }
900
902
  }
901
903
  (isStatic ? genericStatics : genericMethods).set(mName, {
@@ -921,19 +923,7 @@ mixin) {
921
923
  // with arrow functions transparent (they inherit the block's
922
924
  // `this`) and this-binding function forms opaque (their `this` is
923
925
  // their own).
924
- const checkThis = (n) => {
925
- if (ts.isFunctionExpression(n) || ts.isFunctionDeclaration(n) ||
926
- ts.isMethodDeclaration(n) || ts.isConstructorDeclaration(n) ||
927
- ts.isGetAccessor(n) || ts.isSetAccessor(n) ||
928
- ts.isClassDeclaration(n) || ts.isClassExpression(n)) {
929
- return;
930
- }
931
- if (n.kind === ts.SyntaxKind.ThisKeyword || n.kind === ts.SyntaxKind.SuperKeyword) {
932
- L.unsupported("SC1090", n, "'this' in class static blocks (it names the class — reference the class by name instead)");
933
- }
934
- n.forEachChild(checkThis);
935
- };
936
- member.body.forEachChild(checkThis);
926
+ rejectStaticThis(lowerer, member.body, () => "'this' in class static blocks (it names the class — reference the class by name instead)");
937
927
  staticBlocks.push(member);
938
928
  continue;
939
929
  }
@@ -965,17 +955,17 @@ mixin) {
965
955
  (ts.isIdentifier(member.name) || ts.isPrivateIdentifier(member.name)) &&
966
956
  member.initializer &&
967
957
  member.postfixToken?.kind !== ts.SyntaxKind.QuestionToken) {
968
- const type = L.irTypeOf(member.name);
958
+ const type = lowerer.irTypeOf(member.name);
969
959
  if (type.kind === "void")
970
- L.badType(member.name, L.typeOf(member.name));
960
+ lowerer.badType(member.name, lowerer.typeOf(member.name));
971
961
  if (type.kind === "dyn") {
972
- L.unsupported("SC1090", member.name, "'unknown'-typed static fields");
962
+ lowerer.unsupported("SC1090", member.name, "'unknown'-typed static fields");
973
963
  }
974
964
  staticFields.push({
975
965
  name: member.name.text,
976
966
  type,
977
967
  initializer: member.initializer,
978
- globalId: `%g.s.${L.classNamer(decl)}.${member.name.text}`,
968
+ globalId: `%g.s.${lowerer.classNamer(decl)}.${member.name.text}`,
979
969
  readonly: modifiers.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword),
980
970
  });
981
971
  }
@@ -987,7 +977,7 @@ mixin) {
987
977
  member.body &&
988
978
  member.typeParameters === undefined &&
989
979
  member.asteriskToken === undefined) {
990
- const { shapes, funcType: ft } = L.lambdaSignature(member);
980
+ const { shapes, funcType: ft } = lowerer.lambdaSignature(member);
991
981
  staticMethods.set(member.name.text, { params: shapes, ret: ft.ret, member });
992
982
  }
993
983
  // GENERIC static methods monomorphize like top-level generic
@@ -1033,11 +1023,11 @@ mixin) {
1033
1023
  const pname = memberName.text;
1034
1024
  if (base !== null &&
1035
1025
  (base.fields.has(pname) ||
1036
- L.findMethodOn(base, pname) !== null ||
1037
- L.findMethodOn(base, `get:${pname}`) !== null ||
1038
- L.findMethodOn(base, `set:${pname}`) !== null ||
1039
- findGenericMethodOn(L, base, pname) !== null)) {
1040
- L.unsupported("SC1090", memberName, `redeclaring the private name '${pname}' of a base class (JS gives each class its own distinct '${pname}' slot; these layouts have one slot per name — rename one)`);
1026
+ lowerer.findMethodOn(base, pname) !== null ||
1027
+ lowerer.findMethodOn(base, `get:${pname}`) !== null ||
1028
+ lowerer.findMethodOn(base, `set:${pname}`) !== null ||
1029
+ findGenericMethodOn(lowerer, base, pname) !== null)) {
1030
+ lowerer.unsupported("SC1090", memberName, `redeclaring the private name '${pname}' of a base class (JS gives each class its own distinct '${pname}' slot; these layouts have one slot per name — rename one)`);
1041
1031
  }
1042
1032
  }
1043
1033
  // The EventEmitter API surface is runtime-provided: a subclass
@@ -1046,7 +1036,7 @@ mixin) {
1046
1036
  // override is fenced rather than silently split-brained — with ONE
1047
1037
  // exception: `emit` in the forwarding shape on a plain (non-
1048
1038
  // stream) emitter-rooted class monomorphizes per event name
1049
- // (lower-emitter.ts's emit-overrides block). Stream-rooted classes
1039
+ // (lower-event-emitter.ts's emit-overrides block). Stream-rooted classes
1050
1040
  // keep the fence for emit too: the runtime stream machinery emits
1051
1041
  // 'data'/'end'/... internally, which could never route through
1052
1042
  // the override.
@@ -1067,18 +1057,18 @@ mixin) {
1067
1057
  if (memberName.text === "emit" && !streamRooted && !inst && !mixin &&
1068
1058
  ts.isMethodDeclaration(member) &&
1069
1059
  !member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
1070
- const reason = emitOverrideShapeReason(L, member);
1060
+ const reason = emitOverrideShapeReason(lowerer, member);
1071
1061
  if (reason === null) {
1072
- const eventSym = L.checker.getSymbolAtLocation(member.parameters[0].name);
1073
- const restSym = L.checker.getSymbolAtLocation(member.parameters[1].name);
1062
+ const eventSym = lowerer.checker.getSymbolAtLocation(member.parameters[0].name);
1063
+ const restSym = lowerer.checker.getSymbolAtLocation(member.parameters[1].name);
1074
1064
  if (eventSym && restSym) {
1075
1065
  emitOverride = { decl: member, eventSym, restSym };
1076
1066
  continue;
1077
1067
  }
1078
1068
  }
1079
- L.unsupported("SC1090", memberName, `overriding EventEmitter's 'emit' outside the forwarding shape (${reason ?? "its parameters do not resolve statically"}; the compiled form is \`emit(event: string, ...args: unknown[]): boolean\`)`);
1069
+ lowerer.unsupported("SC1090", memberName, `overriding EventEmitter's 'emit' outside the forwarding shape (${reason ?? "its parameters do not resolve statically"}; the compiled form is \`emit(event: string, ...args: unknown[]): boolean\`)`);
1080
1070
  }
1081
- L.unsupported("SC1090", memberName, `overriding the EventEmitter member '${memberName.text}' (the runtime owns the emitter surface)`);
1071
+ lowerer.unsupported("SC1090", memberName, `overriding the EventEmitter member '${memberName.text}' (the runtime owns the emitter surface)`);
1082
1072
  }
1083
1073
  // The stream surface is likewise runtime-provided on stream-rooted
1084
1074
  // subclasses: API members (push/read/write/...) and the property
@@ -1098,15 +1088,15 @@ mixin) {
1098
1088
  if (streamBase) {
1099
1089
  const name = memberName.text;
1100
1090
  if (STREAM_API_MEMBERS.has(name) || STREAM_PROP_MEMBERS.has(name)) {
1101
- L.unsupported("SC1090", memberName, `overriding the stream member '${name}' (the runtime owns the stream surface)`);
1091
+ lowerer.unsupported("SC1090", memberName, `overriding the stream member '${name}' (the runtime owns the stream surface)`);
1102
1092
  }
1103
1093
  if (name === "_writev" || name === "_construct") {
1104
- L.unsupported("SC1090", memberName, `declaring '${name}' on a stream subclass (${name === "_writev" ? "batched writes are" : "deferred construction is"} not lowered — writes deliver one chunk at a time)`);
1094
+ lowerer.unsupported("SC1090", memberName, `declaring '${name}' on a stream subclass (${name === "_writev" ? "batched writes are" : "deferred construction is"} not lowered — writes deliver one chunk at a time)`);
1105
1095
  }
1106
1096
  const accepted = streamCtorShape(streamBase.def.name).accepted;
1107
1097
  for (const [option, methodName] of UNDERSCORE_METHODS) {
1108
1098
  if (name === methodName && !accepted.includes(option)) {
1109
- L.unsupported("SC1090", memberName, `declaring '${name}' on a ${streamBase.def.name.slice(1)} subclass (its constructor consumes ${accepted.map((a) => `'${UNDERSCORE_METHODS.get(a)}'`).join("/")})`);
1099
+ lowerer.unsupported("SC1090", memberName, `declaring '${name}' on a ${streamBase.def.name.slice(1)} subclass (its constructor consumes ${accepted.map((a) => `'${UNDERSCORE_METHODS.get(a)}'`).join("/")})`);
1110
1100
  }
1111
1101
  }
1112
1102
  }
@@ -1127,13 +1117,13 @@ mixin) {
1127
1117
  if (modifiers?.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)) {
1128
1118
  // `accessor x = 1` desugars (in JS) to a private slot plus a
1129
1119
  // get/set pair — declare the field and accessors explicitly.
1130
- L.unsupported("SC1090", member, "auto-accessor fields ('accessor x')");
1120
+ lowerer.unsupported("SC1090", member, "auto-accessor fields ('accessor x')");
1131
1121
  }
1132
1122
  // #private fields ride the ordinary field machinery — the '#'
1133
1123
  // name is unspellable publicly, so the slot never collides, and
1134
1124
  // enumeration surfaces (inspect) exclude it like Node.
1135
1125
  if (!ts.isIdentifier(member.name) && !ts.isPrivateIdentifier(member.name)) {
1136
- L.unsupported("SC1090", member, "computed field names");
1126
+ lowerer.unsupported("SC1090", member, "computed field names");
1137
1127
  }
1138
1128
  // A field initialized with a GENERIC arrow/function expression
1139
1129
  // (`time = async <T>(label, fn) => {...}` — the Output.time
@@ -1148,15 +1138,15 @@ mixin) {
1148
1138
  // an annotation that pins a concrete signature makes an ordinary
1149
1139
  // closure field, which the normal path below owns.
1150
1140
  if (genericFieldFnNodeOf(member) !== null &&
1151
- isGenericCallableMemberType(L.typeOf(member.name), L.checker)) {
1141
+ isGenericCallableMemberType(lowerer.typeOf(member.name), lowerer.checker)) {
1152
1142
  if (fields.has(member.name.text)) {
1153
- L.unsupported("SC1090", member.name, "redeclaring inherited fields");
1143
+ lowerer.unsupported("SC1090", member.name, "redeclaring inherited fields");
1154
1144
  }
1155
- if (L.findMethodOn(base, member.name.text)) {
1156
- L.unsupported("SC1090", member.name, "fields shadowing inherited methods");
1145
+ if (lowerer.findMethodOn(base, member.name.text)) {
1146
+ lowerer.unsupported("SC1090", member.name, "fields shadowing inherited methods");
1157
1147
  }
1158
- if (findGenericMethodOn(L, base, member.name.text)) {
1159
- L.unsupported("SC1090", member.name, `redeclaring the inherited generic member '${member.name.text}' (generic members dispatch statically, so the base's call sites could never reach this redeclaration)`);
1148
+ if (findGenericMethodOn(lowerer, base, member.name.text)) {
1149
+ lowerer.unsupported("SC1090", member.name, `redeclaring the inherited generic member '${member.name.text}' (generic members dispatch statically, so the base's call sites could never reach this redeclaration)`);
1160
1150
  }
1161
1151
  collectGenericMember(member, false);
1162
1152
  continue;
@@ -1165,8 +1155,8 @@ mixin) {
1165
1155
  // the two dispatch worlds (static per-instantiation calls would
1166
1156
  // never see the field's value) — the method-vs-generic mixing
1167
1157
  // fence, field form.
1168
- if (findGenericMethodOn(L, base, member.name.text)) {
1169
- L.unsupported("SC1090", member.name, `fields shadowing the inherited generic member '${member.name.text}' (generic members dispatch statically and would never reach this field's value)`);
1158
+ if (findGenericMethodOn(lowerer, base, member.name.text)) {
1159
+ lowerer.unsupported("SC1090", member.name, `fields shadowing the inherited generic member '${member.name.text}' (generic members dispatch statically and would never reach this field's value)`);
1170
1160
  }
1171
1161
  // OPTIONAL fields (`a?: string`) are the record-field precedent
1172
1162
  // applied to class shapes: the checker already types the slot
@@ -1174,13 +1164,13 @@ mixin) {
1174
1164
  // undefined arm (undefFieldInitLineC — Node defines the property
1175
1165
  // as undefined on construction, verified), and reads/writes ride
1176
1166
  // the ordinary undefined-armed union machinery.
1177
- const type = L.irTypeOf(member.name);
1167
+ const type = lowerer.irTypeOf(member.name);
1178
1168
  if (type.kind === "void")
1179
- L.badType(member.name, L.typeOf(member.name));
1169
+ lowerer.badType(member.name, lowerer.typeOf(member.name));
1180
1170
  // dyn stays out of class fields (KEEP NARROW; record
1181
1171
  // fields and array elements are unmappable via mapType already).
1182
1172
  if (type.kind === "dyn") {
1183
- L.unsupported("SC1090", member.name, "'unknown'-typed class fields");
1173
+ lowerer.unsupported("SC1090", member.name, "'unknown'-typed class fields");
1184
1174
  }
1185
1175
  if (fields.has(member.name.text)) {
1186
1176
  // REDECLARING an inherited field: Node [[Define]]s the OWN
@@ -1200,12 +1190,12 @@ mixin) {
1200
1190
  fieldOrder.push({ name: member.name.text, type, initializer: member.initializer, redeclared: true });
1201
1191
  continue;
1202
1192
  }
1203
- L.unsupported("SC1090", member.name, member.initializer
1193
+ lowerer.unsupported("SC1090", member.name, member.initializer
1204
1194
  ? "redeclaring inherited fields at a different type"
1205
1195
  : "redeclaring inherited fields without an initializer (Node resets the field to undefined)");
1206
1196
  }
1207
- if (L.findMethodOn(base, member.name.text)) {
1208
- L.unsupported("SC1090", member.name, "fields shadowing inherited methods");
1197
+ if (lowerer.findMethodOn(base, member.name.text)) {
1198
+ lowerer.unsupported("SC1090", member.name, "fields shadowing inherited methods");
1209
1199
  }
1210
1200
  // Initializer-less fields whose type ADMITS undefined start as
1211
1201
  // JS's undefined (the allocation writes the interned undefined
@@ -1221,10 +1211,10 @@ mixin) {
1221
1211
  // list checked against the constructor after the member loop
1222
1212
  // (the constructor may be declared later in the class body).
1223
1213
  const admitsUndefined = (type.kind === "union" &&
1224
- (L.unions.get(type.unionId)?.arms.some((a) => a.kind === "undefinedT") ?? false)) ||
1214
+ (lowerer.unions.get(type.unionId)?.arms.some((a) => a.kind === "undefinedT") ?? false)) ||
1225
1215
  type.kind === "jsval";
1226
1216
  if (!member.initializer && !admitsUndefined) {
1227
- const opts = L.program.getCompilerOptions();
1217
+ const opts = lowerer.program.getCompilerOptions();
1228
1218
  const spi = opts.strictPropertyInitialization ?? opts.strict ?? false;
1229
1219
  if (member.postfixToken?.kind === ts.SyntaxKind.ExclamationToken) {
1230
1220
  unguardedFields.push({
@@ -1253,7 +1243,7 @@ mixin) {
1253
1243
  if (!member.body)
1254
1244
  continue;
1255
1245
  if (ctor)
1256
- L.unsupported("SC1090", member, "constructor overloads");
1246
+ lowerer.unsupported("SC1090", member, "constructor overloads");
1257
1247
  // PARAMETER PROPERTIES (`constructor(public x: number)`): pure
1258
1248
  // sugar — the parameter declares a field and assigns it from the
1259
1249
  // parameter's value. Visibility (public/private/protected) and
@@ -1277,39 +1267,39 @@ mixin) {
1277
1267
  // Non-keyword modifiers (parameter decorators) are rejected
1278
1268
  // by tsc under standard decorators; defensive.
1279
1269
  if (p.modifiers?.length)
1280
- L.unsupported("SC1090", p, "this parameter form");
1270
+ lowerer.unsupported("SC1090", p, "this parameter form");
1281
1271
  continue;
1282
1272
  }
1283
1273
  // tsc rejects binding patterns (TS1187) and rest params
1284
1274
  // (TS1317) as parameter properties; defensive.
1285
1275
  if (!ts.isIdentifier(p.name) || p.dotDotDotToken) {
1286
- L.unsupported("SC1090", p, "this parameter property form");
1276
+ lowerer.unsupported("SC1090", p, "this parameter property form");
1287
1277
  }
1288
1278
  const name = p.name.text;
1289
- const shape = L.paramShape(p);
1279
+ const shape = lowerer.paramShape(p);
1290
1280
  const type = shape.bodyType ?? shape.type;
1291
1281
  if (type.kind === "void")
1292
- L.badType(p.name, L.typeOf(p.name));
1282
+ lowerer.badType(p.name, lowerer.typeOf(p.name));
1293
1283
  // The class-field dyn rule verbatim (KEEP NARROW).
1294
1284
  if (type.kind === "dyn") {
1295
- L.unsupported("SC1090", p.name, "'unknown'-typed class fields");
1285
+ lowerer.unsupported("SC1090", p.name, "'unknown'-typed class fields");
1296
1286
  }
1297
1287
  // `override x` (and any same-named inherited member) would
1298
1288
  // redeclare a base slot — the declared-field rule verbatim.
1299
1289
  if (fields.has(name)) {
1300
- L.unsupported("SC1090", p.name, "redeclaring inherited fields");
1290
+ lowerer.unsupported("SC1090", p.name, "redeclaring inherited fields");
1301
1291
  }
1302
- if (L.findMethodOn(base, name)) {
1303
- L.unsupported("SC1090", p.name, "fields shadowing inherited methods");
1292
+ if (lowerer.findMethodOn(base, name)) {
1293
+ lowerer.unsupported("SC1090", p.name, "fields shadowing inherited methods");
1304
1294
  }
1305
1295
  paramProps.push({ name, type, param: p });
1306
1296
  }
1307
1297
  ctor = member;
1308
1298
  }
1309
1299
  else if (ts.isMethodDeclaration(member)) {
1310
- const mName = classMemberNameOf(L, member.name);
1300
+ const mName = classMemberNameOf(lowerer, member.name);
1311
1301
  if (mName === null)
1312
- L.unsupported("SC1090", member, "computed method names");
1302
+ lowerer.unsupported("SC1090", member, "computed method names");
1313
1303
  // PUBLIC generator METHODS stay fenced (virtualCall dispatch
1314
1304
  // over gen-spawn wrappers has no story yet); module-level
1315
1305
  // function* and object-literal *methods compile — and #PRIVATE
@@ -1319,13 +1309,13 @@ mixin) {
1319
1309
  // emitter routes through the gen-spawn wrapper with `this` as
1320
1310
  // param 0 — the async-method precedent, generator form.
1321
1311
  if (member.asteriskToken !== undefined && !ts.isPrivateIdentifier(member.name)) {
1322
- L.unsupported("SC1071", member, "generator methods (a #private generator method compiles — privates never dispatch dynamically; or declare a module-level function* and call it from the method)");
1312
+ lowerer.unsupported("SC1071", member, "generator methods (a #private generator method compiles — privates never dispatch dynamically; or declare a module-level function* and call it from the method)");
1323
1313
  }
1324
1314
  // An async #private generator (`async *#m()`) is still an async
1325
1315
  // generator — the blanket SC1071 fence.
1326
1316
  if (member.asteriskToken !== undefined &&
1327
1317
  member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword)) {
1328
- L.unsupported("SC1071", member, "async generators (async function*)");
1318
+ lowerer.unsupported("SC1071", member, "async generators (async function*)");
1329
1319
  }
1330
1320
  // An ABSTRACT method is a signature with no body — type-world,
1331
1321
  // except that it declares the vtable slot: calls through
@@ -1339,24 +1329,24 @@ mixin) {
1339
1329
  // per-call-site instantiation needs a nearest declarer WITH a
1340
1330
  // body, which an abstract declaration never has.
1341
1331
  if (member.typeParameters !== undefined) {
1342
- L.unsupported("SC1090", member, "abstract generic methods (generic methods monomorphize from the nearest declaration's body, and an abstract declaration has none)");
1332
+ lowerer.unsupported("SC1090", member, "abstract generic methods (generic methods monomorphize from the nearest declaration's body, and an abstract declaration has none)");
1343
1333
  }
1344
- const { shapes, ret } = abstractMemberSignature(L, member);
1334
+ const { shapes, ret } = abstractMemberSignature(lowerer, member);
1345
1335
  if (fields.has(mName)) {
1346
- L.unsupported("SC1090", member.name, "methods shadowing inherited fields");
1336
+ lowerer.unsupported("SC1090", member.name, "methods shadowing inherited fields");
1347
1337
  }
1348
- if (findGenericMethodOn(L, base, mName)) {
1349
- L.unsupported("SC1090", member.name, `overriding the inherited generic method '${mName}' with a non-generic method (generic methods dispatch statically and would never reach this override)`);
1338
+ if (findGenericMethodOn(lowerer, base, mName)) {
1339
+ lowerer.unsupported("SC1090", member.name, `overriding the inherited generic method '${mName}' with a non-generic method (generic methods dispatch statically and would never reach this override)`);
1350
1340
  }
1351
1341
  // Abstract re-declarations keep the overridden ABI exactly,
1352
1342
  // like any override (a concrete implementation below must
1353
1343
  // agree with BOTH, which exactness makes one constraint).
1354
- const overridden = L.findMethodOn(base, mName);
1344
+ const overridden = lowerer.findMethodOn(base, mName);
1355
1345
  if (overridden &&
1356
1346
  (overridden.sig.params.length !== shapes.length ||
1357
1347
  !overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) ||
1358
1348
  !typeEquals(overridden.sig.ret, ret))) {
1359
- L.unsupported("SC1090", member.name, "overriding a method with a different signature (parameter and return types must match the base declaration exactly)");
1349
+ lowerer.unsupported("SC1090", member.name, "overriding a method with a different signature (parameter and return types must match the base declaration exactly)");
1360
1350
  }
1361
1351
  methods.set(mName, { params: shapes, ret, abstract: true });
1362
1352
  continue;
@@ -1373,10 +1363,10 @@ mixin) {
1373
1363
  // calls vs vtable slots — cannot see each other's overrides).
1374
1364
  if (member.typeParameters !== undefined) {
1375
1365
  if (fields.has(mName)) {
1376
- L.unsupported("SC1090", member.name, "methods shadowing inherited fields");
1366
+ lowerer.unsupported("SC1090", member.name, "methods shadowing inherited fields");
1377
1367
  }
1378
- if (L.findMethodOn(base, mName)) {
1379
- L.unsupported("SC1090", member.name, `overriding the inherited method '${mName}' with a generic method (generic methods dispatch statically, so the base's vtable slot could never reach this override)`);
1368
+ if (lowerer.findMethodOn(base, mName)) {
1369
+ lowerer.unsupported("SC1090", member.name, `overriding the inherited method '${mName}' with a generic method (generic methods dispatch statically, so the base's vtable slot could never reach this override)`);
1380
1370
  }
1381
1371
  collectGenericMember(member, false);
1382
1372
  continue;
@@ -1408,9 +1398,9 @@ mixin) {
1408
1398
  ts.isIdentifier(member.name) &&
1409
1399
  inst === undefined && decl.typeParameters === undefined &&
1410
1400
  !fields.has(member.name.text) &&
1411
- !L.findMethodOn(base, member.name.text) &&
1412
- !findGenericMethodOn(L, base, member.name.text)) {
1413
- const implicit = implicitAnyParamSymbolsOf(L, member);
1401
+ !lowerer.findMethodOn(base, member.name.text) &&
1402
+ !findGenericMethodOn(lowerer, base, member.name.text)) {
1403
+ const implicit = implicitAnyParamSymbolsOf(lowerer, member);
1414
1404
  if (implicit) {
1415
1405
  genericMethods.set(member.name.text, {
1416
1406
  decl: member,
@@ -1423,12 +1413,12 @@ mixin) {
1423
1413
  continue;
1424
1414
  }
1425
1415
  }
1426
- const { shapes, funcType: ft } = L.lambdaSignature(member);
1416
+ const { shapes, funcType: ft } = lowerer.lambdaSignature(member);
1427
1417
  if (fields.has(mName)) {
1428
- L.unsupported("SC1090", member.name, "methods shadowing inherited fields");
1418
+ lowerer.unsupported("SC1090", member.name, "methods shadowing inherited fields");
1429
1419
  }
1430
- if (findGenericMethodOn(L, base, mName)) {
1431
- L.unsupported("SC1090", member.name, `overriding the inherited generic method '${mName}' with a non-generic method (generic methods dispatch statically and would never reach this override)`);
1420
+ if (findGenericMethodOn(lowerer, base, mName)) {
1421
+ lowerer.unsupported("SC1090", member.name, `overriding the inherited generic method '${mName}' with a non-generic method (generic methods dispatch statically and would never reach this override)`);
1432
1422
  }
1433
1423
  // Symbol-slot return refinement, INHERITED slots (own ctor-declared
1434
1424
  // slots refine in the post-scan pass below — the constructor hasn't
@@ -1436,7 +1426,7 @@ mixin) {
1436
1426
  // symbolFields/fields). Doing it before the exactness check keeps
1437
1427
  // a derived override of a refined base method agreeing.
1438
1428
  if (ft.ret.kind === "dyn") {
1439
- const refined = symbolSlotReturnType(L, member, symbolFields, fields);
1429
+ const refined = symbolSlotReturnType(lowerer, member, symbolFields, fields);
1440
1430
  if (refined)
1441
1431
  ft.ret = refined;
1442
1432
  }
@@ -1448,18 +1438,18 @@ mixin) {
1448
1438
  // ABI types only (not modes) is deliberate: call sites complete
1449
1439
  // against the STATIC receiver's shape, so `m(x?: number)` and
1450
1440
  // `m(x: number | undefined)` interchange soundly in overrides.
1451
- const overridden = L.findMethodOn(base, mName);
1441
+ const overridden = lowerer.findMethodOn(base, mName);
1452
1442
  if (overridden?.declarer.builtinError) {
1453
1443
  // Error.prototype.toString is a runtime implementation with no
1454
1444
  // vtable slot — calls to it are direct, so an override could
1455
1445
  // never be reached through a base-typed receiver.
1456
- L.unsupported("SC1090", member.name, `overriding the builtin Error method '${mName}'`);
1446
+ lowerer.unsupported("SC1090", member.name, `overriding the builtin Error method '${mName}'`);
1457
1447
  }
1458
1448
  if (overridden &&
1459
1449
  (overridden.sig.params.length !== shapes.length ||
1460
1450
  !overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) ||
1461
1451
  !typeEquals(overridden.sig.ret, ft.ret))) {
1462
- L.unsupported("SC1090", member.name, "overriding a method with a different signature (parameter and return types must match the base declaration exactly)");
1452
+ lowerer.unsupported("SC1090", member.name, "overriding a method with a different signature (parameter and return types must match the base declaration exactly)");
1463
1453
  }
1464
1454
  const asyncMember = member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
1465
1455
  // Async methods dispatch STATICALLY (the body enters through its
@@ -1467,7 +1457,7 @@ mixin) {
1467
1457
  // an override chain touching an async method on either end would
1468
1458
  // put a spawn wrapper behind a virtual slot, so it fences.
1469
1459
  if (overridden && (asyncMember || overridden.sig.async === true)) {
1470
- L.unsupported("SC1090", member.name, `overriding ${overridden.sig.async === true ? "the async method" : "a method with an async method"} '${mName}' (async methods dispatch statically — the vtable slot machinery has no fiber-spawn story)`);
1460
+ lowerer.unsupported("SC1090", member.name, `overriding ${overridden.sig.async === true ? "the async method" : "a method with an async method"} '${mName}' (async methods dispatch statically — the vtable slot machinery has no fiber-spawn story)`);
1471
1461
  }
1472
1462
  // A #private GENERATOR method carries its channels on the sig:
1473
1463
  // the body lowers as a generator IrFunction (`this` as param 0),
@@ -1475,7 +1465,7 @@ mixin) {
1475
1465
  // emitted gen-spawn wrapper, answering the suspended generator.
1476
1466
  if (member.asteriskToken !== undefined) {
1477
1467
  if (ft.ret.kind !== "generator")
1478
- L.badType(member.name, L.typeOf(member.name));
1468
+ lowerer.badType(member.name, lowerer.typeOf(member.name));
1479
1469
  methods.set(mName, { params: shapes, ret: ft.ret, gen: { yieldT: ft.ret.yieldT, nextT: ft.ret.nextT } });
1480
1470
  }
1481
1471
  else {
@@ -1498,7 +1488,7 @@ mixin) {
1498
1488
  // #private accessors collect as "get:#x"/"set:#x" — the same
1499
1489
  // reserved spelling, one more unspellable segment.
1500
1490
  if (!ts.isIdentifier(member.name) && !ts.isPrivateIdentifier(member.name)) {
1501
- L.unsupported("SC1090", member, "computed accessor names");
1491
+ lowerer.unsupported("SC1090", member, "computed accessor names");
1502
1492
  }
1503
1493
  // ABSTRACT accessors are the abstract-method story with property
1504
1494
  // syntax: body-less by definition, they enter `methods` (marked
@@ -1506,23 +1496,23 @@ mixin) {
1506
1496
  // and override exactness verbatim; no module function exists.
1507
1497
  const abstractAccessor = ts.getModifiers(member)?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword) === true;
1508
1498
  if (!member.body && !abstractAccessor)
1509
- L.unsupported("SC1090", member, "bodyless accessors");
1499
+ lowerer.unsupported("SC1090", member, "bodyless accessors");
1510
1500
  const prop = member.name.text;
1511
1501
  const mName = `${isGet ? "get" : "set"}:${prop}`;
1512
1502
  if (fields.has(prop)) {
1513
1503
  // tsc rejects field/accessor mixing (TS2610/2611); defensive.
1514
- L.unsupported("SC1090", member.name, "accessors sharing a name with a field");
1504
+ lowerer.unsupported("SC1090", member.name, "accessors sharing a name with a field");
1515
1505
  }
1516
1506
  let sig;
1517
1507
  if (isGet) {
1518
- const ret = L.declaredReturnType(member, member.name);
1508
+ const ret = lowerer.declaredReturnType(member, member.name);
1519
1509
  if (ret.kind === "void")
1520
- L.badType(member.name, L.typeOf(member.name));
1510
+ lowerer.badType(member.name, lowerer.typeOf(member.name));
1521
1511
  sig = { params: [], ret };
1522
1512
  }
1523
1513
  else {
1524
1514
  // tsc rejects optional/default/rest setter params (TS1051-53).
1525
- sig = { params: L.paramShapes(member.parameters), ret: VOID };
1515
+ sig = { params: lowerer.paramShapes(member.parameters), ret: VOID };
1526
1516
  }
1527
1517
  // One property, ONE type: tsc (5.1+) admits get/set pairs with
1528
1518
  // unrelated annotated types; a property slot here has a single
@@ -1531,16 +1521,16 @@ mixin) {
1531
1521
  const twinType = twin ? (isGet ? twin.params[0].type : twin.ret) : null;
1532
1522
  const ownType = isGet ? sig.ret : sig.params[0].type;
1533
1523
  if (twinType && !typeEquals(twinType, ownType)) {
1534
- L.unsupported("SC1090", member.name, `getter/setter pairs with different types (the property '${prop}' must have one type)`);
1524
+ lowerer.unsupported("SC1090", member.name, `getter/setter pairs with different types (the property '${prop}' must have one type)`);
1535
1525
  }
1536
1526
  // Same exactness rule as methods — an accessor override keeps
1537
1527
  // the overridden accessor's type (getter return / setter param).
1538
- const overridden = L.findMethodOn(base, mName);
1528
+ const overridden = lowerer.findMethodOn(base, mName);
1539
1529
  if (overridden &&
1540
1530
  (overridden.sig.params.length !== sig.params.length ||
1541
1531
  !overridden.sig.params.every((p, i) => typeEquals(p.type, sig.params[i].type)) ||
1542
1532
  !typeEquals(overridden.sig.ret, sig.ret))) {
1543
- L.unsupported("SC1090", member.name, "overriding an accessor with a different type (the property type must match the base declaration exactly)");
1533
+ lowerer.unsupported("SC1090", member.name, "overriding an accessor with a different type (the property type must match the base declaration exactly)");
1544
1534
  }
1545
1535
  methods.set(mName, abstractAccessor ? { ...sig, abstract: true } : sig);
1546
1536
  // Abstract accessors stay OUT of accessorNodes: they are erased
@@ -1551,10 +1541,10 @@ mixin) {
1551
1541
  accessorNodes.set(mName, member);
1552
1542
  }
1553
1543
  else if (ts.isIndexSignatureDeclaration(member)) {
1554
- L.unsupported("SC1090", member, "index signatures");
1544
+ lowerer.unsupported("SC1090", member, "index signatures");
1555
1545
  }
1556
1546
  else if (!ts.isSemicolonClassElement(member)) {
1557
- L.unsupported("SC1090", member, `syntax '${ts.SyntaxKind[member.kind]}'`);
1547
+ lowerer.unsupported("SC1090", member, `syntax '${ts.SyntaxKind[member.kind]}'`);
1558
1548
  }
1559
1549
  }
1560
1550
  // Parameter properties join the shape FIRST among own fields —
@@ -1605,7 +1595,7 @@ mixin) {
1605
1595
  declared.kind !== "map" && declared.kind !== "date" && declared.kind !== "generator" &&
1606
1596
  declared.kind !== "void" &&
1607
1597
  declared.kind !== "caught";
1608
- const armed = armable ? L.withUndefinedArm(declared) : null;
1598
+ const armed = armable ? lowerer.withUndefinedArm(declared) : null;
1609
1599
  if (armed !== null && armed.kind === "union") {
1610
1600
  fields.set(f.name, armed);
1611
1601
  const fo = fieldOrder.find((x) => x.name === f.name);
@@ -1614,7 +1604,7 @@ mixin) {
1614
1604
  deferredInitFields.add(f.name);
1615
1605
  continue;
1616
1606
  }
1617
- L.unsupported("SC1090", f.node, f.why);
1607
+ lowerer.unsupported("SC1090", f.node, f.why);
1618
1608
  }
1619
1609
  }
1620
1610
  // Partial overrides of an inherited accessor pair. JS gives the
@@ -1636,13 +1626,13 @@ mixin) {
1636
1626
  // no accessor pair to shadow, so no throwing setter to
1637
1627
  // synthesize (tsc makes an instantiable class implement it, and
1638
1628
  // that implementation shadows nothing either).
1639
- const baseSet = L.findMethodOn(base, `set:${prop}`);
1629
+ const baseSet = lowerer.findMethodOn(base, `set:${prop}`);
1640
1630
  if (baseSet && baseSet.sig.abstract !== true) {
1641
1631
  if (!typeEquals(baseSet.sig.params[0].type, methods.get(mName).ret)) {
1642
1632
  // Unreachable when the base pair agrees (induction through
1643
1633
  // the exactness rule); a base setter-only + new getter of a
1644
1634
  // different type would break the slot signature.
1645
- L.unsupported("SC1090", node.name, "accessors whose getter and inherited setter types differ");
1635
+ lowerer.unsupported("SC1090", node.name, "accessors whose getter and inherited setter types differ");
1646
1636
  }
1647
1637
  methods.set(`set:${prop}`, { params: [baseSet.sig.params[0]], ret: VOID });
1648
1638
  throwingSetters.push(prop);
@@ -1650,9 +1640,9 @@ mixin) {
1650
1640
  }
1651
1641
  if (mName.startsWith("set:") && !accessorNodes.has(`get:${prop}`)) {
1652
1642
  // The abstract-inherited-getter case is the same erasure story.
1653
- const baseGet = L.findMethodOn(base, `get:${prop}`);
1643
+ const baseGet = lowerer.findMethodOn(base, `get:${prop}`);
1654
1644
  if (baseGet && baseGet.sig.abstract !== true) {
1655
- L.unsupported("SC1090", node.name, `overriding only the setter of an inherited accessor pair (JS shadows the inherited getter — reads of '${prop}' would yield undefined; declare the getter too)`);
1645
+ lowerer.unsupported("SC1090", node.name, `overriding only the setter of an inherited accessor pair (JS shadows the inherited getter — reads of '${prop}' would yield undefined; declare the getter too)`);
1656
1646
  }
1657
1647
  }
1658
1648
  }
@@ -1672,8 +1662,8 @@ mixin) {
1672
1662
  // Named classes (declarations and self-binding expressions) resolve
1673
1663
  // by name; the nameless default-export declaration by its module's
1674
1664
  // default-export symbol.
1675
- const classSym = decl.name ? L.checker.getSymbolAtLocation(decl.name) : ts.isClassDeclaration(decl) ? declSymbolOf(L, decl) : undefined;
1676
- const instType = classSym ? L.checker.getDeclaredTypeOfSymbol(classSym) : undefined;
1665
+ const classSym = decl.name ? lowerer.checker.getSymbolAtLocation(decl.name) : ts.isClassDeclaration(decl) ? declSymbolOf(lowerer, decl) : undefined;
1666
+ const instType = classSym ? lowerer.checker.getDeclaredTypeOfSymbol(classSym) : undefined;
1677
1667
  // LATE-BOUND properties (the checker's `__@name@id` spelling —
1678
1668
  // `this[kLimit] = v` where kLimit is a unique symbol const) by
1679
1669
  // their KEY symbol: the scan below needs the checker's property
@@ -1682,10 +1672,10 @@ mixin) {
1682
1672
  // answers null on element-access declaration sites, so the link
1683
1673
  // goes through the key.
1684
1674
  const lateBoundByKey = new Map();
1685
- for (const p of instType ? L.checker.getPropertiesOfType(instType) : []) {
1675
+ for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
1686
1676
  if (!p.name.startsWith("__@"))
1687
1677
  continue;
1688
- const keySym = lateBoundKeySymOf(L, p);
1678
+ const keySym = lateBoundKeySymOf(lowerer, p);
1689
1679
  if (keySym)
1690
1680
  lateBoundByKey.set(keySym, p);
1691
1681
  }
@@ -1704,20 +1694,20 @@ mixin) {
1704
1694
  // inherited) are writes, not declarations.
1705
1695
  if (fields.has(name))
1706
1696
  continue;
1707
- if (methods.has(name) || L.findMethodOn(base, name)) {
1708
- L.unsupported("SC1090", assign, "constructor-assigned fields shadowing methods");
1697
+ if (methods.has(name) || lowerer.findMethodOn(base, name)) {
1698
+ lowerer.unsupported("SC1090", assign, "constructor-assigned fields shadowing methods");
1709
1699
  }
1710
- const sym = L.checker.getSymbolAtLocation(assign);
1711
- const t = sym ? L.checker.getTypeOfSymbol(sym) : undefined;
1700
+ const sym = lowerer.checker.getSymbolAtLocation(assign);
1701
+ const t = sym ? lowerer.checker.getTypeOfSymbol(sym) : undefined;
1712
1702
  // Implicit-any fields (assigned from UNTYPED ctor params —
1713
1703
  // countdown.js's `this.limit = limit`) take the JS checked-
1714
1704
  // dynamic fallback like every JS binding: the slot holds a dyn
1715
1705
  // box, reads validate per use, writes convert in (dynFrom).
1716
1706
  // TS-annotated `unknown` fields keep their fence (KEEP NARROW
1717
1707
  // applies where an annotation could say better).
1718
- let type = t ? (L.mapTypeOf(t) ?? dynFallbackType(L, assign, t)) : null;
1708
+ let type = t ? (lowerer.mapTypeOf(t) ?? dynFallbackType(lowerer, assign, t)) : null;
1719
1709
  if (!type || type.kind === "void")
1720
- L.badType(assign, t ?? L.typeOf(assign));
1710
+ lowerer.badType(assign, t ?? lowerer.typeOf(assign));
1721
1711
  // A JSDoc claim the BODY contradicts (`@type {Command}`
1722
1712
  // assigned `undefined` — the lazy-init idiom): the
1723
1713
  // representation follows the body — the field widens to the
@@ -1726,13 +1716,13 @@ mixin) {
1726
1716
  // Trust-but-verify: the claim never silently narrows the
1727
1717
  // runtime value.
1728
1718
  {
1729
- const rhsT = L.typeOf(stmt.expression.right);
1719
+ const rhsT = lowerer.typeOf(stmt.expression.right);
1730
1720
  const assignsUndef = (rhsT.flags & ts.TypeFlags.Undefined) !== 0;
1731
1721
  const admitsUndef = type.kind === "dyn" ||
1732
1722
  isUnitType(type) ||
1733
- (type.kind === "union" && L.armTag(type.unionId, UNDEFINED_T) >= 0);
1723
+ (type.kind === "union" && lowerer.armTag(type.unionId, UNDEFINED_T) >= 0);
1734
1724
  if (assignsUndef && !admitsUndef) {
1735
- const widened = L.withUndefinedArmOf(type);
1725
+ const widened = lowerer.withUndefinedArmOf(type);
1736
1726
  if (widened !== null)
1737
1727
  type = widened;
1738
1728
  }
@@ -1752,7 +1742,7 @@ mixin) {
1752
1742
  // late-bound fence below.
1753
1743
  if (lhs && ts.isElementAccessExpression(lhs) &&
1754
1744
  lhs.expression.kind === ts.SyntaxKind.ThisKeyword) {
1755
- const key = uniqueSymbolKeyOf(L, lhs.argumentExpression);
1745
+ const key = uniqueSymbolKeyOf(lowerer, lhs.argumentExpression);
1756
1746
  if (!key)
1757
1747
  continue;
1758
1748
  // A key already declared (own or inherited) makes later
@@ -1762,7 +1752,7 @@ mixin) {
1762
1752
  if (fields.has(key.fieldName)) {
1763
1753
  // Two DISTINCT Symbol(...) consts with one description in
1764
1754
  // one layout would need one printable name for two slots.
1765
- L.unsupported("SC1090", lhs, `distinct symbol keys sharing the printable name '${key.fieldName}' in one class`);
1755
+ lowerer.unsupported("SC1090", lhs, `distinct symbol keys sharing the printable name '${key.fieldName}' in one class`);
1766
1756
  }
1767
1757
  const propSym = lateBoundByKey.get(key.sym);
1768
1758
  // tsgo does not synthesize the late-bound `__@name@id`
@@ -1775,13 +1765,13 @@ mixin) {
1775
1765
  ? stmt.expression.right
1776
1766
  : undefined;
1777
1767
  const t = propSym
1778
- ? L.checker.getTypeOfSymbol(propSym)
1768
+ ? lowerer.checker.getTypeOfSymbol(propSym)
1779
1769
  : rhs
1780
- ? L.checker.getBaseTypeOfLiteralType(L.checker.getTypeAtLocation(rhs))
1770
+ ? lowerer.checker.getBaseTypeOfLiteralType(lowerer.checker.getTypeAtLocation(rhs))
1781
1771
  : undefined;
1782
- const type = t ? (L.mapTypeOf(t) ?? dynFallbackType(L, lhs, t)) : null;
1772
+ const type = t ? (lowerer.mapTypeOf(t) ?? dynFallbackType(lowerer, lhs, t)) : null;
1783
1773
  if (!type || type.kind === "void")
1784
- L.badType(lhs, t ?? L.typeOf(lhs));
1774
+ lowerer.badType(lhs, t ?? lowerer.typeOf(lhs));
1785
1775
  fields.set(key.fieldName, type);
1786
1776
  symbolFields.set(key.sym, key.fieldName);
1787
1777
  fieldOrder.push({ name: key.fieldName, type, initializer: undefined });
@@ -1793,14 +1783,14 @@ mixin) {
1793
1783
  // computed keys — is undefined until its first write, which these
1794
1784
  // static layouts cannot represent. Named fence, at the first
1795
1785
  // assignment site.
1796
- for (const p of instType ? L.checker.getPropertiesOfType(instType) : []) {
1786
+ for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
1797
1787
  if (fields.has(p.name) || methods.has(p.name))
1798
1788
  continue;
1799
1789
  if (methods.has(`get:${p.name}`) || methods.has(`set:${p.name}`))
1800
1790
  continue;
1801
- if (base && (base.fields.has(p.name) || L.findMethodOn(base, p.name)))
1791
+ if (base && (base.fields.has(p.name) || lowerer.findMethodOn(base, p.name)))
1802
1792
  continue;
1803
- const site = L.checker.declarationsOf(p).find((d) => ts.isPropertyAccessExpression(d) || ts.isBinaryExpression(d) ||
1793
+ const site = lowerer.checker.declarationsOf(p).find((d) => ts.isPropertyAccessExpression(d) || ts.isBinaryExpression(d) ||
1804
1794
  ts.isElementAccessExpression(d));
1805
1795
  if (!site)
1806
1796
  continue;
@@ -1811,10 +1801,10 @@ mixin) {
1811
1801
  // descriptions) or assignments outside the constructor's top
1812
1802
  // level.
1813
1803
  if (p.name.startsWith("__@")) {
1814
- const keySym = lateBoundKeySymOf(L, p);
1804
+ const keySym = lateBoundKeySymOf(lowerer, p);
1815
1805
  if (keySym && symbolFields.has(keySym))
1816
1806
  continue;
1817
- L.unsupported("SC1090", site, "symbol-keyed class fields outside the supported form (a module-level `const k = Symbol('desc')` key, assigned unconditionally at the top of the constructor)");
1807
+ lowerer.unsupported("SC1090", site, "symbol-keyed class fields outside the supported form (a module-level `const k = Symbol('desc')` key, assigned unconditionally at the top of the constructor)");
1818
1808
  }
1819
1809
  // JS classes: a property first assigned in a method or a
1820
1810
  // conditional constructor position holds `undefined` until the
@@ -1827,14 +1817,14 @@ mixin) {
1827
1817
  // TypeScript classes keep the loud fence too: an annotated
1828
1818
  // program can spell `T | undefined` itself.
1829
1819
  if (isJsSourceFile(decl.getSourceFile())) {
1830
- const armed = undefArmedFieldType(L, p);
1820
+ const armed = undefArmedFieldType(lowerer, p);
1831
1821
  if (armed !== null) {
1832
1822
  fields.set(p.name, armed);
1833
1823
  fieldOrder.push({ name: p.name, type: armed, initializer: undefined });
1834
1824
  continue;
1835
1825
  }
1836
1826
  }
1837
- L.unsupported("SC1090", site, `fields assigned outside the constructor's top level ('this.${p.name}' would be undefined until the first assignment runs — assign it unconditionally at the top of the constructor)`);
1827
+ lowerer.unsupported("SC1090", site, `fields assigned outside the constructor's top level ('this.${p.name}' would be undefined until the first assignment runs — assign it unconditionally at the top of the constructor)`);
1838
1828
  }
1839
1829
  }
1840
1830
  // Second refinement chance, OWN symbol slots: the member loop ran
@@ -1845,7 +1835,7 @@ mixin) {
1845
1835
  const sig = methods.get(mName);
1846
1836
  if (!sig || sig.ret.kind !== "dyn")
1847
1837
  continue;
1848
- const refined = symbolSlotReturnType(L, node, symbolFields, fields);
1838
+ const refined = symbolSlotReturnType(lowerer, node, symbolFields, fields);
1849
1839
  if (refined)
1850
1840
  sig.ret = refined;
1851
1841
  }
@@ -1857,15 +1847,15 @@ mixin) {
1857
1847
  // parameter never materializes. A rest constructor in a mixin that
1858
1848
  // is NOT the pure forwarding shape has no static story — named
1859
1849
  // fence, never a mis-typed array.
1860
- const mixinForwarding = mixin !== undefined && ctor !== null && mixinForwardingCtor(L, ctor);
1850
+ const mixinForwarding = mixin !== undefined && ctor !== null && mixinForwardingCtor(lowerer, ctor);
1861
1851
  if (mixin && ctor && !mixinForwarding && ctor.parameters.some((p) => p.dotDotDotToken)) {
1862
- L.unsupported("SC1090", ctor.parameters.find((p) => p.dotDotDotToken), "mixin constructors whose rest parameter does anything but forward (`super(...args)` as the first statement is the compiled shape)");
1852
+ lowerer.unsupported("SC1090", ctor.parameters.find((p) => p.dotDotDotToken), "mixin constructors whose rest parameter does anything but forward (`super(...args)` as the first statement is the compiled shape)");
1863
1853
  }
1864
1854
  // Constructor omitted on a derived class: it inherits the base's
1865
1855
  // (tsc types `new Derived(...)` against the inherited signature; the
1866
1856
  // synthesized constructor forwards the same params to super).
1867
1857
  const ctorParams = ctor && !mixinForwarding
1868
- ? L.paramShapes(ctor.parameters)
1858
+ ? lowerer.paramShapes(ctor.parameters)
1869
1859
  : (base?.ctorParams ?? []);
1870
1860
  const info = {
1871
1861
  def: {
@@ -1944,9 +1934,9 @@ mixin) {
1944
1934
  if (familyMode) {
1945
1935
  const typeParams = [];
1946
1936
  for (const tp of decl.typeParameters) {
1947
- const sym = L.checker.getSymbolAtLocation(tp.name);
1937
+ const sym = lowerer.checker.getSymbolAtLocation(tp.name);
1948
1938
  if (!sym)
1949
- L.unsupported("SC1090", tp, "this type parameter form");
1939
+ lowerer.unsupported("SC1090", tp, "this type parameter form");
1950
1940
  typeParams.push(sym);
1951
1941
  }
1952
1942
  info.generic = {
@@ -1956,11 +1946,11 @@ mixin) {
1956
1946
  family: info,
1957
1947
  instances: new Map(),
1958
1948
  };
1959
- L.genericClassByDecl.set(decl, info.generic);
1949
+ lowerer.genericClassByDecl.set(decl, info.generic);
1960
1950
  }
1961
1951
  if (base)
1962
1952
  base.subclasses.push(info);
1963
- L.classes.set(className, info);
1953
+ lowerer.classes.set(className, info);
1964
1954
  // A NAMED class binds its name (declarations in their scope, class
1965
1955
  // expressions inside their own bodies — tsc resolves both to this
1966
1956
  // symbol); a nameless default-export declaration binds its module's
@@ -1971,14 +1961,14 @@ mixin) {
1971
1961
  // classes fence at their use sites).
1972
1962
  const classSymbol = inst || mixin
1973
1963
  ? undefined
1974
- : decl.name ? L.checker.getSymbolAtLocation(decl.name) : ts.isClassDeclaration(decl) ? declSymbolOf(L, decl) : undefined;
1964
+ : decl.name ? lowerer.checker.getSymbolAtLocation(decl.name) : ts.isClassDeclaration(decl) ? declSymbolOf(lowerer, decl) : undefined;
1975
1965
  if (classSymbol)
1976
- L.classBySymbol.set(classSymbol, info);
1966
+ lowerer.classBySymbol.set(classSymbol, info);
1977
1967
  // Static-field storage registers with the module's globals only
1978
1968
  // once the whole shape collected (a poisoned class never leaves a
1979
1969
  // half-registered global behind).
1980
1970
  for (const f of staticFields) {
1981
- L.globalsList.push({ id: f.globalId, name: `${info.def.jsName ?? className}.${f.name}`, type: f.type, mutable: !f.readonly });
1971
+ lowerer.globalsList.push({ id: f.globalId, name: `${info.def.jsName ?? className}.${f.name}`, type: f.type, mutable: !f.readonly });
1982
1972
  }
1983
1973
  }
1984
1974
  }
@@ -1992,15 +1982,15 @@ mixin) {
1992
1982
  * unmapped, the fenced-JS-class story. Null answers (unmappable type
1993
1983
  * arguments, the instance cap, an uncollected family) make the whole
1994
1984
  * reference unmappable — per-site diagnostics own the fence. */
1995
- export function genericClassInstanceType(L, decl, ref) {
1996
- const gci = L.genericClassByDecl.get(decl);
1985
+ export function genericClassInstanceType(lowerer, decl, ref) {
1986
+ const gci = lowerer.genericClassByDecl.get(decl);
1997
1987
  if (!gci) {
1998
1988
  // The family never collected (a deferred/poisoned declaration): the
1999
1989
  // pre-generics answer — the class's own name, unregistered, so dead
2000
1990
  // storage prunes (typeNamesUnregisteredClass) and live references
2001
1991
  // flush the declaration's deferred diagnostics (moduleArtifacts /
2002
1992
  // the validator backstop). Exactly the fenced-class story.
2003
- return { kind: "object", className: L.classNamer(decl) };
1993
+ return { kind: "object", className: lowerer.classNamer(decl) };
2004
1994
  }
2005
1995
  // A degenerate reference collapses to the FAMILY's object type instead
2006
1996
  // of going unmapped: `Box<any>` under a static build, wilder arguments
@@ -2015,11 +2005,11 @@ export function genericClassInstanceType(L, decl, ref) {
2015
2005
  const familyT = { kind: "object", className: gci.family.def.name };
2016
2006
  // The checker appends `this` (and outer type parameters) to
2017
2007
  // getTypeArguments — only the declaration's own count participates.
2018
- const args = L.checker.getTypeArguments(ref).slice(0, gci.typeParams.length);
2008
+ const args = lowerer.checker.getTypeArguments(ref).slice(0, gci.typeParams.length);
2019
2009
  const mapped = [];
2020
2010
  if (args.length === gci.typeParams.length) {
2021
2011
  for (const a of args) {
2022
- const m = L.mapTypeOf(a);
2012
+ const m = lowerer.mapTypeOf(a);
2023
2013
  if (!m || m.kind === "void") {
2024
2014
  // An UNBOUND type parameter argument (`Box<T>` outside any
2025
2015
  // instantiation) stays honestly unmapped — nothing concrete is
@@ -2035,7 +2025,7 @@ export function genericClassInstanceType(L, decl, ref) {
2035
2025
  // Inside an instantiation the CURRENT bindings are the arguments;
2036
2026
  // anywhere else the reference is honestly unmappable.
2037
2027
  for (const tp of gci.typeParams) {
2038
- const b = L.typeParamBindings?.get(tp);
2028
+ const b = lowerer.typeParamBindings?.get(tp);
2039
2029
  if (!b)
2040
2030
  return null;
2041
2031
  mapped.push(b);
@@ -2045,7 +2035,7 @@ export function genericClassInstanceType(L, decl, ref) {
2045
2035
  const existing = gci.instances.get(key);
2046
2036
  if (existing) {
2047
2037
  if (existing.info)
2048
- L.noteGenericClassInstanceDemand(existing.info);
2038
+ lowerer.noteGenericClassInstanceDemand(existing.info);
2049
2039
  return existing.poisoned ? null : { kind: "object", className: existing.name };
2050
2040
  }
2051
2041
  // The generic-fn cap, same rationale (polymorphic recursion through
@@ -2060,14 +2050,14 @@ export function genericClassInstanceType(L, decl, ref) {
2060
2050
  gci.instances.set(key, entry);
2061
2051
  const bindings = new Map();
2062
2052
  gci.typeParams.forEach((tp, i) => bindings.set(tp, mapped[i]));
2063
- const rendered = mapped.map((m) => L.fmt(m)).join(", ");
2053
+ const rendered = mapped.map((m) => lowerer.fmt(m)).join(", ");
2064
2054
  const typeArgsText = `<${rendered.length > 80 ? rendered.slice(0, 77) + "..." : rendered}>`;
2065
- const prevBindings = L.typeParamBindings;
2066
- const prevContext = L.instantiationContext;
2067
- L.typeParamBindings = bindings;
2068
- L.instantiationContext = `instantiating class '${gci.baseName}' with ${typeArgsText}`;
2055
+ const prevBindings = lowerer.typeParamBindings;
2056
+ const prevContext = lowerer.instantiationContext;
2057
+ lowerer.typeParamBindings = bindings;
2058
+ lowerer.instantiationContext = `instantiating class '${gci.baseName}' with ${typeArgsText}`;
2069
2059
  try {
2070
- L.collectClassShapeInner(decl, undefined, { family: gci.family, name, bindings, typeArgsText, ordinal });
2060
+ lowerer.collectClassShapeInner(decl, undefined, { family: gci.family, name, bindings, typeArgsText, ordinal });
2071
2061
  }
2072
2062
  catch (e) {
2073
2063
  // Collection fenced under THESE bindings: the diagnostic (with the
@@ -2078,18 +2068,18 @@ export function genericClassInstanceType(L, decl, ref) {
2078
2068
  return null;
2079
2069
  }
2080
2070
  finally {
2081
- L.typeParamBindings = prevBindings;
2082
- L.instantiationContext = prevContext;
2071
+ lowerer.typeParamBindings = prevBindings;
2072
+ lowerer.instantiationContext = prevContext;
2083
2073
  }
2084
- const info = L.classes.get(name);
2074
+ const info = lowerer.classes.get(name);
2085
2075
  if (!info) {
2086
2076
  entry.poisoned = true;
2087
2077
  return null;
2088
2078
  }
2089
2079
  entry.info = info;
2090
- L.genericClassInstances.push(info);
2091
- L.noteGenericClassInstanceDemand(info);
2092
- L.onLateClassCollected?.(info);
2080
+ lowerer.genericClassInstances.push(info);
2081
+ lowerer.noteGenericClassInstanceDemand(info);
2082
+ lowerer.onLateClassCollected?.(info);
2093
2083
  return { kind: "object", className: name };
2094
2084
  }
2095
2085
  /** Runs a member-lowering thunk under an INSTANTIATION's type-parameter
@@ -2098,7 +2088,7 @@ export function genericClassInstanceType(L, decl, ref) {
2098
2088
  * Coverage counts a generic class's statements once: only the FIRST
2099
2089
  * instantiation contributes (the lowerGenericInstance rule). A no-op
2100
2090
  * for ordinary classes. */
2101
- export function withInstanceBindings(L, info, fn) {
2091
+ function withInstanceBindings(lowerer, info, fn) {
2102
2092
  const gi = info.genericInstance;
2103
2093
  if (!gi) {
2104
2094
  // MIXIN instantiations ride the same mechanism: T (the base
@@ -2108,37 +2098,37 @@ export function withInstanceBindings(L, info, fn) {
2108
2098
  const mi = info.mixinInstance;
2109
2099
  if (!mi)
2110
2100
  return fn();
2111
- const prevBindings = L.typeParamBindings;
2112
- const prevContext = L.instantiationContext;
2113
- const prevSuppress = L.suppressStats;
2114
- const prevMixinCtx = L.mixinTypeContext;
2115
- L.typeParamBindings = mi.bindings;
2116
- L.instantiationContext = mi.context;
2117
- L.suppressStats = prevSuppress || mi.ordinal > 0;
2118
- L.mixinTypeContext = { classNode: info.decl, className: info.def.name };
2101
+ const prevBindings = lowerer.typeParamBindings;
2102
+ const prevContext = lowerer.instantiationContext;
2103
+ const prevSuppress = lowerer.suppressStats;
2104
+ const prevMixinCtx = lowerer.mixinTypeContext;
2105
+ lowerer.typeParamBindings = mi.bindings;
2106
+ lowerer.instantiationContext = mi.context;
2107
+ lowerer.suppressStats = prevSuppress || mi.ordinal > 0;
2108
+ lowerer.mixinTypeContext = { classNode: info.decl, className: info.def.name };
2119
2109
  try {
2120
2110
  return fn();
2121
2111
  }
2122
2112
  finally {
2123
- L.typeParamBindings = prevBindings;
2124
- L.instantiationContext = prevContext;
2125
- L.suppressStats = prevSuppress;
2126
- L.mixinTypeContext = prevMixinCtx;
2113
+ lowerer.typeParamBindings = prevBindings;
2114
+ lowerer.instantiationContext = prevContext;
2115
+ lowerer.suppressStats = prevSuppress;
2116
+ lowerer.mixinTypeContext = prevMixinCtx;
2127
2117
  }
2128
2118
  }
2129
- const prevBindings = L.typeParamBindings;
2130
- const prevContext = L.instantiationContext;
2131
- const prevSuppress = L.suppressStats;
2132
- L.typeParamBindings = gi.bindings;
2133
- L.instantiationContext = `instantiating class '${gi.family.generic?.baseName ?? info.def.jsName ?? ""}' with ${gi.typeArgsText}`;
2134
- L.suppressStats = prevSuppress || gi.ordinal > 0;
2119
+ const prevBindings = lowerer.typeParamBindings;
2120
+ const prevContext = lowerer.instantiationContext;
2121
+ const prevSuppress = lowerer.suppressStats;
2122
+ lowerer.typeParamBindings = gi.bindings;
2123
+ lowerer.instantiationContext = `instantiating class '${gi.family.generic?.baseName ?? info.def.jsName ?? ""}' with ${gi.typeArgsText}`;
2124
+ lowerer.suppressStats = prevSuppress || gi.ordinal > 0;
2135
2125
  try {
2136
2126
  return fn();
2137
2127
  }
2138
2128
  finally {
2139
- L.typeParamBindings = prevBindings;
2140
- L.instantiationContext = prevContext;
2141
- L.suppressStats = prevSuppress;
2129
+ lowerer.typeParamBindings = prevBindings;
2130
+ lowerer.instantiationContext = prevContext;
2131
+ lowerer.suppressStats = prevSuppress;
2142
2132
  }
2143
2133
  }
2144
2134
  /** The `%init` statements for one class's static readonly fields AND
@@ -2147,18 +2137,18 @@ export function withInstanceBindings(L, info, fn) {
2147
2137
  * JS evaluates static initializers and blocks. Field failures poison per
2148
2138
  * field, like fieldInitStmts; a block lowers as the block statement it
2149
2139
  * is, so its statements poison individually inside lowerStmts. */
2150
- export function lowerStaticFieldInits(L, info) {
2140
+ export function lowerStaticFieldInits(lowerer, info) {
2151
2141
  // Mixin instantiations lower their initializers under the
2152
2142
  // instantiation's bindings/context (a no-op for everything else —
2153
2143
  // generic FAMILIES own their statics and carry no genericInstance).
2154
- return withInstanceBindings(L, info, () => lowerStaticFieldInitsInner(L, info));
2144
+ return withInstanceBindings(lowerer, info, () => lowerStaticFieldInitsInner(lowerer, info));
2155
2145
  }
2156
- function lowerStaticFieldInitsInner(L, info) {
2146
+ function lowerStaticFieldInitsInner(lowerer, info) {
2157
2147
  // Decoration first: TC39 evaluates decorator expressions, creates the
2158
2148
  // class, applies the decorators, and only THEN runs static field
2159
2149
  // initializers and static blocks (verified against Node — the
2160
2150
  // decorated result is what `this`/the class name mean inside them).
2161
- const out = [...lowerClassDecoration(L, info)];
2151
+ const out = [...lowerClassDecoration(lowerer, info)];
2162
2152
  const items = [
2163
2153
  ...info.staticFields.map((f) => ({ pos: f.initializer.getStart(), kind: "field", f })),
2164
2154
  ...(info.staticBlocks ?? []).map((b) => ({ pos: b.getStart(), kind: "block", b })),
@@ -2167,38 +2157,26 @@ function lowerStaticFieldInitsInner(L, info) {
2167
2157
  if (item.kind === "block") {
2168
2158
  // The block's body IS a Block statement: lowerStmts scopes its
2169
2159
  // let/const like any nested block and poisons per inner statement.
2170
- out.push(...L.lowerStmts([item.b.body]));
2160
+ out.push(...lowerer.lowerStmts([item.b.body]));
2171
2161
  continue;
2172
2162
  }
2173
2163
  const f = item.f;
2174
- L.stats.statementsTotal++;
2175
- L.bumpFileStat(locOf(f.initializer).file, "total");
2164
+ lowerer.stats.statementsTotal++;
2165
+ lowerer.bumpFileStat(locOf(f.initializer).file, "total");
2176
2166
  try {
2177
2167
  // `this` in a static field initializer names the CLASS (like a
2178
2168
  // static block's), with arrows transparent and this-binding
2179
2169
  // function forms opaque — the static-block rule verbatim, named
2180
2170
  // here so the generic outside-a-method fence never fires first.
2181
- const checkThis = (n) => {
2182
- if (ts.isFunctionExpression(n) || ts.isFunctionDeclaration(n) ||
2183
- ts.isMethodDeclaration(n) || ts.isConstructorDeclaration(n) ||
2184
- ts.isGetAccessor(n) || ts.isSetAccessor(n) ||
2185
- ts.isClassDeclaration(n) || ts.isClassExpression(n)) {
2186
- return;
2187
- }
2188
- if (n.kind === ts.SyntaxKind.ThisKeyword || n.kind === ts.SyntaxKind.SuperKeyword) {
2189
- L.unsupported("SC1090", n, "'this' in static field initializers (it names the class — reference the class by name instead)");
2190
- }
2191
- n.forEachChild(checkThis);
2192
- };
2193
- checkThis(f.initializer);
2194
- const value = L.lowerExprExpecting(f.initializer, f.type);
2171
+ rejectStaticThis(lowerer, f.initializer, () => "'this' in static field initializers (it names the class — reference the class by name instead)", true);
2172
+ const value = lowerer.lowerExprExpecting(f.initializer, f.type);
2195
2173
  out.push({ kind: "assign", localId: f.globalId, value, loc: locOf(f.initializer) });
2196
2174
  }
2197
2175
  catch (e) {
2198
2176
  if (!(e instanceof PoisonError))
2199
2177
  throw e;
2200
- L.stats.statementsFailed++;
2201
- L.bumpFileStat(locOf(f.initializer).file, "failed");
2178
+ lowerer.stats.statementsFailed++;
2179
+ lowerer.bumpFileStat(locOf(f.initializer).file, "failed");
2202
2180
  }
2203
2181
  }
2204
2182
  return out;
@@ -2220,7 +2198,7 @@ function lowerStaticFieldInitsInner(L, info) {
2220
2198
  * build time; the runtime base would be the decoration result) and
2221
2199
  * namespace-nested declarations (qualified references resolve the class
2222
2200
  * directly, not through the rebound value). */
2223
- export function analyzeClassDecoration(L, info) {
2201
+ export function analyzeClassDecoration(lowerer, info) {
2224
2202
  const cd = info.classDecorators;
2225
2203
  if (!cd || cd.shapes !== undefined || cd.poisoned)
2226
2204
  return;
@@ -2243,29 +2221,29 @@ export function analyzeClassDecoration(L, info) {
2243
2221
  ? d.expression
2244
2222
  : null;
2245
2223
  if (ambientCallee !== null) {
2246
- const sym = L.resolveValueSymbol(ambientCallee);
2247
- const vdecl = sym && !L.isStdlibSymbol(sym) ? L.checker.declarationsOf(sym)[0] : undefined;
2224
+ const sym = lowerer.resolveValueSymbol(ambientCallee);
2225
+ const vdecl = sym && !lowerer.isStdlibSymbol(sym) ? lowerer.checker.declarationsOf(sym)[0] : undefined;
2248
2226
  const ambientVar = vdecl !== undefined &&
2249
2227
  ts.isVariableDeclaration(vdecl) &&
2250
2228
  vdecl.initializer === undefined &&
2251
2229
  (ts.getCombinedModifierFlags(vdecl) & ts.ModifierFlags.Ambient) !== 0 &&
2252
2230
  !vdecl.getSourceFile().isDeclarationFile;
2253
- if (ambientVar || ambientUndefinedFnSymbolOf(L, ambientCallee) !== null) {
2231
+ if (ambientVar || ambientUndefinedFnSymbolOf(lowerer, ambientCallee) !== null) {
2254
2232
  shapes.push({ kind: "ambientThrow", name: ambientCallee.text });
2255
2233
  continue;
2256
2234
  }
2257
2235
  }
2258
- const t = L.typeOf(d.expression);
2236
+ const t = lowerer.typeOf(d.expression);
2259
2237
  // Param-count first, off the checker signature: the context-taking
2260
2238
  // shape deserves its own name before mapType (whose failure on
2261
2239
  // ClassDecoratorContext would blur the story).
2262
- const sigs = L.checker.getCallSignatures(t);
2240
+ const sigs = lowerer.checker.getCallSignatures(t);
2263
2241
  if (sigs.length === 1 && sigs[0].getParameters().length > 1) {
2264
- L.unsupported("SC1090", d, "class decorators that take the standard 'context' parameter (its object — addInitializer, metadata — has no static lowering; single-parameter decorators compile)");
2242
+ lowerer.unsupported("SC1090", d, "class decorators that take the standard 'context' parameter (its object — addInitializer, metadata — has no static lowering; single-parameter decorators compile)");
2265
2243
  }
2266
- const mapped = L.mapTypeOf(t);
2244
+ const mapped = lowerer.mapTypeOf(t);
2267
2245
  if (!mapped || mapped.kind !== "func" || mapped.rest === true || mapped.params.length > 1) {
2268
- L.unsupported("SC1090", d, "class decorators without one concrete (class) => class-or-void signature ('any'-typed and generic decorators have no compilable call ABI — declare the parameter as the class type)");
2246
+ lowerer.unsupported("SC1090", d, "class decorators without one concrete (class) => class-or-void signature ('any'-typed and generic decorators have no compilable call ABI — declare the parameter as the class type)");
2269
2247
  }
2270
2248
  // The parameter: a classval slot the decorated class's object can
2271
2249
  // legally inhabit — the class itself, or a BASE with the same
@@ -2274,13 +2252,13 @@ export function analyzeClassDecoration(L, info) {
2274
2252
  const p = mapped.params[0];
2275
2253
  const paramOk = p.kind === "classval" &&
2276
2254
  (p.className === info.def.name ||
2277
- (isSubclassOf(L, info.def.name, p.className) &&
2255
+ (isSubclassOf(lowerer, info.def.name, p.className) &&
2278
2256
  (() => {
2279
- const sup = L.classes.get(p.className);
2280
- return sup !== undefined && !sup.generic && ctorAbiEquals(L, info, sup);
2257
+ const sup = lowerer.classes.get(p.className);
2258
+ return sup !== undefined && !sup.generic && ctorAbiEquals(lowerer, info, sup);
2281
2259
  })()));
2282
2260
  if (!paramOk) {
2283
- L.unsupported("SC1090", d, `class decorators whose parameter is not the decorated class ('${display}' cannot flow into a '${L.fmt(p)}' slot — declare the parameter as 'typeof ${display}' or a base class sharing its constructor signature)`);
2261
+ lowerer.unsupported("SC1090", d, `class decorators whose parameter is not the decorated class ('${display}' cannot flow into a '${lowerer.fmt(p)}' slot — declare the parameter as 'typeof ${display}' or a base class sharing its constructor signature)`);
2284
2262
  }
2285
2263
  }
2286
2264
  // The return: void/undefined keeps the original binding; the class
@@ -2292,17 +2270,17 @@ export function analyzeClassDecoration(L, info) {
2292
2270
  const replaces = ret.kind === "classval";
2293
2271
  if (replaces) {
2294
2272
  const retOk = ret.className === info.def.name ||
2295
- (isSubclassOf(L, ret.className, info.def.name) &&
2273
+ (isSubclassOf(lowerer, ret.className, info.def.name) &&
2296
2274
  (() => {
2297
- const sub = L.classes.get(ret.className);
2298
- return sub !== undefined && !sub.generic && ctorAbiEquals(L, sub, info);
2275
+ const sub = lowerer.classes.get(ret.className);
2276
+ return sub !== undefined && !sub.generic && ctorAbiEquals(lowerer, sub, info);
2299
2277
  })());
2300
2278
  if (!retOk) {
2301
- L.unsupported("SC1090", d, `class decorators returning '${L.fmt(ret)}' (a replacement must be '${display}' itself or a subclass sharing its constructor signature — tsc's structural check admits shapes the compiled nominal hierarchy cannot rebind)`);
2279
+ lowerer.unsupported("SC1090", d, `class decorators returning '${lowerer.fmt(ret)}' (a replacement must be '${display}' itself or a subclass sharing its constructor signature — tsc's structural check admits shapes the compiled nominal hierarchy cannot rebind)`);
2302
2280
  }
2303
2281
  }
2304
2282
  else if (ret.kind !== "void") {
2305
- L.unsupported("SC1090", d, `class decorators returning '${L.fmt(ret)}' (supported returns: the decorated class type, a subclass with the same constructor signature, or void)`);
2283
+ lowerer.unsupported("SC1090", d, `class decorators returning '${lowerer.fmt(ret)}' (supported returns: the decorated class type, a subclass with the same constructor signature, or void)`);
2306
2284
  }
2307
2285
  shapes.push({ kind: "call", funcType: mapped, replaces });
2308
2286
  }
@@ -2314,13 +2292,13 @@ export function analyzeClassDecoration(L, info) {
2314
2292
  // and namespace-nested declarations (the qualified-access paths
2315
2293
  // resolve the class directly, not through the rebound binding).
2316
2294
  if (info.subclasses.length > 0) {
2317
- L.unsupported("SC1090", cd.nodes[0], `class decorators that can replace a class with subclasses ('${info.subclasses[0].def.jsName ?? info.subclasses[0].def.name}' extends '${display}', but the runtime base would be the decoration result — return void, or decorate the leaf classes)`);
2295
+ lowerer.unsupported("SC1090", cd.nodes[0], `class decorators that can replace a class with subclasses ('${info.subclasses[0].def.jsName ?? info.subclasses[0].def.name}' extends '${display}', but the runtime base would be the decoration result — return void, or decorate the leaf classes)`);
2318
2296
  }
2319
2297
  if (info.decl && !ts.isSourceFile(info.decl.parent)) {
2320
- L.unsupported("SC1090", cd.nodes[0], "class decorators that can replace a namespace-nested class (qualified references resolve the declaration directly — return void, or declare the class at top level)");
2298
+ lowerer.unsupported("SC1090", cd.nodes[0], "class decorators that can replace a namespace-nested class (qualified references resolve the declaration directly — return void, or declare the class at top level)");
2321
2299
  }
2322
2300
  const globalId = `%g.dec.${info.def.name}`;
2323
- L.globalsList.push({
2301
+ lowerer.globalsList.push({
2324
2302
  id: globalId,
2325
2303
  name: `${display}.decorated`,
2326
2304
  type: { kind: "classval", className: info.def.name },
@@ -2345,7 +2323,7 @@ export function analyzeClassDecoration(L, info) {
2345
2323
  * object, each replacing decorator's non-undefined result feeding the
2346
2324
  * next application; the final value binds the class name (the mutable
2347
2325
  * classval global) when any decorator can replace. */
2348
- export function lowerClassDecoration(L, info) {
2326
+ function lowerClassDecoration(lowerer, info) {
2349
2327
  const cd = info.classDecorators;
2350
2328
  if (!cd || cd.poisoned || cd.shapes === undefined || info.decl === null)
2351
2329
  return [];
@@ -2364,16 +2342,16 @@ export function lowerClassDecoration(L, info) {
2364
2342
  const d = cd.nodes[i];
2365
2343
  const shape = cd.shapes[i];
2366
2344
  if (shape.kind === "ambientThrow") {
2367
- stmts.push({ kind: "exprStmt", expr: nsUndefRead(L, shape.name, d, F64), loc: locOf(d) });
2345
+ stmts.push({ kind: "exprStmt", expr: nsUndefRead(lowerer, shape.name, d, F64), loc: locOf(d) });
2368
2346
  return stmts;
2369
2347
  }
2370
- const value = L.lowerExprExpecting(d.expression, shape.funcType);
2371
- const local = L.declareHiddenLocal("dec", shape.funcType);
2348
+ const value = lowerer.lowerExprExpecting(d.expression, shape.funcType);
2349
+ const local = lowerer.declareHiddenLocal("dec", shape.funcType);
2372
2350
  stmts.push({ kind: "varDecl", localId: local.id, init: value, loc: locOf(d) });
2373
2351
  temps.push({ localId: local.id, funcType: shape.funcType, replaces: shape.replaces });
2374
2352
  }
2375
2353
  // 2. Applications, reverse order, over the accumulating class value.
2376
- let current = classValueRef(L, info, info.decl);
2354
+ let current = classValueRef(lowerer, info, info.decl);
2377
2355
  for (let i = temps.length - 1; i >= 0; i--) {
2378
2356
  const t = temps[i];
2379
2357
  const dLoc = locOf(cd.nodes[i]);
@@ -2381,16 +2359,16 @@ export function lowerClassDecoration(L, info) {
2381
2359
  const args = [];
2382
2360
  if (t.funcType.params.length === 1) {
2383
2361
  const p = t.funcType.params[0];
2384
- const widened = L.coerceToExpected(current, p);
2385
- L.requireExactShape(cd.nodes[i], widened.type, p);
2362
+ const widened = lowerer.coerceToExpected(current, p);
2363
+ lowerer.requireExactShape(cd.nodes[i], widened.type, p);
2386
2364
  args.push(widened);
2387
2365
  }
2388
2366
  const call = { kind: "callValue", callee, args, type: t.funcType.ret, loc: dLoc };
2389
2367
  if (t.replaces) {
2390
2368
  const target = { kind: "classval", className: info.def.name };
2391
- const widened = L.coerceToExpected(call, target);
2392
- L.requireExactShape(cd.nodes[i], widened.type, target);
2393
- const res = L.declareHiddenLocal("decres", target);
2369
+ const widened = lowerer.coerceToExpected(call, target);
2370
+ lowerer.requireExactShape(cd.nodes[i], widened.type, target);
2371
+ const res = lowerer.declareHiddenLocal("decres", target);
2394
2372
  stmts.push({ kind: "varDecl", localId: res.id, init: widened, loc: dLoc });
2395
2373
  current = { kind: "varRef", localId: res.id, type: target, loc: dLoc };
2396
2374
  }
@@ -2407,8 +2385,8 @@ export function lowerClassDecoration(L, info) {
2407
2385
  catch (e) {
2408
2386
  if (!(e instanceof PoisonError))
2409
2387
  throw e;
2410
- L.stats.statementsFailed++;
2411
- L.bumpFileStat(loc.file, "failed");
2388
+ lowerer.stats.statementsFailed++;
2389
+ lowerer.bumpFileStat(loc.file, "failed");
2412
2390
  return [];
2413
2391
  }
2414
2392
  }
@@ -2416,7 +2394,7 @@ export function lowerClassDecoration(L, info) {
2416
2394
  * the compile-time prototype-chain walk (`D.x` reads C's global when C
2417
2395
  * declared x and nothing between redeclares it; a redeclaration shadows
2418
2396
  * with its OWN storage, exactly JS). */
2419
- export function findStaticOn(L, info, name) {
2397
+ export function findStaticOn(lowerer, info, name) {
2420
2398
  for (let c = info; c; c = c.base) {
2421
2399
  const field = c.staticFields.find((s) => s.name === name);
2422
2400
  if (field)
@@ -2431,15 +2409,15 @@ export function findStaticOn(L, info, name) {
2431
2409
  * the through-a-VALUE devirtualization test: a classval(info) slot can
2432
2410
  * hold any descendant, and a shadowing redeclaration means the runtime
2433
2411
  * class decides which storage answers. */
2434
- export function staticShadowBelow(L, info, name) {
2412
+ export function staticShadowBelow(lowerer, info, name) {
2435
2413
  return info.subclasses.some((s) => s.staticFields.some((f) => f.name === name) ||
2436
2414
  s.staticMethods?.has(name) === true ||
2437
2415
  s.genericStatics?.has(name) === true ||
2438
- staticShadowBelow(L, s, name));
2416
+ staticShadowBelow(lowerer, s, name));
2439
2417
  }
2440
2418
  /** The nearest GENERIC static declaration of `name` at/above `info` —
2441
2419
  * findStaticOn's twin over the genericStatics tables. */
2442
- export function findGenericStaticOn(L, info, name) {
2420
+ export function findGenericStaticOn(lowerer, info, name) {
2443
2421
  for (let c = info; c; c = c.base) {
2444
2422
  const gs = c.genericStatics?.get(name);
2445
2423
  if (gs)
@@ -2450,16 +2428,16 @@ export function findGenericStaticOn(L, info, name) {
2450
2428
  /** A static METHOD taken as a value: the zero-capture closure over its
2451
2429
  * module function — the declared-function-as-value rule verbatim
2452
2430
  * (interned by the backend, so `C.m === C.m` holds). */
2453
- function staticMethodValue(L, declarer, name, sig, blame, loc) {
2431
+ function staticMethodValue(lowerer, declarer, name, sig, blame, loc) {
2454
2432
  const fnName = `%${declarer.def.name}.static:${name}`;
2455
- L.noteEdge(fnName);
2433
+ lowerer.noteEdge(fnName);
2456
2434
  const funcType = {
2457
2435
  kind: "func",
2458
2436
  params: sig.params.filter((p) => p.mode !== "dynRest").map((p) => p.type),
2459
2437
  ret: sig.ret,
2460
2438
  ...(sig.params.some((p) => p.mode === "dynRest") ? { rest: true } : {}),
2461
2439
  };
2462
- L.requireExactArityValue(blame, blame, sig.params, funcType);
2440
+ lowerer.requireExactArityValue(blame, blame, sig.params, funcType);
2463
2441
  return { kind: "closure", fnName, captures: [], type: funcType, loc };
2464
2442
  }
2465
2443
  /** The class itself taken as a VALUE (`const X = C`, an argument, an
@@ -2470,26 +2448,26 @@ function staticMethodValue(L, declarer, name, sig, blame, loc) {
2470
2448
  * constructor (Error/EventEmitter/stream chains complete their `new`
2471
2449
  * by special rules) — are named fences here. The constructor edge is
2472
2450
  * noted at every classRef: a value can always be constructed through. */
2473
- export function classValueRef(L, info, blame) {
2451
+ export function classValueRef(lowerer, info, blame) {
2474
2452
  const display = info.def.name.replace(/^%|^%m\d+\./, "");
2475
- fenceDecorationThrows(L, info, blame);
2453
+ fenceDecorationThrows(lowerer, info, blame);
2476
2454
  if (info.generic) {
2477
2455
  // `typeof Box` — the uninstantiated FAMILY as a value: no thunk, no
2478
2456
  // single constructor ABI. INSTANTIATIONS have class objects
2479
2457
  // (`const B = Box<number>`, `new (v: number) => Box<number>` slots).
2480
- L.unsupported("SC1090", blame, `generic classes as values ('typeof ${display}' keeps the type parameter — instantiation expressions ('${display}<number>') and concrete constructor-typed slots compile)`);
2458
+ lowerer.unsupported("SC1090", blame, `generic classes as values ('typeof ${display}' keeps the type parameter — instantiation expressions ('${display}<number>') and concrete constructor-typed slots compile)`);
2481
2459
  }
2482
2460
  if (info.builtinError || info.builtinEmitter || info.builtinStream !== undefined) {
2483
- L.unsupported("SC1090", blame, `builtin classes as values ('${display}' is runtime-provided — reference program-declared classes instead)`);
2461
+ lowerer.unsupported("SC1090", blame, `builtin classes as values ('${display}' is runtime-provided — reference program-declared classes instead)`);
2484
2462
  }
2485
- if (L.inheritsBuiltinErrorCtor(info) || L.inheritsBuiltinEmitterCtor(info) ||
2486
- inheritsBuiltinStreamCtor(L, info) ||
2463
+ if (lowerer.inheritsBuiltinErrorCtor(info) || lowerer.inheritsBuiltinEmitterCtor(info) ||
2464
+ inheritsBuiltinStreamCtor(lowerer, info) ||
2487
2465
  (() => { for (let c = info.base; c; c = c.base)
2488
2466
  if (c.builtinError || c.builtinEmitter || c.builtinStream !== undefined)
2489
2467
  return true; return false; })()) {
2490
- L.unsupported("SC1090", blame, `classes extending builtin bases as values ('${display}' inherits a runtime-provided constructor)`);
2468
+ lowerer.unsupported("SC1090", blame, `classes extending builtin bases as values ('${display}' inherits a runtime-provided constructor)`);
2491
2469
  }
2492
- L.noteEdge(`%${info.def.name}.constructor`);
2470
+ lowerer.noteEdge(`%${info.def.name}.constructor`);
2493
2471
  return {
2494
2472
  kind: "classRef",
2495
2473
  className: info.def.name,
@@ -2502,7 +2480,7 @@ export function classValueRef(L, info, blame) {
2502
2480
  * constructor signature equals C's (same count, modes, and ABI types),
2503
2481
  * which is what keeps newValue completion against C's one signature
2504
2482
  * sound for every value legally in the slot. */
2505
- export function ctorAbiEquals(L, sub, sup) {
2483
+ export function ctorAbiEquals(lowerer, sub, sup) {
2506
2484
  const a = sub.ctorParams;
2507
2485
  const b = sup.ctorParams;
2508
2486
  return a.length === b.length && a.every((p, i) => p.mode === b[i].mode && typeEquals(p.type, b[i].type));
@@ -2513,18 +2491,18 @@ export function ctorAbiEquals(L, sub, sup) {
2513
2491
  * compile-time name. Null for everything else — unresolved members
2514
2492
  * fall through to the ordinary chain so the static fence or the
2515
2493
  * generic member rejection names the site. */
2516
- export function lowerStaticFieldRead(L, expr) {
2494
+ export function lowerStaticFieldRead(lowerer, expr) {
2517
2495
  if (expr.questionDotToken)
2518
2496
  return null;
2519
2497
  if (!ts.isIdentifier(expr.expression))
2520
2498
  return null;
2521
- const symbol = L.resolveValueSymbol(expr.expression);
2522
- const info = (symbol ? L.classBySymbol.get(symbol) : undefined) ??
2499
+ const symbol = lowerer.resolveValueSymbol(expr.expression);
2500
+ const info = (symbol ? lowerer.classBySymbol.get(symbol) : undefined) ??
2523
2501
  // A require binding over `module.exports = class {…}` (the alias
2524
2502
  // lands on the expression's own symbol): resolve/collect on demand,
2525
2503
  // or `C.name` below would fall through to paths that answer for
2526
2504
  // stdlib globals instead of this class.
2527
- propertyAssignedClassInfoOf(L, symbol) ??
2505
+ propertyAssignedClassInfoOf(lowerer, symbol) ??
2528
2506
  undefined;
2529
2507
  if (!info)
2530
2508
  return null;
@@ -2536,27 +2514,27 @@ export function lowerStaticFieldRead(L, expr) {
2536
2514
  if (info.classDecorators?.valueGlobalId !== undefined)
2537
2515
  return null;
2538
2516
  const loc = locOf(expr);
2539
- const found = findStaticOn(L, info, expr.name.text);
2517
+ const found = findStaticOn(lowerer, info, expr.name.text);
2540
2518
  // A #private static resolves only through the DECLARING class's own
2541
2519
  // name: in JS the brand lives on that one constructor object, so
2542
2520
  // `D.#s` (a subclass receiver) throws Node's TypeError instead of
2543
2521
  // reaching up the chain — fenced rather than silently resolved.
2544
2522
  if (found && expr.name.text.startsWith("#") && found.declarer !== info) {
2545
- L.unsupported("SC1090", expr, `reading the private static '${expr.name.text}' 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)`);
2523
+ lowerer.unsupported("SC1090", expr, `reading the private static '${expr.name.text}' 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)`);
2546
2524
  }
2547
2525
  if (found?.field !== undefined) {
2548
- return L.maybeNarrow({ kind: "varRef", localId: found.field.globalId, type: found.field.type, loc }, expr);
2526
+ return lowerer.maybeNarrow({ kind: "varRef", localId: found.field.globalId, type: found.field.type, loc }, expr);
2549
2527
  }
2550
2528
  if (found) {
2551
- return staticMethodValue(L, found.declarer, expr.name.text, found.method, expr, loc);
2529
+ return staticMethodValue(lowerer, found.declarer, expr.name.text, found.method, expr, loc);
2552
2530
  }
2553
2531
  // A GENERIC static method as a VALUE: the pinned-value rule verbatim
2554
2532
  // (lowerGenericFnValue) — a slot spelling one concrete signature names
2555
2533
  // an instance, an unpinned reference fences by name.
2556
2534
  {
2557
- const gfound = findGenericStaticOn(L, info, expr.name.text);
2535
+ const gfound = findGenericStaticOn(lowerer, info, expr.name.text);
2558
2536
  if (gfound)
2559
- return L.lowerGenericFnValue(expr, gfound.info);
2537
+ return lowerer.lowerGenericFnValue(expr, gfound.info);
2560
2538
  }
2561
2539
  // `C.name` — the JS-observable class name, a compile-time constant on
2562
2540
  // the direct spelling (tsc rejects user statics named `name`, so the
@@ -2599,8 +2577,8 @@ function namedEvaluationName(expr) {
2599
2577
  * once. Statics-bearing expressions additionally restrict to positions
2600
2578
  * where "immediately before the enclosing statement" IS the evaluation
2601
2579
  * point (lowerFileInit drains pendingClassExprInits there). */
2602
- export function lowerClassExpressionInfo(L, expr) {
2603
- const cached = L.exprClassInfoByNode.get(expr);
2580
+ export function lowerClassExpressionInfo(lowerer, expr) {
2581
+ const cached = lowerer.exprClassInfoByNode.get(expr);
2604
2582
  if (cached)
2605
2583
  return cached;
2606
2584
  // Reentrancy guard: heritage resolution can DEMAND another class
@@ -2610,30 +2588,30 @@ export function lowerClassExpressionInfo(L, expr) {
2610
2588
  // can see (TS2506/TS2303 — direct, indirect, and cross-file require
2611
2589
  // cycles all probed); this fence is the backstop that turns anything
2612
2590
  // it misses into a diagnostic instead of a stack overflow.
2613
- if (L.collectingExprClasses.has(expr)) {
2614
- L.unsupported("SC1090", expr, "class expressions whose extends chain re-enters their own collection (a cyclic base through property assignments)");
2591
+ if (lowerer.collectingExprClasses.has(expr)) {
2592
+ lowerer.unsupported("SC1090", expr, "class expressions whose extends chain re-enters their own collection (a cyclic base through property assignments)");
2615
2593
  }
2616
- if (L.instantiationContext) {
2617
- L.unsupported("SC1090", expr, "class expressions inside generic functions (each instantiation would need its own class)");
2594
+ if (lowerer.instantiationContext) {
2595
+ lowerer.unsupported("SC1090", expr, "class expressions inside generic functions (each instantiation would need its own class)");
2618
2596
  }
2619
2597
  for (let p = expr.parent; !ts.isSourceFile(p); p = p.parent) {
2620
2598
  if (ts.isFunctionLike(p) || ts.isClassStaticBlockDeclaration(p)) {
2621
- L.unsupported("SC1090", expr, "class expressions inside functions (each evaluation creates a DISTINCT class in JS — fresh identity, fresh statics; declare the class at top level)");
2599
+ lowerer.unsupported("SC1090", expr, "class expressions inside functions (each evaluation creates a DISTINCT class in JS — fresh identity, fresh statics; declare the class at top level)");
2622
2600
  }
2623
2601
  }
2624
- L.collectingExprClasses.add(expr);
2602
+ lowerer.collectingExprClasses.add(expr);
2625
2603
  try {
2626
- L.collectClassShapeInner(expr, namedEvaluationName(expr));
2604
+ lowerer.collectClassShapeInner(expr, namedEvaluationName(expr));
2627
2605
  }
2628
2606
  finally {
2629
- L.collectingExprClasses.delete(expr);
2607
+ lowerer.collectingExprClasses.delete(expr);
2630
2608
  }
2631
- const info = L.classes.get(L.classNamer(expr));
2609
+ const info = lowerer.classes.get(lowerer.classNamer(expr));
2632
2610
  if (!info)
2633
2611
  throw new PoisonError(); // collection poisoned and reported
2634
- L.exprClassInfoByNode.set(expr, info);
2635
- L.exprClasses.push(info);
2636
- L.onExprClassCollected?.(info);
2612
+ lowerer.exprClassInfoByNode.set(expr, info);
2613
+ lowerer.exprClasses.push(info);
2614
+ lowerer.onExprClassCollected?.(info);
2637
2615
  // Static field initializers and static blocks run when the class
2638
2616
  // expression EVALUATES. The supported positions evaluate exactly once,
2639
2617
  // at the top-level statement containing the expression — the pending
@@ -2659,9 +2637,9 @@ export function lowerClassExpressionInfo(L, expr) {
2659
2637
  ts.isSourceFile(holder.parent.parent)) ||
2660
2638
  (ts.isExpressionStatement(holder) && ts.isSourceFile(holder.parent));
2661
2639
  if (!wholeInit) {
2662
- L.unsupported("SC1090", expr, "class expressions with static initializers or static blocks outside a whole-initializer position (their declaration-time code must run exactly where the expression evaluates — bind the class in its own top-level `const C = class …` statement)");
2640
+ lowerer.unsupported("SC1090", expr, "class expressions with static initializers or static blocks outside a whole-initializer position (their declaration-time code must run exactly where the expression evaluates — bind the class in its own top-level `const C = class …` statement)");
2663
2641
  }
2664
- L.pendingClassExprInits.push(...L.lowerStaticFieldInits(info));
2642
+ lowerer.pendingClassExprInits.push(...lowerer.lowerStaticFieldInits(info));
2665
2643
  }
2666
2644
  return info;
2667
2645
  }
@@ -2673,20 +2651,20 @@ export function lowerClassExpressionInfo(L, expr) {
2673
2651
  * ReferenceError, so it lowers to exactly that read — every evaluation
2674
2652
  * throws identically, which is why the once-evaluated restriction and
2675
2653
  * the member fences don't apply. */
2676
- export function lowerClassExpression(L, expr) {
2654
+ export function lowerClassExpression(lowerer, expr) {
2677
2655
  if (decoratorNodesOf(expr).length > 0 ||
2678
2656
  expr.members.some((m) => decoratorNodesOf(m).length > 0)) {
2679
2657
  if (!isJsSourceFile(expr.getSourceFile()) && expr.typeParameters === undefined) {
2680
- const thrown = guaranteedDecorationThrow(L, expr);
2658
+ const thrown = guaranteedDecorationThrow(lowerer, expr);
2681
2659
  if (thrown) {
2682
2660
  // The expression's static type never materializes — the read
2683
2661
  // throws — so the nominal IR type only has to satisfy the
2684
2662
  // consumer. F64 is the ambient-undefRead convention.
2685
- return nsUndefRead(L, thrown.name, expr, F64);
2663
+ return nsUndefRead(lowerer, thrown.name, expr, F64);
2686
2664
  }
2687
2665
  }
2688
2666
  }
2689
- return classValueRef(L, lowerClassExpressionInfo(L, expr), expr);
2667
+ return classValueRef(lowerer, lowerClassExpressionInfo(lowerer, expr), expr);
2690
2668
  }
2691
2669
  /** The EXACT class a receiver expression is statically known to BE (not
2692
2670
  * merely be typed by): the class name itself, or a `const` binding
@@ -2694,20 +2672,20 @@ export function lowerClassExpression(L, expr) {
2694
2672
  * can never hold a subclass at runtime, so static WRITES through them
2695
2673
  * hit the declaring class's storage exactly (the shadowing hazards of
2696
2674
  * general class values don't arise). Null for everything else. */
2697
- export function exactClassOfReceiver(L, expr) {
2675
+ export function exactClassOfReceiver(lowerer, expr) {
2698
2676
  if (!ts.isIdentifier(expr))
2699
2677
  return null;
2700
- const symbol = L.resolveValueSymbol(expr);
2678
+ const symbol = lowerer.resolveValueSymbol(expr);
2701
2679
  if (!symbol)
2702
2680
  return null;
2703
- const direct = L.classBySymbol.get(symbol);
2681
+ const direct = lowerer.classBySymbol.get(symbol);
2704
2682
  // A rebindable decorated name is NOT exactly its class — the binding
2705
2683
  // may hold a replacing decorator's result (a subclass value), where a
2706
2684
  // static write would create an own property in JS. The general
2707
2685
  // class-value write fence answers instead.
2708
2686
  if (direct)
2709
2687
  return direct.classDecorators?.valueGlobalId !== undefined ? null : direct;
2710
- const decl = L.checker.valueDeclarationOf(symbol);
2688
+ const decl = lowerer.checker.valueDeclarationOf(symbol);
2711
2689
  if (!decl || !ts.isVariableDeclaration(decl) || decl.initializer === undefined ||
2712
2690
  !ts.isVariableDeclarationList(decl.parent) ||
2713
2691
  (decl.parent.flags & ts.NodeFlags.Const) === 0) {
@@ -2717,10 +2695,10 @@ export function exactClassOfReceiver(L, expr) {
2717
2695
  while (ts.isParenthesizedExpression(init))
2718
2696
  init = init.expression;
2719
2697
  if (ts.isClassExpression(init))
2720
- return L.exprClassInfoByNode.get(init) ?? null;
2698
+ return lowerer.exprClassInfoByNode.get(init) ?? null;
2721
2699
  if (ts.isIdentifier(init)) {
2722
- const initSym = L.resolveValueSymbol(init);
2723
- const aliased = initSym ? (L.classBySymbol.get(initSym) ?? null) : null;
2700
+ const initSym = lowerer.resolveValueSymbol(init);
2701
+ const aliased = initSym ? (lowerer.classBySymbol.get(initSym) ?? null) : null;
2724
2702
  // `const X = C` over a rebindable decorated name: X holds the
2725
2703
  // decoration result — not exactly C (see the direct case above).
2726
2704
  return aliased?.classDecorators?.valueGlobalId !== undefined ? null : aliased;
@@ -2742,14 +2720,14 @@ export function exactClassOfReceiver(L, expr) {
2742
2720
  * fence names it. Collection is on demand and idempotent
2743
2721
  * (lowerClassExpressionInfo), so resolution order between files and
2744
2722
  * passes never matters. */
2745
- export function propertyAssignedClassInfoOf(L, symbol) {
2723
+ export function propertyAssignedClassInfoOf(lowerer, symbol) {
2746
2724
  if (!symbol)
2747
2725
  return null;
2748
- const resolved = symbol.flags & ts.SymbolFlags.Alias ? L.checker.getAliasedSymbol(symbol) : symbol;
2749
- const registered = L.classBySymbol.get(resolved);
2726
+ const resolved = symbol.flags & ts.SymbolFlags.Alias ? lowerer.checker.getAliasedSymbol(symbol) : symbol;
2727
+ const registered = lowerer.classBySymbol.get(resolved);
2750
2728
  if (registered)
2751
2729
  return registered;
2752
- const decls = L.checker.declarationsOf(resolved);
2730
+ const decls = lowerer.checker.declarationsOf(resolved);
2753
2731
  // The class expression's OWN symbol (tsgo's answer through CJS export
2754
2732
  // aliases): the declaration is the expression itself. Its top-level
2755
2733
  // assignment statement must be the binding's ONLY producer. The
@@ -2760,8 +2738,8 @@ export function propertyAssignedClassInfoOf(L, symbol) {
2760
2738
  const assign = enclosingTopLevelClassAssignment(decls[0]);
2761
2739
  if (!assign || countAssignmentsTo(assign) !== 1)
2762
2740
  return null;
2763
- const info = L.lowerClassExpressionInfo(decls[0]);
2764
- L.classBySymbol.set(resolved, info);
2741
+ const info = lowerer.lowerClassExpressionInfo(decls[0]);
2742
+ lowerer.classBySymbol.set(resolved, info);
2765
2743
  return info;
2766
2744
  }
2767
2745
  // The expando property symbol: every top-level `X.N = …` assignment is
@@ -2778,8 +2756,8 @@ export function propertyAssignedClassInfoOf(L, symbol) {
2778
2756
  rhs = rhs.expression;
2779
2757
  if (!ts.isClassExpression(rhs))
2780
2758
  return null;
2781
- const info = L.lowerClassExpressionInfo(rhs);
2782
- L.classBySymbol.set(resolved, info);
2759
+ const info = lowerer.lowerClassExpressionInfo(rhs);
2760
+ lowerer.classBySymbol.set(resolved, info);
2783
2761
  return info;
2784
2762
  }
2785
2763
  /** The top-level `… = <this class expression>` assignment a class
@@ -2830,7 +2808,7 @@ function countAssignmentsTo(assign) {
2830
2808
  * global and calls through the value. Null when the receiver isn't a
2831
2809
  * class name/value or the member doesn't resolve (the fences name the
2832
2810
  * site downstream). */
2833
- export function lowerStaticMethodCall(L, call, access) {
2811
+ export function lowerStaticMethodCall(lowerer, call, access) {
2834
2812
  if (access.questionDotToken)
2835
2813
  return null;
2836
2814
  // `module.exports.describe()` in a module whose whole export IS a
@@ -2843,28 +2821,28 @@ export function lowerStaticMethodCall(L, call, access) {
2843
2821
  const whole = cjsClassExprWholeExportOf(access.getSourceFile());
2844
2822
  if (!whole)
2845
2823
  return null;
2846
- return staticCallOn(L, call, access, L.lowerClassExpressionInfo(whole.classExpr), false);
2824
+ return staticCallOn(lowerer, call, access, lowerer.lowerClassExpressionInfo(whole.classExpr), false);
2847
2825
  }
2848
- const symbol = L.resolveValueSymbol(access.expression);
2849
- const direct = (symbol ? L.classBySymbol.get(symbol) : undefined) ??
2826
+ const symbol = lowerer.resolveValueSymbol(access.expression);
2827
+ const direct = (symbol ? lowerer.classBySymbol.get(symbol) : undefined) ??
2850
2828
  // A require binding over `module.exports = class {…}`: the alias
2851
2829
  // lands on the expression's own symbol — exact, like the name.
2852
- propertyAssignedClassInfoOf(L, symbol) ??
2830
+ propertyAssignedClassInfoOf(lowerer, symbol) ??
2853
2831
  undefined;
2854
2832
  let info = direct ?? null;
2855
2833
  // A rebindable decorated name is a class VALUE receiver: the call
2856
2834
  // devirtualizes under the value rules (shadow fences below).
2857
2835
  let throughValue = direct?.classDecorators?.valueGlobalId !== undefined;
2858
2836
  if (!info) {
2859
- const recvT = L.mapTypeOf(L.typeOf(access.expression));
2837
+ const recvT = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
2860
2838
  if (recvT?.kind !== "classval")
2861
2839
  return null;
2862
- info = L.classes.get(recvT.className) ?? null;
2840
+ info = lowerer.classes.get(recvT.className) ?? null;
2863
2841
  throughValue = true;
2864
2842
  }
2865
2843
  if (!info)
2866
2844
  return null;
2867
- return staticCallOn(L, call, access, info, throughValue);
2845
+ return staticCallOn(lowerer, call, access, info, throughValue);
2868
2846
  }
2869
2847
  /** True when a class-VALUE receiver can only hold `info`'s own class
2870
2848
  * object at runtime: the receiver provably IS the class
@@ -2876,10 +2854,10 @@ export function lowerStaticMethodCall(L, call, access) {
2876
2854
  * rebindable global). Exactly then a #private static access through
2877
2855
  * the value always carries the declaring class's brand — Node's
2878
2856
  * TypeError cannot arise. */
2879
- function classValueIsExactlyOwn(L, recv, info) {
2880
- return exactClassOfReceiver(L, recv) === info || info.subclasses.length === 0;
2857
+ function classValueIsExactlyOwn(lowerer, recv, info) {
2858
+ return exactClassOfReceiver(lowerer, recv) === info || info.subclasses.length === 0;
2881
2859
  }
2882
- function staticCallOn(L, call, access, info, throughValue) {
2860
+ function staticCallOn(lowerer, call, access, info, throughValue) {
2883
2861
  const loc = locOf(call);
2884
2862
  // #private statics: through-a-VALUE receiver the call devirtualizes
2885
2863
  // exactly when the value can only BE the declaring class
@@ -2887,29 +2865,29 @@ function staticCallOn(L, call, access, info, throughValue) {
2887
2865
  // runtime fences, since only the declaring class object carries the
2888
2866
  // brand in JS), and the direct spelling resolves only on the
2889
2867
  // declaring class itself — `D.#s` is Node's TypeError.
2890
- if (access.name.text.startsWith("#") && throughValue && !classValueIsExactlyOwn(L, access.expression, info)) {
2891
- L.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)`);
2868
+ if (access.name.text.startsWith("#") && throughValue && !classValueIsExactlyOwn(lowerer, access.expression, info)) {
2869
+ 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)`);
2892
2870
  }
2893
- const found = findStaticOn(L, info, access.name.text);
2871
+ const found = findStaticOn(lowerer, info, access.name.text);
2894
2872
  if (found && access.name.text.startsWith("#") && found.declarer !== info) {
2895
- L.unsupported("SC1090", call, `calling the private static '${access.name.text}' 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)`);
2873
+ lowerer.unsupported("SC1090", call, `calling the private static '${access.name.text}' 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)`);
2896
2874
  }
2897
2875
  if (!found) {
2898
2876
  // GENERIC static methods: monomorphized like top-level generic
2899
2877
  // functions, called directly as `%C.static:m%n` — with the same
2900
2878
  // through-a-VALUE shadowing fence as plain statics.
2901
- const gfound = findGenericStaticOn(L, info, access.name.text);
2879
+ const gfound = findGenericStaticOn(lowerer, info, access.name.text);
2902
2880
  if (!gfound)
2903
2881
  return null;
2904
- if (throughValue && staticShadowBelow(L, info, access.name.text)) {
2905
- L.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)`);
2882
+ if (throughValue && staticShadowBelow(lowerer, info, access.name.text)) {
2883
+ 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)`);
2906
2884
  }
2907
- const instance = genericCallInstance(L, call, gfound.info);
2908
- const args = L.completeArgs(call.arguments, instance.params, loc, call);
2885
+ const instance = genericCallInstance(lowerer, call, gfound.info);
2886
+ const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
2909
2887
  return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
2910
2888
  }
2911
- if (throughValue && staticShadowBelow(L, info, access.name.text)) {
2912
- L.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)`);
2889
+ if (throughValue && staticShadowBelow(lowerer, info, access.name.text)) {
2890
+ 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)`);
2913
2891
  }
2914
2892
  if (found.field !== undefined) {
2915
2893
  // A func-typed static field in call position: read the global,
@@ -2918,19 +2896,19 @@ function staticCallOn(L, call, access, info, throughValue) {
2918
2896
  return null;
2919
2897
  const callee = { kind: "varRef", localId: found.field.globalId, type: found.field.type, loc };
2920
2898
  const params = found.field.type.params;
2921
- const args = call.arguments.map((a, i) => L.lowerExprExpecting(a, params[i]));
2899
+ const args = call.arguments.map((a, i) => lowerer.lowerExprExpecting(a, params[i]));
2922
2900
  for (let i = args.length; i < params.length; i++) {
2923
- const absent = omittedArgFor(L, params[i], loc);
2901
+ const absent = omittedArgFor(lowerer, params[i], loc);
2924
2902
  if (!absent) {
2925
- L.unsupported("SC1090", call, "calls omitting a non-optional parameter of the callee's type");
2903
+ lowerer.unsupported("SC1090", call, "calls omitting a non-optional parameter of the callee's type");
2926
2904
  }
2927
2905
  args.push(absent);
2928
2906
  }
2929
2907
  return { kind: "callValue", callee, args, type: found.field.type.ret, loc };
2930
2908
  }
2931
2909
  const fnName = `%${found.declarer.def.name}.static:${access.name.text}`;
2932
- L.noteEdge(fnName);
2933
- const args = L.completeArgs(call.arguments, found.method.params, loc, call);
2910
+ lowerer.noteEdge(fnName);
2911
+ const args = lowerer.completeArgs(call.arguments, found.method.params, loc, call);
2934
2912
  return { kind: "call", callee: fnName, args, type: found.method.ret, loc };
2935
2913
  }
2936
2914
  /** Static member access through a class VALUE (`X.m` where X is
@@ -2940,10 +2918,10 @@ function staticCallOn(L, call, access, info, throughValue) {
2940
2918
  * genuinely dynamic member: the class.name libCall reads the runtime
2941
2919
  * class object's stored name. Null when the receiver isn't a class
2942
2920
  * value or the member doesn't resolve. */
2943
- export function lowerClassValueProperty(L, expr) {
2921
+ export function lowerClassValueProperty(lowerer, expr) {
2944
2922
  if (expr.questionDotToken)
2945
2923
  return null;
2946
- const recvT = L.mapTypeOf(L.typeOf(expr.expression));
2924
+ const recvT = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
2947
2925
  if (recvT?.kind !== "classval")
2948
2926
  return null;
2949
2927
  const loc = locOf(expr);
@@ -2952,7 +2930,7 @@ export function lowerClassValueProperty(L, expr) {
2952
2930
  // genuinely dynamic member. It CONSUMES the receiver (no evaluation
2953
2931
  // is discarded), so any receiver expression is fine here.
2954
2932
  if (member === "name") {
2955
- const recv = L.lowerExpr(expr.expression);
2933
+ const recv = lowerer.lowerExpr(expr.expression);
2956
2934
  if (recv.type.kind !== "classval")
2957
2935
  return null;
2958
2936
  return { kind: "libCall", fn: "class.name", args: [recv], type: STRING, loc };
@@ -2965,16 +2943,16 @@ export function lowerClassValueProperty(L, expr) {
2965
2943
  // Devirtualized reads DISCARD the receiver value, so only
2966
2944
  // side-effect-free receivers are claimed (the instanceOf fold
2967
2945
  // rule); computed ones meet the pointed fence with a bindable fix.
2968
- L.unsupported("SC1090", expr, "static member access through a computed class-value expression (bind the class value to a variable first)");
2946
+ lowerer.unsupported("SC1090", expr, "static member access through a computed class-value expression (bind the class value to a variable first)");
2969
2947
  }
2970
2948
  // The direct class-name spelling resolved in lowerStaticFieldRead;
2971
2949
  // reaching here means the receiver is a classval-typed BINDING.
2972
- const info = L.classes.get(recvT.className);
2950
+ const info = lowerer.classes.get(recvT.className);
2973
2951
  if (!info)
2974
2952
  return null;
2975
- const found = findStaticOn(L, info, member);
2953
+ const found = findStaticOn(lowerer, info, member);
2976
2954
  if (!found) {
2977
- L.unsupported("SC1090", expr, `the static member '${member}' of class '${info.def.name.replace(/^%|^%m\d+\./, "")}' (static accessors and initializer-less static fields have no lowering, and Function members like .call/.bind/.prototype have no value form)`);
2955
+ lowerer.unsupported("SC1090", expr, `the static member '${member}' of class '${info.def.name.replace(/^%|^%m\d+\./, "")}' (static accessors and initializer-less static fields have no lowering, and Function members like .call/.bind/.prototype have no value form)`);
2978
2956
  }
2979
2957
  // #private statics read through a class VALUE exactly when the value
2980
2958
  // can only BE the declaring class (classValueIsExactlyOwn — a const
@@ -2985,35 +2963,35 @@ export function lowerClassValueProperty(L, expr) {
2985
2963
  // lowerStaticFieldRead, so a private reaching here is a
2986
2964
  // classval-typed binding.
2987
2965
  if (member.startsWith("#")) {
2988
- if (!classValueIsExactlyOwn(L, expr.expression, info)) {
2989
- L.unsupported("SC1090", expr, `reading the private static '${member}' through a class value (JS brands the declaring class object alone — spell the declaring class's name)`);
2966
+ if (!classValueIsExactlyOwn(lowerer, expr.expression, info)) {
2967
+ lowerer.unsupported("SC1090", expr, `reading the private static '${member}' through a class value (JS brands the declaring class object alone — spell the declaring class's name)`);
2990
2968
  }
2991
2969
  if (found.declarer !== info) {
2992
- L.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)`);
2970
+ 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)`);
2993
2971
  }
2994
2972
  }
2995
- if (staticShadowBelow(L, info, member)) {
2996
- L.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)`);
2973
+ if (staticShadowBelow(lowerer, info, member)) {
2974
+ 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)`);
2997
2975
  }
2998
2976
  if (found.field !== undefined) {
2999
- return L.maybeNarrow({ kind: "varRef", localId: found.field.globalId, type: found.field.type, loc }, expr);
2977
+ return lowerer.maybeNarrow({ kind: "varRef", localId: found.field.globalId, type: found.field.type, loc }, expr);
3000
2978
  }
3001
- return staticMethodValue(L, found.declarer, member, found.method, expr, loc);
2979
+ return staticMethodValue(lowerer, found.declarer, member, found.method, expr, loc);
3002
2980
  }
3003
2981
  /** An abstract method's signature — lambdaSignature minus the body check
3004
2982
  * (an abstract declaration IS exactly a signature; tsc rejects the
3005
2983
  * async/generator/generic-with-body combinations before this runs, and
3006
2984
  * the generic case fences at the caller). */
3007
- function abstractMemberSignature(L, member) {
2985
+ function abstractMemberSignature(lowerer, member) {
3008
2986
  for (const param of member.parameters) {
3009
2987
  if (!ts.isIdentifier(param.name))
3010
- L.unsupported("SC1031", param);
2988
+ lowerer.unsupported("SC1031", param);
3011
2989
  }
3012
- return { shapes: L.paramShapes(member.parameters), ret: L.declaredReturnType(member, member.name) };
2990
+ return { shapes: lowerer.paramShapes(member.parameters), ret: lowerer.declaredReturnType(member, member.name) };
3013
2991
  }
3014
2992
  /** The nearest declaration of `name` at or above `info` — the method a
3015
2993
  * receiver of that static class runs when nothing below overrides it. */
3016
- export function findMethodOn(L, info, name) {
2994
+ export function findMethodOn(lowerer, info, name) {
3017
2995
  for (let c = info; c; c = c.base) {
3018
2996
  const sig = c.methods.get(name);
3019
2997
  if (sig)
@@ -3022,8 +3000,8 @@ export function findMethodOn(L, info, name) {
3022
3000
  return null;
3023
3001
  }
3024
3002
  /** True when `sub` is a STRICT descendant of `sup` in the class graph. */
3025
- export function isSubclassOf(L, sub, sup) {
3026
- for (let c = L.classes.get(sub)?.base ?? null; c; c = c.base) {
3003
+ export function isSubclassOf(lowerer, sub, sup) {
3004
+ for (let c = lowerer.classes.get(sub)?.base ?? null; c; c = c.base) {
3027
3005
  if (c.def.name === sup)
3028
3006
  return true;
3029
3007
  }
@@ -3032,7 +3010,7 @@ export function isSubclassOf(L, sub, sup) {
3032
3010
  /** In an extends-hierarchy (as base or derived): the class carries a
3033
3011
  * vtable and participates in dynamic instanceof; standalone classes keep
3034
3012
  * their exact pre-inheritance layout and behavior. */
3035
- export function inHierarchy(L, info) {
3013
+ export function inHierarchy(lowerer, info) {
3036
3014
  // The runtime emitter class is ALWAYS a hierarchy member: ScrEmitter
3037
3015
  // carries its vtable word whether or not the program subclasses it
3038
3016
  // (the runtime allocates bare instances with scr_emitter_vt).
@@ -3043,15 +3021,15 @@ export function inHierarchy(L, info) {
3043
3021
  * class can reach a distinct implementation, so it must dispatch
3044
3022
  * dynamically. Abstract re-declarations don't count (they carry no
3045
3023
  * implementation; the concrete ones below them do, via the recursion). */
3046
- export function overrideBelow(L, info, name) {
3024
+ export function overrideBelow(lowerer, info, name) {
3047
3025
  return info.subclasses.some((s) => {
3048
3026
  const m = s.methods.get(name);
3049
- return (m !== undefined && m.abstract !== true) || L.overrideBelow(s, name);
3027
+ return (m !== undefined && m.abstract !== true) || lowerer.overrideBelow(s, name);
3050
3028
  });
3051
3029
  }
3052
3030
  /** The nearest GENERIC-method declaration of `name` at/above `info` —
3053
3031
  * findMethodOn's twin over the genericMethods tables. */
3054
- export function findGenericMethodOn(L, info, name) {
3032
+ export function findGenericMethodOn(lowerer, info, name) {
3055
3033
  for (let c = info; c; c = c.base) {
3056
3034
  const gm = c.genericMethods?.get(name);
3057
3035
  if (gm)
@@ -3063,8 +3041,8 @@ export function findGenericMethodOn(L, info, name) {
3063
3041
  * method `name` — overrideBelow's twin: generic methods have no vtable
3064
3042
  * slot, so a call that could reach an override compiles only when the
3065
3043
  * receiver's runtime class is statically exact. */
3066
- export function genericOverrideBelow(L, info, name) {
3067
- return info.subclasses.some((s) => s.genericMethods?.has(name) === true || genericOverrideBelow(L, s, name));
3044
+ function genericOverrideBelow(lowerer, info, name) {
3045
+ return info.subclasses.some((s) => s.genericMethods?.has(name) === true || genericOverrideBelow(lowerer, s, name));
3068
3046
  }
3069
3047
  /** The receiver's EXACT runtime class, when the expression proves it: a
3070
3048
  * `new C(...)` expression directly, or a const binding initialized with
@@ -3072,23 +3050,23 @@ export function genericOverrideBelow(L, info, name) {
3072
3050
  * The class is read off the mapped INITIALIZER type — a `const b: Base =
3073
3051
  * new D()` receiver is exactly D, not its annotation. Distinct from
3074
3052
  * exactClassOfReceiver, which answers for CLASS-VALUE receivers. */
3075
- export function exactInstanceClassOf(L, expr) {
3053
+ export function exactInstanceClassOf(lowerer, expr) {
3076
3054
  let e = expr;
3077
3055
  while (ts.isParenthesizedExpression(e))
3078
3056
  e = e.expression;
3079
3057
  const classOfNew = (n) => {
3080
3058
  if (!ts.isNewExpression(n))
3081
3059
  return null;
3082
- const t = L.mapTypeOf(L.typeOf(n));
3083
- return t?.kind === "object" ? (L.classes.get(t.className) ?? null) : null;
3060
+ const t = lowerer.mapTypeOf(lowerer.typeOf(n));
3061
+ return t?.kind === "object" ? (lowerer.classes.get(t.className) ?? null) : null;
3084
3062
  };
3085
3063
  const direct = classOfNew(e);
3086
3064
  if (direct)
3087
3065
  return direct;
3088
3066
  if (!ts.isIdentifier(e))
3089
3067
  return null;
3090
- const symbol = L.resolveValueSymbol(e);
3091
- const decl = symbol ? L.checker.valueDeclarationOf(symbol) : undefined;
3068
+ const symbol = lowerer.resolveValueSymbol(e);
3069
+ const decl = symbol ? lowerer.checker.valueDeclarationOf(symbol) : undefined;
3092
3070
  if (!decl || !ts.isVariableDeclaration(decl) || decl.initializer === undefined ||
3093
3071
  !ts.isVariableDeclarationList(decl.parent) ||
3094
3072
  (decl.parent.flags & ts.NodeFlags.Const) === 0) {
@@ -3111,7 +3089,7 @@ export function exactInstanceClassOf(L, expr) {
3111
3089
  * and uses that want the empty record width-coerce at the use site.
3112
3090
  * Const + direct `new` only — a reassignable binding or a produced
3113
3091
  * value keeps today's record story and its fences. */
3114
- export function genericIfaceBindingKeepsClass(L, decl, declaredType) {
3092
+ export function genericIfaceBindingKeepsClass(lowerer, decl, declaredType) {
3115
3093
  if (declaredType.kind !== "record")
3116
3094
  return false;
3117
3095
  if (!ts.isIdentifier(decl.name) || decl.initializer === undefined || decl.type === undefined)
@@ -3123,14 +3101,14 @@ export function genericIfaceBindingKeepsClass(L, decl, declaredType) {
3123
3101
  init = init.expression;
3124
3102
  if (!ts.isNewExpression(init))
3125
3103
  return false;
3126
- const shape = L.shapes.get(declaredType.shapeId);
3104
+ const shape = lowerer.shapes.get(declaredType.shapeId);
3127
3105
  if (!shape || shape.fields.length > 0 || shape.indexValue !== undefined || shape.tuple === true)
3128
3106
  return false;
3129
- const annT = L.typeOf(decl.name);
3130
- const props = L.checker.getPropertiesOfType(annT);
3107
+ const annT = lowerer.typeOf(decl.name);
3108
+ const props = lowerer.checker.getPropertiesOfType(annT);
3131
3109
  if (props.length === 0)
3132
3110
  return false;
3133
- return props.every((p) => isGenericCallableMemberType(L.checker.getTypeOfSymbol(p), L.checker));
3111
+ return props.every((p) => isGenericCallableMemberType(lowerer.checker.getTypeOfSymbol(p), lowerer.checker));
3134
3112
  }
3135
3113
  /** `recv.m<T>(args)` — a GENERIC method call, dispatched STATICALLY: the
3136
3114
  * checker's resolved signature (type arguments substituted, inferred or
@@ -3140,14 +3118,14 @@ export function genericIfaceBindingKeepsClass(L, decl, declaredType) {
3140
3118
  * runtime class could OVERRIDE the method (genericOverrideBelow) must be
3141
3119
  * statically exact (exactInstanceClassOf) — the override set then
3142
3120
  * resolves at compile time — or fences by name. */
3143
- export function lowerClassGenericMethodCall(L, call, access, recvInfo, found, recvIr) {
3121
+ export function lowerClassGenericMethodCall(lowerer, call, access, recvInfo, found, recvIr) {
3144
3122
  const name = access.name.text;
3145
3123
  let { declarer, info } = found;
3146
- if (genericOverrideBelow(L, recvInfo, name)) {
3147
- const exact = exactInstanceClassOf(L, access.expression);
3148
- const refound = exact ? findGenericMethodOn(L, exact, name) : null;
3124
+ if (genericOverrideBelow(lowerer, recvInfo, name)) {
3125
+ const exact = exactInstanceClassOf(lowerer, access.expression);
3126
+ const refound = exact ? findGenericMethodOn(lowerer, exact, name) : null;
3149
3127
  if (!refound) {
3150
- L.unsupported("SC1090", call, `calling the generic method '${name}' through a receiver whose runtime class may override it (a subclass of '${recvInfo.def.name.replace(/^%|^%m\d+\./, "")}' redeclares it and generic methods dispatch statically — bind the receiver to a const initialized with its 'new' expression)`);
3128
+ lowerer.unsupported("SC1090", call, `calling the generic method '${name}' through a receiver whose runtime class may override it (a subclass of '${recvInfo.def.name.replace(/^%|^%m\d+\./, "")}' redeclares it and generic methods dispatch statically — bind the receiver to a const initialized with its 'new' expression)`);
3151
3129
  }
3152
3130
  ({ declarer, info } = refound);
3153
3131
  }
@@ -3156,23 +3134,23 @@ export function lowerClassGenericMethodCall(L, call, access, recvInfo, found, re
3156
3134
  // type parameters); everything else about the dispatch — static
3157
3135
  // resolution, the exactness rule above — is the generic story.
3158
3136
  const instance = info.implicitParams
3159
- ? implicitCallInstance(L, call, info)
3160
- : genericCallInstance(L, call, info);
3161
- const receiver = recvIr ?? L.lowerExpr(access.expression);
3137
+ ? implicitCallInstance(lowerer, call, info)
3138
+ : genericCallInstance(lowerer, call, info);
3139
+ const receiver = recvIr ?? lowerer.lowerExpr(access.expression);
3162
3140
  const loc = locOf(call);
3163
3141
  // The declarer sits at/above the receiver's static class on the plain
3164
3142
  // path; the EXACT path can land below it (a base-typed const provably
3165
3143
  // holding the subclass) — that direction is the checker-grade downcast
3166
3144
  // (the exactness proof is static, stronger than an instanceof guard).
3167
- const thisArg = receiver.type.kind === "object" && isSubclassOf(L, declarer.def.name, receiver.type.className)
3145
+ const thisArg = receiver.type.kind === "object" && isSubclassOf(lowerer, declarer.def.name, receiver.type.className)
3168
3146
  ? { kind: "downcast", value: receiver, type: { kind: "object", className: declarer.def.name }, loc }
3169
- : upcastTo(L, receiver, declarer.def.name);
3170
- const args = L.completeArgs(call.arguments, instance.params, loc, call);
3147
+ : upcastTo(lowerer, receiver, declarer.def.name);
3148
+ const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
3171
3149
  return { kind: "call", callee: instance.name, args: [thisArg, ...args], type: instance.returnType, loc };
3172
3150
  }
3173
3151
  /** Wraps a derived-class expression in an upcast when the target base
3174
3152
  * class differs (a no-op reinterpret at runtime; keeps IR types exact). */
3175
- export function upcastTo(L, expr, className) {
3153
+ export function upcastTo(lowerer, expr, className) {
3176
3154
  if (expr.type.kind === "object" && expr.type.className !== className) {
3177
3155
  return { kind: "upcast", value: expr, type: { kind: "object", className }, loc: expr.loc };
3178
3156
  }
@@ -3190,14 +3168,14 @@ export function upcastTo(L, expr, className) {
3190
3168
  * and no other reference to the parameter — the one rest-constructor
3191
3169
  * form with an exact static story under monomorphization (the
3192
3170
  * instantiation adopts the base's ABI; see collectClassShapeInner). */
3193
- function mixinForwardingCtor(L, ctor) {
3171
+ function mixinForwardingCtor(lowerer, ctor) {
3194
3172
  if (ctor.parameters.length !== 1 || !ctor.body)
3195
3173
  return false;
3196
3174
  const p = ctor.parameters[0];
3197
3175
  if (!p.dotDotDotToken || !ts.isIdentifier(p.name))
3198
3176
  return false;
3199
3177
  const paramName = p.name;
3200
- const paramSym = L.checker.getSymbolAtLocation(paramName);
3178
+ const paramSym = lowerer.checker.getSymbolAtLocation(paramName);
3201
3179
  if (!paramSym)
3202
3180
  return false;
3203
3181
  const first = ctor.body.statements[0];
@@ -3212,13 +3190,13 @@ function mixinForwardingCtor(L, ctor) {
3212
3190
  if (!ts.isSpreadElement(a) || !ts.isIdentifier(a.expression))
3213
3191
  return false;
3214
3192
  const spreadIdent = a.expression;
3215
- if (L.checker.getSymbolAtLocation(spreadIdent) !== paramSym)
3193
+ if (lowerer.checker.getSymbolAtLocation(spreadIdent) !== paramSym)
3216
3194
  return false;
3217
3195
  let extraRef = false;
3218
3196
  ts.walkPreorder(ctor.body, (n) => {
3219
3197
  if (n === spreadIdent)
3220
3198
  return undefined;
3221
- if (ts.isIdentifier(n) && n.text === paramName.text && L.checker.getSymbolAtLocation(n) === paramSym) {
3199
+ if (ts.isIdentifier(n) && n.text === paramName.text && lowerer.checker.getSymbolAtLocation(n) === paramSym) {
3222
3200
  extraRef = true;
3223
3201
  return "stop";
3224
3202
  }
@@ -3226,7 +3204,7 @@ function mixinForwardingCtor(L, ctor) {
3226
3204
  });
3227
3205
  return !extraRef;
3228
3206
  }
3229
- export function lowerClassMembers(L, info) {
3207
+ export function lowerClassMembers(lowerer, info) {
3230
3208
  const out = [];
3231
3209
  const className = info.def.name;
3232
3210
  // Generic-class INSTANTIATIONS (and mixin instantiations) are
@@ -3242,20 +3220,20 @@ export function lowerClassMembers(L, info) {
3242
3220
  // exists): the diagnostic is recorded — the member skips like a
3243
3221
  // signature-blocked function (lowerStaticMethod's rule) instead of
3244
3222
  // crashing the whole lowering.
3245
- if (!info.generic && (always || L.wantBody(`%${className}.constructor`))) {
3223
+ if (!info.generic && (always || lowerer.wantBody(`%${className}.constructor`))) {
3246
3224
  try {
3247
- out.push(L.lowerClassCtor(info));
3225
+ out.push(lowerer.lowerClassCtor(info));
3248
3226
  }
3249
3227
  catch (e) {
3250
3228
  if (!(e instanceof PoisonError))
3251
3229
  throw e;
3252
3230
  }
3253
3231
  }
3254
- for (const { mName, member } of L.classMethodMembers(info)) {
3255
- if (!always && !L.wantBody(`%${className}.${mName}`))
3232
+ for (const { mName, member } of lowerer.classMethodMembers(info)) {
3233
+ if (!always && !lowerer.wantBody(`%${className}.${mName}`))
3256
3234
  continue;
3257
3235
  try {
3258
- const fn = L.lowerClassMethodMember(info, member);
3236
+ const fn = lowerer.lowerClassMethodMember(info, member);
3259
3237
  if (fn)
3260
3238
  out.push(fn);
3261
3239
  }
@@ -3265,15 +3243,15 @@ export function lowerClassMembers(L, info) {
3265
3243
  }
3266
3244
  }
3267
3245
  for (const name of info.staticMethods?.keys() ?? []) {
3268
- if (!L.wantBody(`%${className}.static:${name}`))
3246
+ if (!lowerer.wantBody(`%${className}.static:${name}`))
3269
3247
  continue;
3270
- const fn = lowerStaticMethod(L, info, name);
3248
+ const fn = lowerStaticMethod(lowerer, info, name);
3271
3249
  if (fn)
3272
3250
  out.push(fn);
3273
3251
  }
3274
3252
  for (const prop of info.throwingSetters) {
3275
- if (always || L.wantBody(`%${className}.set:${prop}`))
3276
- out.push(L.throwingSetterFn(info, prop));
3253
+ if (always || lowerer.wantBody(`%${className}.set:${prop}`))
3254
+ out.push(lowerer.throwingSetterFn(info, prop));
3277
3255
  }
3278
3256
  return out;
3279
3257
  }
@@ -3281,17 +3259,17 @@ export function lowerClassMembers(L, info) {
3281
3259
  * base class runs just its field initializers; a derived class inherits
3282
3260
  * the base's signature — forward every param to super(), then run own
3283
3261
  * field initializers. */
3284
- export function lowerClassCtor(L, info) {
3285
- return withInstanceBindings(L, info, () => lowerClassCtorInner(L, info));
3262
+ export function lowerClassCtor(lowerer, info) {
3263
+ return withInstanceBindings(lowerer, info, () => lowerClassCtorInner(lowerer, info));
3286
3264
  }
3287
- function lowerClassCtorInner(L, info) {
3265
+ function lowerClassCtorInner(lowerer, info) {
3288
3266
  const className = info.def.name;
3289
3267
  const thisType = { kind: "object", className };
3290
- const prevClass = L.currentClass;
3291
- L.currentClass = info;
3292
- L.fnStack.push(newFnCtx(false, null, null, VOID));
3268
+ const prevClass = lowerer.currentClass;
3269
+ lowerer.currentClass = info;
3270
+ lowerer.fnStack.push(newFnCtx(false, null, null, VOID));
3293
3271
  try {
3294
- const thisLocal = L.declareThis(thisType);
3272
+ const thisLocal = lowerer.declareThis(thisType);
3295
3273
  const params = [{ localId: thisLocal.id, name: "this", type: thisType }];
3296
3274
  const body = [];
3297
3275
  // The construction-relevant base: generic families are transparent
@@ -3306,17 +3284,17 @@ function lowerClassCtorInner(L, info) {
3306
3284
  const loc = locOf(info.ctor);
3307
3285
  const forward = info.ctorParams.map((shape, i) => {
3308
3286
  const local = { id: `arg${i}.0`, name: `arg${i}`, type: shape.type, mutable: false };
3309
- L.ctx.locals.push(local);
3287
+ lowerer.ctx.locals.push(local);
3310
3288
  params.push({ localId: local.id, name: local.name, type: shape.type });
3311
3289
  return { kind: "varRef", localId: local.id, type: shape.type, loc };
3312
3290
  });
3313
- body.push(...L.lowerDerivedCtorBody(info, thisLocal, forward));
3291
+ body.push(...lowerer.lowerDerivedCtorBody(info, thisLocal, forward));
3314
3292
  }
3315
3293
  else if (info.ctor) {
3316
3294
  // The default-param prologue runs FIRST — before field initializers
3317
3295
  // and (in a derived class) before super(): JS evaluates parameter
3318
3296
  // defaults on entry, ahead of everything the body does.
3319
- const declared = L.declareParams(info.ctor.parameters, info.ctorParams);
3297
+ const declared = lowerer.declareParams(info.ctor.parameters, info.ctorParams);
3320
3298
  params.push(...declared.params);
3321
3299
  body.push(...declared.prologue);
3322
3300
  if (!ctorBase) {
@@ -3324,13 +3302,13 @@ function lowerClassCtorInner(L, info) {
3324
3302
  // of construction, the parameter-property assignments open the
3325
3303
  // constructor body (probed — a field initializer reading a
3326
3304
  // parameter property sees undefined).
3327
- body.push(...L.fieldInitStmts(info, thisLocal));
3328
- body.push(...paramPropInitStmts(L, info, thisLocal));
3305
+ body.push(...lowerer.fieldInitStmts(info, thisLocal));
3306
+ body.push(...paramPropInitStmts(lowerer, info, thisLocal));
3329
3307
  if (info.ctor.body)
3330
- body.push(...L.lowerStmts(info.ctor.body.statements));
3308
+ body.push(...lowerer.lowerStmts(info.ctor.body.statements));
3331
3309
  }
3332
3310
  else if (info.ctor.body) {
3333
- body.push(...L.lowerDerivedCtorBody(info, thisLocal));
3311
+ body.push(...lowerer.lowerDerivedCtorBody(info, thisLocal));
3334
3312
  }
3335
3313
  }
3336
3314
  else {
@@ -3342,12 +3320,12 @@ function lowerClassCtorInner(L, info) {
3342
3320
  const loc = locOf(info.decl);
3343
3321
  const superArgs = info.ctorParams.map((shape, i) => {
3344
3322
  const local = { id: `arg${i}.0`, name: `arg${i}`, type: shape.type, mutable: false };
3345
- L.ctx.locals.push(local);
3323
+ lowerer.ctx.locals.push(local);
3346
3324
  params.push({ localId: local.id, name: local.name, type: shape.type });
3347
3325
  return { kind: "varRef", localId: local.id, type: shape.type, loc };
3348
3326
  });
3349
3327
  try {
3350
- body.push(L.superCallStmt(info, thisLocal, superArgs, loc));
3328
+ body.push(lowerer.superCallStmt(info, thisLocal, superArgs, loc));
3351
3329
  }
3352
3330
  catch (e) {
3353
3331
  // A synthesized super() can fence (a stream base whose
@@ -3357,20 +3335,20 @@ function lowerClassCtorInner(L, info) {
3357
3335
  throw e;
3358
3336
  }
3359
3337
  }
3360
- body.push(...L.fieldInitStmts(info, thisLocal));
3338
+ body.push(...lowerer.fieldInitStmts(info, thisLocal));
3361
3339
  }
3362
3340
  return {
3363
3341
  name: `%${className}.constructor`,
3364
3342
  params,
3365
3343
  returnType: VOID,
3366
- locals: L.ctx.locals,
3344
+ locals: lowerer.ctx.locals,
3367
3345
  body,
3368
3346
  loc: locOf(info.ctor ?? info.decl),
3369
3347
  };
3370
3348
  }
3371
3349
  finally {
3372
- L.fnStack.pop();
3373
- L.currentClass = prevClass;
3350
+ lowerer.fnStack.pop();
3351
+ lowerer.currentClass = prevClass;
3374
3352
  }
3375
3353
  }
3376
3354
  /** The lowered method-map name of a class member: identifier text, a
@@ -3382,7 +3360,7 @@ function lowerClassCtorInner(L, info) {
3382
3360
  * accessor "get:x" convention; for-of, spreads, and array destructuring
3383
3361
  * dispatch to it through the iterator protocol). Null for genuinely
3384
3362
  * runtime-keyed names — the computed-member fences stay. */
3385
- export function classMemberNameOf(L, name) {
3363
+ export function classMemberNameOf(lowerer, name) {
3386
3364
  if (ts.isIdentifier(name))
3387
3365
  return name.text;
3388
3366
  // #private methods key by their spelled name ('#m') — '#' is
@@ -3394,37 +3372,37 @@ export function classMemberNameOf(L, name) {
3394
3372
  let e = name.expression;
3395
3373
  while (ts.isParenthesizedExpression(e))
3396
3374
  e = e.expression;
3397
- if (ts.isPropertyAccessExpression(e) && L.stdlibGlobalMember(e, "Symbol") === "iterator") {
3375
+ if (ts.isPropertyAccessExpression(e) && lowerer.stdlibGlobalMember(e, "Symbol") === "iterator") {
3398
3376
  return "sym:iterator";
3399
3377
  }
3400
- return L.foldedStringKeyOf(name.expression);
3378
+ return lowerer.foldedStringKeyOf(name.expression);
3401
3379
  }
3402
- export function classIteratorOf(L, t) {
3380
+ export function classIteratorOf(lowerer, t) {
3403
3381
  if (t.kind !== "object")
3404
3382
  return null;
3405
- const info = L.classes.get(t.className);
3383
+ const info = lowerer.classes.get(t.className);
3406
3384
  if (!info)
3407
3385
  return null;
3408
- const iter = findMethodOn(L, info, "sym:iterator");
3386
+ const iter = findMethodOn(lowerer, info, "sym:iterator");
3409
3387
  if (!iter || iter.sig.params.length !== 0 || iter.sig.abstract === true)
3410
3388
  return null;
3411
3389
  const iterT = iter.sig.ret;
3412
3390
  if (iterT.kind !== "object")
3413
3391
  return null;
3414
- const itInfo = L.classes.get(iterT.className);
3392
+ const itInfo = lowerer.classes.get(iterT.className);
3415
3393
  if (!itInfo)
3416
3394
  return null;
3417
3395
  // IteratorClose honesty: a declared return()/throw() would be called
3418
3396
  // by JS on abrupt completion; these desugars never close.
3419
- if (findMethodOn(L, itInfo, "return") || findMethodOn(L, itInfo, "throw"))
3397
+ if (findMethodOn(lowerer, itInfo, "return") || findMethodOn(lowerer, itInfo, "throw"))
3420
3398
  return null;
3421
- const next = findMethodOn(L, itInfo, "next");
3399
+ const next = findMethodOn(lowerer, itInfo, "next");
3422
3400
  if (!next || next.sig.params.length !== 0 || next.sig.abstract === true)
3423
3401
  return null;
3424
3402
  const resultT = next.sig.ret;
3425
3403
  if (resultT.kind !== "record")
3426
3404
  return null;
3427
- const shape = L.shapes.get(resultT.shapeId);
3405
+ const shape = lowerer.shapes.get(resultT.shapeId);
3428
3406
  const value = shape?.fields.find((f) => f.name === "value");
3429
3407
  if (!shape || !value)
3430
3408
  return null;
@@ -3435,12 +3413,12 @@ export function classIteratorOf(L, t) {
3435
3413
  }
3436
3414
  /** The `it.next()` step of a class iterator as an ordinary (possibly
3437
3415
  * virtual) method call. */
3438
- export function classIteratorNextCall(L, cit, itRef, loc) {
3439
- return accessorCall(L, cit.iterT.className, "next", itRef, [], cit.resultT, loc);
3416
+ export function classIteratorNextCall(lowerer, cit, itRef, loc) {
3417
+ return accessorCall(lowerer, cit.iterT.className, "next", itRef, [], cit.resultT, loc);
3440
3418
  }
3441
3419
  /** `recv[Symbol.iterator]()` as an ordinary method call. */
3442
- export function classIteratorOpenCall(L, cit, recv, loc) {
3443
- return accessorCall(L, cit.className, "sym:iterator", recv, [], cit.iterT, loc);
3420
+ export function classIteratorOpenCall(lowerer, cit, recv, loc) {
3421
+ return accessorCall(lowerer, cit.className, "sym:iterator", recv, [], cit.iterT, loc);
3444
3422
  }
3445
3423
  /** `[...new C]` / `f(...new C)` over a CLASS ITERABLE: the eager drain —
3446
3424
  * an interned `%iter.drain.<n>(recv)` lifted function running the
@@ -3451,23 +3429,23 @@ export function classIteratorOpenCall(L, cit, recv, loc) {
3451
3429
  * `(number | symbol)[]`) pushes each value wrapped into its arm. Null
3452
3430
  * when the value isn't a recognized class iterable or the element
3453
3431
  * doesn't coerce — spread fences stay. */
3454
- export function classIteratorDrainCall(L, src, loc, elemT) {
3455
- const cit = classIteratorOf(L, src.type);
3432
+ export function classIteratorDrainCall(lowerer, src, loc, elemT) {
3433
+ const cit = classIteratorOf(lowerer, src.type);
3456
3434
  if (!cit)
3457
3435
  return null;
3458
3436
  const outElem = elemT ?? cit.valueT;
3459
3437
  // Probe the element coercion purely: identical types, or an arm of a
3460
3438
  // union destination (the wrap coerceToExpected applies below).
3461
3439
  if (!typeEquals(outElem, cit.valueT)) {
3462
- if (outElem.kind !== "union" || L.armTag(outElem.unionId, cit.valueT) < 0)
3440
+ if (outElem.kind !== "union" || lowerer.armTag(outElem.unionId, cit.valueT) < 0)
3463
3441
  return null;
3464
3442
  }
3465
3443
  const outT = arrayOf(outElem);
3466
3444
  const key = `${cit.className}:${typeKey(outElem)}`;
3467
- let name = L.iterDrainHelpers.get(key);
3445
+ let name = lowerer.iterDrainHelpers.get(key);
3468
3446
  if (!name) {
3469
- name = `%iter.drain.${L.iterDrainHelpers.size}`;
3470
- L.iterDrainHelpers.set(key, name);
3447
+ name = `%iter.drain.${lowerer.iterDrainHelpers.size}`;
3448
+ lowerer.iterDrainHelpers.set(key, name);
3471
3449
  const recvT = { kind: "object", className: cit.className };
3472
3450
  const recvRef = { kind: "varRef", localId: "r.0", type: recvT, loc };
3473
3451
  const itRef = { kind: "varRef", localId: "it.0", type: cit.iterT, loc };
@@ -3475,7 +3453,7 @@ export function classIteratorDrainCall(L, src, loc, elemT) {
3475
3453
  const resRef = { kind: "varRef", localId: "res.0", type: cit.resultT, loc };
3476
3454
  const valueRead = { kind: "recordGet", obj: resRef, shapeId: cit.resultT.shapeId, field: "value", type: cit.valueT, loc };
3477
3455
  const loop = [
3478
- { kind: "varDecl", localId: "res.0", init: classIteratorNextCall(L, cit, itRef, loc), loc },
3456
+ { kind: "varDecl", localId: "res.0", init: classIteratorNextCall(lowerer, cit, itRef, loc), loc },
3479
3457
  ...(cit.hasDone
3480
3458
  ? [
3481
3459
  {
@@ -3493,14 +3471,14 @@ export function classIteratorDrainCall(L, src, loc, elemT) {
3493
3471
  kind: "arrIntrinsic",
3494
3472
  method: "push",
3495
3473
  receiver: outRef,
3496
- args: [L.coerceToExpected(valueRead, outElem)],
3474
+ args: [lowerer.coerceToExpected(valueRead, outElem)],
3497
3475
  type: F64,
3498
3476
  loc,
3499
3477
  },
3500
3478
  loc,
3501
3479
  },
3502
3480
  ];
3503
- L.liftedFns.push({
3481
+ lowerer.liftedFns.push({
3504
3482
  name,
3505
3483
  params: [{ localId: "r.0", name: "r", type: recvT }],
3506
3484
  returnType: outT,
@@ -3512,7 +3490,7 @@ export function classIteratorDrainCall(L, src, loc, elemT) {
3512
3490
  ],
3513
3491
  body: [
3514
3492
  { kind: "varDecl", localId: "out.0", init: { kind: "arrayLit", elems: [], type: outT, loc }, loc },
3515
- { kind: "varDecl", localId: "it.0", init: classIteratorOpenCall(L, cit, recvRef, loc), loc },
3493
+ { kind: "varDecl", localId: "it.0", init: classIteratorOpenCall(lowerer, cit, recvRef, loc), loc },
3516
3494
  {
3517
3495
  kind: "while",
3518
3496
  cond: { kind: "boolLit", value: true, type: BOOL, loc },
@@ -3535,18 +3513,18 @@ export function classIteratorDrainCall(L, src, loc, elemT) {
3535
3513
  /** The tail of a class iterable's protocol from an already-open ITERATOR
3536
3514
  * object (`var [a, ...rest] = new C` — the rest element drains whatever
3537
3515
  * next() still yields): the drain loop keyed by the iterator class. */
3538
- export function classIteratorRestDrainCall(L, cit, itVal, loc) {
3516
+ export function classIteratorRestDrainCall(lowerer, cit, itVal, loc) {
3539
3517
  const outT = arrayOf(cit.valueT);
3540
3518
  const key = `it:${cit.iterT.className}`;
3541
- let name = L.iterDrainHelpers.get(key);
3519
+ let name = lowerer.iterDrainHelpers.get(key);
3542
3520
  if (!name) {
3543
- name = `%iter.drain.${L.iterDrainHelpers.size}`;
3544
- L.iterDrainHelpers.set(key, name);
3521
+ name = `%iter.drain.${lowerer.iterDrainHelpers.size}`;
3522
+ lowerer.iterDrainHelpers.set(key, name);
3545
3523
  const itRef = { kind: "varRef", localId: "it.0", type: cit.iterT, loc };
3546
3524
  const outRef = { kind: "varRef", localId: "out.0", type: outT, loc };
3547
3525
  const resRef = { kind: "varRef", localId: "res.0", type: cit.resultT, loc };
3548
3526
  const loop = [
3549
- { kind: "varDecl", localId: "res.0", init: classIteratorNextCall(L, cit, itRef, loc), loc },
3527
+ { kind: "varDecl", localId: "res.0", init: classIteratorNextCall(lowerer, cit, itRef, loc), loc },
3550
3528
  ...(cit.hasDone
3551
3529
  ? [
3552
3530
  {
@@ -3571,7 +3549,7 @@ export function classIteratorRestDrainCall(L, cit, itVal, loc) {
3571
3549
  loc,
3572
3550
  },
3573
3551
  ];
3574
- L.liftedFns.push({
3552
+ lowerer.liftedFns.push({
3575
3553
  name,
3576
3554
  params: [{ localId: "it.0", name: "it", type: cit.iterT }],
3577
3555
  returnType: outT,
@@ -3597,13 +3575,13 @@ export function classIteratorRestDrainCall(L, cit, itVal, loc) {
3597
3575
  /** One method or accessor body as its module function `%C.name`
3598
3576
  * (accessors are methods with property syntax: "get:x"/"set:x" entries —
3599
3577
  * see collectClassShape). */
3600
- export function lowerClassMethodMember(L, info, fnLike) {
3601
- return withInstanceBindings(L, info, () => lowerClassMethodMemberInner(L, info, fnLike));
3578
+ export function lowerClassMethodMember(lowerer, info, fnLike) {
3579
+ return withInstanceBindings(lowerer, info, () => lowerClassMethodMemberInner(lowerer, info, fnLike));
3602
3580
  }
3603
- function lowerClassMethodMemberInner(L, info, fnLike) {
3581
+ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
3604
3582
  const className = info.def.name;
3605
3583
  const thisType = { kind: "object", className };
3606
- const memberName = ts.isMethodDeclaration(fnLike) ? classMemberNameOf(L, fnLike.name) : ts.isIdentifier(fnLike.name) || ts.isPrivateIdentifier(fnLike.name) ? fnLike.name.text : null;
3584
+ const memberName = ts.isMethodDeclaration(fnLike) ? classMemberNameOf(lowerer, fnLike.name) : ts.isIdentifier(fnLike.name) || ts.isPrivateIdentifier(fnLike.name) ? fnLike.name.text : null;
3607
3585
  if (memberName === null)
3608
3586
  return null;
3609
3587
  const mName = ts.isMethodDeclaration(fnLike)
@@ -3612,8 +3590,8 @@ function lowerClassMethodMemberInner(L, info, fnLike) {
3612
3590
  const sig = info.methods.get(mName);
3613
3591
  if (!sig || !fnLike.body)
3614
3592
  return null;
3615
- const prevClass = L.currentClass;
3616
- L.currentClass = info;
3593
+ const prevClass = lowerer.currentClass;
3594
+ lowerer.currentClass = info;
3617
3595
  // ASYNC methods: the module function is an async IrFunction — its
3618
3596
  // body returns the promise's INNER type (a `return v` fulfills with
3619
3597
  // v) and every call enters through the emitted fiber spawn wrapper
@@ -3630,26 +3608,26 @@ function lowerClassMethodMemberInner(L, info, fnLike) {
3630
3608
  const bodyReturn = isAsync && sig.ret.kind === "promise"
3631
3609
  ? sig.ret.inner
3632
3610
  : genCh !== null
3633
- ? L.genBodyReturnType(sig.ret)
3611
+ ? lowerer.genBodyReturnType(sig.ret)
3634
3612
  : sig.ret;
3635
3613
  const fnCtx = newFnCtx(false, null, null, bodyReturn);
3636
3614
  fnCtx.isAsync = isAsync;
3637
3615
  if (genCh !== null)
3638
3616
  fnCtx.generator = genCh;
3639
- L.fnStack.push(fnCtx);
3617
+ lowerer.fnStack.push(fnCtx);
3640
3618
  try {
3641
- const thisLocal = L.declareThis(thisType);
3619
+ const thisLocal = lowerer.declareThis(thisType);
3642
3620
  const params = [{ localId: thisLocal.id, name: "this", type: thisType }];
3643
3621
  // `this` is declared first, so method parameter DEFAULTS may use it
3644
3622
  // (JS allows this in method defaults; it is param 0 here).
3645
- const declared = L.declareParams(fnLike.parameters, sig.params);
3623
+ const declared = lowerer.declareParams(fnLike.parameters, sig.params);
3646
3624
  params.push(...declared.params);
3647
- const body = [...declared.prologue, ...L.lowerStmts(fnLike.body.statements)];
3625
+ const body = [...declared.prologue, ...lowerer.lowerStmts(fnLike.body.statements)];
3648
3626
  const fn = {
3649
3627
  name: `%${className}.${mName}`,
3650
3628
  params,
3651
3629
  returnType: bodyReturn,
3652
- locals: L.ctx.locals,
3630
+ locals: lowerer.ctx.locals,
3653
3631
  body,
3654
3632
  loc: locOf(fnLike),
3655
3633
  };
@@ -3660,8 +3638,8 @@ function lowerClassMethodMemberInner(L, info, fnLike) {
3660
3638
  return fn;
3661
3639
  }
3662
3640
  finally {
3663
- L.fnStack.pop();
3664
- L.currentClass = prevClass;
3641
+ lowerer.fnStack.pop();
3642
+ lowerer.currentClass = prevClass;
3665
3643
  }
3666
3644
  }
3667
3645
  /** One static method body as its module function `%C.static:m` — an
@@ -3671,22 +3649,10 @@ function lowerClassMethodMemberInner(L, info, fnLike) {
3671
3649
  * named fences, with arrow functions transparent (they inherit the
3672
3650
  * method's `this`) and this-binding function forms opaque — the static-
3673
3651
  * block rule verbatim. */
3674
- export function lowerStaticMethod(L, info, name) {
3652
+ export function lowerStaticMethod(lowerer, info, name) {
3675
3653
  const entry = info.staticMethods?.get(name);
3676
3654
  if (!entry?.member.body)
3677
3655
  return null;
3678
- const checkThis = (n) => {
3679
- if (ts.isFunctionExpression(n) || ts.isFunctionDeclaration(n) ||
3680
- ts.isMethodDeclaration(n) || ts.isConstructorDeclaration(n) ||
3681
- ts.isGetAccessor(n) || ts.isSetAccessor(n) ||
3682
- ts.isClassDeclaration(n) || ts.isClassExpression(n)) {
3683
- return;
3684
- }
3685
- if (n.kind === ts.SyntaxKind.ThisKeyword || n.kind === ts.SyntaxKind.SuperKeyword) {
3686
- L.unsupported("SC1090", n, `'${n.kind === ts.SyntaxKind.ThisKeyword ? "this" : "super"}' in static methods (it names the RECEIVER class — a dynamic value; reference the class by name instead)`);
3687
- }
3688
- n.forEachChild(checkThis);
3689
- };
3690
3656
  // Async statics: an async IrFunction like any module function — the
3691
3657
  // body returns the promise's INNER type, calls enter through the
3692
3658
  // fiber spawn wrapper (callTargetC routes by fn.async).
@@ -3695,16 +3661,16 @@ export function lowerStaticMethod(L, info, name) {
3695
3661
  const bodyReturn = isAsync && entry.ret.kind === "promise" ? entry.ret.inner : entry.ret;
3696
3662
  const fnCtx = newFnCtx(false, null, null, bodyReturn);
3697
3663
  fnCtx.isAsync = isAsync;
3698
- L.fnStack.push(fnCtx);
3664
+ lowerer.fnStack.push(fnCtx);
3699
3665
  try {
3700
- entry.member.body.forEachChild(checkThis);
3701
- const declared = L.declareParams(entry.member.parameters, entry.params);
3702
- const body = [...declared.prologue, ...L.lowerStmts(entry.member.body.statements)];
3666
+ rejectStaticThis(lowerer, entry.member.body, (keyword) => `'${keyword}' in static methods (it names the RECEIVER class — a dynamic value; reference the class by name instead)`);
3667
+ const declared = lowerer.declareParams(entry.member.parameters, entry.params);
3668
+ const body = [...declared.prologue, ...lowerer.lowerStmts(entry.member.body.statements)];
3703
3669
  const fn = {
3704
3670
  name: `%${info.def.name}.static:${name}`,
3705
3671
  params: declared.params,
3706
3672
  returnType: bodyReturn,
3707
- locals: L.ctx.locals,
3673
+ locals: lowerer.ctx.locals,
3708
3674
  body,
3709
3675
  loc: locOf(entry.member),
3710
3676
  };
@@ -3722,7 +3688,7 @@ export function lowerStaticMethod(L, info, name) {
3722
3688
  return null;
3723
3689
  }
3724
3690
  finally {
3725
- L.fnStack.pop();
3691
+ lowerer.fnStack.pop();
3726
3692
  }
3727
3693
  }
3728
3694
  /** A synthesized throwing setter: a getter-only override shadows the
@@ -3730,7 +3696,7 @@ export function lowerStaticMethod(L, info, name) {
3730
3696
  * throw exactly like Node's TypeError — a real instance (a typed catch's
3731
3697
  * `e instanceof TypeError` matches), catchable, exit 1 uncaught (message
3732
3698
  * text is compiler-worded; stdout and exit code are the contract). */
3733
- export function throwingSetterFn(L, info, prop) {
3699
+ export function throwingSetterFn(lowerer, info, prop) {
3734
3700
  const className = info.def.name;
3735
3701
  const thisType = { kind: "object", className };
3736
3702
  const sig = info.methods.get(`set:${prop}`);
@@ -3773,23 +3739,23 @@ export function throwingSetterFn(L, info, prop) {
3773
3739
  * null when the generic class extends nothing, exactly the source's
3774
3740
  * story (tsc forbids super() there). Ordinary classes answer their base
3775
3741
  * unchanged. */
3776
- export function superBaseOf(info) {
3742
+ function superBaseOf(info) {
3777
3743
  const b = info.base;
3778
3744
  return b?.generic ? b.base : b;
3779
3745
  }
3780
3746
  /** The class's OWN field initializers as fieldSet statements (declaration
3781
3747
  * order) — a base constructor's prologue, a derived constructor's
3782
3748
  * super()-return continuation. */
3783
- export function fieldInitStmts(L, info, thisLocal) {
3749
+ export function fieldInitStmts(lowerer, info, thisLocal) {
3784
3750
  const out = [];
3785
3751
  const thisType = { kind: "object", className: info.def.name };
3786
3752
  for (const f of info.fieldOrder) {
3787
3753
  if (!f.initializer)
3788
3754
  continue;
3789
- L.stats.statementsTotal++;
3790
- L.bumpFileStat(locOf(f.initializer).file, "total");
3755
+ lowerer.stats.statementsTotal++;
3756
+ lowerer.bumpFileStat(locOf(f.initializer).file, "total");
3791
3757
  try {
3792
- const value = L.lowerExprExpecting(f.initializer, f.type);
3758
+ const value = lowerer.lowerExprExpecting(f.initializer, f.type);
3793
3759
  out.push({
3794
3760
  kind: "fieldSet",
3795
3761
  obj: { kind: "varRef", localId: thisLocal.id, type: thisType, loc: locOf(f.initializer) },
@@ -3802,8 +3768,8 @@ export function fieldInitStmts(L, info, thisLocal) {
3802
3768
  catch (e) {
3803
3769
  if (!(e instanceof PoisonError))
3804
3770
  throw e;
3805
- L.stats.statementsFailed++;
3806
- L.bumpFileStat(locOf(f.initializer).file, "failed");
3771
+ lowerer.stats.statementsFailed++;
3772
+ lowerer.bumpFileStat(locOf(f.initializer).file, "failed");
3807
3773
  }
3808
3774
  }
3809
3775
  return out;
@@ -3817,16 +3783,16 @@ export function fieldInitStmts(L, info, thisLocal) {
3817
3783
  * Each assignment reads the parameter's BODY local (defaults already
3818
3784
  * applied by the declareParams prologue), whose type the collection made
3819
3785
  * the field's type — slot-exact by construction. */
3820
- export function paramPropInitStmts(L, info, thisLocal) {
3786
+ function paramPropInitStmts(lowerer, info, thisLocal) {
3821
3787
  const out = [];
3822
3788
  const thisType = { kind: "object", className: info.def.name };
3823
3789
  for (const pp of info.paramProps ?? []) {
3824
3790
  const loc = locOf(pp.param);
3825
- const local = ts.isIdentifier(pp.param.name) ? L.resolveLocal(pp.param.name) : null;
3791
+ const local = ts.isIdentifier(pp.param.name) ? lowerer.resolveLocal(pp.param.name) : null;
3826
3792
  if (!local || !typeEquals(local.type, pp.type)) {
3827
3793
  // Defensive: collection derived the field type from the same
3828
3794
  // paramShape the ctor's declareParams bound — they cannot diverge.
3829
- L.unsupported("SC1090", pp.param, "this parameter property form");
3795
+ lowerer.unsupported("SC1090", pp.param, "this parameter property form");
3830
3796
  }
3831
3797
  out.push({
3832
3798
  kind: "fieldSet",
@@ -3846,7 +3812,7 @@ export function paramPropInitStmts(L, info, thisLocal) {
3846
3812
  * guarantees a super call exists and runs before any this-use; the
3847
3813
  * supported form is a top-level expression statement — anywhere else
3848
3814
  * (conditionals, expression positions) is rejected, not misordered. */
3849
- export function lowerDerivedCtorBody(L, info, thisLocal,
3815
+ export function lowerDerivedCtorBody(lowerer, info, thisLocal,
3850
3816
  /** Mixin forwarding-constructor mode: `super(...args)` forwards these
3851
3817
  * pre-declared synthetic params directly (the spread never lowers —
3852
3818
  * the base's ABI is this constructor's ABI). */
@@ -3860,49 +3826,49 @@ forward) {
3860
3826
  ? stmt.expression
3861
3827
  : null;
3862
3828
  if (!superCall) {
3863
- out.push(...L.lowerStmts([stmt]));
3829
+ out.push(...lowerer.lowerStmts([stmt]));
3864
3830
  continue;
3865
3831
  }
3866
- if (!L.suppressStats) {
3867
- L.stats.statementsTotal++;
3868
- L.bumpFileStat(locOf(stmt).file, "total");
3832
+ if (!lowerer.suppressStats) {
3833
+ lowerer.stats.statementsTotal++;
3834
+ lowerer.bumpFileStat(locOf(stmt).file, "total");
3869
3835
  }
3870
3836
  try {
3871
3837
  if (superSeen)
3872
- L.unsupported("SC1090", stmt, "multiple super() calls");
3838
+ lowerer.unsupported("SC1090", stmt, "multiple super() calls");
3873
3839
  superSeen = true;
3874
3840
  const base = superBaseOf(info);
3875
3841
  if (base.builtinEmitter && superCall.arguments.length > 0) {
3876
3842
  // @types/node admits super({ captureRejections }) — no lowering.
3877
- L.unsupported("SC1090", superCall, "EventEmitter constructor options ('captureRejections')");
3843
+ lowerer.unsupported("SC1090", superCall, "EventEmitter constructor options ('captureRejections')");
3878
3844
  }
3879
3845
  if (base.builtinStream) {
3880
3846
  // super(options?) into a runtime stream base: the stream spoke
3881
3847
  // parses the options and binds overridden underscore methods.
3882
- out.push(...lowerStreamSuperCall(L, info, base, superCall.arguments, thisLocal, locOf(stmt), stmt));
3883
- out.push(...L.fieldInitStmts(info, thisLocal));
3884
- out.push(...paramPropInitStmts(L, info, thisLocal));
3848
+ out.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments, thisLocal, locOf(stmt), stmt));
3849
+ out.push(...lowerer.fieldInitStmts(info, thisLocal));
3850
+ out.push(...paramPropInitStmts(lowerer, info, thisLocal));
3885
3851
  continue;
3886
3852
  }
3887
3853
  const args = forward !== undefined
3888
3854
  ? forward
3889
3855
  : base.builtinError
3890
- ? [L.errorMessageArg(superCall.arguments, locOf(stmt), stmt)]
3856
+ ? [lowerer.errorMessageArg(superCall.arguments, locOf(stmt), stmt)]
3891
3857
  : base.builtinEmitter
3892
3858
  ? []
3893
- : L.completeArgs(superCall.arguments, base.ctorParams, locOf(stmt), stmt);
3894
- out.push(L.superCallStmt(info, thisLocal, args, locOf(stmt)));
3859
+ : lowerer.completeArgs(superCall.arguments, base.ctorParams, locOf(stmt), stmt);
3860
+ out.push(lowerer.superCallStmt(info, thisLocal, args, locOf(stmt)));
3895
3861
  // super() returns → field initializers → parameter-property
3896
3862
  // assignments (Node's order, probed) → the rest of the body.
3897
- out.push(...L.fieldInitStmts(info, thisLocal));
3898
- out.push(...paramPropInitStmts(L, info, thisLocal));
3863
+ out.push(...lowerer.fieldInitStmts(info, thisLocal));
3864
+ out.push(...paramPropInitStmts(lowerer, info, thisLocal));
3899
3865
  }
3900
3866
  catch (e) {
3901
3867
  if (!(e instanceof PoisonError))
3902
3868
  throw e;
3903
- if (!L.suppressStats) {
3904
- L.stats.statementsFailed++;
3905
- L.bumpFileStat(locOf(stmt).file, "failed");
3869
+ if (!lowerer.suppressStats) {
3870
+ lowerer.stats.statementsFailed++;
3871
+ lowerer.bumpFileStat(locOf(stmt).file, "failed");
3906
3872
  }
3907
3873
  }
3908
3874
  }
@@ -3910,14 +3876,14 @@ forward) {
3910
3876
  // tsc guarantees the call exists somewhere; if it wasn't a top-level
3911
3877
  // statement the per-site rejection above already fired — this is the
3912
3878
  // constructor-level backstop so a half-initialized ctor never emits.
3913
- L.pushDiag(unsupportedDiag("SC1090", locOf(info.ctor), "super() calls anywhere but as a top-level constructor statement"));
3879
+ lowerer.pushDiag(unsupportedDiag("SC1090", locOf(info.ctor), "super() calls anywhere but as a top-level constructor statement"));
3914
3880
  }
3915
3881
  return out;
3916
3882
  }
3917
3883
  /** `super(args)` → direct call of the base constructor with the SAME
3918
3884
  * `this` (upcast; retained by the varRef read — the callee owns and
3919
3885
  * releases its param per the universal convention). */
3920
- export function superCallStmt(L, info, thisLocal, args, loc) {
3886
+ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
3921
3887
  const base = superBaseOf(info);
3922
3888
  const thisRef = {
3923
3889
  kind: "varRef",
@@ -3935,7 +3901,7 @@ export function superCallStmt(L, info, thisLocal, args, loc) {
3935
3901
  expr: {
3936
3902
  kind: "libCall",
3937
3903
  fn: "error.ctor",
3938
- args: [L.upcastTo(thisRef, base.def.name), ...args],
3904
+ args: [lowerer.upcastTo(thisRef, base.def.name), ...args],
3939
3905
  type: VOID,
3940
3906
  loc,
3941
3907
  },
@@ -3952,7 +3918,7 @@ export function superCallStmt(L, info, thisLocal, args, loc) {
3952
3918
  expr: {
3953
3919
  kind: "libCall",
3954
3920
  fn: "emitter.ctor",
3955
- args: [L.upcastTo(thisRef, base.def.name)],
3921
+ args: [lowerer.upcastTo(thisRef, base.def.name)],
3956
3922
  type: VOID,
3957
3923
  loc,
3958
3924
  },
@@ -3964,15 +3930,15 @@ export function superCallStmt(L, info, thisLocal, args, loc) {
3964
3930
  // super() with default options (underscore methods still bind; a
3965
3931
  // construction passing options requires a declared constructor —
3966
3932
  // lowerNew fences that). Zero options ⇒ exactly one init stmt.
3967
- return lowerStreamSuperCall(L, info, base, [], thisLocal, loc, info.decl ?? info.ctor)[0];
3933
+ return lowerStreamSuperCall(lowerer, info, base, [], thisLocal, loc, info.decl ?? info.ctor)[0];
3968
3934
  }
3969
- L.noteEdge(`%${base.def.name}.constructor`);
3935
+ lowerer.noteEdge(`%${base.def.name}.constructor`);
3970
3936
  return {
3971
3937
  kind: "exprStmt",
3972
3938
  expr: {
3973
3939
  kind: "call",
3974
3940
  callee: `%${base.def.name}.constructor`,
3975
- args: [L.upcastTo(thisRef, base.def.name), ...args],
3941
+ args: [lowerer.upcastTo(thisRef, base.def.name), ...args],
3976
3942
  type: VOID,
3977
3943
  loc,
3978
3944
  },
@@ -3982,37 +3948,37 @@ export function superCallStmt(L, info, thisLocal, args, loc) {
3982
3948
  /** `super.method(args)`: the base chain's implementation, called
3983
3949
  * DIRECTLY over this method's own `this` (upcast to the declarer) —
3984
3950
  * super dispatch is static in JS too, never through the dynamic class. */
3985
- export function lowerSuperMethodCall(L, call, access) {
3986
- const cls = L.currentClass;
3951
+ export function lowerSuperMethodCall(lowerer, call, access) {
3952
+ const cls = lowerer.currentClass;
3987
3953
  if (!cls?.base) {
3988
3954
  // tsc rejects super outside derived-class bodies first; defensive.
3989
- L.unsupported("SC1090", access, "'super' outside a derived class");
3955
+ lowerer.unsupported("SC1090", access, "'super' outside a derived class");
3990
3956
  }
3991
3957
  // An emit-override SPECIALIZATION body's forward — `super.emit(event,
3992
3958
  // ...args)` — carries no literal event name; the specialization's own
3993
3959
  // context answers it (matched before any lookup: neither identifier
3994
3960
  // resolves through the ordinary lowering).
3995
- const forward = emitSpecSuperForward(L, call, access);
3961
+ const forward = emitSpecSuperForward(lowerer, call, access);
3996
3962
  if (forward)
3997
3963
  return forward;
3998
- const found = L.findMethodOn(cls.base, access.name.text);
3964
+ const found = lowerer.findMethodOn(cls.base, access.name.text);
3999
3965
  if (!found) {
4000
3966
  // `super.m(...)` of a GENERIC method: super dispatch is static in JS
4001
3967
  // too, so the base chain's declaration answers unconditionally — the
4002
3968
  // ordinary instantiation route over this method's own `this`.
4003
- const gfound = findGenericMethodOn(L, cls.base, access.name.text);
3969
+ const gfound = findGenericMethodOn(lowerer, cls.base, access.name.text);
4004
3970
  if (gfound) {
4005
- const thisL = L.resolveThis();
3971
+ const thisL = lowerer.resolveThis();
4006
3972
  if (!thisL)
4007
- L.unsupported("SC1080", access);
4008
- const instance = genericCallInstance(L, call, gfound.info);
3973
+ lowerer.unsupported("SC1080", access);
3974
+ const instance = genericCallInstance(lowerer, call, gfound.info);
4009
3975
  const loc = locOf(call);
4010
3976
  const thisRef = { kind: "varRef", localId: thisL.id, type: thisL.type, loc };
4011
- const args = L.completeArgs(call.arguments, instance.params, loc, call);
3977
+ const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
4012
3978
  return {
4013
3979
  kind: "call",
4014
3980
  callee: instance.name,
4015
- args: [L.upcastTo(thisRef, gfound.declarer.def.name), ...args],
3981
+ args: [lowerer.upcastTo(thisRef, gfound.declarer.def.name), ...args],
4016
3982
  type: instance.returnType,
4017
3983
  loc,
4018
3984
  };
@@ -4023,43 +3989,43 @@ export function lowerSuperMethodCall(L, call, access) {
4023
3989
  // spoke lowers with this method's own `this` as the receiver (an
4024
3990
  // emit override at-or-below `cls` never answers; the nearest one
4025
3991
  // strictly above does).
4026
- if (EMITTER_API_MEMBERS.has(access.name.text) && emitterRooted(L, cls.base)) {
4027
- const viaEmitter = lowerEmitterSuperCall(L, call, access, cls);
3992
+ if (EMITTER_API_MEMBERS.has(access.name.text) && emitterRooted(lowerer, cls.base)) {
3993
+ const viaEmitter = lowerEmitterSuperCall(lowerer, call, access, cls);
4028
3994
  if (viaEmitter)
4029
3995
  return viaEmitter;
4030
3996
  }
4031
- L.unsupported("SC1090", access, `'super.${access.name.text}' (no base class declares it)`);
3997
+ lowerer.unsupported("SC1090", access, `'super.${access.name.text}' (no base class declares it)`);
4032
3998
  }
4033
3999
  // tsc rejects super-access of abstract members (TS2513); defensive —
4034
4000
  // no function exists behind an abstract declaration.
4035
4001
  if (found.sig.abstract === true) {
4036
- L.unsupported("SC1090", access, `'super.${access.name.text}' of an abstract method`);
4002
+ lowerer.unsupported("SC1090", access, `'super.${access.name.text}' of an abstract method`);
4037
4003
  }
4038
- const thisLocal = L.resolveThis();
4004
+ const thisLocal = lowerer.resolveThis();
4039
4005
  if (!thisLocal)
4040
- L.unsupported("SC1080", access);
4041
- L.noteEdge(`%${found.declarer.def.name}.${access.name.text}`);
4006
+ lowerer.unsupported("SC1080", access);
4007
+ lowerer.noteEdge(`%${found.declarer.def.name}.${access.name.text}`);
4042
4008
  const loc = locOf(call);
4043
4009
  const thisRef = { kind: "varRef", localId: thisLocal.id, type: thisLocal.type, loc };
4044
- const args = L.completeArgs(call.arguments, found.sig.params, loc, call);
4010
+ const args = lowerer.completeArgs(call.arguments, found.sig.params, loc, call);
4045
4011
  return {
4046
4012
  kind: "call",
4047
4013
  callee: `%${found.declarer.def.name}.${access.name.text}`,
4048
- args: [L.upcastTo(thisRef, found.declarer.def.name), ...args],
4014
+ args: [lowerer.upcastTo(thisRef, found.declarer.def.name), ...args],
4049
4015
  type: found.sig.ret,
4050
4016
  loc,
4051
4017
  };
4052
4018
  }
4053
4019
  /** The `this` reference for super accessor reads/writes, with the shared
4054
4020
  * validity checks (derived-class body, resolvable this). */
4055
- export function superThisRef(L, access) {
4056
- const cls = L.currentClass;
4021
+ export function superThisRef(lowerer, access) {
4022
+ const cls = lowerer.currentClass;
4057
4023
  if (!cls?.base) {
4058
- L.unsupported("SC1090", access, "'super' outside a derived class");
4024
+ lowerer.unsupported("SC1090", access, "'super' outside a derived class");
4059
4025
  }
4060
- const thisLocal = L.resolveThis();
4026
+ const thisLocal = lowerer.resolveThis();
4061
4027
  if (!thisLocal)
4062
- L.unsupported("SC1080", access);
4028
+ lowerer.unsupported("SC1080", access);
4063
4029
  const loc = locOf(access);
4064
4030
  return {
4065
4031
  thisRef: { kind: "varRef", localId: thisLocal.id, type: thisLocal.type, loc },
@@ -4069,49 +4035,49 @@ export function superThisRef(L, access) {
4069
4035
  /** `super.x` read: a DIRECT call of the base chain's getter over this
4070
4036
  * method's own `this` (upcast to the declarer) — like super.method(),
4071
4037
  * never through the vtable. */
4072
- export function lowerSuperAccessorRead(L, access) {
4073
- const { thisRef, base } = L.superThisRef(access);
4038
+ export function lowerSuperAccessorRead(lowerer, access) {
4039
+ const { thisRef, base } = lowerer.superThisRef(access);
4074
4040
  const name = access.name.text;
4075
- const found = L.findMethodOn(base, `get:${name}`);
4041
+ const found = lowerer.findMethodOn(base, `get:${name}`);
4076
4042
  if (!found) {
4077
- L.unsupported("SC1090", access, L.findMethodOn(base, name)
4043
+ lowerer.unsupported("SC1090", access, lowerer.findMethodOn(base, name)
4078
4044
  ? `bound method references through 'super' (call 'super.${name}(...)' directly)`
4079
4045
  : `'super.${name}' (only base-class methods and getter properties are readable through 'super')`);
4080
4046
  }
4081
4047
  // tsc rejects super-access of abstract members (TS2513); defensive.
4082
4048
  if (found.sig.abstract === true) {
4083
- L.unsupported("SC1090", access, `'super.${name}' of an abstract accessor`);
4049
+ lowerer.unsupported("SC1090", access, `'super.${name}' of an abstract accessor`);
4084
4050
  }
4085
- L.noteEdge(`%${found.declarer.def.name}.get:${name}`);
4051
+ lowerer.noteEdge(`%${found.declarer.def.name}.get:${name}`);
4086
4052
  return {
4087
4053
  kind: "call",
4088
4054
  callee: `%${found.declarer.def.name}.get:${name}`,
4089
- args: [L.upcastTo(thisRef, found.declarer.def.name)],
4055
+ args: [lowerer.upcastTo(thisRef, found.declarer.def.name)],
4090
4056
  type: found.sig.ret,
4091
4057
  loc: locOf(access),
4092
4058
  };
4093
4059
  }
4094
4060
  /** `super.x = v`: a DIRECT call of the base chain's setter (same
4095
4061
  * static-dispatch rule as every super member access). */
4096
- export function lowerSuperAccessorWrite(L, access, rhs, loc) {
4097
- const { thisRef, base } = L.superThisRef(access);
4062
+ export function lowerSuperAccessorWrite(lowerer, access, rhs, loc) {
4063
+ const { thisRef, base } = lowerer.superThisRef(access);
4098
4064
  const name = access.name.text;
4099
- const found = L.findMethodOn(base, `set:${name}`);
4065
+ const found = lowerer.findMethodOn(base, `set:${name}`);
4100
4066
  if (!found) {
4101
- L.unsupported("SC1090", access, `assignment to 'super.${name}' (no base class declares a setter for it)`);
4067
+ lowerer.unsupported("SC1090", access, `assignment to 'super.${name}' (no base class declares a setter for it)`);
4102
4068
  }
4103
4069
  // tsc rejects super-access of abstract members (TS2513); defensive.
4104
4070
  if (found.sig.abstract === true) {
4105
- L.unsupported("SC1090", access, `assignment to 'super.${name}' of an abstract accessor`);
4071
+ lowerer.unsupported("SC1090", access, `assignment to 'super.${name}' of an abstract accessor`);
4106
4072
  }
4107
- L.noteEdge(`%${found.declarer.def.name}.set:${name}`);
4108
- const value = L.lowerExprExpecting(rhs, found.sig.params[0].type);
4073
+ lowerer.noteEdge(`%${found.declarer.def.name}.set:${name}`);
4074
+ const value = lowerer.lowerExprExpecting(rhs, found.sig.params[0].type);
4109
4075
  return {
4110
4076
  kind: "exprStmt",
4111
4077
  expr: {
4112
4078
  kind: "call",
4113
4079
  callee: `%${found.declarer.def.name}.set:${name}`,
4114
- args: [L.upcastTo(thisRef, found.declarer.def.name), value],
4080
+ args: [lowerer.upcastTo(thisRef, found.declarer.def.name), value],
4115
4081
  type: VOID,
4116
4082
  loc,
4117
4083
  },
@@ -4122,7 +4088,7 @@ export function lowerSuperAccessorWrite(L, access, rhs, loc) {
4122
4088
  * inherited through ctor-less bases — is a builtin error class's. Such
4123
4089
  * classes construct with the error message rule, and their synthesized
4124
4090
  * constructors forward one plain string to error.ctor. */
4125
- export function inheritsBuiltinErrorCtor(L, info) {
4091
+ export function inheritsBuiltinErrorCtor(lowerer, info) {
4126
4092
  for (let c = info; c; c = c.base) {
4127
4093
  if (c.builtinError)
4128
4094
  return true;
@@ -4133,7 +4099,7 @@ export function inheritsBuiltinErrorCtor(L, info) {
4133
4099
  }
4134
4100
  /** The EventEmitter twin: a ctor-less chain into the emitter base
4135
4101
  * inherits `new C()` — zero arguments (the options bag fences). */
4136
- export function inheritsBuiltinEmitterCtor(L, info) {
4102
+ export function inheritsBuiltinEmitterCtor(lowerer, info) {
4137
4103
  for (let c = info; c; c = c.base) {
4138
4104
  if (c.builtinStream)
4139
4105
  return false; // the stream story owns the chain
@@ -4149,7 +4115,7 @@ export function inheritsBuiltinEmitterCtor(L, info) {
4149
4115
  * super() with default options; passing options through an inherited
4150
4116
  * constructor would need the literal at the new-site to plumb, so it
4151
4117
  * asks for a declared constructor instead). */
4152
- export function inheritsBuiltinStreamCtor(L, info) {
4118
+ function inheritsBuiltinStreamCtor(lowerer, info) {
4153
4119
  for (let c = info; c; c = c.base) {
4154
4120
  if (c.builtinStream)
4155
4121
  return true;
@@ -4164,19 +4130,19 @@ export function inheritsBuiltinStreamCtor(L, info) {
4164
4130
  * super() call: "" when omitted or explicitly undefined (Node's message
4165
4131
  * property default), the string otherwise. The lib signature's second
4166
4132
  * parameter (options/cause) has no lowering. */
4167
- export function errorMessageArg(L, args, loc, blame) {
4133
+ export function errorMessageArg(lowerer, args, loc, blame) {
4168
4134
  if (args.length > 1) {
4169
- L.unsupported("SC1090", args[1] ?? blame, "Error constructor options ('cause')");
4135
+ lowerer.unsupported("SC1090", args[1] ?? blame, "Error constructor options ('cause')");
4170
4136
  }
4171
4137
  if (args.length === 0)
4172
4138
  return { kind: "strLit", value: "", type: STRING, loc };
4173
- const value = L.lowerExpr(args[0]);
4139
+ const value = lowerer.lowerExpr(args[0]);
4174
4140
  if (value.type.kind === "string")
4175
4141
  return value;
4176
4142
  if (value.kind === "unitLit" && value.unit === "undefined") {
4177
4143
  return { kind: "strLit", value: "", type: STRING, loc };
4178
4144
  }
4179
- L.unsupported("SC1090", args[0], `Error messages of type '${L.fmt(value.type)}' (the message must be a string)`);
4145
+ lowerer.unsupported("SC1090", args[0], `Error messages of type '${lowerer.fmt(value.type)}' (the message must be a string)`);
4180
4146
  }
4181
4147
  /** `new C(...)` of a registered PROGRAM class — the shared tail of the
4182
4148
  * identifier and namespace-qualified construction forms. */
@@ -4184,48 +4150,48 @@ export function errorMessageArg(L, args, loc, blame) {
4184
4150
  * class resolves to the INSTANTIATION the expression's checker type names
4185
4151
  * (inference and explicit type arguments both land there; defaults apply).
4186
4152
  * The identity function for ordinary classes. */
4187
- function genericNewTarget(L, expr, info) {
4153
+ function genericNewTarget(lowerer, expr, info) {
4188
4154
  if (!info.generic)
4189
4155
  return info;
4190
- const t = L.typeOf(expr);
4191
- const mapped = L.mapTypeOf(t);
4192
- const instInfo = mapped?.kind === "object" ? L.classes.get(mapped.className) : undefined;
4156
+ const t = lowerer.typeOf(expr);
4157
+ const mapped = lowerer.mapTypeOf(t);
4158
+ const instInfo = mapped?.kind === "object" ? lowerer.classes.get(mapped.className) : undefined;
4193
4159
  // Unmappable type arguments (or a poisoned instantiation): the site
4194
4160
  // reports the type it cannot compile — the instantiation's own
4195
4161
  // diagnostic (context-tagged) already told the deeper story.
4196
4162
  if (!instInfo || instInfo.generic)
4197
- L.badType(expr, t);
4163
+ lowerer.badType(expr, t);
4198
4164
  return instInfo;
4199
4165
  }
4200
4166
  /** A class whose decoration provably throws has no reachable VALUE form:
4201
4167
  * the binding never initializes (the %init ReferenceError unwinds first),
4202
4168
  * so `new`, the class as a value, and `extends` all fence — reaching one
4203
4169
  * in compiled code would require executing past the throw. */
4204
- export function fenceDecorationThrows(L, info, blame) {
4170
+ function fenceDecorationThrows(lowerer, info, blame) {
4205
4171
  if (info.decorationThrows === undefined)
4206
4172
  return;
4207
- L.unsupported("SC1090", blame, `using the class '${info.def.jsName || info.def.name}' whose decoration provably throws ('${info.decorationThrows.name}' is an ambient name nothing defines — the class statement crashes before the binding exists)`);
4173
+ lowerer.unsupported("SC1090", blame, `using the class '${info.def.jsName || info.def.name}' whose decoration provably throws ('${info.decorationThrows.name}' is an ambient name nothing defines — the class statement crashes before the binding exists)`);
4208
4174
  }
4209
- function lowerProgramClassNew(L, expr, info0, loc) {
4210
- const info = genericNewTarget(L, expr, info0);
4211
- fenceDecorationThrows(L, info, expr);
4212
- L.noteEdge(`%${info.def.name}.constructor`);
4175
+ function lowerProgramClassNew(lowerer, expr, declaredInfo, loc) {
4176
+ const info = genericNewTarget(lowerer, expr, declaredInfo);
4177
+ fenceDecorationThrows(lowerer, info, expr);
4178
+ lowerer.noteEdge(`%${info.def.name}.constructor`);
4213
4179
  // A ctor-less chain into an EventEmitter base inherits `new C()` —
4214
4180
  // zero arguments (the options bag fences, like the super() form).
4215
4181
  // Stream subclasses come first: their chain roots at the emitter
4216
4182
  // too, but the message should name the stream story.
4217
- if (inheritsBuiltinStreamCtor(L, info) && (expr.arguments ?? []).length > 0) {
4218
- L.noLowering(`new ${info.def.name.replace(/^%/, "")} with arguments through an inherited stream constructor`, expr.arguments[0], "declare a constructor that passes an inline options object to super(...)");
4183
+ if (inheritsBuiltinStreamCtor(lowerer, info) && (expr.arguments ?? []).length > 0) {
4184
+ lowerer.noLowering(`new ${info.def.name.replace(/^%/, "")} with arguments through an inherited stream constructor`, expr.arguments[0], "declare a constructor that passes an inline options object to super(...)");
4219
4185
  }
4220
- if (L.inheritsBuiltinEmitterCtor(info) && (expr.arguments ?? []).length > 0) {
4221
- L.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
4186
+ if (lowerer.inheritsBuiltinEmitterCtor(info) && (expr.arguments ?? []).length > 0) {
4187
+ lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
4222
4188
  }
4223
4189
  // A ctor-less chain into a builtin error base inherits `new
4224
4190
  // C(message?)` — completed by the error rule (one plain string),
4225
4191
  // not the general ABI completion.
4226
- const args = L.inheritsBuiltinErrorCtor(info)
4227
- ? [L.errorMessageArg(expr.arguments ?? [], loc, expr)]
4228
- : L.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
4192
+ const args = lowerer.inheritsBuiltinErrorCtor(info)
4193
+ ? [lowerer.errorMessageArg(expr.arguments ?? [], loc, expr)]
4194
+ : lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
4229
4195
  return {
4230
4196
  kind: "new",
4231
4197
  className: info.def.name,
@@ -4234,18 +4200,18 @@ function lowerProgramClassNew(L, expr, info0, loc) {
4234
4200
  loc,
4235
4201
  };
4236
4202
  }
4237
- export function lowerNew(L, expr) {
4203
+ export function lowerNew(lowerer, expr) {
4238
4204
  const loc = locOf(expr);
4239
4205
  // `new X(...)` where X is a package-declared class, in a static build:
4240
4206
  // the per-package requires-dynamic diagnostic (the constructor runs in
4241
4207
  // the embedded engine). Under --dynamic, X is jsval-typed and lowers
4242
4208
  // to the construct op below.
4243
- if (!L.dynamic) {
4209
+ if (!lowerer.dynamic) {
4244
4210
  const pkg = ts.isIdentifier(expr.expression)
4245
- ? L.npmPackageOfSymbol(L.resolveValueSymbol(expr.expression) ?? undefined)
4211
+ ? lowerer.npmPackageOfSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)
4246
4212
  : null;
4247
4213
  if (pkg) {
4248
- L.pushDiag(requiresDynamicPackageDiag(pkg, loc));
4214
+ lowerer.pushDiag(requiresDynamicPackageDiag(pkg, loc));
4249
4215
  throw new PoisonError();
4250
4216
  }
4251
4217
  }
@@ -4253,23 +4219,23 @@ export function lowerNew(L, expr) {
4253
4219
  // or any 'any'-typed constructor value) runs JS_CallConstructor —
4254
4220
  // `new Command()` is the npm entry point. Arguments marshal in; the
4255
4221
  // instance stays an island handle.
4256
- if (L.isIslandExpr(expr.expression)) {
4257
- const callee = L.lowerExpr(expr.expression);
4258
- const args = (expr.arguments ?? []).map((a) => L.jsvalIn(L.lowerExpr(a), a));
4222
+ if (lowerer.isIslandExpr(expr.expression)) {
4223
+ const callee = lowerer.lowerExpr(expr.expression);
4224
+ const args = (expr.arguments ?? []).map((a) => lowerer.jsvalIn(lowerer.lowerExpr(a), a));
4259
4225
  return { kind: "jsOp", op: "construct", args: [callee, ...args], type: JSVAL, loc };
4260
4226
  }
4261
4227
  // `new events.EventEmitter()` — the namespace-member (and CJS
4262
4228
  // `require('events').EventEmitter`) construction form: the property's
4263
4229
  // symbol resolves to the same ambient class as the named import.
4264
4230
  if (ts.isPropertyAccessExpression(expr.expression) && ts.isIdentifier(expr.expression.name)) {
4265
- const memberSym = L.checker.getSymbolAtLocation(expr.expression.name);
4231
+ const memberSym = lowerer.checker.getSymbolAtLocation(expr.expression.name);
4266
4232
  const resolved = memberSym && memberSym.flags & ts.SymbolFlags.Alias
4267
- ? L.checker.getAliasedSymbol(memberSym)
4233
+ ? lowerer.checker.getAliasedSymbol(memberSym)
4268
4234
  : memberSym;
4269
- const emitterInfo = L.builtinEmitterInfoOf(resolved);
4235
+ const emitterInfo = lowerer.builtinEmitterInfoOf(resolved);
4270
4236
  if (emitterInfo) {
4271
4237
  if ((expr.arguments ?? []).length > 0) {
4272
- L.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
4238
+ lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
4273
4239
  }
4274
4240
  return {
4275
4241
  kind: "libCall",
@@ -4281,41 +4247,41 @@ export function lowerNew(L, expr) {
4281
4247
  }
4282
4248
  // `new stream.Readable({...})` — the namespace-member (and CJS
4283
4249
  // `require('stream').Readable`) construction form.
4284
- const streamInfoNs = builtinStreamInfoOf(L, resolved);
4250
+ const streamInfoNs = builtinStreamInfoOf(lowerer, resolved);
4285
4251
  if (streamInfoNs)
4286
- return lowerStreamNew(L, expr, streamInfoNs);
4252
+ return lowerStreamNew(lowerer, expr, streamInfoNs);
4287
4253
  // `new N.C(...)` / `new a.Point(...)` — construction through a
4288
4254
  // USER namespace qualifier (import= alias chains included): the
4289
4255
  // member resolves to the registered program class, guarded by the
4290
4256
  // namespace source-order fences (lower-namespaces.ts).
4291
- if (!expr.expression.questionDotToken && nsMemberIdentOf(L, expr.expression)) {
4257
+ if (!expr.expression.questionDotToken && nsMemberIdentOf(lowerer, expr.expression)) {
4292
4258
  if (memberSym)
4293
- fenceEarlyNsMemberRef(L, expr.expression, memberSym);
4259
+ fenceEarlyNsMemberRef(lowerer, expr.expression, memberSym);
4294
4260
  // resolveValueSymbol (not the bare alias chase): the reference
4295
4261
  // must flush deferred collection diagnostics like any other.
4296
- const classSym = L.resolveValueSymbol(expr.expression.name);
4297
- const info = classSym ? L.classBySymbol.get(classSym) : undefined;
4262
+ const classSym = lowerer.resolveValueSymbol(expr.expression.name);
4263
+ const info = classSym ? lowerer.classBySymbol.get(classSym) : undefined;
4298
4264
  // Qualified spellings of a rebindable decorated class (an import=
4299
4265
  // alias chain landing on it) cannot construct the declaration
4300
4266
  // directly — the decoration result decides. The bare-name path
4301
4267
  // routes through the class VALUE; the qualified one fences.
4302
4268
  if (info?.classDecorators?.valueGlobalId !== undefined) {
4303
- L.unsupported("SC1090", expr, "constructing a decorated class through a qualified name (a replacing decorator rebinds the class name — construct through the bare name)");
4269
+ lowerer.unsupported("SC1090", expr, "constructing a decorated class through a qualified name (a replacing decorator rebinds the class name — construct through the bare name)");
4304
4270
  }
4305
4271
  if (info)
4306
- return lowerProgramClassNew(L, expr, info, loc);
4307
- L.unsupported("SC1090", expr, `constructing '${expr.expression.name.text}' (a namespace member with no class lowering)`);
4272
+ return lowerProgramClassNew(lowerer, expr, info, loc);
4273
+ lowerer.unsupported("SC1090", expr, `constructing '${expr.expression.name.text}' (a namespace member with no class lowering)`);
4308
4274
  }
4309
4275
  // `new B.C()` where B is an AMBIENT namespace (fundule merges
4310
4276
  // included): Node evaluates the callee first and throws
4311
4277
  // ReferenceError before any argument runs — undefRead reproduces it
4312
4278
  // exactly.
4313
4279
  if (!expr.expression.questionDotToken) {
4314
- const ambientRoot = ambientNsRootOf(L, expr.expression.expression);
4280
+ const ambientRoot = ambientNsRootOf(lowerer, expr.expression.expression);
4315
4281
  if (ambientRoot !== null) {
4316
- const t = ambientUndefReadType(L, expr);
4282
+ const t = ambientUndefReadType(lowerer, expr);
4317
4283
  if (t)
4318
- return nsUndefRead(L, ambientRoot.text, expr, t);
4284
+ return nsUndefRead(lowerer, ambientRoot.text, expr, t);
4319
4285
  }
4320
4286
  }
4321
4287
  // Construction through a CJS export member tsgo types `any`
@@ -4331,9 +4297,9 @@ export function lowerNew(L, expr) {
4331
4297
  (isModuleExportsAccess(expr.expression.expression) ||
4332
4298
  (ts.isIdentifier(expr.expression.expression) &&
4333
4299
  expr.expression.expression.text === "exports" &&
4334
- !L.peekLocal(expr.expression.expression) &&
4335
- !L.globalOf(expr.expression.expression)))) ||
4336
- L.cjsLocalModuleBindingOf(expr.expression.expression))) {
4300
+ !lowerer.peekLocal(expr.expression.expression) &&
4301
+ !lowerer.globalOf(expr.expression.expression)))) ||
4302
+ lowerer.cjsLocalModuleBindingOf(expr.expression.expression))) {
4337
4303
  // Candidate symbols for the export global: the member symbol as
4338
4304
  // spelled, its alias-chased resolution (resolveValueSymbol carries
4339
4305
  // the dep-module fallback tsgo needs at member-use sites), and the
@@ -4341,28 +4307,28 @@ export function lowerNew(L, expr) {
4341
4307
  const candidates = [
4342
4308
  memberSym,
4343
4309
  resolved,
4344
- L.resolveValueSymbol(expr.expression.name) ?? undefined,
4345
- L.cjsModuleExportSymbol(expr.getSourceFile(), expr.expression.name.text),
4310
+ lowerer.resolveValueSymbol(expr.expression.name) ?? undefined,
4311
+ lowerer.cjsModuleExportSymbol(expr.getSourceFile(), expr.expression.name.text),
4346
4312
  ];
4347
4313
  const exportSym = candidates.find((s) => s !== undefined);
4348
4314
  const g = candidates
4349
- .map((s) => (s ? L.globalsBySymbol.get(s) : undefined))
4315
+ .map((s) => (s ? lowerer.globalsBySymbol.get(s) : undefined))
4350
4316
  .find((x) => x !== undefined);
4351
4317
  if (g && g.type.kind === "classval") {
4352
- const info = L.classes.get(g.type.className) ??
4353
- propertyAssignedClassInfoOf(L, exportSym) ??
4354
- L.classes.get(g.type.className);
4318
+ const info = lowerer.classes.get(g.type.className) ??
4319
+ propertyAssignedClassInfoOf(lowerer, exportSym) ??
4320
+ lowerer.classes.get(g.type.className);
4355
4321
  if (info && !info.generic) {
4356
- L.noteEdge(`%${info.def.name}.constructor`);
4322
+ lowerer.noteEdge(`%${info.def.name}.constructor`);
4357
4323
  const below = (c) => {
4358
4324
  for (const s of c.subclasses) {
4359
- L.noteEdge(`%${s.def.name}.constructor`);
4325
+ lowerer.noteEdge(`%${s.def.name}.constructor`);
4360
4326
  below(s);
4361
4327
  }
4362
4328
  };
4363
4329
  below(info);
4364
4330
  const callee = { kind: "varRef", localId: g.id, type: g.type, loc };
4365
- const args = L.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
4331
+ const args = lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
4366
4332
  return {
4367
4333
  kind: "newValue",
4368
4334
  callee,
@@ -4378,7 +4344,7 @@ export function lowerNew(L, expr) {
4378
4344
  // of http.createServer (Node's Server class IS the factory's
4379
4345
  // product); routed to lower-server ahead of the stdlib-ctor fences.
4380
4346
  {
4381
- const httpServer = lowerHttpServerNew(L, expr);
4347
+ const httpServer = lowerHttpServerNew(lowerer, expr);
4382
4348
  if (httpServer)
4383
4349
  return httpServer;
4384
4350
  }
@@ -4386,20 +4352,20 @@ export function lowerNew(L, expr) {
4386
4352
  // handle (lower-server): getName/destroy/counters through the dyn
4387
4353
  // handle ops, requests thread it via the agent option.
4388
4354
  {
4389
- const agent = lowerHttpAgentNew(L, expr);
4355
+ const agent = lowerHttpAgentNew(lowerer, expr);
4390
4356
  if (agent)
4391
4357
  return agent;
4392
4358
  }
4393
4359
  if (ts.isIdentifier(expr.expression)) {
4394
4360
  // `import C = N.C; new C()` — the alias's own source-order guards
4395
4361
  // (a no-op for every non-import= binding).
4396
- fenceEarlyAliasUse(L, expr.expression, expr);
4397
- const symbol = L.resolveValueSymbol(expr.expression);
4362
+ fenceEarlyAliasUse(lowerer, expr.expression, expr);
4363
+ const symbol = lowerer.resolveValueSymbol(expr.expression);
4398
4364
  // `new Error(msg?)` (and TypeError/RangeError/SyntaxError): the
4399
4365
  // runtime-provided classes construct through one libCall — the result
4400
4366
  // TYPE names which builtin, and the message completes to "" exactly
4401
4367
  // like Node's message property default.
4402
- const errInfo = L.builtinErrorInfoOf(symbol);
4368
+ const errInfo = lowerer.builtinErrorInfoOf(symbol);
4403
4369
  // `new DOMException(message?, nameOrOptions?)`: both arguments cross
4404
4370
  // as dyn values (absent → the dyn undefined), and the runtime owns
4405
4371
  // WebIDL's resolution — ToString of the message ("" for undefined),
@@ -4409,18 +4375,18 @@ export function lowerNew(L, expr) {
4409
4375
  if (errInfo && errInfo.def.name === "%DOMException") {
4410
4376
  const args = expr.arguments ?? [];
4411
4377
  if (args.length > 2) {
4412
- L.noLowering(`new DOMException with ${args.length} arguments`, expr);
4378
+ lowerer.noLowering(`new DOMException with ${args.length} arguments`, expr);
4413
4379
  }
4414
4380
  const toDynArg = (a) => {
4415
4381
  if (!a)
4416
4382
  return dynUndefinedExpr(loc);
4417
- const v = L.lowerExpr(a);
4383
+ const v = lowerer.lowerExpr(a);
4418
4384
  if (v.type.kind === "dyn")
4419
4385
  return v;
4420
- if (v.kind === "unitLit" || (v.type.kind !== "jsval" && L.dynConvertible(v.type))) {
4386
+ if (v.kind === "unitLit" || (v.type.kind !== "jsval" && lowerer.dynConvertible(v.type))) {
4421
4387
  return { kind: "dynFrom", value: v, type: DYN, loc };
4422
4388
  }
4423
- L.noLowering(`new DOMException with a '${L.fmt(v.type)}' argument`, a, "message strings and string/options-object names lower (Node ToStrings other values — convert explicitly)");
4389
+ lowerer.noLowering(`new DOMException with a '${lowerer.fmt(v.type)}' argument`, a, "message strings and string/options-object names lower (Node ToStrings other values — convert explicitly)");
4424
4390
  };
4425
4391
  const msgArg = toDynArg(args[0]);
4426
4392
  const nameArg = toDynArg(args[1]);
@@ -4433,7 +4399,7 @@ export function lowerNew(L, expr) {
4433
4399
  };
4434
4400
  }
4435
4401
  if (errInfo) {
4436
- const msg = L.errorMessageArg(expr.arguments ?? [], loc, expr);
4402
+ const msg = lowerer.errorMessageArg(expr.arguments ?? [], loc, expr);
4437
4403
  return {
4438
4404
  kind: "libCall",
4439
4405
  fn: "error.new",
@@ -4445,10 +4411,10 @@ export function lowerNew(L, expr) {
4445
4411
  // `new EventEmitter()`: the runtime-provided emitter constructs
4446
4412
  // through one libCall. Zero arguments — the options bag
4447
4413
  // (@types/node's captureRejections) has no lowering.
4448
- const emitterInfo = L.builtinEmitterInfoOf(symbol);
4414
+ const emitterInfo = lowerer.builtinEmitterInfoOf(symbol);
4449
4415
  if (emitterInfo) {
4450
4416
  if ((expr.arguments ?? []).length > 0) {
4451
- L.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
4417
+ lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
4452
4418
  }
4453
4419
  return {
4454
4420
  kind: "libCall",
@@ -4460,9 +4426,9 @@ export function lowerNew(L, expr) {
4460
4426
  }
4461
4427
  // `new Readable({...})` and the other stream classes: the options
4462
4428
  // object parses structurally in the stream spoke.
4463
- const streamInfo = builtinStreamInfoOf(L, symbol);
4429
+ const streamInfo = builtinStreamInfoOf(lowerer, symbol);
4464
4430
  if (streamInfo)
4465
- return lowerStreamNew(L, expr, streamInfo);
4431
+ return lowerStreamNew(lowerer, expr, streamInfo);
4466
4432
  // `new URL(input)`: the WHATWG URL class (stdlib/@types provenance —
4467
4433
  // a user's own `class URL` resolves through classBySymbol below).
4468
4434
  // One string argument; invalid input throws a catchable TypeError
@@ -4473,17 +4439,17 @@ export function lowerNew(L, expr) {
4473
4439
  // so bad input throws Node's catchable SyntaxError at construction.
4474
4440
  // String arguments only (Node also accepts a RegExp to copy — that
4475
4441
  // form keeps the fence).
4476
- if (symbol && symbol.name === "RegExp" && L.isStdlibSymbol(symbol)) {
4442
+ if (symbol && symbol.name === "RegExp" && lowerer.isStdlibSymbol(symbol)) {
4477
4443
  const args = expr.arguments ?? [];
4478
4444
  if (args.length > 2) {
4479
- L.noLowering(`new RegExp with ${args.length} arguments`, expr);
4445
+ lowerer.noLowering(`new RegExp with ${args.length} arguments`, expr);
4480
4446
  }
4481
4447
  const strArg = (a, what) => {
4482
4448
  if (!a)
4483
4449
  return { kind: "strLit", value: "", type: STRING, loc };
4484
- const v = L.lowerExpr(a);
4450
+ const v = lowerer.lowerExpr(a);
4485
4451
  if (v.type.kind !== "string") {
4486
- L.noLowering(`new RegExp with a '${L.fmt(v.type)}' ${what}`, a, "string arguments are the lowered form (a RegExp copy or ToString coercion has no lowering)");
4452
+ lowerer.noLowering(`new RegExp with a '${lowerer.fmt(v.type)}' ${what}`, a, "string arguments are the lowered form (a RegExp copy or ToString coercion has no lowering)");
4487
4453
  }
4488
4454
  return v;
4489
4455
  };
@@ -4491,32 +4457,32 @@ export function lowerNew(L, expr) {
4491
4457
  const flags = strArg(args[1], "flags argument");
4492
4458
  return { kind: "libCall", fn: "regex.new", args: [pattern, flags], type: { kind: "regex" }, loc };
4493
4459
  }
4494
- if (symbol && symbol.name === "URL" && L.isStdlibSymbol(symbol)) {
4460
+ if (symbol && symbol.name === "URL" && lowerer.isStdlibSymbol(symbol)) {
4495
4461
  const args = expr.arguments ?? [];
4496
4462
  if (args.length !== 1) {
4497
- L.noLowering(`new URL with ${args.length} argument${args.length === 1 ? "" : "s"}`, expr, "one absolute-URL string is the supported form (resolve relative inputs against a base yourself)", symbol);
4463
+ lowerer.noLowering(`new URL with ${args.length} argument${args.length === 1 ? "" : "s"}`, expr, "one absolute-URL string is the supported form (resolve relative inputs against a base yourself)", symbol);
4498
4464
  }
4499
- const input = L.lowerExprExpecting(args[0], STRING);
4465
+ const input = lowerer.lowerExprExpecting(args[0], STRING);
4500
4466
  return { kind: "libCall", fn: "url.new", args: [input], type: URL_T, loc };
4501
4467
  }
4502
4468
  // `new URLSearchParams(init?)`: the WHATWG list (stdlib provenance —
4503
4469
  // see lowerSearchParamsNew for the lowered init shapes).
4504
- if (symbol && symbol.name === "URLSearchParams" && L.isStdlibSymbol(symbol)) {
4505
- return lowerSearchParamsNew(L, expr, loc);
4470
+ if (symbol && symbol.name === "URLSearchParams" && lowerer.isStdlibSymbol(symbol)) {
4471
+ return lowerSearchParamsNew(lowerer, expr, loc);
4506
4472
  }
4507
4473
  // Date's read-only value slice: store the constructor's TimeClip'd
4508
4474
  // epoch milliseconds as the scalar date kind. That is sufficient
4509
4475
  // for every getter and toISOString; identity and setters stay
4510
4476
  // fenced, so copying the scalar cannot create an observable lie.
4511
- if (symbol && symbol.name === "Date" && L.isStdlibSymbol(symbol)) {
4477
+ if (symbol && symbol.name === "Date" && lowerer.isStdlibSymbol(symbol)) {
4512
4478
  const args = expr.arguments ?? [];
4513
4479
  if (args.some(ts.isSpreadElement) || args.length > 1) {
4514
- L.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);
4480
+ 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);
4515
4481
  }
4516
4482
  if (args.length === 0) {
4517
4483
  return { kind: "libCall", fn: "date.newNow", args: [], type: DATE_T, loc };
4518
4484
  }
4519
- const arg = L.lowerExpr(args[0]);
4485
+ const arg = lowerer.lowerExpr(args[0]);
4520
4486
  if (arg.type.kind === "f64") {
4521
4487
  return { kind: "libCall", fn: "date.newMs", args: [arg], type: DATE_T, loc };
4522
4488
  }
@@ -4526,7 +4492,7 @@ export function lowerNew(L, expr) {
4526
4492
  if (arg.type.kind === "date") {
4527
4493
  return arg;
4528
4494
  }
4529
- L.noLowering(`new Date of '${L.fmt(arg.type)}' values`, args[0], "pass milliseconds, a date string, or another Date value", symbol);
4495
+ lowerer.noLowering(`new Date of '${lowerer.fmt(arg.type)}' values`, args[0], "pass milliseconds, a date string, or another Date value", symbol);
4530
4496
  }
4531
4497
  // `new StringDecoder(encoding?)` (node:string_decoder): the decoder
4532
4498
  // is a two-field record — the CANONICAL encoding name (aliases fold
@@ -4534,15 +4500,15 @@ export function lowerNew(L, expr) {
4534
4500
  // the packed-f64 pending state starting at 0 (nothing buffered).
4535
4501
  // The encoding must be a literal (Node's alias set); omitted means
4536
4502
  // utf8, Node's default.
4537
- if (symbol && symbol.name === "StringDecoder" && L.isStdlibSymbol(symbol)) {
4503
+ if (symbol && symbol.name === "StringDecoder" && lowerer.isStdlibSymbol(symbol)) {
4538
4504
  const args = expr.arguments ?? [];
4539
4505
  if (args.length > 1) {
4540
- L.noLowering("new StringDecoder with 2 arguments", expr, undefined, symbol);
4506
+ lowerer.noLowering("new StringDecoder with 2 arguments", expr, undefined, symbol);
4541
4507
  }
4542
- const encName = args.length === 1 ? bufEncoding(L, "new StringDecoder", args[0]) : "utf8";
4543
- const decT = L.mapTypeOf(L.typeOf(expr));
4508
+ const encName = args.length === 1 ? bufEncoding(lowerer, "new StringDecoder", args[0]) : "utf8";
4509
+ const decT = lowerer.mapTypeOf(lowerer.typeOf(expr));
4544
4510
  if (decT?.kind !== "record")
4545
- L.badType(expr, L.typeOf(expr));
4511
+ lowerer.badType(expr, lowerer.typeOf(expr));
4546
4512
  return {
4547
4513
  kind: "recordLit",
4548
4514
  fields: [
@@ -4556,8 +4522,8 @@ export function lowerNew(L, expr) {
4556
4522
  // Encoder objects likewise never exist: lowerTextCodecCall claims
4557
4523
  // composed calls before the receiver lowers, while the same-scope
4558
4524
  // const store-then-call declaration is erased before reaching here.
4559
- if (symbol && (symbol.name === "TextDecoder" || symbol.name === "TextEncoder") && L.isStdlibSymbol(symbol)) {
4560
- L.noLowering(`new ${symbol.name}`, expr, `${symbol.name} values have no representation — a same-scope const store-then-call or the composed form compiles: ` +
4525
+ if (symbol && (symbol.name === "TextDecoder" || symbol.name === "TextEncoder") && lowerer.isStdlibSymbol(symbol)) {
4526
+ lowerer.noLowering(`new ${symbol.name}`, expr, `${symbol.name} values have no representation — a same-scope const store-then-call or the composed form compiles: ` +
4561
4527
  (symbol.name === "TextDecoder"
4562
4528
  ? "new TextDecoder().decode(bytes)"
4563
4529
  : "new TextEncoder().encode(s)"), symbol);
@@ -4567,20 +4533,20 @@ export function lowerNew(L, expr) {
4567
4533
  // representation (stdlib provenance — see lowerBytesNew for the
4568
4534
  // lowered argument shapes; a user's own class with one of the names
4569
4535
  // resolves through classBySymbol below).
4570
- const bytesNew = L.lowerBytesNew(expr, symbol);
4536
+ const bytesNew = lowerer.lowerBytesNew(expr, symbol);
4571
4537
  if (bytesNew)
4572
4538
  return bytesNew;
4573
- const info = (symbol ? L.classBySymbol.get(symbol) : undefined) ??
4539
+ const info = (symbol ? lowerer.classBySymbol.get(symbol) : undefined) ??
4574
4540
  // `const C = require('./x'); new C()` over `module.exports =
4575
4541
  // class {…}`: the binding aliases the expression's own symbol —
4576
4542
  // the declaration story, collected on demand.
4577
- propertyAssignedClassInfoOf(L, symbol) ??
4543
+ propertyAssignedClassInfoOf(lowerer, symbol) ??
4578
4544
  undefined;
4579
4545
  // A rebindable decorated name constructs through its VALUE (the
4580
4546
  // classval-typed path below — newValue through the decoration
4581
4547
  // result's construct thunk), never the declaration directly.
4582
4548
  if (info && info.classDecorators?.valueGlobalId === undefined) {
4583
- return lowerProgramClassNew(L, expr, info, loc);
4549
+ return lowerProgramClassNew(lowerer, expr, info, loc);
4584
4550
  }
4585
4551
  // `new Map<K, V>()`: the lib Map constructor. The SEEDED forms: an
4586
4552
  // entries ARRAY LITERAL of PAIR LITERALS at the construction site
@@ -4605,46 +4571,46 @@ export function lowerNew(L, expr) {
4605
4571
  // returns its argument for objects and BOXES primitives — the wrapper
4606
4572
  // story with no lowering — so it keeps the constructor fence.
4607
4573
  if (symbol?.name === "Object" &&
4608
- L.isStdlibSymbol(symbol) &&
4574
+ lowerer.isStdlibSymbol(symbol) &&
4609
4575
  (expr.arguments ?? []).length === 0) {
4610
4576
  return {
4611
4577
  kind: "recordLit",
4612
4578
  fields: [],
4613
- type: { kind: "record", shapeId: L.shapes.intern([]) },
4579
+ type: { kind: "record", shapeId: lowerer.shapes.intern([]) },
4614
4580
  loc,
4615
4581
  };
4616
4582
  }
4617
- if (symbol?.name === "Array" && L.isStdlibSymbol(symbol)) {
4583
+ if (symbol?.name === "Array" && lowerer.isStdlibSymbol(symbol)) {
4618
4584
  const args = expr.arguments ?? [];
4619
4585
  if (args.some(ts.isSpreadElement)) {
4620
- L.noLowering("new Array with spread arguments", expr, "write the array literal: [...xs]");
4586
+ lowerer.noLowering("new Array with spread arguments", expr, "write the array literal: [...xs]");
4621
4587
  }
4622
- if (args.length === 1 && L.mapTypeOf(L.typeOf(args[0]))?.kind === "f64") {
4623
- L.noLowering("new Array(count)", expr, "the one-number form allocates HOLES (reads answer undefined, which the element type cannot carry) — build and push, or use the elements form: new Array(a, b)");
4588
+ if (args.length === 1 && lowerer.mapTypeOf(lowerer.typeOf(args[0]))?.kind === "f64") {
4589
+ lowerer.noLowering("new Array(count)", expr, "the one-number form allocates HOLES (reads answer undefined, which the element type cannot carry) — build and push, or use the elements form: new Array(a, b)");
4624
4590
  }
4625
- let t = L.mapTypeOf(L.typeOf(expr));
4591
+ let t = lowerer.mapTypeOf(lowerer.typeOf(expr));
4626
4592
  // JS's `new Array()` types any[]; the contextual type carries the
4627
4593
  // annotation when one exists (the new Map() stance).
4628
4594
  if (t?.kind !== "array") {
4629
- const ctx = L.checker.getContextualType(expr);
4630
- const ctxMapped = ctx ? L.mapTypeOf(ctx) : null;
4595
+ const ctx = lowerer.checker.getContextualType(expr);
4596
+ const ctxMapped = ctx ? lowerer.mapTypeOf(ctx) : null;
4631
4597
  if (ctxMapped?.kind === "array")
4632
4598
  t = ctxMapped;
4633
4599
  }
4634
4600
  if (t?.kind !== "array")
4635
- L.badType(expr, L.typeOf(expr));
4636
- const elems = args.map((a) => L.lowerExprExpecting(a, t.elem));
4601
+ lowerer.badType(expr, lowerer.typeOf(expr));
4602
+ const elems = args.map((a) => lowerer.lowerExprExpecting(a, t.elem));
4637
4603
  return { kind: "arrayLit", elems, type: t, loc };
4638
4604
  }
4639
- if (symbol?.name === "Map" && L.isStdlibSymbol(symbol)) {
4605
+ if (symbol?.name === "Map" && lowerer.isStdlibSymbol(symbol)) {
4640
4606
  const seedArg = (expr.arguments?.length ?? 0) === 1 ? expr.arguments[0] : null;
4641
4607
  const isPairLit = (el) => ts.isArrayLiteralExpression(el) && el.elements.length === 2 &&
4642
4608
  !el.elements.some(ts.isSpreadElement);
4643
4609
  const entriesLit = seedArg && ts.isArrayLiteralExpression(seedArg) && seedArg.elements.every(isPairLit)
4644
4610
  ? seedArg.elements.filter(isPairLit)
4645
4611
  : null;
4646
- let tsType = L.typeOf(expr);
4647
- let mapped = L.mapTypeOf(tsType);
4612
+ let tsType = lowerer.typeOf(expr);
4613
+ let mapped = lowerer.mapTypeOf(tsType);
4648
4614
  // JavaScript's `new Map()` has no type-argument syntax: the no-arg
4649
4615
  // constructor overload pins Map<any, any> whatever the JSDoc says
4650
4616
  // (`@type` on the declaration types the VARIABLE, not this
@@ -4652,20 +4618,20 @@ export function lowerNew(L, expr) {
4652
4618
  // it when it is a supported map. TS type arguments keep winning:
4653
4619
  // their expression type already maps.
4654
4620
  if (mapped?.kind !== "map") {
4655
- const ctx = L.checker.getContextualType(expr);
4656
- const ctxMapped = ctx ? L.mapTypeOf(ctx) : null;
4621
+ const ctx = lowerer.checker.getContextualType(expr);
4622
+ const ctxMapped = ctx ? lowerer.mapTypeOf(ctx) : null;
4657
4623
  if (ctx && ctxMapped?.kind === "map") {
4658
4624
  tsType = ctx;
4659
4625
  mapped = ctxMapped;
4660
4626
  }
4661
4627
  }
4662
4628
  if (seedArg && !entriesLit && mapped?.kind === "map") {
4663
- const seeded = lowerMapSeedArrayNew(L, seedArg, mapped);
4629
+ const seeded = lowerMapSeedArrayNew(lowerer, seedArg, mapped);
4664
4630
  if (seeded)
4665
4631
  return seeded;
4666
4632
  }
4667
4633
  if ((expr.arguments?.length ?? 0) > 0 && !entriesLit) {
4668
- L.noLowering("new Map(entries)", expr, "supported seeds: an array literal of [key, value] pair literals, or a " +
4634
+ lowerer.noLowering("new Map(entries)", expr, "supported seeds: an array literal of [key, value] pair literals, or a " +
4669
4635
  "[K, V][]-typed tuple-array value — construct the Map empty and set() " +
4670
4636
  "each entry otherwise");
4671
4637
  }
@@ -4673,12 +4639,12 @@ export function lowerNew(L, expr) {
4673
4639
  if (!entriesLit)
4674
4640
  return { kind: "mapNew", type: mapped, loc };
4675
4641
  const seed = entriesLit.map((pair) => ({
4676
- key: L.lowerExprExpecting(pair.elements[0], mapped.key),
4677
- value: L.lowerExprExpecting(pair.elements[1], mapped.value),
4642
+ key: lowerer.lowerExprExpecting(pair.elements[0], mapped.key),
4643
+ value: lowerer.lowerExprExpecting(pair.elements[1], mapped.value),
4678
4644
  }));
4679
4645
  return { kind: "mapNew", seed, type: mapped, loc };
4680
4646
  }
4681
- const targs = L.checker.getTypeArguments(tsType);
4647
+ const targs = lowerer.checker.getTypeArguments(tsType);
4682
4648
  // JAVASCRIPT `new Map()` whose arguments never resolved past
4683
4649
  // Map<any, any> (no annotation, no contextual type, no seed): the
4684
4650
  // WeakMap stance below — the VALUE lowers as an opaque dyn object
@@ -4693,17 +4659,17 @@ export function lowerNew(L, expr) {
4693
4659
  targs.every((t) => (t.flags & ts.TypeFlags.Any) !== 0)) {
4694
4660
  return { kind: "dynObjLit", type: DYN, loc };
4695
4661
  }
4696
- const keyIr = targs[0] ? L.mapTypeOf(targs[0]) : null;
4662
+ const keyIr = targs[0] ? lowerer.mapTypeOf(targs[0]) : null;
4697
4663
  if (targs[0] && (!keyIr || !isSupportedMapKey(keyIr))) {
4698
- L.unsupported("SC1090", expr, `Map keys of type '${L.checker.typeToString(targs[0])}' ` +
4664
+ lowerer.unsupported("SC1090", expr, `Map keys of type '${lowerer.checker.typeToString(targs[0])}' ` +
4699
4665
  `(Map keys must be string or number)`);
4700
4666
  }
4701
4667
  if (targs[1]) {
4702
- L.unsupported("SC1090", expr, `Map values of type '${L.checker.typeToString(targs[1])}' ` +
4668
+ lowerer.unsupported("SC1090", expr, `Map values of type '${lowerer.checker.typeToString(targs[1])}' ` +
4703
4669
  `(Map values must be number, string, boolean, records, class instances, ` +
4704
4670
  `arrays, promises, or unions of those — not functions, Maps, 'unknown', or 'any')`);
4705
4671
  }
4706
- L.badType(expr, tsType);
4672
+ lowerer.badType(expr, tsType);
4707
4673
  }
4708
4674
  // `new Set<T>()`: Map's sibling. The SEEDED form lowers for any
4709
4675
  // T[]-typed argument — literal or variable, T already a legal
@@ -4718,14 +4684,14 @@ export function lowerNew(L, expr) {
4718
4684
  // every reached METHOD use meets its own per-site fence → runtime
4719
4685
  // fence). TypeScript keeps the compile fence.
4720
4686
  if ((symbol?.name === "WeakMap" || symbol?.name === "WeakSet") &&
4721
- L.isStdlibSymbol(symbol) &&
4687
+ lowerer.isStdlibSymbol(symbol) &&
4722
4688
  isJsSourceFile(expr.getSourceFile()) &&
4723
4689
  (expr.arguments?.length ?? 0) === 0) {
4724
4690
  return { kind: "dynObjLit", type: DYN, loc };
4725
4691
  }
4726
- if (symbol?.name === "Set" && L.isStdlibSymbol(symbol)) {
4727
- const tsType = L.typeOf(expr);
4728
- const mapped = L.mapTypeOf(tsType);
4692
+ if (symbol?.name === "Set" && lowerer.isStdlibSymbol(symbol)) {
4693
+ const tsType = lowerer.typeOf(expr);
4694
+ const mapped = lowerer.mapTypeOf(tsType);
4729
4695
  if (mapped?.kind === "set" && (expr.arguments?.length ?? 0) === 1) {
4730
4696
  const argNode = expr.arguments[0];
4731
4697
  // An array LITERAL seed builds element-wise (its contextual type
@@ -4733,14 +4699,14 @@ export function lowerNew(L, expr) {
4733
4699
  // union — unmappable, so the generic literal path can't type it);
4734
4700
  // an array-typed VALUE seed lowers as itself.
4735
4701
  if (ts.isArrayLiteralExpression(argNode) && !argNode.elements.some(ts.isSpreadElement)) {
4736
- const elems = argNode.elements.map((el) => L.lowerExprExpecting(el, mapped.elem));
4702
+ const elems = argNode.elements.map((el) => lowerer.lowerExprExpecting(el, mapped.elem));
4737
4703
  const seed = { kind: "arrayLit", elems, type: arrayOf(mapped.elem), loc };
4738
4704
  return { kind: "setNew", seed, type: mapped, loc };
4739
4705
  }
4740
4706
  if (!ts.isSpreadElement(argNode)) {
4741
- const argIr = L.mapTypeOf(L.typeOf(argNode));
4707
+ const argIr = lowerer.mapTypeOf(lowerer.typeOf(argNode));
4742
4708
  if (argIr?.kind === "array" && typeEquals(argIr.elem, mapped.elem)) {
4743
- let seed = L.lowerExpr(argNode);
4709
+ let seed = lowerer.lowerExpr(argNode);
4744
4710
  // A T[]-DECLARED seed whose value is an island handle (a
4745
4711
  // package's exported array — the binding never held a
4746
4712
  // static array): the VALIDATED exit copies the engine
@@ -4748,7 +4714,7 @@ export function lowerNew(L, expr) {
4748
4714
  // lying handle), and the bulk add proceeds on the copy —
4749
4715
  // construction reads the seed once, so the aliasing
4750
4716
  // divergence has nothing to observe.
4751
- if (seed.type.kind === "jsval" && L.boundaryExitSafe(arrayOf(mapped.elem))) {
4717
+ if (seed.type.kind === "jsval" && lowerer.boundaryExitSafe(arrayOf(mapped.elem))) {
4752
4718
  seed = { kind: "jsExit", value: seed, type: arrayOf(mapped.elem), loc: seed.loc };
4753
4719
  }
4754
4720
  if (typeEquals(seed.type, arrayOf(mapped.elem))) {
@@ -4770,7 +4736,7 @@ export function lowerNew(L, expr) {
4770
4736
  ts.isArrayLiteralExpression(expr.arguments[0]) &&
4771
4737
  !expr.arguments[0].elements.some(ts.isSpreadElement)) {
4772
4738
  const lit = expr.arguments[0];
4773
- const elems = lit.elements.map((el) => L.lowerExpr(el));
4739
+ const elems = lit.elements.map((el) => lowerer.lowerExpr(el));
4774
4740
  const first = elems[0];
4775
4741
  if (first !== undefined &&
4776
4742
  (first.type.kind === "string" || first.type.kind === "f64") &&
@@ -4781,35 +4747,35 @@ export function lowerNew(L, expr) {
4781
4747
  }
4782
4748
  }
4783
4749
  if ((expr.arguments?.length ?? 0) > 0) {
4784
- L.noLowering("new Set(values)", expr, "construct the Set empty and add() each value — only an array of " +
4750
+ lowerer.noLowering("new Set(values)", expr, "construct the Set empty and add() each value — only an array of " +
4785
4751
  "already-legal elements (string or number) seeds a Set");
4786
4752
  }
4787
4753
  if (mapped?.kind === "set")
4788
4754
  return { kind: "setNew", type: mapped, loc };
4789
- const targs = L.checker.getTypeArguments(tsType);
4755
+ const targs = lowerer.checker.getTypeArguments(tsType);
4790
4756
  if (targs[0]) {
4791
- L.unsupported("SC1090", expr, `Set elements of type '${L.checker.typeToString(targs[0])}' ` +
4757
+ lowerer.unsupported("SC1090", expr, `Set elements of type '${lowerer.checker.typeToString(targs[0])}' ` +
4792
4758
  `(Set elements must be string or number — Map's key kinds — or a server handle, which stores under reference identity)`);
4793
4759
  }
4794
- L.badType(expr, tsType);
4760
+ lowerer.badType(expr, tsType);
4795
4761
  }
4796
4762
  // `new AsyncLocalStorage()` (node:async_hooks): a fresh store id —
4797
- // an f64 handle (types.ts), the Channel story. Construction options
4763
+ // an f64 handle (type-mapper.ts), the Channel story. Construction options
4798
4764
  // ({ defaultValue, name }) have no lowering yet.
4799
- if (symbol?.name === "AsyncLocalStorage" && L.isStdlibSymbol(symbol)) {
4765
+ if (symbol?.name === "AsyncLocalStorage" && lowerer.isStdlibSymbol(symbol)) {
4800
4766
  if ((expr.arguments?.length ?? 0) > 0) {
4801
- L.noLowering("new AsyncLocalStorage(options)", expr, "the zero-argument constructor is the supported form (defaultValue/name options have no lowering yet)");
4767
+ lowerer.noLowering("new AsyncLocalStorage(options)", expr, "the zero-argument constructor is the supported form (defaultValue/name options have no lowering yet)");
4802
4768
  }
4803
4769
  return { kind: "libCall", fn: "als.new", args: [], type: F64, loc };
4804
4770
  }
4805
4771
  // `new Promise<T>((resolve) => ...)`: the ambient Promise constructor.
4806
- if (symbol?.name === "Promise" && L.isStdlibSymbol(symbol)) {
4807
- const type = L.irTypeOf(expr);
4772
+ if (symbol?.name === "Promise" && lowerer.isStdlibSymbol(symbol)) {
4773
+ const type = lowerer.irTypeOf(expr);
4808
4774
  if (type.kind !== "promise")
4809
- L.badType(expr, L.typeOf(expr));
4775
+ lowerer.badType(expr, lowerer.typeOf(expr));
4810
4776
  const args = expr.arguments ?? [];
4811
4777
  if (args.length !== 1) {
4812
- L.unsupported("SC1090", expr, "Promise construction without an executor");
4778
+ lowerer.unsupported("SC1090", expr, "Promise construction without an executor");
4813
4779
  }
4814
4780
  // `new Promise(setImmediate)` (the Node-suite early-exit shape):
4815
4781
  // the executor IS the stdlib setImmediate, so resolve rides the
@@ -4818,9 +4784,9 @@ export function lowerNew(L, expr) {
4818
4784
  {
4819
4785
  const a0 = args[0];
4820
4786
  if (ts.isIdentifier(a0) && a0.text === "setImmediate") {
4821
- const sym = L.checker.getSymbolAtLocation(a0);
4822
- const decls = sym ? L.checker.declarationsOf(sym) : [];
4823
- if (decls.length > 0 && decls.every((d) => L.isStdlibFile(d.getSourceFile()))) {
4787
+ const sym = lowerer.checker.getSymbolAtLocation(a0);
4788
+ const decls = sym ? lowerer.checker.declarationsOf(sym) : [];
4789
+ if (decls.length > 0 && decls.every((d) => lowerer.isStdlibFile(d.getSourceFile()))) {
4824
4790
  // The settled value is the undefined dyn value — the result
4825
4791
  // is promise<dyn> whatever T the checker inferred for the
4826
4792
  // unusual executor (Promise<unknown> in the suite's shape).
@@ -4841,9 +4807,9 @@ export function lowerNew(L, expr) {
4841
4807
  // catch-side instanceof and the uncaught printer working). First
4842
4808
  // settle wins, exactly JS: reject-after-resolve and double-reject
4843
4809
  // are no-ops, and an executor throw after any settle is swallowed.
4844
- const executor = L.lowerExpr(args[0]);
4810
+ const executor = lowerer.lowerExpr(args[0]);
4845
4811
  if (executor.type.kind !== "func")
4846
- L.badType(args[0], L.typeOf(args[0]));
4812
+ lowerer.badType(args[0], lowerer.typeOf(args[0]));
4847
4813
  if (executor.type.params.length > 1) {
4848
4814
  const rj = executor.type.params[1];
4849
4815
  if (executor.type.params.length > 2 ||
@@ -4854,7 +4820,7 @@ export function lowerNew(L, expr) {
4854
4820
  rj.params[0].className !== "%Error") {
4855
4821
  // A non-contextually-typed executor VALUE whose second param
4856
4822
  // isn't the pinned (reason: Error) => void shape.
4857
- L.unsupported("SC1090", args[0], "Promise executors whose reject parameter is not '(reason: Error) => void'");
4823
+ lowerer.unsupported("SC1090", args[0], "Promise executors whose reject parameter is not '(reason: Error) => void'");
4858
4824
  }
4859
4825
  }
4860
4826
  return { kind: "newPromise", executor, type, loc };
@@ -4865,7 +4831,7 @@ export function lowerNew(L, expr) {
4865
4831
  // TextEncoder, ...) typechecks and reports SC2020 here. The named
4866
4832
  // families carry pointed hints: each states WHY no honest static
4867
4833
  // lowering exists (or what to use instead).
4868
- if (L.isStdlibSymbol(symbol ?? undefined)) {
4834
+ if (lowerer.isStdlibSymbol(symbol ?? undefined)) {
4869
4835
  // The deprecated `new Buffer(string, encoding?)` ctor's string arm
4870
4836
  // with a NON-STRING first argument and a string second: Node
4871
4837
  // throws ERR_INVALID_ARG_TYPE synchronously (and DEP0005 never
@@ -4875,16 +4841,16 @@ export function lowerNew(L, expr) {
4875
4841
  if (expr.expression.text === "Buffer" &&
4876
4842
  expr.arguments?.length === 2 &&
4877
4843
  !expr.arguments.some(ts.isSpreadElement) &&
4878
- L.mapTypeOf(L.typeOf(expr.arguments[0]))?.kind !== "string" &&
4879
- L.mapTypeOf(L.typeOf(expr.arguments[1]))?.kind === "string") {
4880
- const first = L.lowerExpr(expr.arguments[0]);
4881
- if (first.kind === "unitLit" || first.type.kind === "dyn" || L.dynConvertible(first.type)) {
4844
+ lowerer.mapTypeOf(lowerer.typeOf(expr.arguments[0]))?.kind !== "string" &&
4845
+ lowerer.mapTypeOf(lowerer.typeOf(expr.arguments[1]))?.kind === "string") {
4846
+ const first = lowerer.lowerExpr(expr.arguments[0]);
4847
+ if (first.kind === "unitLit" || first.type.kind === "dyn" || lowerer.dynConvertible(first.type)) {
4882
4848
  const got = first.type.kind === "dyn" ? first : { kind: "dynFrom", value: first, type: DYN, loc };
4883
4849
  // The encoding argument still evaluates in Node before the
4884
4850
  // throw only via the ctor body's later reads — it does NOT
4885
4851
  // observe it before throwing, so dropping it is exact for
4886
4852
  // effect-free operands; effectful ones keep the fence.
4887
- const enc = L.lowerExpr(expr.arguments[1]);
4853
+ const enc = lowerer.lowerExpr(expr.arguments[1]);
4888
4854
  if (enc.kind === "strLit" || pureReemittable(enc)) {
4889
4855
  return { kind: "libCall", fn: "buffer.newStringFail", args: [got], type: bytesOf("u8"), loc };
4890
4856
  }
@@ -4904,7 +4870,7 @@ export function lowerNew(L, expr) {
4904
4870
  Proxy: "property-access metaprogramming has no static lowering (every property read must resolve at compile time)",
4905
4871
  Function: "runtime code generation cannot be compiled ahead of time (the eval stance) — write the function",
4906
4872
  };
4907
- L.noLowering(`new ${expr.expression.text}`, expr, ctorHints[expr.expression.text], symbol);
4873
+ lowerer.noLowering(`new ${expr.expression.text}`, expr, ctorHints[expr.expression.text], symbol);
4908
4874
  }
4909
4875
  }
4910
4876
  // `new crypto.X509Certificate(data)` — the Dirent-style data record:
@@ -4923,37 +4889,37 @@ export function lowerNew(L, expr) {
4923
4889
  const callee = expr.expression;
4924
4890
  const isX509 = (ts.isPropertyAccessExpression(callee) &&
4925
4891
  callee.name.text === "X509Certificate" &&
4926
- L.builtinNamespaceModuleOf(callee.expression) === "crypto") ||
4892
+ lowerer.builtinNamespaceModuleOf(callee.expression) === "crypto") ||
4927
4893
  (ts.isIdentifier(callee) &&
4928
4894
  (() => {
4929
- const bi = L.builtinImportOf(callee);
4895
+ const bi = lowerer.builtinImportOf(callee);
4930
4896
  return bi?.module === "crypto" && bi.member === "X509Certificate";
4931
4897
  })());
4932
4898
  if (isX509) {
4933
4899
  const args = expr.arguments ?? [];
4934
4900
  if (args.length !== 1) {
4935
- L.noLowering("X509Certificate with this argument shape", expr, "the supported form is new X509Certificate(readFileSync(path))");
4901
+ lowerer.noLowering("X509Certificate with this argument shape", expr, "the supported form is new X509Certificate(readFileSync(path))");
4936
4902
  }
4937
- const data = L.lowerExpr(args[0]);
4903
+ const data = lowerer.lowerExpr(args[0]);
4938
4904
  const isBytes = data.type.kind === "bytes" && data.type.elem === "u8";
4939
4905
  if (!isBytes && data.type.kind !== "string") {
4940
- L.noLowering(`X509Certificate over '${L.fmt(data.type)}' data`, args[0], "pass the certificate Buffer or PEM string (an fs.readFileSync result)");
4906
+ lowerer.noLowering(`X509Certificate over '${lowerer.fmt(data.type)}' data`, args[0], "pass the certificate Buffer or PEM string (an fs.readFileSync result)");
4941
4907
  }
4942
- const t = L.mapTypeOf(L.typeOf(expr));
4908
+ const t = lowerer.mapTypeOf(lowerer.typeOf(expr));
4943
4909
  if (t?.kind !== "record")
4944
- L.badType(expr, L.typeOf(expr));
4910
+ lowerer.badType(expr, lowerer.typeOf(expr));
4945
4911
  const key = `x509.record:${isBytes ? "bytes" : "str"}`;
4946
- let helper = L.widthHelpers.get(key);
4912
+ let helper = lowerer.widthHelpers.get(key);
4947
4913
  if (!helper) {
4948
- helper = `%x509.record.${L.widthHelpers.size}`;
4949
- L.widthHelpers.set(key, helper);
4914
+ helper = `%x509.record.${lowerer.widthHelpers.size}`;
4915
+ lowerer.widthHelpers.set(key, helper);
4950
4916
  const dataT = data.type;
4951
4917
  const dRef = { kind: "varRef", localId: "d.0", type: dataT, loc };
4952
4918
  const field = (name, fn) => ({
4953
4919
  name,
4954
4920
  value: { kind: "libCall", fn, args: [dRef], type: STRING, loc },
4955
4921
  });
4956
- L.liftedFns.push({
4922
+ lowerer.liftedFns.push({
4957
4923
  name: helper,
4958
4924
  params: [{ localId: "d.0", name: "d", type: dataT }],
4959
4925
  returnType: t,
@@ -4989,47 +4955,47 @@ export function lowerNew(L, expr) {
4989
4955
  // callee (unannotated heterogeneous registries) keeps a pointed
4990
4956
  // fence — annotate the slot with the common constructor type.
4991
4957
  {
4992
- const calleeT = L.mapTypeOf(L.typeOf(expr.expression));
4958
+ const calleeT = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
4993
4959
  if (calleeT?.kind === "classval") {
4994
- let info = L.classes.get(calleeT.className);
4960
+ let info = lowerer.classes.get(calleeT.className);
4995
4961
  if (!info && ts.isPropertyAccessExpression(expr.expression) && ts.isIdentifier(expr.expression.name)) {
4996
4962
  // A property-assigned class expression not collected yet (this
4997
4963
  // body lowers ahead of the assignment statement — hoisted
4998
4964
  // functions): collect it on demand and retry, keeping the
4999
4965
  // dynamic newValue dispatch below (the runtime field value
5000
4966
  // decides, exactly Node under reassignment-through-aliases).
5001
- propertyAssignedClassInfoOf(L, L.checker.getSymbolAtLocation(expr.expression.name));
5002
- info = L.classes.get(calleeT.className);
4967
+ propertyAssignedClassInfoOf(lowerer, lowerer.checker.getSymbolAtLocation(expr.expression.name));
4968
+ info = lowerer.classes.get(calleeT.className);
5003
4969
  }
5004
4970
  if (!info) {
5005
4971
  // The TYPE world names a class the lowering never registered —
5006
4972
  // a fenced class expression, an abstract/deferred declaration:
5007
4973
  // flush its own diagnostics (they tell the real story) and
5008
4974
  // poison this construction site, never an ICE.
5009
- L.flushDeferredClass(calleeT.className);
5010
- L.unsupported("SC1090", expr, "constructing through a class value whose class has no lowering (the class declaration itself was rejected — see its own diagnostic)");
4975
+ lowerer.flushDeferredClass(calleeT.className);
4976
+ lowerer.unsupported("SC1090", expr, "constructing through a class value whose class has no lowering (the class declaration itself was rejected — see its own diagnostic)");
5011
4977
  }
5012
4978
  // A classval of a generic FAMILY (`new () => Box<any>` slots): no
5013
4979
  // single constructor ABI exists to complete against. No producer
5014
4980
  // can fill such a slot (family values and widenings both fence),
5015
4981
  // so the construction site is the honest place to name it.
5016
4982
  if (info.generic) {
5017
- L.unsupported("SC1090", expr, "constructing through a class value of an uninstantiated generic type (annotate the slot with a concrete instantiation — e.g. 'new (v: number) => Box<number>')");
4983
+ lowerer.unsupported("SC1090", expr, "constructing through a class value of an uninstantiated generic type (annotate the slot with a concrete instantiation — e.g. 'new (v: number) => Box<number>')");
5018
4984
  }
5019
- const callee = L.lowerExpr(expr.expression);
4985
+ const callee = lowerer.lowerExpr(expr.expression);
5020
4986
  if (callee.type.kind !== "classval")
5021
- L.badType(expr.expression, L.typeOf(expr.expression));
5022
- L.noteEdge(`%${info.def.name}.constructor`);
4987
+ lowerer.badType(expr.expression, lowerer.typeOf(expr.expression));
4988
+ lowerer.noteEdge(`%${info.def.name}.constructor`);
5023
4989
  // Every constructor a value in this slot can dispatch to is a
5024
4990
  // descendant's — mark them reachable like a virtual edge.
5025
4991
  const below = (c) => {
5026
4992
  for (const s of c.subclasses) {
5027
- L.noteEdge(`%${s.def.name}.constructor`);
4993
+ lowerer.noteEdge(`%${s.def.name}.constructor`);
5028
4994
  below(s);
5029
4995
  }
5030
4996
  };
5031
4997
  below(info);
5032
- const args = L.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
4998
+ const args = lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
5033
4999
  return {
5034
5000
  kind: "newValue",
5035
5001
  callee,
@@ -5039,9 +5005,9 @@ export function lowerNew(L, expr) {
5039
5005
  };
5040
5006
  }
5041
5007
  if (calleeT?.kind === "union") {
5042
- const def = L.unions.get(calleeT.unionId);
5008
+ const def = lowerer.unions.get(calleeT.unionId);
5043
5009
  if (def?.arms.some((a) => a.kind === "classval")) {
5044
- L.unsupported("SC1090", expr, "constructing through a union of class values (annotate the slot with the common constructor type — e.g. `new () => Base` — or narrow first)");
5010
+ lowerer.unsupported("SC1090", expr, "constructing through a union of class values (annotate the slot with the common constructor type — e.g. `new () => Base` — or narrow first)");
5045
5011
  }
5046
5012
  }
5047
5013
  }
@@ -5058,45 +5024,45 @@ export function lowerNew(L, expr) {
5058
5024
  ? expr.expression.name
5059
5025
  : null;
5060
5026
  if (ctorName !== null) {
5061
- const raw = L.checker.getSymbolAtLocation(ctorName);
5062
- const sym = raw && raw.flags & ts.SymbolFlags.Alias ? L.checker.getAliasedSymbol(raw) : raw;
5063
- const hint = sym && L.isStdlibSymbol(sym) ? own(STDLIB_CTOR_HINTS, sym.name) : undefined;
5027
+ const raw = lowerer.checker.getSymbolAtLocation(ctorName);
5028
+ const sym = raw && raw.flags & ts.SymbolFlags.Alias ? lowerer.checker.getAliasedSymbol(raw) : raw;
5029
+ const hint = sym && lowerer.isStdlibSymbol(sym) ? own(STDLIB_CTOR_HINTS, sym.name) : undefined;
5064
5030
  if (hint !== undefined) {
5065
- L.unsupported("SC1090", expr, hint);
5031
+ lowerer.unsupported("SC1090", expr, hint);
5066
5032
  }
5067
5033
  }
5068
5034
  }
5069
- L.unsupported("SC1090", expr, "constructing values other than classes declared in the program");
5035
+ lowerer.unsupported("SC1090", expr, "constructing values other than classes declared in the program");
5070
5036
  }
5071
5037
  /** A getter/setter invocation over an accessor target's receiver — the
5072
5038
  * same whole-program devirtualization as method calls: a virtualCall
5073
5039
  * when some strict subclass of the receiver's static class overrides
5074
5040
  * this HALF of the accessor (get and set devirtualize independently),
5075
5041
  * a direct call of the nearest declaration otherwise. */
5076
- export function accessorCall(L, className, member, obj, extraArgs, ret, loc) {
5077
- const info = L.classes.get(className);
5042
+ export function accessorCall(lowerer, className, member, obj, extraArgs, ret, loc) {
5043
+ const info = lowerer.classes.get(className);
5078
5044
  if (!info)
5079
- throw new Error(`lowerer bug: accessor call on unknown class ${className}`);
5080
- const found = L.findMethodOn(info, member);
5045
+ throw new InternalCompilerError(`lowerer bug: accessor call on unknown class ${className}`);
5046
+ const found = lowerer.findMethodOn(info, member);
5081
5047
  if (!found)
5082
- throw new Error(`lowerer bug: no ${member} on ${className}`);
5048
+ throw new InternalCompilerError(`lowerer bug: no ${member} on ${className}`);
5083
5049
  // The abstract direct-call fence, accessor form (see
5084
5050
  // lowerObjectMethodCall): an abstract accessor with no concrete
5085
5051
  // override below has no implementation for a direct call to target.
5086
- if (found.sig.abstract === true && !L.overrideBelow(info, member)) {
5087
- L.pushDiag(unsupportedDiag("SC1090", loc, `${member.startsWith("get:") ? "reads" : "writes"} of the abstract accessor '${member.slice(4)}' with no concrete implementation below the receiver's static class`));
5052
+ if (found.sig.abstract === true && !lowerer.overrideBelow(info, member)) {
5053
+ lowerer.pushDiag(unsupportedDiag("SC1090", loc, `${member.startsWith("get:") ? "reads" : "writes"} of the abstract accessor '${member.slice(4)}' with no concrete implementation below the receiver's static class`));
5088
5054
  throw new PoisonError();
5089
5055
  }
5090
- if (L.overrideBelow(info, member))
5091
- L.noteVirtualEdge(info, member);
5056
+ if (lowerer.overrideBelow(info, member))
5057
+ lowerer.noteVirtualEdge(info, member);
5092
5058
  else
5093
- L.noteEdge(`%${found.declarer.def.name}.${member}`);
5094
- if (L.overrideBelow(info, member)) {
5059
+ lowerer.noteEdge(`%${found.declarer.def.name}.${member}`);
5060
+ if (lowerer.overrideBelow(info, member)) {
5095
5061
  return {
5096
5062
  kind: "virtualCall",
5097
5063
  className: info.def.name,
5098
5064
  method: member,
5099
- args: [L.upcastTo(obj, info.def.name), ...extraArgs],
5065
+ args: [lowerer.upcastTo(obj, info.def.name), ...extraArgs],
5100
5066
  type: ret,
5101
5067
  loc,
5102
5068
  };
@@ -5104,7 +5070,7 @@ export function accessorCall(L, className, member, obj, extraArgs, ret, loc) {
5104
5070
  return {
5105
5071
  kind: "call",
5106
5072
  callee: `%${found.declarer.def.name}.${member}`,
5107
- args: [L.upcastTo(obj, found.declarer.def.name), ...extraArgs],
5073
+ args: [lowerer.upcastTo(obj, found.declarer.def.name), ...extraArgs],
5108
5074
  type: ret,
5109
5075
  loc,
5110
5076
  };
@@ -5113,7 +5079,7 @@ export function accessorCall(L, className, member, obj, extraArgs, ret, loc) {
5113
5079
  * `time = async <T>(...) => {...}` or `= function g<T>(...) {...}`
5114
5080
  * (parens stripped): bindingGenericFnNodeOf's shape rule, member form.
5115
5081
  * Null when the field isn't that shape. */
5116
- export function genericFieldFnNodeOf(member) {
5082
+ function genericFieldFnNodeOf(member) {
5117
5083
  if (member.initializer === undefined)
5118
5084
  return null;
5119
5085
  let init = member.initializer;