@scriptc/compiler 0.2.0 → 0.2.2

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 (284) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +84 -19
  2. package/dist/backend/cycle-analysis.js +1 -0
  3. package/dist/backend/cycle-analysis.js.map +1 -1
  4. package/dist/backend/llvm/classes.js +21 -5
  5. package/dist/backend/llvm/classes.js.map +1 -1
  6. package/dist/backend/llvm/dyn.d.ts +8 -0
  7. package/dist/backend/llvm/dyn.js +247 -108
  8. package/dist/backend/llvm/dyn.js.map +1 -1
  9. package/dist/backend/llvm/emitter.d.ts +6 -3
  10. package/dist/backend/llvm/emitter.js +99 -25
  11. package/dist/backend/llvm/emitter.js.map +1 -1
  12. package/dist/backend/llvm/emitter.test.js +9 -1
  13. package/dist/backend/llvm/emitter.test.js.map +1 -1
  14. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  15. package/dist/backend/llvm/expr-bytes.js +28 -17
  16. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  17. package/dist/backend/llvm/expr-containers.js +5 -0
  18. package/dist/backend/llvm/expr-containers.js.map +1 -1
  19. package/dist/backend/llvm/expr-control.js +1 -1
  20. package/dist/backend/llvm/expr-control.js.map +1 -1
  21. package/dist/backend/llvm/expr-dynamic.js +47 -13
  22. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  23. package/dist/backend/llvm/expr-primitives.js +11 -1
  24. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  25. package/dist/backend/llvm/expr-records.js +11 -3
  26. package/dist/backend/llvm/expr-records.js.map +1 -1
  27. package/dist/backend/llvm/expr-stream-bridges.js +187 -18
  28. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  29. package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
  30. package/dist/backend/llvm/expr-stream-callbacks.js +7 -57
  31. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  32. package/dist/backend/llvm/lib-dispatch.js +41 -3
  33. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  34. package/dist/backend/llvm/lib-filesystem.js +12 -9
  35. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  36. package/dist/backend/llvm/lib-process.js +23 -3
  37. package/dist/backend/llvm/lib-process.js.map +1 -1
  38. package/dist/backend/llvm/lib-shared.js +80 -3
  39. package/dist/backend/llvm/lib-shared.js.map +1 -1
  40. package/dist/backend/llvm/shapes.js +8 -2
  41. package/dist/backend/llvm/shapes.js.map +1 -1
  42. package/dist/backend/may-throw.js +4 -0
  43. package/dist/backend/may-throw.js.map +1 -1
  44. package/dist/backend/native-codegen.d.ts +1 -1
  45. package/dist/backend/native-codegen.js +4 -3
  46. package/dist/backend/native-codegen.js.map +1 -1
  47. package/dist/backend/native-codegen.test.js +11 -0
  48. package/dist/backend/native-codegen.test.js.map +1 -1
  49. package/dist/backend/native-toolchain.d.ts +3 -6
  50. package/dist/backend/native-toolchain.js +53 -23
  51. package/dist/backend/native-toolchain.js.map +1 -1
  52. package/dist/backend/native-toolchain.test.js +72 -0
  53. package/dist/backend/native-toolchain.test.js.map +1 -1
  54. package/dist/backend/runtime-abi.d.ts +2 -2
  55. package/dist/backend/runtime-abi.js +2 -2
  56. package/dist/backend/runtime-pack-native.js +4 -1
  57. package/dist/backend/runtime-pack-native.js.map +1 -1
  58. package/dist/backend/runtime-pack-targets.test.js +1 -1
  59. package/dist/backend/runtime-pack.test.js +1 -1
  60. package/dist/backend/target-diagnostics.d.ts +5 -0
  61. package/dist/backend/target-diagnostics.js +72 -1
  62. package/dist/backend/target-diagnostics.js.map +1 -1
  63. package/dist/backend/target-diagnostics.test.d.ts +1 -0
  64. package/dist/backend/target-diagnostics.test.js +68 -0
  65. package/dist/backend/target-diagnostics.test.js.map +1 -0
  66. package/dist/backend/targets.js +10 -6
  67. package/dist/backend/targets.js.map +1 -1
  68. package/dist/backend/targets.test.js +7 -0
  69. package/dist/backend/targets.test.js.map +1 -1
  70. package/dist/compat/fetch-profile.js +34 -4
  71. package/dist/compat/fetch-profile.js.map +1 -1
  72. package/dist/coverage/surface-manifest.js +5 -3
  73. package/dist/coverage/surface-manifest.js.map +1 -1
  74. package/dist/diagnostics/diagnostic.js +2 -7
  75. package/dist/diagnostics/diagnostic.js.map +1 -1
  76. package/dist/executable/executable-cache.d.ts +7 -3
  77. package/dist/executable/executable-cache.js +47 -11
  78. package/dist/executable/executable-cache.js.map +1 -1
  79. package/dist/executable/executable-cache.test.js +109 -2
  80. package/dist/executable/executable-cache.test.js.map +1 -1
  81. package/dist/executable/prepare.js +2 -1
  82. package/dist/executable/prepare.js.map +1 -1
  83. package/dist/frontend/builtin-modules.d.ts +1 -1
  84. package/dist/frontend/builtin-modules.js +1 -1
  85. package/dist/frontend/builtin-modules.js.map +1 -1
  86. package/dist/frontend/function-completion.d.ts +6 -0
  87. package/dist/frontend/function-completion.js +50 -0
  88. package/dist/frontend/function-completion.js.map +1 -0
  89. package/dist/frontend/lowering/abstract-equality.js +5 -1
  90. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  91. package/dist/frontend/lowering/checked-iterable-spread.d.ts +4 -0
  92. package/dist/frontend/lowering/checked-iterable-spread.js +30 -0
  93. package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -0
  94. package/dist/frontend/lowering/checked-promise-all.d.ts +5 -0
  95. package/dist/frontend/lowering/checked-promise-all.js +31 -0
  96. package/dist/frontend/lowering/checked-promise-all.js.map +1 -0
  97. package/dist/frontend/lowering/class-callbacks.d.ts +4 -4
  98. package/dist/frontend/lowering/class-callbacks.js +29 -17
  99. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  100. package/dist/frontend/lowering/class-construction.d.ts +14 -0
  101. package/dist/frontend/lowering/class-construction.js +185 -0
  102. package/dist/frontend/lowering/class-construction.js.map +1 -0
  103. package/dist/frontend/lowering/class-descriptors.d.ts +2 -1
  104. package/dist/frontend/lowering/class-descriptors.js +58 -10
  105. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  106. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +36 -1
  107. package/dist/frontend/lowering/class-dynamic-dispatch.js +965 -91
  108. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  109. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +66 -3
  110. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  111. package/dist/frontend/lowering/class-instance-constructor.d.ts +1 -1
  112. package/dist/frontend/lowering/class-instance-constructor.js +15 -42
  113. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  114. package/dist/frontend/lowering/class-method-values.d.ts +20 -1
  115. package/dist/frontend/lowering/class-method-values.js +120 -24
  116. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  117. package/dist/frontend/lowering/class-prototypes.d.ts +10 -3
  118. package/dist/frontend/lowering/class-prototypes.js +188 -21
  119. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  120. package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
  121. package/dist/frontend/lowering/class-runtime-statics.js +84 -0
  122. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
  123. package/dist/frontend/lowering/class-static-data.d.ts +1 -0
  124. package/dist/frontend/lowering/class-static-data.js +6 -4
  125. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  126. package/dist/frontend/lowering/containers/bytes.js +66 -17
  127. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  128. package/dist/frontend/lowering/containers/string-and-regexp.js +24 -47
  129. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  130. package/dist/frontend/lowering/deferred-module-initializers.d.ts +13 -0
  131. package/dist/frontend/lowering/deferred-module-initializers.js +410 -0
  132. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -0
  133. package/dist/frontend/lowering/deferred-module-initializers.test.d.ts +1 -0
  134. package/dist/frontend/lowering/deferred-module-initializers.test.js +92 -0
  135. package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -0
  136. package/dist/frontend/lowering/error-methods.d.ts +4 -1
  137. package/dist/frontend/lowering/error-methods.js +100 -1
  138. package/dist/frontend/lowering/error-methods.js.map +1 -1
  139. package/dist/frontend/lowering/expressions/native-proxy.js +3 -1
  140. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
  141. package/dist/frontend/lowering/expressions/nullish-assignment.js +19 -11
  142. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  143. package/dist/frontend/lowering/expressions/object-literals.js +68 -7
  144. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  145. package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
  146. package/dist/frontend/lowering/expressions/optional-chains.js +72 -20
  147. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  148. package/dist/frontend/lowering/function-context.d.ts +11 -3
  149. package/dist/frontend/lowering/function-context.js +11 -5
  150. package/dist/frontend/lowering/function-context.js.map +1 -1
  151. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -0
  152. package/dist/frontend/lowering/generator-dynamic-dispatch.js +39 -1
  153. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  154. package/dist/frontend/lowering/lib-boundary.d.ts +2 -0
  155. package/dist/frontend/lowering/lib-boundary.js +54 -1
  156. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  157. package/dist/frontend/lowering/lower-builtin-values.d.ts +7 -1
  158. package/dist/frontend/lowering/lower-builtin-values.js +113 -3
  159. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  160. package/dist/frontend/lowering/lower-builtins.d.ts +10 -14
  161. package/dist/frontend/lowering/lower-builtins.js +443 -88
  162. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  163. package/dist/frontend/lowering/lower-calls.d.ts +8 -5
  164. package/dist/frontend/lowering/lower-calls.js +717 -142
  165. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  166. package/dist/frontend/lowering/lower-classes.d.ts +18 -13
  167. package/dist/frontend/lowering/lower-classes.js +1076 -188
  168. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  169. package/dist/frontend/lowering/lower-containers.d.ts +9 -0
  170. package/dist/frontend/lowering/lower-containers.js +172 -51
  171. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  172. package/dist/frontend/lowering/lower-dgram.js +3 -2
  173. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  174. package/dist/frontend/lowering/lower-exprs.d.ts +12 -8
  175. package/dist/frontend/lowering/lower-exprs.js +802 -232
  176. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  177. package/dist/frontend/lowering/lower-generators.js +17 -2
  178. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  179. package/dist/frontend/lowering/lower-inspect.js +15 -1
  180. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  181. package/dist/frontend/lowering/lower-island.d.ts +2 -0
  182. package/dist/frontend/lowering/lower-island.js +36 -10
  183. package/dist/frontend/lowering/lower-island.js.map +1 -1
  184. package/dist/frontend/lowering/lower-island.test.d.ts +1 -0
  185. package/dist/frontend/lowering/lower-island.test.js +51 -0
  186. package/dist/frontend/lowering/lower-island.test.js.map +1 -0
  187. package/dist/frontend/lowering/lower-modules.d.ts +1 -3
  188. package/dist/frontend/lowering/lower-modules.js +380 -73
  189. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  190. package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
  191. package/dist/frontend/lowering/lower-modules.test.js +107 -0
  192. package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
  193. package/dist/frontend/lowering/lower-stmts.d.ts +7 -3
  194. package/dist/frontend/lowering/lower-stmts.js +221 -47
  195. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  196. package/dist/frontend/lowering/lower-stmts.test.d.ts +1 -0
  197. package/dist/frontend/lowering/lower-stmts.test.js +77 -0
  198. package/dist/frontend/lowering/lower-stmts.test.js.map +1 -0
  199. package/dist/frontend/lowering/lower-stream.js +3 -1
  200. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  201. package/dist/frontend/lowering/lower-url.d.ts +2 -1
  202. package/dist/frontend/lowering/lower-url.js +32 -9
  203. package/dist/frontend/lowering/lower-url.js.map +1 -1
  204. package/dist/frontend/lowering/lowerer.d.ts +53 -10
  205. package/dist/frontend/lowering/lowerer.js +390 -77
  206. package/dist/frontend/lowering/lowerer.js.map +1 -1
  207. package/dist/frontend/lowering/lowerer.test.js +187 -3
  208. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  209. package/dist/frontend/lowering/module-namespace-elements.d.ts +7 -0
  210. package/dist/frontend/lowering/module-namespace-elements.js +54 -0
  211. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -0
  212. package/dist/frontend/lowering/object-factory-new.d.ts +4 -3
  213. package/dist/frontend/lowering/object-factory-new.js +27 -14
  214. package/dist/frontend/lowering/object-factory-new.js.map +1 -1
  215. package/dist/frontend/lowering/surfaces.d.ts +3 -0
  216. package/dist/frontend/lowering/surfaces.js +48 -19
  217. package/dist/frontend/lowering/surfaces.js.map +1 -1
  218. package/dist/frontend/lowering/text-decoder-encoding.d.ts +2 -0
  219. package/dist/frontend/lowering/text-decoder-encoding.js +8 -0
  220. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
  221. package/dist/frontend/lowering/text-decoder-encoding.test.js +2 -1
  222. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -1
  223. package/dist/frontend/lowering/unregistered-class-types.test.js +3 -3
  224. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
  225. package/dist/frontend/npm-static-prune.js +116 -34
  226. package/dist/frontend/npm-static-prune.js.map +1 -1
  227. package/dist/frontend/npm-static-prune.test.js +8 -0
  228. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  229. package/dist/frontend/program.d.ts +1 -1
  230. package/dist/frontend/program.js +57 -26
  231. package/dist/frontend/program.js.map +1 -1
  232. package/dist/frontend/program.test.js +18 -0
  233. package/dist/frontend/program.test.js.map +1 -1
  234. package/dist/frontend/ts7/ast.js +4 -3
  235. package/dist/frontend/ts7/ast.js.map +1 -1
  236. package/dist/frontend/ts7/semantic-json.js +5 -10
  237. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  238. package/dist/frontend/type-mapper.d.ts +9 -1
  239. package/dist/frontend/type-mapper.js +169 -23
  240. package/dist/frontend/type-mapper.js.map +1 -1
  241. package/dist/frontend/type-mapper.test.js +23 -0
  242. package/dist/frontend/type-mapper.test.js.map +1 -1
  243. package/dist/frontend/union-discriminants.d.ts +1 -1
  244. package/dist/frontend/union-discriminants.js +24 -9
  245. package/dist/frontend/union-discriminants.js.map +1 -1
  246. package/dist/index.js +16 -10
  247. package/dist/index.js.map +1 -1
  248. package/dist/ir/analysis.js +2 -0
  249. package/dist/ir/analysis.js.map +1 -1
  250. package/dist/ir/ir.d.ts +74 -41
  251. package/dist/ir/ir.js +167 -43
  252. package/dist/ir/ir.js.map +1 -1
  253. package/dist/ir/ir.test.js +35 -0
  254. package/dist/ir/ir.test.js.map +1 -1
  255. package/dist/ir/serialize.js +35 -3
  256. package/dist/ir/serialize.js.map +1 -1
  257. package/dist/ir/serialize.test.js +26 -1
  258. package/dist/ir/serialize.test.js.map +1 -1
  259. package/dist/ir/traverse.d.ts +0 -3
  260. package/dist/ir/traverse.js +33 -20
  261. package/dist/ir/traverse.js.map +1 -1
  262. package/dist/ir/validate.js +136 -16
  263. package/dist/ir/validate.js.map +1 -1
  264. package/dist/ir/validate.test.js +77 -1
  265. package/dist/ir/validate.test.js.map +1 -1
  266. package/dist/library/compiler-self-identity.js +1 -1
  267. package/dist/library/compiler-self-identity.test.js +2 -2
  268. package/dist/library/compiler-self-identity.test.js.map +1 -1
  269. package/dist/library/int-infer.d.ts +2 -2
  270. package/dist/library/int-infer.js +10 -7
  271. package/dist/library/int-infer.js.map +1 -1
  272. package/dist/library/int-infer.test.js +44 -0
  273. package/dist/library/int-infer.test.js.map +1 -1
  274. package/dist/library/prepare.js +2 -1
  275. package/dist/library/prepare.js.map +1 -1
  276. package/dist/native/sanitizer.js +3 -1
  277. package/dist/native/sanitizer.js.map +1 -1
  278. package/dist/native/toolchain.d.ts +1 -1
  279. package/dist/native/toolchain.js +26 -6
  280. package/dist/native/toolchain.js.map +1 -1
  281. package/dist/native/toolchain.test.js +53 -1
  282. package/dist/native/toolchain.test.js.map +1 -1
  283. package/package.json +20 -20
  284. package/surface-manifest.json +170 -93
@@ -1,3 +1,4 @@
1
+ import { lowerDynObjectLiteral } from "./expressions/object-literals.js";
1
2
  import { InternalCompilerError } from "../../errors.js";
2
3
  /* Statement lowering: the statement dispatch (lowerStmt), variable
3
4
  * declarations including destructuring patterns, scoped blocks, control
@@ -10,7 +11,7 @@ import { lowerForAwaitGenerator, lowerForOfGenerator, lowerYieldStarStatement }
10
11
  import { lowerForAwaitBuiltin } from "./lower-async-iteration.js";
11
12
  import { BOOL, BYTES_U8, CAUGHT, DYN, F64, JSVAL, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals } from "../../ir/ir.js";
12
13
  import { PoisonError, boundIdentifiersOf, dynFallbackType, dynUndefinedExpr, importCallHandleType, neverTaintedJsType, staticImportNamespaceType, stmtUsesIsland, uncheckedOverloadHandleCall } from "./lowerer.js";
13
- import { enforceLibBoundary } from "./lib-boundary.js";
14
+ import { enforceLibBoundary, lowerSurplusCalls } from "./lib-boundary.js";
14
15
  import { cjsExportAssignmentOf, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile, isNodeEsmFile, locOf, requireSpecOf } from "../program.js";
15
16
  import { COMPOUND_ASSIGN_OPS, STR_METHODS, UNSUPPORTED_STMT, isStdlibMember, sideEffectFreeOptionValue, stdlibGlobalAliasDecl, stdlibGlobalAliasNameOf, stdlibGlobalNameOf } from "./surfaces.js";
16
17
  import { isNativeBuiltinValueInitializer } from "./lower-builtin-values.js";
@@ -18,18 +19,19 @@ import { isProvenanceSourceFile } from "../provenance-registry.js";
18
19
  import { ambientUndefVarRootOf, lowerImportEquals, nsUndefRead, nsWritableTarget, trapDeclRootOf } from "./lower-namespaces.js";
19
20
  import { expandoWritableTarget, lowerExpandoAssignStmt } from "./lower-expando.js";
20
21
  import { lowerForOfArrayIter, lowerForOfMap, lowerForOfSearchParams, lowerForOfSet, lowerSafeIndexRead, objectIterOverIndexShape, strCharsCall } from "./lower-containers.js";
21
- import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, bindingNeverReassigned, deadUnmappableBinding, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, nullishExprUnitOf, nullishGenericBindingUnitOf, recordKeysArrayCall, registerOverloadedCallableAlias } from "./lower-calls.js";
22
+ import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, bindingNeverReassigned, deadUnmappableBinding, hasExplicitJsDocReturn, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, nullishExprUnitOf, nullishGenericBindingUnitOf, recordKeysArrayCall, registerOverloadedCallableAlias } from "./lower-calls.js";
22
23
  import { isMixinFnBinding, mixinResultBindingClassOf } from "./lower-mixins.js";
23
24
  import { isCompiledPrototypeMember } from "./class-prototypes.js";
24
25
  import { classStaticDataFor } from "./class-static-data.js";
25
26
  import { objectFactorySignature } from "./object-factory-new.js";
26
- import { lowerClassCallbackAssign } from "./class-callbacks.js";
27
+ import { isClassCallback, lowerClassCallbackAssign } from "./class-callbacks.js";
28
+ import { classForInHasKey, classPropertiesHelper } from "./class-dynamic-dispatch.js";
27
29
  import { genericIfaceBindingKeepsClass, staticFieldWriteTarget } from "./lower-classes.js";
28
30
  import { lowerStreamUnderscoreAssign, streamClassAliasDecl } from "./lower-stream.js";
29
31
  import { lowerHttpResPropertyAssignment, lowerHttpServerTimeoutAssignment, lowerServerCloseOverrideAssignment } from "./lower-server.js";
30
32
  import { isNativeFfiRequire, builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, lowerNodeModuleCall, registerBuiltinCallableAlias } from "./lower-builtins.js";
31
33
  import { lowerEnumDeclaration } from "./lower-enums.js";
32
- import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerCompoundValueToTarget, lowerElementCompound, lowerGroupsProjection, matchResultNamedGroupsOf, runtimeOptionalGuardIds, runtimeOptionalTrueIds, symbolFieldInfo, withRuntimeOptionalNarrowed } from "./lower-exprs.js";
34
+ import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerCompoundValueToTarget, lowerElementCompound, lowerIncDec, lowerGroupsProjection, matchResultNamedGroupsOf, runtimeOptionalGuardIds, runtimeOptionalTrueIds, symbolFieldInfo, withRuntimeOptionalNarrowed } from "./lower-exprs.js";
33
35
  import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
34
36
  import { globalSymbolKey } from "./expressions/global-symbols.js";
35
37
  import { lowerShortCircuitAssignment } from "./expressions/nullish-assignment.js";
@@ -69,6 +71,8 @@ function npmStaticReturnedEmptyArrayType(lowerer, decl) {
69
71
  const ownerBody = owner !== undefined && ts.isFunctionLike(owner) ? owner.body : undefined;
70
72
  if (ownerBody === undefined || !ts.isBlock(ownerBody))
71
73
  return null;
74
+ if (owner && ts.isFunctionLike(owner) && !owner.type && !hasExplicitJsDocReturn(owner))
75
+ return null;
72
76
  let returned = false;
73
77
  ts.walkPreorder(ownerBody, (node) => {
74
78
  if (node !== ownerBody && ts.isFunctionLike(node))
@@ -424,13 +428,16 @@ export function lowerStmts(lowerer, stmts) {
424
428
  // fence — inside this statement's poison window, so a JS fence
425
429
  // becomes the statement's runtimeFence exactly like every other
426
430
  // deferred rejection.
427
- if (lowered)
428
- enforceLibBoundary(lowerer, lowered);
429
- if (!appended) {
431
+ if (lowered) {
432
+ const body = [];
430
433
  if (Array.isArray(lowered))
431
- out.push(...lowered);
432
- else if (lowered)
433
- out.push(lowered);
434
+ body.push(...lowered);
435
+ else
436
+ body.push(lowered);
437
+ const rewritten = lowerSurplusCalls(lowerer, body);
438
+ enforceLibBoundary(lowerer, rewritten);
439
+ if (!appended)
440
+ out.push(...rewritten);
434
441
  }
435
442
  // Island accounting (--dynamic coverage): a statement that lowered
436
443
  // but carries island constructs compiles DYNAMICALLY — its work
@@ -588,7 +595,12 @@ export function predeclareForwardCapture(lowerer, symbol) {
588
595
  // TDZ read until the initializing assign completes — JS exactly.
589
596
  if (idx < entry.index || entry.ctx === lowerer.ctx || entry.ctx.tdzPredeclared.has(symbol))
590
597
  return false;
591
- const type = lowerer.irTypeOf(decl.name);
598
+ let type = lowerer.irTypeOf(decl.name);
599
+ if (isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) &&
600
+ (ts.isObjectLiteralExpression(decl.initializer) ||
601
+ (ts.isCallExpression(decl.initializer) && ts.isPropertyAccessExpression(decl.initializer.expression) &&
602
+ decl.initializer.expression.name.text === "assign" && lowerer.isStdlibGlobal(decl.initializer.expression.expression, "Object"))) && lowerer.dynConvertible(type))
603
+ type = DYN;
592
604
  if (!TDZ_KINDS.has(type.kind) || isUnitType(type))
593
605
  return false;
594
606
  const name = decl.name.text;
@@ -1030,12 +1042,9 @@ export function lowerStmt(lowerer, stmt) {
1030
1042
  // (JS), which the undefined arm carries — tsc only allows the bare
1031
1043
  // form when the return type includes undefined/void. A CHECKED-
1032
1044
  // DYNAMIC return slot holds the dyn undefined directly (the
1033
- // appendImplicitUndefinedReturn rule). What remains is JS-only —
1034
- // a JSDoc return claim the body contradicts (ms's parse: `@return
1035
- // {Number}` with a bare early `return;`): no undefined fits the
1036
- // declared representation, so the statement fences honestly (the
1037
- // per-statement JS deferral — the claimed paths still run) instead
1038
- // of slipping an empty return past the validator.
1045
+ // appendImplicitUndefinedReturn rule). JavaScript signatures include
1046
+ // observed empty returns even when JSDoc omits undefined. Any remaining
1047
+ // incompatible boundary keeps the ordinary per-statement refusal.
1039
1048
  let value = null;
1040
1049
  if (stmt.expression) {
1041
1050
  return lowerer.lowerReturnStmt(stmt.expression, locOf(stmt));
@@ -1562,8 +1571,11 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
1562
1571
  * bound name, recursing through hidden temps for nested patterns. */
1563
1572
  export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, out, dynSpell, allowDynObject = false) {
1564
1573
  if (ts.isObjectBindingPattern(pattern)) {
1565
- const patternSymbol = lowerer.typeOf(pattern).getSymbol();
1574
+ const patternType = lowerer.typeOf(pattern);
1575
+ const patternSymbol = patternType.getSymbol();
1566
1576
  allowDynObject ||= patternSymbol?.name === "SegmentData" && lowerer.isStdlibSymbol(patternSymbol);
1577
+ allowDynObject ||= (patternType.flags & ts.TypeFlags.Object) !== 0 && lowerer.mapTypeOf(patternType)?.kind === "dyn";
1578
+ allowDynObject ||= (patternType.flags & ts.TypeFlags.Any) !== 0;
1567
1579
  }
1568
1580
  const present = patternSourceValue(lowerer, srcRef(), ts.isArrayBindingPattern(pattern), out, locOf(pattern), dynSpell);
1569
1581
  if (!typeEquals(present.type, srcType)) {
@@ -1724,13 +1736,13 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
1724
1736
  out.push({
1725
1737
  kind: "varDecl",
1726
1738
  localId: pack.id,
1727
- init: {
1739
+ init: pattern.elements.some((element) => ts.isBindingElement(element) && element.dotDotDotToken) ? {
1728
1740
  kind: "libCall",
1729
1741
  fn: "dyn.iterPack",
1730
1742
  args: [srcRef(), { kind: "strLit", value: dynSpell ?? "", type: STRING, loc }],
1731
1743
  type: DYN,
1732
1744
  loc,
1733
- },
1745
+ } : { kind: "dynIterN", value: srcRef(), count: pattern.elements.length, ...(dynSpell ? { notIterableMessage: dynSpell } : {}), type: DYN, loc },
1734
1746
  loc,
1735
1747
  });
1736
1748
  pattern.elements.forEach((el, i) => {
@@ -1738,7 +1750,9 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
1738
1750
  return; // hole: the position skips
1739
1751
  const elLoc = locOf(el);
1740
1752
  if (el.dotDotDotToken) {
1741
- lowerer.unsupported("SC1031", el, "rest elements over checked-dynamic sources");
1753
+ lowerer.bindPatternTarget(el.name, { kind: "dynInvoke", recv: varRef(pack.id, DYN, elLoc),
1754
+ method: "slice", calleeName: "Array.prototype.slice", args: [lowerer.coerceToExpected(numLit(i, elLoc), DYN)], type: DYN, loc: elLoc }, isLet, out);
1755
+ return;
1742
1756
  }
1743
1757
  let value = {
1744
1758
  kind: "dynKeyGet",
@@ -1752,7 +1766,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
1752
1766
  // its value converting into the checked-dynamic tree like any dyn-slot value.
1753
1767
  const rl = lowerer.declareHiddenLocal("%delem", DYN);
1754
1768
  out.push({ kind: "varDecl", localId: rl.id, init: value, loc: elLoc });
1755
- const dflt = lowerer.coerceToExpected(lowerer.lowerExpr(el.initializer), DYN);
1769
+ const dflt = lowerer.coerceInto(el.initializer, lowerer.lowerExpr(el.initializer), DYN);
1756
1770
  if (dflt.type.kind !== "dyn") {
1757
1771
  lowerer.unsupported("SC1031", el.initializer, `defaults of '${lowerer.fmt(dflt.type)}' type over checked-dynamic sources (the value cannot convert into the checked-dynamic tree)`);
1758
1772
  }
@@ -1875,14 +1889,30 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
1875
1889
  // scoped TypeScript exception: its declared result/token types are
1876
1890
  // deliberately carried by the checked-dynamic tree, so their ordinary
1877
1891
  // object patterns use the same exact keyed-read desugar.
1878
- if (srcType.kind === "dyn" &&
1879
- (isJsSourceFile(pattern.getSourceFile()) || allowDynObject)) {
1892
+ if (srcType.kind === "union" && isJsSourceFile(pattern.getSourceFile()) && lowerer.dynConvertible(srcType)) {
1893
+ lowerer.lowerBindingPattern(pattern, () => lowerer.coerceToExpected(srcRef(), DYN), DYN, isLet, out, dynSpell, allowDynObject);
1894
+ return;
1895
+ }
1896
+ if (srcType.kind === "dyn") {
1880
1897
  for (const el of pattern.elements) {
1881
1898
  if (el.name === undefined)
1882
1899
  continue;
1883
1900
  const loc = locOf(el);
1884
1901
  if (el.dotDotDotToken) {
1885
- lowerer.unsupported("SC1031", el, "rest elements over checked-dynamic sources (the remaining-fields object has no lowering yet)");
1902
+ const keys = [];
1903
+ for (const sibling of pattern.elements) {
1904
+ if (sibling === el || sibling.dotDotDotToken)
1905
+ continue;
1906
+ const key = sibling.propertyName ?? sibling.name;
1907
+ const name = ts.isIdentifier(key) || ts.isStringLiteralLike(key) || ts.isNumericLiteral(key) || ts.isComputedPropertyName(key)
1908
+ ? patternKeyNameOf(lowerer, key) : null;
1909
+ if (name === null)
1910
+ lowerer.unsupported("SC1031", sibling, "rest bindings beside runtime computed keys");
1911
+ keys.push({ kind: "dynFrom", value: { kind: "strLit", value: name, type: STRING, loc }, type: DYN, loc });
1912
+ }
1913
+ lowerer.bindPatternTarget(el.name, { kind: "libCall", fn: "dyn.objectRest", args: [srcRef(),
1914
+ { kind: "dynArrLit", elems: keys, type: DYN, loc }], type: DYN, loc }, isLet, out, allowDynObject);
1915
+ continue;
1886
1916
  }
1887
1917
  const prop = el.propertyName ?? el.name;
1888
1918
  const propName = ts.isIdentifier(prop) || ts.isComputedPropertyName(prop) || ts.isStringLiteralLike(prop) || ts.isNumericLiteral(prop)
@@ -2117,6 +2147,17 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
2117
2147
  lowerer.bindPatternTarget(el.name, value, isLet, out);
2118
2148
  continue;
2119
2149
  }
2150
+ if (!fieldType && isJsSourceFile(el.getSourceFile())) {
2151
+ // Inferred JavaScript shapes can omit optional own properties and
2152
+ // inherit values from their prototype. Read the live checked view.
2153
+ const loc = locOf(el);
2154
+ let value = { kind: "dynKeyGet", value: lowerer.coerceToExpected(srcRef(), DYN),
2155
+ key: { kind: "strLit", value: propName, type: STRING, loc }, type: DYN, loc };
2156
+ if (el.initializer)
2157
+ value = applyBindingDefault(lowerer, el, value);
2158
+ lowerer.bindPatternTarget(el.name, value, isLet, out);
2159
+ continue;
2160
+ }
2120
2161
  if (!fieldType) {
2121
2162
  // The pattern names a field the source SHAPE does not carry —
2122
2163
  // `for (let {x = 1} of [{}])` (signature 08): tsc types the binding
@@ -2437,6 +2478,14 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
2437
2478
  * alike (the caller's bindPatternTarget recurses through the latter). */
2438
2479
  function applyBindingDefault(lowerer, el, value) {
2439
2480
  const name = el.name; // callers skip nameless elisions
2481
+ if (value.type.kind === "dyn") {
2482
+ const loc = value.loc;
2483
+ const local = lowerer.declareHiddenLocal("%bindingDefault", DYN);
2484
+ const ref = varRef(local.id, DYN, loc);
2485
+ const result = { kind: "ternary", cond: { kind: "dynTest", test: "undefined", value: ref, type: BOOL, loc },
2486
+ then: lowerer.lowerExprExpecting(el.initializer, DYN), else_: ref, type: DYN, loc };
2487
+ return { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: local.id, init: value, loc }], result, type: DYN, loc };
2488
+ }
2440
2489
  if (value.type.kind !== "union")
2441
2490
  return value; // no undefined arm: dead default
2442
2491
  if (lowerer.armTag(value.type.unionId, UNDEFINED_T) < 0)
@@ -3282,7 +3331,7 @@ function inferredEvolvingLetType(lowerer, decl) {
3282
3331
  invalid = true;
3283
3332
  return "stop";
3284
3333
  }
3285
- if (ts.isCallExpression(node.right) && implicitMethodCallInfersReturn(lowerer, node.right)) {
3334
+ if (ts.isCallExpression(node.right) && (implicitMethodCallInfersReturn(lowerer, node.right) || isJsSourceFile(node.right.getSourceFile()))) {
3286
3335
  invalid = true;
3287
3336
  return "stop";
3288
3337
  }
@@ -3504,7 +3553,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3504
3553
  : (declSymbol ? lowerer.globalsBySymbol.get(declSymbol) : undefined);
3505
3554
  if (g) {
3506
3555
  let promotedGlobal = lowerer.runtimeOptionalBindingType(decl.name, g.type);
3507
- if (g.type.kind === "func" && decl.initializer !== undefined && ts.isIdentifier(decl.initializer)) {
3556
+ if (g.type.kind === "func" && !decl.type && !hasJsTypeAnnotation(decl) &&
3557
+ decl.initializer !== undefined && ts.isIdentifier(decl.initializer)) {
3508
3558
  const sig = lowerer.fnSigOf(decl.initializer);
3509
3559
  if (sig) {
3510
3560
  promotedGlobal = {
@@ -3537,7 +3587,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3537
3587
  return null;
3538
3588
  }
3539
3589
  const raw = lowerVariableInitializer(lowerer, decl.initializer, g.type.kind === "dyn" && (isNativeBuiltinValueInitializer(lowerer, decl.initializer) ||
3540
- ts.isArrayLiteralExpression(decl.initializer)) ? DYN : undefined);
3590
+ ts.isArrayLiteralExpression(decl.initializer) || ts.isObjectLiteralExpression(decl.initializer)) ? DYN : undefined);
3591
+ if (isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) && raw.type.kind === "dyn" &&
3592
+ (g.type.kind === "record" || g.type.kind === "object"))
3593
+ g.type = DYN;
3594
+ g.type = inferredOptionalRecordType(lowerer, decl, g.type, raw.type);
3541
3595
  const arithmetic = raw.type.kind === "union"
3542
3596
  ? lowerer.unions.get(raw.type.unionId)?.arms
3543
3597
  : undefined;
@@ -3606,7 +3660,14 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3606
3660
  // poisons, still declare the local when its type is representable, so
3607
3661
  // later references to this name don't produce cascading errors.
3608
3662
  const inferredObjectType = isJsSourceFile(decl.getSourceFile()) ? lowerer.mapTypeOf(lowerer.typeOf(decl.name)) : null;
3609
- const expandsObject = inferredObjectType?.kind === "record" && jsObjectBindingExpands(lowerer, decl, inferredObjectType);
3663
+ const inferredObjectArms = inferredObjectType?.kind === "union"
3664
+ ? lowerer.unions.get(inferredObjectType.unionId)?.arms ?? [] : inferredObjectType ? [inferredObjectType] : [];
3665
+ const expandsObject = !decl.type && !hasJsTypeAnnotation(decl) && inferredObjectType !== null &&
3666
+ jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn" ||
3667
+ inferredObjectArms.some((arm) => arm.kind === "record" && jsObjectBindingExpands(lowerer, decl, arm)) ||
3668
+ isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) &&
3669
+ ts.isObjectLiteralExpression(decl.initializer) && decl.initializer.properties.some((property) => ts.isMethodDeclaration(property) || ts.isAccessor(property) || ts.isPropertyAssignment(property) &&
3670
+ (ts.isFunctionExpression(property.initializer) || ts.isArrowFunction(property.initializer)));
3610
3671
  let init;
3611
3672
  try {
3612
3673
  init = expandsObject || (isJsSourceFile(decl.getSourceFile()) && !decl.type &&
@@ -3661,6 +3722,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3661
3722
  staticImportNamespaceType(lowerer, decl.initializer) ??
3662
3723
  (init.type.kind === "moduleNs" ? init.type : null) ??
3663
3724
  (init.type.kind === "dyn" ? DYN : null);
3725
+ if (isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) && init.type.kind === "func")
3726
+ type = init.type;
3664
3727
  if (lowerer.implicitParamTypes !== null &&
3665
3728
  init.type.kind === "dyn" &&
3666
3729
  isJsSourceFile(decl.getSourceFile()) &&
@@ -3669,10 +3732,12 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3669
3732
  }
3670
3733
  const preservesObjectIdentity = init.type.kind === "dyn" &&
3671
3734
  (inferredObjectType?.kind === "record" || inferredObjectType?.kind === "array" ||
3735
+ (isJsSourceFile(decl.getSourceFile()) && inferredObjectArms.some((arm) => arm.kind === "record") &&
3736
+ inferredObjectArms.every((arm) => isUnitType(arm) || arm.kind === "record")) ||
3672
3737
  (isJsSourceFile(decl.getSourceFile()) && inferredObjectType !== null &&
3673
- (inferredObjectType.kind === "date" || inferredObjectType.kind === "func" || jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn")) ||
3738
+ (inferredObjectType.kind === "date" || inferredObjectType.kind === "func" || inferredObjectType.kind === "object" || jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn")) ||
3674
3739
  (isJsSourceFile(decl.getSourceFile()) && inferredObjectType !== null &&
3675
- (isUnitType(inferredObjectType) || inferredObjectType.kind === "union" && lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType)))) &&
3740
+ (inferredObjectType.kind === "void" || isUnitType(inferredObjectType) || inferredObjectType.kind === "union" && lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType)))) &&
3676
3741
  !decl.type && !hasJsTypeAnnotation(decl);
3677
3742
  if (expandsObject || preservesObjectIdentity || (isJsSourceFile(decl.getSourceFile()) &&
3678
3743
  !decl.type && isNativeBuiltinValueInitializer(lowerer, decl.initializer))) {
@@ -3694,6 +3759,10 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3694
3759
  if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
3695
3760
  type = DYN;
3696
3761
  }
3762
+ if (isLet && type !== null && isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) &&
3763
+ (type.kind === "object" || type.kind === "symbol" || jsBindingHasOpenWrites(lowerer, decl))) {
3764
+ type = DYN;
3765
+ }
3697
3766
  const returnedEmptyArrayType = npmStaticReturnedEmptyArrayType(lowerer, decl);
3698
3767
  if (returnedEmptyArrayType !== null) {
3699
3768
  type = returnedEmptyArrayType;
@@ -3753,6 +3822,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3753
3822
  type = init.type;
3754
3823
  runtimeOptional = true;
3755
3824
  }
3825
+ if (type !== null)
3826
+ type = inferredOptionalRecordType(lowerer, decl, type, init.type);
3756
3827
  // A JS binding whose checker type spells a FUNCTION but whose VALUE is
3757
3828
  // already checked-dynamic (`const cb = mustCall(fn)` — the helper's
3758
3829
  // return rides its own box): keep the box. Extracting into the spelled
@@ -3764,6 +3835,9 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3764
3835
  !decl.type && !hasJsTypeAnnotation(decl) && type.rest === true && type.restAbi === undefined)) {
3765
3836
  type = DYN;
3766
3837
  }
3838
+ if (isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) && init.type.kind === "dyn" &&
3839
+ (type?.kind === "record" || type?.kind === "object"))
3840
+ type = DYN;
3767
3841
  // A checker-`any` CONST whose initializer lowered to a STATIC type
3768
3842
  // (`const name = rawName ? rawName.replace(...) : null` — the
3769
3843
  // dyn-receiver machinery and the any-ternary join answer static IR):
@@ -3799,7 +3873,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3799
3873
  lowerer.badType(decl.name, lowerer.typeOf(decl.name));
3800
3874
  let settledType = type;
3801
3875
  if (!isLet && isJsSourceFile(decl.getSourceFile()) && !hasJsTypeAnnotation(decl) && decl.initializer && ts.isNewExpression(decl.initializer)) {
3802
- settledType = objectFactorySignature(lowerer, decl.initializer)?.returnType ?? settledType;
3876
+ settledType = init.type.kind === "dyn" ? DYN : objectFactorySignature(lowerer, decl.initializer)?.returnType ?? settledType;
3803
3877
  }
3804
3878
  const arithmeticType = decl.initializer ? lowerer.runtimeOptionalArithmeticTypes.get(decl.initializer) : undefined;
3805
3879
  const isStringArithmeticUnion = (t) => {
@@ -3934,6 +4008,21 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3934
4008
  }
3935
4009
  return { kind: "varDecl", localId: local.id, init, loc: locOf(decl) };
3936
4010
  }
4011
+ // lib.d.ts declares named captures as strings, but nonparticipating captures
4012
+ // are undefined. Inferred index records retain that runtime representation;
4013
+ // explicit annotations still require a checked conversion at the boundary.
4014
+ function inferredOptionalRecordType(lowerer, decl, declared, actual) {
4015
+ if (decl.type || hasJsTypeAnnotation(decl) || declared.kind !== "record" || actual.kind !== "record")
4016
+ return declared;
4017
+ const target = lowerer.shapes.get(declared.shapeId);
4018
+ const source = lowerer.shapes.get(actual.shapeId);
4019
+ if (!target || !source || target.fields.length || source.fields.length || target.tuple || source.tuple ||
4020
+ !target.indexValue || source.indexValue?.kind !== "union" ||
4021
+ lowerer.armTag(source.indexValue.unionId, UNDEFINED_T) < 0 ||
4022
+ !typeEquals(lowerer.stripUndefinedArm(source.indexValue), target.indexValue))
4023
+ return declared;
4024
+ return actual;
4025
+ }
3937
4026
  function lowerVariableInitializer(lowerer, node, expected) {
3938
4027
  let value = node;
3939
4028
  while (ts.isParenthesizedExpression(value) ||
@@ -3954,6 +4043,8 @@ function lowerVariableInitializer(lowerer, node, expected) {
3954
4043
  return ts.isArrayLiteralExpression(value) || ts.isConditionalExpression(value)
3955
4044
  ? lowerer.lowerExprExpecting(node, expected) : lowerer.lowerExpr(node);
3956
4045
  }
4046
+ if (expected?.kind === "dyn")
4047
+ return lowerDynObjectLiteral(lowerer, value);
3957
4048
  const previous = new Map();
3958
4049
  for (const property of value.properties) {
3959
4050
  if (!ts.isPropertyAssignment(property) || !ts.isComputedPropertyName(property.name))
@@ -3987,7 +4078,7 @@ function jsObjectBindingExpands(lowerer, decl, type) {
3987
4078
  let initializer = decl.initializer;
3988
4079
  while (ts.isParenthesizedExpression(initializer))
3989
4080
  initializer = initializer.expression;
3990
- if (!ts.isObjectLiteralExpression(initializer))
4081
+ if (!ts.isObjectLiteralExpression(initializer) && !ts.isCallExpression(initializer))
3991
4082
  return false;
3992
4083
  if (hasJsTypeAnnotation(decl))
3993
4084
  return false;
@@ -4050,6 +4141,13 @@ function jsObjectBindingExpands(lowerer, decl, type) {
4050
4141
  }
4051
4142
  if (ts.isDeleteExpression(node) && property(node.expression) !== undefined)
4052
4143
  expands = true;
4144
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "setPrototypeOf" &&
4145
+ lowerer.isStdlibGlobal(node.expression.expression, "Object")) {
4146
+ const target = node.arguments[0];
4147
+ const sym = target && ts.isIdentifier(target) ? lowerer.resolveValueSymbol(target) : undefined;
4148
+ if (sym && aliases.has(sym))
4149
+ expands = true;
4150
+ }
4053
4151
  ts.forEachChild(node, visit);
4054
4152
  };
4055
4153
  visit(scope);
@@ -4059,6 +4157,36 @@ export function hasJsTypeAnnotation(decl) {
4059
4157
  const statement = decl.parent?.parent;
4060
4158
  return !!statement && /@type\b/.test(decl.getSourceFile().text.slice(statement.pos, decl.getStart()));
4061
4159
  }
4160
+ /** Inferred JS scalar initializers do not constrain later writes through
4161
+ * an any-valued callback. Keep those bindings open, including captured writes. */
4162
+ export function jsBindingHasOpenWrites(lowerer, decl) {
4163
+ if (!isJsSourceFile(decl.getSourceFile()) || decl.type || hasJsTypeAnnotation(decl) || !ts.isIdentifier(decl.name))
4164
+ return false;
4165
+ const symbol = lowerer.resolveValueSymbol(decl.name);
4166
+ if (!symbol)
4167
+ return false;
4168
+ let owner = decl;
4169
+ while (owner.parent && !ts.isFunctionLike(owner) && !ts.isSourceFile(owner))
4170
+ owner = owner.parent;
4171
+ let writes = lowerer.jsBindingWritesByOwner.get(owner);
4172
+ if (!writes) {
4173
+ const indexed = new Map();
4174
+ ts.walkPreorder(owner, (node) => {
4175
+ if (!ts.isBinaryExpression(node) || node.operatorToken.kind < ts.SyntaxKind.FirstAssignment ||
4176
+ node.operatorToken.kind > ts.SyntaxKind.LastAssignment || !ts.isIdentifier(node.left))
4177
+ return;
4178
+ const entries = indexed.get(node.left.text);
4179
+ if (entries)
4180
+ entries.push(node);
4181
+ else
4182
+ indexed.set(node.left.text, [node]);
4183
+ });
4184
+ writes = indexed;
4185
+ lowerer.jsBindingWritesByOwner.set(owner, writes);
4186
+ }
4187
+ return (writes.get(decl.name.text) ?? []).some((node) => lowerer.resolveValueSymbol(node.left) === symbol &&
4188
+ (lowerer.typeOf(node.right).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0);
4189
+ }
4062
4190
  function immediatelyGuardedAbsenceProbe(lowerer, decl) {
4063
4191
  if (decl.type || !ts.isIdentifier(decl.name) || !decl.initializer)
4064
4192
  return false;
@@ -4171,11 +4299,10 @@ function lowerDynSwitch(lowerer, stmt, disc, labels) {
4171
4299
  if (test.kind === "unitLit") {
4172
4300
  return { kind: "dynTest", test: test.unit, value: stableDisc, type: BOOL, loc: locOf(expression) };
4173
4301
  }
4174
- if (test.type.kind !== "string" && test.type.kind !== "f64" &&
4175
- test.type.kind !== "bool" && test.type.kind !== "dyn") {
4302
+ if (!lowerer.dynConvertible(test.type)) {
4176
4303
  lowerer.unsupported("SC1100", expression, "switch case values that cannot compare strictly with 'unknown'");
4177
4304
  }
4178
- return { kind: "dynScalarEq", left: stableDisc, right: test, type: BOOL, loc: locOf(expression) };
4305
+ return { kind: "dynScalarEq", left: stableDisc, right: lowerer.coerceInto(expression, test, DYN), type: BOOL, loc: locOf(expression) };
4179
4306
  });
4180
4307
  }
4181
4308
  function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
@@ -4228,9 +4355,10 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
4228
4355
  * narrowing tests (`e instanceof C` over hierarchy classes, `typeof e
4229
4356
  * === "string"/"number"/"boolean"`), reads under a proven narrow
4230
4357
  * (caughtRead bridges them with caughtNarrow, trust-the-checker like
4231
- * unionNarrow), and rethrow (`throw e`). Raw uses, captures, and
4232
- * assignment are fenced (SC1063 and friends); destructuring patterns
4233
- * are SC1062. The `: any` / `: unknown` annotations tsc admits both
4358
+ * unionNarrow), and rethrow (`throw e`). Unsupported raw uses and
4359
+ * assignments are fenced (SC1063 and friends); destructuring patterns
4360
+ * are SC1062. Captures retain the snapshot beyond the catch scope.
4361
+ * The `: any` / `: unknown` annotations tsc admits both
4234
4362
  * lower the same way (tsc narrows either through the tests).
4235
4363
  * - `finally` runs on normal completion, exception paths, and every
4236
4364
  * abrupt completion that crosses it. Return values are snapshotted
@@ -4343,6 +4471,16 @@ function lowerDeleteStatement(lowerer, expr) {
4343
4471
  };
4344
4472
  }
4345
4473
  let obj = lowerer.lowerExpr(target.expression);
4474
+ if (isJsSourceFile(expr.getSourceFile()) && obj.type.kind === "object") {
4475
+ const info = lowerer.classes.get(obj.type.className);
4476
+ const keyType = ts.isElementAccessExpression(target) ? lowerer.typeOf(target.argumentExpression) : null;
4477
+ const name = ts.isPropertyAccessExpression(target) ? target.name.text
4478
+ : keyType?.isStringLiteralType() ? keyType.value : null;
4479
+ if (info && name !== null && isClassCallback(lowerer, info, name)) {
4480
+ obj = { kind: "call", callee: classPropertiesHelper(lowerer, loc).name,
4481
+ args: [lowerer.coerceToExpected(obj, DYN)], type: DYN, loc };
4482
+ }
4483
+ }
4346
4484
  if (isJsSourceFile(expr.getSourceFile()) && obj.type.kind === "func" && lowerer.dynConvertible(obj.type)) {
4347
4485
  obj = lowerer.coerceToExpected(obj, DYN);
4348
4486
  }
@@ -4650,7 +4788,7 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
4650
4788
  const exportSym = lowerer.checker.getSymbolAtLocation(expr.left);
4651
4789
  if (exportSym && !lowerer.classBySymbol.has(exportSym))
4652
4790
  lowerer.classBySymbol.set(exportSym, info);
4653
- return { kind: "block", body: [], loc };
4791
+ return { kind: "exprStmt", expr: lowerer.lowerClassExpression(rhs), loc };
4654
4792
  }
4655
4793
  const g = lowerer.globalsByDeclNode.get(expr);
4656
4794
  if (!g)
@@ -5092,6 +5230,11 @@ export function lowerExprStatement(lowerer, expr) {
5092
5230
  if (viaStream)
5093
5231
  return viaStream;
5094
5232
  }
5233
+ if (expr.left.name.text === "lastIndex" && lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression))?.kind === "regex") {
5234
+ const loc = locOf(expr);
5235
+ return { kind: "exprStmt", expr: { kind: "libCall", fn: "regex.resetLastIndex",
5236
+ args: [lowerer.lowerExpr(expr.left.expression), lowerer.lowerExprExpecting(expr.right, F64)], type: VOID, loc }, loc };
5237
+ }
5095
5238
  const unionWrite = lowerUnionFieldWrite(lowerer, expr.left, expr.right);
5096
5239
  if (unionWrite)
5097
5240
  return unionWrite;
@@ -5111,6 +5254,20 @@ export function lowerExprStatement(lowerer, expr) {
5111
5254
  }
5112
5255
  if (!expr.left.questionDotToken) {
5113
5256
  const recv = tryLowerExpression(lowerer, expr.left.expression);
5257
+ if (recv && (recv.type.kind === "dyn" || isJsSourceFile(expr.getSourceFile()) &&
5258
+ recv.type.kind === "union" && lowerer.dynConvertible(recv.type))) {
5259
+ const loc = locOf(expr);
5260
+ return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keySet", args: [lowerer.coerceInto(expr.left.expression, recv, DYN),
5261
+ { kind: "strLit", value: expr.left.name.text, type: STRING, loc },
5262
+ lowerer.lowerExprExpecting(expr.right, DYN)], type: VOID, loc }, loc };
5263
+ }
5264
+ if (recv?.type.kind === "object" && recv.type.className === "%Error") {
5265
+ const loc = locOf(expr);
5266
+ return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keySet", args: [
5267
+ lowerer.coerceToExpected(recv, DYN), { kind: "strLit", value: expr.left.name.text, type: STRING, loc },
5268
+ lowerer.lowerExprExpecting(expr.right, DYN),
5269
+ ], type: VOID, loc }, loc };
5270
+ }
5114
5271
  if (recv && isDynTypedRefType(recv.type)) {
5115
5272
  const info = lowerer.classes.get(recv.type.className);
5116
5273
  if (info && !info.def.runtime && !info.builtinError && !info.builtinEmitter && !info.builtinStream &&
@@ -5213,6 +5370,16 @@ export function lowerExprStatement(lowerer, expr) {
5213
5370
  if ((ts.isPrefixUnaryExpression(expr) || ts.isPostfixUnaryExpression(expr)) &&
5214
5371
  (expr.operator === ts.SyntaxKind.PlusPlusToken ||
5215
5372
  expr.operator === ts.SyntaxKind.MinusMinusToken)) {
5373
+ if (ts.isPropertyAccessExpression(expr.operand) || ts.isElementAccessExpression(expr.operand)) {
5374
+ // Statement and value positions share ToNumeric and reference order.
5375
+ // Namespace/expando globals retain their direct binding path below.
5376
+ const binding = ts.isPropertyAccessExpression(expr.operand)
5377
+ ? expandoWritableTarget(lowerer, expr.operand) ?? nsWritableTarget(lowerer, expr.operand)
5378
+ : null;
5379
+ if (binding)
5380
+ return lowerIncDecToTarget(lowerer, expr, binding);
5381
+ return { kind: "exprStmt", expr: lowerIncDec(lowerer, expr, ts.isPrefixUnaryExpression(expr)), loc: locOf(expr) };
5382
+ }
5216
5383
  // Statement position only: pre/post distinction is unobservable, so
5217
5384
  // both desugar to `x = x ± 1`.
5218
5385
  if (ts.isPropertyAccessExpression(expr.operand) ||
@@ -7713,9 +7880,8 @@ function lowerForOfString(lowerer, stmt, iterable, labels) {
7713
7880
  * properties, so the enumeration is honestly EMPTY (zero iterations;
7714
7881
  * the body typechecked but never evaluates — SEMANTICS.md documents
7715
7882
  * the divergence).
7716
- * - class instances fence: which keys exist on one depends on runtime
7717
- * property creation (unset declared fields, useDefineForClassFields)
7718
- * that the struct model does not track — named, not guessed.
7883
+ * - JavaScript program classes use their live property-creation table.
7884
+ * TypeScript and runtime-owned layouts keep the class-instance fence.
7719
7885
  * Bindings mirror for-of's: const/let declare the per-iteration string
7720
7886
  * local, `var` assigns the hoisted shared slot, a pre-declared
7721
7887
  * identifier target assigns per pass; destructuring heads are tsc
@@ -7726,7 +7892,17 @@ function lowerForIn(lowerer, stmt) {
7726
7892
  if (stdlibGlobalNameOf(lowerer, stmt.expression) === "globalThis") {
7727
7893
  return { kind: "block", body: [], loc };
7728
7894
  }
7729
- const receiver = lowerer.lowerExpr(stmt.expression);
7895
+ let receiver = lowerer.lowerExpr(stmt.expression);
7896
+ if (receiver.type.kind === "object") {
7897
+ const info = lowerer.classes.get(receiver.type.className);
7898
+ let root = info;
7899
+ while (root?.base)
7900
+ root = root.base;
7901
+ if (info?.decl && isJsSourceFile(info.decl.getSourceFile()) && !info.def.runtime &&
7902
+ !root?.def.runtime && !info.builtinError && !info.builtinEmitter && !info.builtinStream) {
7903
+ receiver = lowerer.coerceToExpected(receiver, DYN);
7904
+ }
7905
+ }
7730
7906
  const recvT = receiver.type;
7731
7907
  if (recvT.kind === "dyn") {
7732
7908
  const recv = lowerer.declareHiddenLocal("%indyn", DYN);
@@ -7735,9 +7911,7 @@ function lowerForIn(lowerer, stmt) {
7735
7911
  kind: "dynCheck", value: { kind: "libCall", fn: "dyn.forInKeys", args: [ref], type: DYN, loc },
7736
7912
  type: arrayOf(STRING), loc,
7737
7913
  };
7738
- const loop = lowerForInOverKeys(lowerer, stmt, keys, labels, (key) => ({
7739
- kind: "libCall", fn: "dyn.hasKey", args: [ref, key], type: BOOL, loc,
7740
- }));
7914
+ const loop = lowerForInOverKeys(lowerer, stmt, keys, labels, (key) => classForInHasKey(lowerer, ref, key, loc));
7741
7915
  return { kind: "block", body: [{ kind: "varDecl", localId: recv.id, init: receiver, loc }, loop], loc };
7742
7916
  }
7743
7917
  if (recvT.kind === "array")