@scriptc/compiler 0.2.1 → 0.2.3

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 (315) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +158 -31
  2. package/dist/backend/cycle-analysis.js +63 -50
  3. package/dist/backend/cycle-analysis.js.map +1 -1
  4. package/dist/backend/cycle-analysis.test.js +51 -0
  5. package/dist/backend/cycle-analysis.test.js.map +1 -1
  6. package/dist/backend/llvm/borrowed-receivers.d.ts +9 -0
  7. package/dist/backend/llvm/borrowed-receivers.js +58 -0
  8. package/dist/backend/llvm/borrowed-receivers.js.map +1 -0
  9. package/dist/backend/llvm/call-lifetimes.d.ts +20 -0
  10. package/dist/backend/llvm/call-lifetimes.js +179 -0
  11. package/dist/backend/llvm/call-lifetimes.js.map +1 -0
  12. package/dist/backend/llvm/call-lifetimes.test.d.ts +1 -0
  13. package/dist/backend/llvm/call-lifetimes.test.js +205 -0
  14. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -0
  15. package/dist/backend/llvm/dyn.d.ts +5 -2
  16. package/dist/backend/llvm/dyn.js +163 -47
  17. package/dist/backend/llvm/dyn.js.map +1 -1
  18. package/dist/backend/llvm/emitter.d.ts +37 -1
  19. package/dist/backend/llvm/emitter.js +209 -21
  20. package/dist/backend/llvm/emitter.js.map +1 -1
  21. package/dist/backend/llvm/emitter.test.js +29 -2
  22. package/dist/backend/llvm/emitter.test.js.map +1 -1
  23. package/dist/backend/llvm/expr-async.js +1 -1
  24. package/dist/backend/llvm/expr-async.js.map +1 -1
  25. package/dist/backend/llvm/expr-calls.js +42 -5
  26. package/dist/backend/llvm/expr-calls.js.map +1 -1
  27. package/dist/backend/llvm/expr-containers.js +75 -13
  28. package/dist/backend/llvm/expr-containers.js.map +1 -1
  29. package/dist/backend/llvm/expr-dynamic.js +31 -6
  30. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  31. package/dist/backend/llvm/expr-primitives.js +6 -5
  32. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  33. package/dist/backend/llvm/expr-records.js +1 -1
  34. package/dist/backend/llvm/expr-records.js.map +1 -1
  35. package/dist/backend/llvm/expr-stream-bridges.js +75 -19
  36. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  37. package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
  38. package/dist/backend/llvm/expr-stream-callbacks.js +7 -57
  39. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  40. package/dist/backend/llvm/lib-dispatch.js +41 -3
  41. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  42. package/dist/backend/llvm/lib-filesystem.js +12 -9
  43. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  44. package/dist/backend/llvm/lib-shared.js +70 -2
  45. package/dist/backend/llvm/lib-shared.js.map +1 -1
  46. package/dist/backend/llvm/local-array-reads.d.ts +44 -0
  47. package/dist/backend/llvm/local-array-reads.js +313 -0
  48. package/dist/backend/llvm/local-array-reads.js.map +1 -0
  49. package/dist/backend/llvm/local-array-reads.test.d.ts +1 -0
  50. package/dist/backend/llvm/local-array-reads.test.js +446 -0
  51. package/dist/backend/llvm/local-array-reads.test.js.map +1 -0
  52. package/dist/backend/llvm/map-read-lifetimes.d.ts +36 -0
  53. package/dist/backend/llvm/map-read-lifetimes.js +128 -0
  54. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -0
  55. package/dist/backend/llvm/map-read-lifetimes.test.d.ts +1 -0
  56. package/dist/backend/llvm/map-read-lifetimes.test.js +123 -0
  57. package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -0
  58. package/dist/backend/llvm/shapes.js +1 -0
  59. package/dist/backend/llvm/shapes.js.map +1 -1
  60. package/dist/backend/llvm/split.js +15 -5
  61. package/dist/backend/llvm/split.js.map +1 -1
  62. package/dist/backend/llvm/split.test.js +17 -0
  63. package/dist/backend/llvm/split.test.js.map +1 -1
  64. package/dist/backend/llvm/stack-unions.d.ts +20 -0
  65. package/dist/backend/llvm/stack-unions.js +61 -0
  66. package/dist/backend/llvm/stack-unions.js.map +1 -0
  67. package/dist/backend/llvm/stack-unions.test.d.ts +1 -0
  68. package/dist/backend/llvm/stack-unions.test.js +241 -0
  69. package/dist/backend/llvm/stack-unions.test.js.map +1 -0
  70. package/dist/backend/llvm/string-lifetimes.d.ts +12 -0
  71. package/dist/backend/llvm/string-lifetimes.js +70 -0
  72. package/dist/backend/llvm/string-lifetimes.js.map +1 -0
  73. package/dist/backend/llvm/string-lifetimes.test.d.ts +1 -0
  74. package/dist/backend/llvm/string-lifetimes.test.js +230 -0
  75. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -0
  76. package/dist/backend/mangle.d.ts +2 -0
  77. package/dist/backend/mangle.js +4 -0
  78. package/dist/backend/mangle.js.map +1 -1
  79. package/dist/backend/may-throw.js +71 -29
  80. package/dist/backend/may-throw.js.map +1 -1
  81. package/dist/backend/may-throw.test.js +104 -1
  82. package/dist/backend/may-throw.test.js.map +1 -1
  83. package/dist/backend/native-codegen.d.ts +1 -1
  84. package/dist/backend/native-codegen.js +4 -3
  85. package/dist/backend/native-codegen.js.map +1 -1
  86. package/dist/backend/native-codegen.test.js +11 -0
  87. package/dist/backend/native-codegen.test.js.map +1 -1
  88. package/dist/backend/native-toolchain.d.ts +2 -2
  89. package/dist/backend/native-toolchain.js +2 -0
  90. package/dist/backend/native-toolchain.js.map +1 -1
  91. package/dist/backend/target-diagnostics.d.ts +5 -0
  92. package/dist/backend/target-diagnostics.js +72 -1
  93. package/dist/backend/target-diagnostics.js.map +1 -1
  94. package/dist/backend/target-diagnostics.test.d.ts +1 -0
  95. package/dist/backend/target-diagnostics.test.js +68 -0
  96. package/dist/backend/target-diagnostics.test.js.map +1 -0
  97. package/dist/coverage/surface-manifest.js +5 -3
  98. package/dist/coverage/surface-manifest.js.map +1 -1
  99. package/dist/executable/executable-cache.d.ts +7 -3
  100. package/dist/executable/executable-cache.js +47 -11
  101. package/dist/executable/executable-cache.js.map +1 -1
  102. package/dist/executable/executable-cache.test.js +109 -2
  103. package/dist/executable/executable-cache.test.js.map +1 -1
  104. package/dist/executable/prepare.js +2 -1
  105. package/dist/executable/prepare.js.map +1 -1
  106. package/dist/frontend/builtin-modules.d.ts +1 -1
  107. package/dist/frontend/builtin-modules.js +1 -1
  108. package/dist/frontend/builtin-modules.js.map +1 -1
  109. package/dist/frontend/function-completion.d.ts +6 -0
  110. package/dist/frontend/function-completion.js +50 -0
  111. package/dist/frontend/function-completion.js.map +1 -0
  112. package/dist/frontend/input-tracker.js +3 -3
  113. package/dist/frontend/input-tracker.js.map +1 -1
  114. package/dist/frontend/input-tracker.test.js +38 -2
  115. package/dist/frontend/input-tracker.test.js.map +1 -1
  116. package/dist/frontend/lowering/abstract-equality.js +5 -1
  117. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  118. package/dist/frontend/lowering/checked-iterable-spread.d.ts +4 -0
  119. package/dist/frontend/lowering/checked-iterable-spread.js +30 -0
  120. package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -0
  121. package/dist/frontend/lowering/checked-promise-all.d.ts +5 -0
  122. package/dist/frontend/lowering/checked-promise-all.js +31 -0
  123. package/dist/frontend/lowering/checked-promise-all.js.map +1 -0
  124. package/dist/frontend/lowering/class-callbacks.d.ts +1 -1
  125. package/dist/frontend/lowering/class-callbacks.js +7 -6
  126. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  127. package/dist/frontend/lowering/class-construction.d.ts +2 -0
  128. package/dist/frontend/lowering/class-construction.js +34 -5
  129. package/dist/frontend/lowering/class-construction.js.map +1 -1
  130. package/dist/frontend/lowering/class-descriptors.d.ts +1 -1
  131. package/dist/frontend/lowering/class-descriptors.js +12 -5
  132. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  133. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +25 -0
  134. package/dist/frontend/lowering/class-dynamic-dispatch.js +597 -78
  135. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  136. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +64 -2
  137. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  138. package/dist/frontend/lowering/class-instance-constructor.d.ts +1 -1
  139. package/dist/frontend/lowering/class-instance-constructor.js +11 -41
  140. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  141. package/dist/frontend/lowering/class-method-values.d.ts +16 -0
  142. package/dist/frontend/lowering/class-method-values.js +60 -29
  143. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  144. package/dist/frontend/lowering/class-prototypes.d.ts +5 -1
  145. package/dist/frontend/lowering/class-prototypes.js +69 -10
  146. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  147. package/dist/frontend/lowering/class-runtime-statics.d.ts +4 -4
  148. package/dist/frontend/lowering/class-runtime-statics.js +26 -8
  149. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  150. package/dist/frontend/lowering/class-static-data.d.ts +1 -0
  151. package/dist/frontend/lowering/class-static-data.js +4 -2
  152. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  153. package/dist/frontend/lowering/collection-ingestion.d.ts +31 -0
  154. package/dist/frontend/lowering/collection-ingestion.js +215 -0
  155. package/dist/frontend/lowering/collection-ingestion.js.map +1 -0
  156. package/dist/frontend/lowering/containers/bytes.js +19 -4
  157. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  158. package/dist/frontend/lowering/containers/string-and-regexp.js +6 -1
  159. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  160. package/dist/frontend/lowering/deferred-module-initializers.d.ts +13 -0
  161. package/dist/frontend/lowering/deferred-module-initializers.js +410 -0
  162. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -0
  163. package/dist/frontend/lowering/deferred-module-initializers.test.d.ts +1 -0
  164. package/dist/frontend/lowering/deferred-module-initializers.test.js +92 -0
  165. package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -0
  166. package/dist/frontend/lowering/expressions/object-literals.js +31 -1
  167. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  168. package/dist/frontend/lowering/expressions/optional-chains.js +3 -3
  169. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  170. package/dist/frontend/lowering/import-meta.d.ts +10 -0
  171. package/dist/frontend/lowering/import-meta.js +52 -0
  172. package/dist/frontend/lowering/import-meta.js.map +1 -0
  173. package/dist/frontend/lowering/lower-assert.js +105 -41
  174. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  175. package/dist/frontend/lowering/lower-builtin-values.d.ts +2 -0
  176. package/dist/frontend/lowering/lower-builtin-values.js +22 -1
  177. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  178. package/dist/frontend/lowering/lower-builtins.d.ts +7 -22
  179. package/dist/frontend/lowering/lower-builtins.js +439 -95
  180. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  181. package/dist/frontend/lowering/lower-calls.js +289 -76
  182. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  183. package/dist/frontend/lowering/lower-classes.d.ts +5 -0
  184. package/dist/frontend/lowering/lower-classes.js +443 -29
  185. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  186. package/dist/frontend/lowering/lower-containers.d.ts +6 -2
  187. package/dist/frontend/lowering/lower-containers.js +79 -20
  188. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  189. package/dist/frontend/lowering/lower-exprs.d.ts +10 -6
  190. package/dist/frontend/lowering/lower-exprs.js +329 -170
  191. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  192. package/dist/frontend/lowering/lower-generators.js +5 -1
  193. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  194. package/dist/frontend/lowering/lower-inspect.js +58 -1
  195. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  196. package/dist/frontend/lowering/lower-island.js +4 -0
  197. package/dist/frontend/lowering/lower-island.js.map +1 -1
  198. package/dist/frontend/lowering/lower-island.test.d.ts +1 -0
  199. package/dist/frontend/lowering/lower-island.test.js +51 -0
  200. package/dist/frontend/lowering/lower-island.test.js.map +1 -0
  201. package/dist/frontend/lowering/lower-modules.d.ts +1 -3
  202. package/dist/frontend/lowering/lower-modules.js +186 -82
  203. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  204. package/dist/frontend/lowering/lower-modules.test.js +69 -1
  205. package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
  206. package/dist/frontend/lowering/lower-stmts.js +172 -103
  207. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  208. package/dist/frontend/lowering/lower-stmts.test.d.ts +1 -0
  209. package/dist/frontend/lowering/lower-stmts.test.js +77 -0
  210. package/dist/frontend/lowering/lower-stmts.test.js.map +1 -0
  211. package/dist/frontend/lowering/lower-stream.js +2 -0
  212. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  213. package/dist/frontend/lowering/lower-system-errors.d.ts +6 -0
  214. package/dist/frontend/lowering/lower-system-errors.js +29 -0
  215. package/dist/frontend/lowering/lower-system-errors.js.map +1 -0
  216. package/dist/frontend/lowering/lower-url.d.ts +2 -1
  217. package/dist/frontend/lowering/lower-url.js +32 -9
  218. package/dist/frontend/lowering/lower-url.js.map +1 -1
  219. package/dist/frontend/lowering/lowerer.d.ts +30 -12
  220. package/dist/frontend/lowering/lowerer.js +268 -49
  221. package/dist/frontend/lowering/lowerer.js.map +1 -1
  222. package/dist/frontend/lowering/lowerer.test.js +38 -0
  223. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  224. package/dist/frontend/lowering/module-namespace-elements.d.ts +7 -0
  225. package/dist/frontend/lowering/module-namespace-elements.js +54 -0
  226. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -0
  227. package/dist/frontend/lowering/object-factory-new.d.ts +4 -3
  228. package/dist/frontend/lowering/object-factory-new.js +27 -14
  229. package/dist/frontend/lowering/object-factory-new.js.map +1 -1
  230. package/dist/frontend/lowering/surfaces.d.ts +3 -2
  231. package/dist/frontend/lowering/surfaces.js +93 -33
  232. package/dist/frontend/lowering/surfaces.js.map +1 -1
  233. package/dist/frontend/lowering/text-decoder-encoding.js +3 -0
  234. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
  235. package/dist/frontend/lowering/text-decoder-encoding.test.js +2 -1
  236. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -1
  237. package/dist/frontend/module-syntax.d.ts +1 -1
  238. package/dist/frontend/module-syntax.js +8 -1
  239. package/dist/frontend/module-syntax.js.map +1 -1
  240. package/dist/frontend/module-syntax.test.js +10 -0
  241. package/dist/frontend/module-syntax.test.js.map +1 -1
  242. package/dist/frontend/npm.d.ts +4 -0
  243. package/dist/frontend/npm.js +86 -33
  244. package/dist/frontend/npm.js.map +1 -1
  245. package/dist/frontend/npm.test.js +103 -0
  246. package/dist/frontend/npm.test.js.map +1 -1
  247. package/dist/frontend/pipeline-native.js +2 -1
  248. package/dist/frontend/pipeline-native.js.map +1 -1
  249. package/dist/frontend/program.js +4 -2
  250. package/dist/frontend/program.js.map +1 -1
  251. package/dist/frontend/services-node.js +3 -2
  252. package/dist/frontend/services-node.js.map +1 -1
  253. package/dist/frontend/services.d.ts +5 -1
  254. package/dist/frontend/services.js +9 -1
  255. package/dist/frontend/services.js.map +1 -1
  256. package/dist/frontend/services.test.js +21 -0
  257. package/dist/frontend/services.test.js.map +1 -1
  258. package/dist/frontend/ts7/ast-node.d.ts +2 -0
  259. package/dist/frontend/ts7/ast-node.js +30 -4
  260. package/dist/frontend/ts7/ast-node.js.map +1 -1
  261. package/dist/frontend/ts7/ast-node.test.js +60 -1
  262. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  263. package/dist/frontend/type-mapper.js +89 -14
  264. package/dist/frontend/type-mapper.js.map +1 -1
  265. package/dist/frontend/union-discriminants.js +22 -7
  266. package/dist/frontend/union-discriminants.js.map +1 -1
  267. package/dist/index.js +19 -12
  268. package/dist/index.js.map +1 -1
  269. package/dist/ir/analysis.js +1 -0
  270. package/dist/ir/analysis.js.map +1 -1
  271. package/dist/ir/integer-loops.d.ts +7 -0
  272. package/dist/ir/integer-loops.js +23 -0
  273. package/dist/ir/integer-loops.js.map +1 -1
  274. package/dist/ir/integer-loops.test.d.ts +1 -0
  275. package/dist/ir/integer-loops.test.js +41 -0
  276. package/dist/ir/integer-loops.test.js.map +1 -0
  277. package/dist/ir/ir.d.ts +44 -26
  278. package/dist/ir/ir.js +69 -11
  279. package/dist/ir/ir.js.map +1 -1
  280. package/dist/ir/ir.test.js +18 -0
  281. package/dist/ir/ir.test.js.map +1 -1
  282. package/dist/ir/serialize.js +21 -1
  283. package/dist/ir/serialize.js.map +1 -1
  284. package/dist/ir/serialize.test.js +21 -0
  285. package/dist/ir/serialize.test.js.map +1 -1
  286. package/dist/ir/traverse.d.ts +0 -3
  287. package/dist/ir/traverse.js +33 -20
  288. package/dist/ir/traverse.js.map +1 -1
  289. package/dist/ir/validate.js +216 -80
  290. package/dist/ir/validate.js.map +1 -1
  291. package/dist/ir/validate.test.js +244 -1
  292. package/dist/ir/validate.test.js.map +1 -1
  293. package/dist/library/compiler-self-identity.js +1 -1
  294. package/dist/library/compiler-self-identity.test.js +2 -2
  295. package/dist/library/compiler-self-identity.test.js.map +1 -1
  296. package/dist/library/fence-eval.js +9 -2
  297. package/dist/library/fence-eval.js.map +1 -1
  298. package/dist/library/fence-eval.test.d.ts +1 -0
  299. package/dist/library/fence-eval.test.js +21 -0
  300. package/dist/library/fence-eval.test.js.map +1 -0
  301. package/dist/library/int-infer.d.ts +2 -2
  302. package/dist/library/int-infer.js +10 -7
  303. package/dist/library/int-infer.js.map +1 -1
  304. package/dist/library/int-infer.test.js +44 -0
  305. package/dist/library/int-infer.test.js.map +1 -1
  306. package/dist/library/prepare.js +2 -1
  307. package/dist/library/prepare.js.map +1 -1
  308. package/dist/native/runtime-typescript.d.ts +4 -0
  309. package/dist/native/runtime-typescript.js +61 -0
  310. package/dist/native/runtime-typescript.js.map +1 -0
  311. package/dist/native/runtime-typescript.test.d.ts +1 -0
  312. package/dist/native/runtime-typescript.test.js +41 -0
  313. package/dist/native/runtime-typescript.test.js.map +1 -0
  314. package/package.json +20 -20
  315. package/surface-manifest.json +385 -29
@@ -1,5 +1,5 @@
1
- import { pathModuleValue } from "./lower-builtin-values.js";
2
- import { everyExprChild, everyStmtChild } from "../../ir/traverse.js";
1
+ import { lowerUtilTypeValue, pathModuleValue, utilTypesModuleValue } from "./lower-builtin-values.js";
2
+ import { everyExprChild, everyStmtChild, transformStmtList } from "../../ir/traverse.js";
3
3
  import { RuntimeOptionalLocals } from "./runtime-optional-locals.js";
4
4
  import { sanitizeUnregisteredClassTypes } from "./sanitize-class-types.js";
5
5
  import { UnregisteredClassTypes } from "./unregistered-class-types.js";
@@ -9,7 +9,8 @@ import { bindingInContext, captureContextBinding, declareContextLocal, declareCo
9
9
  export { newFnCtx } from "./function-context.js";
10
10
  import { InternalCompilerError } from "../../errors.js";
11
11
  import { defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "./optional-arguments.js";
12
- import { ClassDynamicDispatch } from "./class-dynamic-dispatch.js";
12
+ import { ClassDynamicDispatch, trackClassFieldCreation } from "./class-dynamic-dispatch.js";
13
+ import { DeferredModuleInitializers } from "./deferred-module-initializers.js";
13
14
  import { finalizeClassMethodValues } from "./class-method-values.js";
14
15
  /* AST + checker → IR.
15
16
  *
@@ -37,7 +38,7 @@ import {} from "../npm.js";
37
38
  import { provenanceActive } from "../provenance-registry.js";
38
39
  import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
39
40
  import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, ISLAND_AMBIENT_TYPES, isUnitOnlyTsType, jsOpenObjectType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
40
- import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
41
+ import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalNameOf, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
41
42
  import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules, appendForkModules } from "./lower-modules.js";
42
43
  import { prepareCjsModuleGraph } from "./lower-node-module.js";
43
44
  import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, findGenericMethodOn, findGenericStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorConstructorArgs, lowerNew, accessorCall } from "./lower-classes.js";
@@ -57,8 +58,9 @@ import { lowerDgramDnsModuleCall, lowerDgramMethodCall } from "./lower-dgram.js"
57
58
  import { lowerNodeTestModuleCall, lowerTestDirectCall, lowerTestMethodCall, lowerTestCtxProperty } from "./lower-test.js";
58
59
  import { lowerAssertModuleCall, lowerAssertDirectCall } from "./lower-assert.js";
59
60
  import { lowerUtilModuleCall } from "./lower-inspect.js";
61
+ import { lowerSystemErrorMapValue } from "./lower-system-errors.js";
60
62
  import { lowerComptime, comptimeBakeable, rejectComptimeCaptures, comptimeValueToIr } from "./lower-comptime.js";
61
- import { lowerStmts, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, lowerJsvalBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement } from "./lower-stmts.js";
63
+ import { lowerStmts, hasJsTypeAnnotation, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, lowerJsvalBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement } from "./lower-stmts.js";
62
64
  import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf } from "./lower-exprs.js";
63
65
  import { finishOptionalChain, isOptionalChainTail, lowerOptionalChain } from "./expressions/optional-chains.js";
64
66
  import { foldedStringKeyOf, lowerDynObjectLiteral, lowerObjectLiteral, lowerShorthandValue, rejectThisInObjectMethod } from "./expressions/object-literals.js";
@@ -751,18 +753,34 @@ function anyPiecedFuncType(lowerer, node, t) {
751
753
  return null;
752
754
  return { kind: "func", params, ret };
753
755
  }
754
- /** The best-effort JS `Function.prototype.name` of an expression flowing
755
- * into a dyn slot (the boxed function kind's inspect/error name):
756
- * identifier and property reads answer the referenced NAME (a
757
- * REFERENCE-SITE approximation of JS's creation-site naming — an aliased
758
- * binding reports the alias; SEMANTICS.md), named function expressions
756
+ /** The JS `Function.prototype.name` of an expression flowing into a dyn
757
+ * slot. Immutable identifier aliases retain their creation-site name; property
758
+ * reads answer the referenced name. Named function expressions
759
759
  * their own name, anonymous function/arrow expressions their
760
760
  * NamedEvaluation home (a variable initializer or property assignment).
761
761
  * Null when nothing names the value (the box stays anonymous). */
762
- export function jsFuncNameOf(node) {
762
+ export function jsFuncNameOf(node, lowerer) {
763
763
  let n = node;
764
764
  while (ts.isParenthesizedExpression(n))
765
765
  n = n.expression;
766
+ const seen = new Set();
767
+ while (lowerer && ts.isIdentifier(n)) {
768
+ const symbol = lowerer.resolveValueSymbol(n);
769
+ if (!symbol || seen.has(symbol))
770
+ break;
771
+ seen.add(symbol);
772
+ const declaration = lowerer.checker.valueDeclarationOf(symbol);
773
+ if (declaration && ts.isFunctionDeclaration(declaration)) {
774
+ n = declaration;
775
+ break;
776
+ }
777
+ if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer ||
778
+ (ts.getCombinedNodeFlags(declaration) & ts.NodeFlags.Const) === 0)
779
+ break;
780
+ n = declaration.initializer;
781
+ while (ts.isParenthesizedExpression(n))
782
+ n = n.expression;
783
+ }
766
784
  if (ts.isIdentifier(n))
767
785
  return n.text;
768
786
  if (ts.isPropertyAccessExpression(n))
@@ -811,6 +829,9 @@ export class Lowerer {
811
829
  /** Per-symbol result of the never-reassigned file scan
812
830
  * (bindingNeverReassigned — object-literal generic-method receivers). */
813
831
  neverReassignedCache = new Map();
832
+ /** Syntactic writes indexed once per JS scope. Symbol and RHS type
833
+ * checks remain contextual to each binding probe. */
834
+ jsBindingWritesByOwner = new Map();
814
835
  /** TRAP bindings: declarations whose initializer provably throws before
815
836
  * producing a value (its chain roots at an ambient-undefined name —
816
837
  * ambientUndefVarRootOf). Module init unwinds at the declaration, so no
@@ -1090,7 +1111,7 @@ export class Lowerer {
1090
1111
  // the initializer cannot fall back to a narrowing adapter.
1091
1112
  if (ts.isIdentifier(node) && fallback?.kind === "func") {
1092
1113
  const decl = this.checker.valueDeclarationOf(symbol);
1093
- if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
1114
+ if (decl && ts.isVariableDeclaration(decl) && !decl.type && !hasJsTypeAnnotation(decl) && decl.initializer) {
1094
1115
  let init = decl.initializer;
1095
1116
  while (ts.isParenthesizedExpression(init))
1096
1117
  init = init.expression;
@@ -1124,14 +1145,14 @@ export class Lowerer {
1124
1145
  }
1125
1146
  /** Recover the original optional union when a checked single-arm helper
1126
1147
  * was installed before a strict property consumer could name its member.
1127
- * Recovery is limited to array element reads and storage roots marked by
1128
- * the optional-read analysis, so ordinary assertions keep their generic
1148
+ * Recovery covers member reads and storage roots marked by the
1149
+ * optional-read analysis, so ordinary assertions keep their generic
1129
1150
  * checked-narrow behavior. */
1130
1151
  runtimeOptionalSourceValue(node, value) {
1131
1152
  let origin = node;
1132
1153
  while (ts.isParenthesizedExpression(origin))
1133
1154
  origin = origin.expression;
1134
- let optionalOrigin = ts.isElementAccessExpression(origin);
1155
+ let optionalOrigin = ts.isElementAccessExpression(origin) || ts.isPropertyAccessExpression(origin);
1135
1156
  if (ts.isIdentifier(origin)) {
1136
1157
  const local = this.resolveLocal(origin);
1137
1158
  const root = local ? this.runtimeOptionalRootOf(local) : null;
@@ -1143,6 +1164,10 @@ export class Lowerer {
1143
1164
  }
1144
1165
  if (!optionalOrigin)
1145
1166
  return null;
1167
+ // A checked JavaScript indexed read can already be boxed. The checker
1168
+ // calls the element present, but that inference is not a runtime guard.
1169
+ if (isJsSourceFile(node.getSourceFile()) && value.kind === "dynCheck" && value.value.type.kind === "dyn")
1170
+ return value.value;
1146
1171
  let source = value;
1147
1172
  if (value.kind === "call" &&
1148
1173
  this.checkedNarrowHelpers.has(value.callee) &&
@@ -1348,10 +1373,12 @@ export class Lowerer {
1348
1373
  copyRetagHelpers = new Map();
1349
1374
  unionLiteralOwners = new Map();
1350
1375
  strippedUndefinedArms = new Map();
1376
+ addedUndefinedArms = new Map();
1351
1377
  stdlibSymbols = new Map();
1352
1378
  /** Method adapter names are owned by class-method-values. Looking them
1353
1379
  * up must not scan and retain every unrelated lifted function. */
1354
1380
  classMethodValueHelpers = new Set();
1381
+ classMethodValueSelections = new Map();
1355
1382
  /** Callee names of every interned coercion helper whose CALL mints a
1356
1383
  * FRESH closure per evaluation (%fn.width.*, %fn.adapt.*,
1357
1384
  * %fnval.spawnres.*). Registered at the mint site — NOT recovered by
@@ -1442,9 +1469,15 @@ export class Lowerer {
1442
1469
  /** Inferred JS methods participating in an override chain keep a vtable
1443
1470
  * ABI instead of call-site specialization. Filled before class collection. */
1444
1471
  virtualJsMethods = new Set();
1472
+ /** Descendant writes must widen the original JS field before collecting
1473
+ * any class layout; base and derived instances share its storage ABI. */
1474
+ inheritedJsFieldWrites = new Map();
1445
1475
  /** Largest fixed argument list below a JS method, discovered before any
1446
1476
  * base vtable signature is collected. Unused checked slots carry undefined. */
1447
1477
  virtualJsMethodArity = new Map();
1478
+ checkedVirtualJsMethods = new Set();
1479
+ checkedVirtualJsAccessors = new Set();
1480
+ checkedVirtualJsValueReturns = new Set();
1448
1481
  /** The class whose members are lowering — `super` binds lexically to it
1449
1482
  * (arrows inside methods lower within this window, so they see it too). */
1450
1483
  currentClass = null;
@@ -1583,6 +1616,7 @@ export class Lowerer {
1583
1616
  * a reference to a lowerable body reports its name here — recorded even
1584
1617
  * when the enclosing statement later poisons. */
1585
1618
  onEdge = null;
1619
+ deferredModuleInitializers = null;
1586
1620
  // Stack of function contexts (bottom = the function being declared at
1587
1621
  // top level, top = the innermost nested function currently lowering).
1588
1622
  fnStack = [];
@@ -1621,6 +1655,15 @@ export class Lowerer {
1621
1655
  * is assembled directly. The configured reachable set remains null so
1622
1656
  * demand-driven instance lowering keeps its existing gates. */
1623
1657
  reachableForArtifacts = null;
1658
+ /** Constructors retained by the active worklist. A boxed base receiver
1659
+ * can contain any retained descendant, but importing its declaration
1660
+ * alone does not make every descendant constructible. */
1661
+ constructedClasses = null;
1662
+ virtualEdges = new Map();
1663
+ classCanBeConstructed(info) {
1664
+ return this.constructedClasses === null || this.constructedClasses.has(info.def.name) ||
1665
+ info.genericInstance !== undefined || info.mixinInstance !== undefined;
1666
+ }
1624
1667
  /** Coverage remainder mode: the reachability gate inverts (see wantBody)
1625
1668
  * and no module is built. */
1626
1669
  remainder;
@@ -2467,8 +2510,11 @@ export class Lowerer {
2467
2510
  if (!symbol)
2468
2511
  return null;
2469
2512
  const g = this.globalsBySymbol.get(symbol);
2470
- if (g)
2513
+ if (g) {
2514
+ if (g.type.kind === "func")
2515
+ g.type = this.runtimeOptionalBindingType(ident, g.type);
2471
2516
  return g;
2517
+ }
2472
2518
  for (const d of this.checker.declarationsOf(symbol)) {
2473
2519
  const byDecl = this.globalsByDeclNode.get(d);
2474
2520
  if (byDecl)
@@ -2713,6 +2759,14 @@ export class Lowerer {
2713
2759
  return null;
2714
2760
  return s.flags & ts.SymbolFlags.Alias ? this.checker.getAliasedSymbol(s) : s;
2715
2761
  };
2762
+ const signatureOf = (node) => {
2763
+ const symbol = symbolOf(node);
2764
+ if (!symbol)
2765
+ return null;
2766
+ const projection = this.staticCallables.get(symbol);
2767
+ return this.fnSigsBySymbol.get(symbol) ??
2768
+ (projection?.kind === "declared-function" ? projection.signature : null);
2769
+ };
2716
2770
  const functionDeclBySymbol = new Map();
2717
2771
  const signatureBySymbol = new Map();
2718
2772
  const methodFamilies = new Map();
@@ -2736,7 +2790,7 @@ export class Lowerer {
2736
2790
  });
2737
2791
  }
2738
2792
  for (const info of this.classes.values()) {
2739
- for (const { mName, member } of this.classMethodMembers(info)) {
2793
+ for (const { mName, member } of this.classMethodMembers(info, true)) {
2740
2794
  if (!member.name || !(ts.isIdentifier(member.name) || ts.isStringLiteral(member.name)))
2741
2795
  continue;
2742
2796
  const symbol = symbolOf(member.name);
@@ -2866,9 +2920,11 @@ export class Lowerer {
2866
2920
  }
2867
2921
  if (ts.isBinaryExpression(e)) {
2868
2922
  const op = e.operatorToken.kind;
2869
- if (op === ts.SyntaxKind.AmpersandAmpersandToken ||
2870
- op === ts.SyntaxKind.BarBarToken ||
2871
- op === ts.SyntaxKind.QuestionQuestionToken)
2923
+ // Nullish/falsy left values select the fallback, so only that
2924
+ // fallback can make the whole expression undefined.
2925
+ if (op === ts.SyntaxKind.BarBarToken || op === ts.SyntaxKind.QuestionQuestionToken)
2926
+ return mayBeOptional(e.right);
2927
+ if (op === ts.SyntaxKind.AmpersandAmpersandToken)
2872
2928
  return mayBeOptional(e.left) || mayBeOptional(e.right);
2873
2929
  }
2874
2930
  if (ts.isPropertyAccessExpression(e) && ts.isIdentifier(e.expression)) {
@@ -2994,6 +3050,29 @@ export class Lowerer {
2994
3050
  found = true;
2995
3051
  return found;
2996
3052
  };
3053
+ const jsLambdas = [];
3054
+ for (const sf of sourceFiles) {
3055
+ if (!isJsSourceFile(sf))
3056
+ continue;
3057
+ ts.walkPreorder(sf, (node) => {
3058
+ if (ts.isArrowFunction(node) || ts.isFunctionExpression(node))
3059
+ jsLambdas.push(node);
3060
+ });
3061
+ }
3062
+ for (const [symbol, signature] of signatureBySymbol) {
3063
+ const declaration = functionDeclBySymbol.get(symbol);
3064
+ if (!declaration || !isJsSourceFile(declaration.getSourceFile()))
3065
+ continue;
3066
+ const checked = this.checker.getSignatureFromDeclaration(declaration);
3067
+ const checkedReturn = checked ? this.checker.getReturnTypeOfSignature(checked) : null;
3068
+ // Checker-known optional results already narrow at each use. Only
3069
+ // propagate undefined that JavaScript's runtime ABI adds beyond them.
3070
+ if (checkedReturn && ((checkedReturn.flags & ts.TypeFlags.Undefined) !== 0 ||
3071
+ checkedReturn.isUnionType() && ts.constituentTypes(checkedReturn).some((arm) => (arm.flags & ts.TypeFlags.Undefined) !== 0)))
3072
+ continue;
3073
+ if (signature.returnType.kind === "union" && this.armTag(signature.returnType.unionId, UNDEFINED_T) >= 0)
3074
+ optionalReturns.add(symbol);
3075
+ }
2997
3076
  const promoteHofCallback = (callback, parameterIndices, seen = new Set()) => {
2998
3077
  let changed = false;
2999
3078
  const checkerTypeContainsTypeParameter = (type) => {
@@ -3381,21 +3460,32 @@ export class Lowerer {
3381
3460
  }
3382
3461
  return;
3383
3462
  }
3384
- const set = optionalParams.get(symbol) ?? new Set();
3385
- shape.type = addUndefined(shape.type);
3386
- const before = set.size;
3387
- set.add(i);
3388
- optionalParams.set(symbol, set);
3389
- if (set.size !== before) {
3390
- changed = true;
3391
- const callee = functionDeclBySymbol.get(symbol);
3392
- const parameter = callee?.parameters[i];
3393
- if (parameter) {
3394
- for (const bound of boundIdentifiersOf(parameter.name)) {
3395
- const boundSymbol = symbolOf(bound);
3396
- if (boundSymbol && !optionalSymbols.has(boundSymbol)) {
3397
- optionalSymbols.add(boundSymbol);
3398
- changed = true;
3463
+ // A virtual slot has one argument representation, even when
3464
+ // the unchecked read reaches only a base-typed call site.
3465
+ // Promote every implementation and its parameter bindings so
3466
+ // downstream calls and returns see the same optional value.
3467
+ const family = familyBySymbol.get(symbol);
3468
+ if (family)
3469
+ optionalMethodFamilies.add(family);
3470
+ for (const target of family ?? [symbol]) {
3471
+ const parameterShape = signatureBySymbol.get(target)?.params[i];
3472
+ if (!parameterShape)
3473
+ continue;
3474
+ parameterShape.type = addUndefined(parameterShape.type);
3475
+ const set = optionalParams.get(target) ?? new Set();
3476
+ const before = set.size;
3477
+ set.add(i);
3478
+ optionalParams.set(target, set);
3479
+ if (set.size !== before) {
3480
+ changed = true;
3481
+ const parameter = functionDeclBySymbol.get(target)?.parameters[i];
3482
+ if (parameter) {
3483
+ for (const bound of boundIdentifiersOf(parameter.name)) {
3484
+ const boundSymbol = symbolOf(bound);
3485
+ if (boundSymbol && !optionalSymbols.has(boundSymbol)) {
3486
+ optionalSymbols.add(boundSymbol);
3487
+ changed = true;
3488
+ }
3399
3489
  }
3400
3490
  }
3401
3491
  }
@@ -3431,6 +3521,23 @@ export class Lowerer {
3431
3521
  for (const [symbol, decl] of functionDeclBySymbol)
3432
3522
  if (scanReturns(symbol, decl))
3433
3523
  changed = true;
3524
+ for (const fn of jsLambdas) {
3525
+ if (!bodyReturnsOptional(fn))
3526
+ continue;
3527
+ const mapped = this.mapTypeOf(this.typeOf(fn));
3528
+ if (mapped?.kind !== "func")
3529
+ continue;
3530
+ const previous = this.runtimeOptionalFunctionReturnType(fn, mapped.ret);
3531
+ if (previous.kind === "generator")
3532
+ continue;
3533
+ const next = previous.kind === "promise"
3534
+ ? { ...previous, inner: this.runtimeOptionalType(previous.inner) }
3535
+ : this.runtimeOptionalType(previous);
3536
+ if (!typeEquals(previous, next)) {
3537
+ this.runtimeOptionalFunctionReturns.set(fn, next);
3538
+ changed = true;
3539
+ }
3540
+ }
3434
3541
  // Every implementation of a virtual slot must retain the same ABI,
3435
3542
  // including when just one body forwards an omitted parameter.
3436
3543
  for (const family of optionalMethodFamilies) {
@@ -3475,6 +3582,14 @@ export class Lowerer {
3475
3582
  this.runtimeOptionalFunctionReturns.set(decl, arithmetic);
3476
3583
  }
3477
3584
  }
3585
+ for (const [declaration, global] of this.globalsByDeclNode) {
3586
+ if (global.type.kind !== "func" || !ts.isBinaryExpression(declaration) || !isJsSourceFile(declaration.getSourceFile()))
3587
+ continue;
3588
+ const value = peel(declaration.right);
3589
+ if (!ts.isFunctionExpression(value) && !ts.isArrowFunction(value))
3590
+ continue;
3591
+ global.type = { ...global.type, ret: this.runtimeOptionalFunctionReturnType(value, global.type.ret) };
3592
+ }
3478
3593
  for (const sf of sourceFiles) {
3479
3594
  ts.walkPreorder(sf, (node) => {
3480
3595
  if (!ts.isVariableDeclaration(node) || !ts.isIdentifier(node.name))
@@ -3482,6 +3597,23 @@ export class Lowerer {
3482
3597
  const symbol = symbolOf(node.name);
3483
3598
  if (!symbol)
3484
3599
  return;
3600
+ if (isJsSourceFile(sf) && !node.type && !hasJsTypeAnnotation(node) && node.initializer &&
3601
+ (ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer))) {
3602
+ const global = this.globalsBySymbol.get(symbol);
3603
+ if (global?.type.kind === "func")
3604
+ global.type = { ...global.type, ret: this.runtimeOptionalFunctionReturnType(node.initializer, global.type.ret) };
3605
+ }
3606
+ if (!node.type && !hasJsTypeAnnotation(node) && node.initializer && ts.isIdentifier(node.initializer)) {
3607
+ const global = this.globalsBySymbol.get(symbol);
3608
+ const current = global?.type ?? this.mapTypeOf(this.typeOf(node.name));
3609
+ const source = current?.kind === "func" ? signatureOf(node.initializer) : null;
3610
+ if (source && current?.kind === "func") {
3611
+ const promoted = { ...current, params: source.params.filter((param) => param.mode !== "dynRest" && param.mode !== "arguments").map((param) => param.type), ret: source.returnType };
3612
+ this.runtimeOptionalBindingTypes.set(symbol, promoted);
3613
+ if (global)
3614
+ global.type = promoted;
3615
+ }
3616
+ }
3485
3617
  const fields = optionalFields.get(symbol);
3486
3618
  if (!dynamicObjectEntryRows.has(symbol) && !optionalSymbols.has(symbol) && !fields)
3487
3619
  return;
@@ -3492,7 +3624,7 @@ export class Lowerer {
3492
3624
  if (!dynamicObjectEntryRows.has(symbol) && optionalSymbols.has(symbol))
3493
3625
  promoted = addUndefined(promoted);
3494
3626
  if (promoted.kind === "func" && node.initializer && ts.isIdentifier(node.initializer)) {
3495
- const sourceSig = this.fnSigOf(node.initializer);
3627
+ const sourceSig = signatureOf(node.initializer);
3496
3628
  if (sourceSig) {
3497
3629
  promoted = {
3498
3630
  ...promoted,
@@ -3692,6 +3824,7 @@ export class Lowerer {
3692
3824
  * and the retained reachability worklist. */
3693
3825
  finishModule(functions) {
3694
3826
  finalizeClassMethodValues(this, functions);
3827
+ trackClassFieldCreation(this, functions);
3695
3828
  // Globals typed by a class that never REGISTERED (a JS class whose
3696
3829
  // collection fenced — Symbol-keyed fields, an unsupported base): the
3697
3830
  // declaration statement and every use compiled to runtime fences, but
@@ -3862,6 +3995,7 @@ export class Lowerer {
3862
3995
  * body; both fire edges through the same hooks and are not units
3863
3996
  * themselves. */
3864
3997
  emitReachable(extraRoots) {
3998
+ this.deferredModuleInitializers = new DeferredModuleInitializers();
3865
3999
  const parts = this.splitFiles();
3866
4000
  // Direct lowering callers do not necessarily run program preflight.
3867
4001
  // Establish the same managed header/top-level batch here before
@@ -4028,6 +4162,7 @@ export class Lowerer {
4028
4162
  return owner;
4029
4163
  };
4030
4164
  const reachable = new Set();
4165
+ this.constructedClasses = new Set();
4031
4166
  const queue = [];
4032
4167
  const loweredUnits = new Map();
4033
4168
  const initFunctions = [];
@@ -4038,6 +4173,12 @@ export class Lowerer {
4038
4173
  reachable.add(name);
4039
4174
  if (units.has(name))
4040
4175
  queue.push(name);
4176
+ if (this.constructedClasses && name.endsWith(".constructor")) {
4177
+ this.constructedClasses.add(name.slice(1, -".constructor".length));
4178
+ for (const [owner, methods] of this.virtualEdges)
4179
+ for (const method of methods)
4180
+ this.noteVirtualEdge(owner, method);
4181
+ }
4041
4182
  };
4042
4183
  // Class EXPRESSIONS collect while init bodies lower (below): their
4043
4184
  // member units register the moment collection finishes — before any
@@ -4188,10 +4329,13 @@ export class Lowerer {
4188
4329
  const classDispatch = new ClassDynamicDispatch(extraRoots !== undefined);
4189
4330
  for (;;) {
4190
4331
  drainInstances();
4332
+ const initializerChanged = this.deferredModuleInitializers.process(this, [
4333
+ ...loweredUnits.values(), ...initFunctions, ...instanceFunctions, ...this.liftedFns, ...this.implicitFns,
4334
+ ]);
4191
4335
  const dispatchChanged = classDispatch.process(this, [
4192
4336
  ...loweredUnits.values(), ...initFunctions, ...instanceFunctions, ...this.liftedFns, ...this.implicitFns,
4193
4337
  ]);
4194
- if (queue.length === 0 && !dispatchChanged)
4338
+ if (queue.length === 0 && !dispatchChanged && !initializerChanged)
4195
4339
  break;
4196
4340
  drainUnits();
4197
4341
  this.restoreGenericInstanceOrder(instLowered);
@@ -4214,6 +4358,20 @@ export class Lowerer {
4214
4358
  ...this.liftedFns,
4215
4359
  ...this.implicitFns,
4216
4360
  ];
4361
+ // The worklist can leave a virtual site with only its base method.
4362
+ // Devirtualize after construction/override reachability has settled.
4363
+ for (const fn of functions)
4364
+ fn.body = transformStmtList(fn.body, { stmt: (statement) => statement, expr: (expression) => {
4365
+ if (expression.kind !== "virtualCall")
4366
+ return expression;
4367
+ const info = this.classes.get(expression.className);
4368
+ const method = info && this.findMethodOn(info, expression.method);
4369
+ if (!method || method.sig.abstract || [...this.classes.values()].some((candidate) => this.isSubclassOf(candidate.def.name, expression.className) && candidate.def.name !== expression.className &&
4370
+ candidate.methods.has(expression.method) && reachable.has(`%${candidate.def.name}.${expression.method}`)))
4371
+ return expression;
4372
+ return { kind: "call", callee: `%${method.declarer.def.name}.${expression.method}`,
4373
+ args: [this.upcastTo(expression.args[0], method.declarer.def.name), ...expression.args.slice(1)], type: expression.type, loc: expression.loc };
4374
+ } });
4217
4375
  this.reachableForArtifacts = reachable;
4218
4376
  return { reachable, result: this.finishModule(functions) };
4219
4377
  }
@@ -4231,12 +4389,17 @@ export class Lowerer {
4231
4389
  noteVirtualEdge(info, method) {
4232
4390
  if (!this.onEdge)
4233
4391
  return;
4392
+ if (this.constructedClasses) {
4393
+ const methods = this.virtualEdges.get(info) ?? new Set();
4394
+ methods.add(method);
4395
+ this.virtualEdges.set(info, methods);
4396
+ }
4234
4397
  const above = this.findMethodOn(info, method);
4235
4398
  if (above)
4236
4399
  this.noteEdge(`%${above.declarer.def.name}.${method}`);
4237
4400
  const below = (c) => {
4238
4401
  for (const s of c.subclasses) {
4239
- if (s.methods.has(method))
4402
+ if (this.classCanBeConstructed(s) && s.methods.has(method))
4240
4403
  this.noteEdge(`%${s.def.name}.${method}`);
4241
4404
  below(s);
4242
4405
  }
@@ -4587,6 +4750,16 @@ export class Lowerer {
4587
4750
  return fenceStaticReadableStreamMember(this, access, use);
4588
4751
  }
4589
4752
  typeOf(node) {
4753
+ if (ts.isPropertyAccessExpression(node) && isJsSourceFile(node.getSourceFile())) {
4754
+ const receiver = node.expression.kind === ts.SyntaxKind.ThisKeyword && this.fnStack.length > 0
4755
+ ? this.resolveThis()?.type : this.mapTypeOf(this.checker.getTypeAtLocation(node.expression));
4756
+ const checkedThis = node.expression.kind === ts.SyntaxKind.ThisKeyword && this.fnStack.length > 0 && receiver?.kind === "dyn"
4757
+ ? this.currentClass : null;
4758
+ if (receiver?.kind === "object" && this.classes.get(receiver.className)?.fields.get(node.name.text)?.kind === "dyn" ||
4759
+ checkedThis?.fields.get(node.name.text)?.kind === "dyn") {
4760
+ return this.checker.getUnknownType();
4761
+ }
4762
+ }
4590
4763
  // A checked JS method receives its actual call-site receiver. Its
4591
4764
  // declaration's inferred class type must not turn property reads back
4592
4765
  // into native field loads when the method is borrowed by another object.
@@ -4637,8 +4810,15 @@ export class Lowerer {
4637
4810
  // A checked value can contain any runtime kind. A checker-proven
4638
4811
  // branch narrow therefore cannot contradict this specialization;
4639
4812
  // reads still validate the payload through maybeNarrow.
4640
- if (boundIr.kind === "dyn")
4641
- return t;
4813
+ if (boundIr.kind === "dyn") {
4814
+ // JSDoc and initializer inference are declaration types, not flow
4815
+ // proofs. A checked specialization must not reinstate those
4816
+ // stale layouts (mutable/null slots and heterogeneous JS arrays).
4817
+ const declaration = sym && this.checker.valueDeclarationOf(sym);
4818
+ const declared = declaration && ts.isParameter(declaration)
4819
+ ? this.mapTypeOf(this.checker.getTypeAtLocation(declaration.name)) : null;
4820
+ return declared && typeEquals(declared, narrowedIr) ? bound : t;
4821
+ }
4642
4822
  // A union binding narrowed to one of its arms (typeof/equality
4643
4823
  // guards over string|number bindings) — the narrow is truth.
4644
4824
  if (boundIr.kind === "union") {
@@ -5063,7 +5243,14 @@ export class Lowerer {
5063
5243
  // undefined/null literals store the dyn unit values. Types outside the
5064
5244
  // dyn's domain (bytes, classes, Maps, ...) fall through to
5065
5245
  // requireExactShape's SC1101 fence.
5066
- // A promise flowing into a VOID-promise slot (an inferred
5246
+ // Promise payloads may widen at a checked return boundary, including
5247
+ // arrays inferred as tuple results by Promise.all. Keep both payload
5248
+ // ABIs explicit: box settlement, then validate the destination payload.
5249
+ if (expected.kind === "promise" && expected.inner.kind !== "void" && expr.type.kind === "promise" &&
5250
+ !typeEquals(expected, expr.type) && this.dynConvertible(expr.type) &&
5251
+ canDynCheckTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id))) {
5252
+ return { kind: "dynCheck", value: this.coerceToExpected(expr, DYN), type: expected, loc: expr.loc };
5253
+ }
5067
5254
  // Promise<never> return holding a `return Promise.reject(value)` the
5068
5255
  // dyn arm typed promise<dyn>): awaiting through the slot ignores the
5069
5256
  // fulfillment payload (scr_await_void) and rejections flow untyped,
@@ -7749,7 +7936,7 @@ export class Lowerer {
7749
7936
  // NamedEvaluation through a variable initializer) — inspect prints
7750
7937
  // [Function: name] and call errors spell it, like Node.
7751
7938
  if (e.kind === "dynFrom" && e.value.type.kind === "func" && e.fnName === undefined) {
7752
- const name = jsFuncNameOf(node);
7939
+ const name = jsFuncNameOf(node, this);
7753
7940
  if (name !== null)
7754
7941
  e = { ...e, fnName: name };
7755
7942
  }
@@ -8039,7 +8226,7 @@ export class Lowerer {
8039
8226
  }
8040
8227
  }
8041
8228
  let e = this.lowerExpr(node);
8042
- if (expected?.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0) {
8229
+ if (expected?.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0 || expected?.kind === "dyn" && isJsSourceFile(node.getSourceFile())) {
8043
8230
  // A destination that accepts undefined must retain an unchecked
8044
8231
  // read's storage value even when the checker still calls it present.
8045
8232
  e = this.runtimeOptionalSourceValue(node, e) ?? e;
@@ -8100,7 +8287,19 @@ export class Lowerer {
8100
8287
  * declared result type of an index-signature read under
8101
8288
  * noUncheckedIndexedAccess. Null when the type cannot take the arm. */
8102
8289
  withUndefinedArmOf(t) {
8103
- return withUndefinedArmCanonical(t, this.unions);
8290
+ if (t.kind !== "union")
8291
+ return withUndefinedArmCanonical(t, this.unions);
8292
+ const cached = this.addedUndefinedArms.get(t.unionId);
8293
+ if (cached && cached.unions === this.unions.revision)
8294
+ return cached.type;
8295
+ // As with removing undefined, repeated optional-read propagation can
8296
+ // reuse the exact union transformation until a recursive contract closes.
8297
+ // An unknown id is not cached: a later interning can create it.
8298
+ if (!this.unions.get(t.unionId))
8299
+ return null;
8300
+ const type = withUndefinedArmCanonical(t, this.unions);
8301
+ this.addedUndefinedArms.set(t.unionId, { type, unions: this.unions.revision });
8302
+ return type;
8104
8303
  }
8105
8304
  /** True when a static type converts to a dyn value (the dynFrom
8106
8305
  * walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the checked-dynamic tree's
@@ -8562,9 +8761,10 @@ export class Lowerer {
8562
8761
  lowerStaticFieldInits(info) {
8563
8762
  return lowerStaticFieldInits(this, info);
8564
8763
  }
8565
- /** The method-like members (methods and accessors) of a class that have
8566
- * lowerable bodies, with their collected method-map names. */
8567
- *classMethodMembers(info) {
8764
+ /** Method-like members with their collected method-map names. Body
8765
+ * lowering omits abstract declarations; ABI analysis must include them
8766
+ * because an abstract-typed call selects the same virtual slot. */
8767
+ *classMethodMembers(info, includeAbstract = false) {
8568
8768
  if (!info.decl)
8569
8769
  return; // builtin error classes: runtime-provided bodies
8570
8770
  for (const member of info.decl.members) {
@@ -8588,7 +8788,8 @@ export class Lowerer {
8588
8788
  if (baseName === null)
8589
8789
  continue;
8590
8790
  const mName = ts.isMethodDeclaration(fnLike) ? baseName : `${ts.isGetAccessor(fnLike) ? "get" : "set"}:${baseName}`;
8591
- if (!info.methods.get(mName) || !fnLike.body)
8791
+ const signature = info.methods.get(mName);
8792
+ if (!signature || (!fnLike.body && !(includeAbstract && signature.abstract)))
8592
8793
  continue;
8593
8794
  yield { mName, member: fnLike };
8594
8795
  }
@@ -9755,6 +9956,13 @@ export class Lowerer {
9755
9956
  * member access that IS a module in its own right (`fs.promises` — the
9756
9957
  * same object as node:fs/promises, Node's rule). Null otherwise. */
9757
9958
  builtinNamespaceModuleOf(expr) {
9959
+ // Default and CommonJS process bindings alias the global object, whose
9960
+ // methods and properties keep their existing process lowerings.
9961
+ if (stdlibGlobalNameOf(this, expr) === "process")
9962
+ return null;
9963
+ const imported = ts.isIdentifier(expr) ? this.builtinImportOf(expr) : null;
9964
+ if (imported?.module === "util" && imported.member === "types")
9965
+ return "util/types";
9758
9966
  const stored = ts.isIdentifier(expr)
9759
9967
  ? (this.peekLocal(expr)?.type ?? this.globalOf(expr)?.type)
9760
9968
  : undefined;
@@ -10040,6 +10248,12 @@ export class Lowerer {
10040
10248
  * deliberately narrower than table membership because many table rows
10041
10249
  * are only dispatch sentinels for call-site-specific lowering. */
10042
10250
  lowerBuiltinCallableValue(bi, loc) {
10251
+ if (bi.module === "util" && bi.member === "types")
10252
+ return utilTypesModuleValue(this, loc);
10253
+ if (bi.module === "util/types" && builtinModuleFnOf(this, bi.module, bi.member))
10254
+ return lowerUtilTypeValue(this, bi.member, loc);
10255
+ if (bi.module === "util" && bi.member === "getSystemErrorMap")
10256
+ return lowerSystemErrorMapValue(this, loc);
10043
10257
  if (bi.module === "fs" && builtinModuleFnOf(this, bi.module, bi.member)?.fn === "fs.callbackCall") {
10044
10258
  return { kind: "libCall", fn: "fs.callbackValue", args: [{ kind: "strLit", value: bi.member, type: STRING, loc }], type: DYN, loc };
10045
10259
  }
@@ -10054,6 +10268,8 @@ export class Lowerer {
10054
10268
  if (param.mode === "rest")
10055
10269
  return { mode: "rest", type: arrayOf(param.type) };
10056
10270
  if (param.mode === "optional") {
10271
+ if (param.type.kind === "dyn" && param.defaultValue === undefined)
10272
+ return { mode: "omittable", type: DYN };
10057
10273
  return { mode: "omittable", type: this.withUndefinedArm(param.type), bodyType: param.type };
10058
10274
  }
10059
10275
  return { mode: "required", type: param.type };
@@ -10085,7 +10301,10 @@ export class Lowerer {
10085
10301
  };
10086
10302
  if (valueParam.mode !== "optional")
10087
10303
  return ref;
10088
- if ((valueParam.type.kind !== "string" && valueParam.type.kind !== "f64") || param.type.kind !== "union") {
10304
+ // Checked runtime APIs consume undefined directly for omitted options.
10305
+ if (valueParam.type.kind === "dyn" && valueParam.defaultValue === undefined)
10306
+ return ref;
10307
+ if (valueParam.defaultValue === undefined || (valueParam.type.kind !== "string" && valueParam.type.kind !== "f64") || param.type.kind !== "union") {
10089
10308
  throw new InternalCompilerError(`builtin callable value '${display}' has an unsupported optional default`);
10090
10309
  }
10091
10310
  const undefTag = this.armTag(param.type.unionId, UNDEFINED_T);