@scriptc/compiler 0.2.0 → 0.2.1

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 (194) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +25 -15
  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 +5 -0
  7. package/dist/backend/llvm/dyn.js +166 -99
  8. package/dist/backend/llvm/dyn.js.map +1 -1
  9. package/dist/backend/llvm/emitter.d.ts +2 -2
  10. package/dist/backend/llvm/emitter.js +79 -20
  11. package/dist/backend/llvm/emitter.js.map +1 -1
  12. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  13. package/dist/backend/llvm/expr-bytes.js +28 -17
  14. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  15. package/dist/backend/llvm/expr-control.js +1 -1
  16. package/dist/backend/llvm/expr-control.js.map +1 -1
  17. package/dist/backend/llvm/expr-dynamic.js +18 -9
  18. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  19. package/dist/backend/llvm/expr-primitives.js +11 -1
  20. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  21. package/dist/backend/llvm/expr-records.js +11 -3
  22. package/dist/backend/llvm/expr-records.js.map +1 -1
  23. package/dist/backend/llvm/expr-stream-bridges.js +125 -17
  24. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  25. package/dist/backend/llvm/lib-process.js +23 -3
  26. package/dist/backend/llvm/lib-process.js.map +1 -1
  27. package/dist/backend/llvm/lib-shared.js +45 -2
  28. package/dist/backend/llvm/lib-shared.js.map +1 -1
  29. package/dist/backend/llvm/shapes.js +8 -2
  30. package/dist/backend/llvm/shapes.js.map +1 -1
  31. package/dist/backend/native-toolchain.d.ts +3 -6
  32. package/dist/backend/native-toolchain.js +53 -23
  33. package/dist/backend/native-toolchain.js.map +1 -1
  34. package/dist/backend/native-toolchain.test.js +72 -0
  35. package/dist/backend/native-toolchain.test.js.map +1 -1
  36. package/dist/backend/runtime-abi.d.ts +2 -2
  37. package/dist/backend/runtime-abi.js +2 -2
  38. package/dist/backend/runtime-pack-native.js +4 -1
  39. package/dist/backend/runtime-pack-native.js.map +1 -1
  40. package/dist/backend/runtime-pack-targets.test.js +1 -1
  41. package/dist/backend/runtime-pack.test.js +1 -1
  42. package/dist/backend/targets.js +10 -6
  43. package/dist/backend/targets.js.map +1 -1
  44. package/dist/backend/targets.test.js +7 -0
  45. package/dist/backend/targets.test.js.map +1 -1
  46. package/dist/compat/fetch-profile.js +34 -4
  47. package/dist/compat/fetch-profile.js.map +1 -1
  48. package/dist/diagnostics/diagnostic.js +2 -7
  49. package/dist/diagnostics/diagnostic.js.map +1 -1
  50. package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
  51. package/dist/frontend/lowering/class-callbacks.js +26 -15
  52. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  53. package/dist/frontend/lowering/class-construction.d.ts +12 -0
  54. package/dist/frontend/lowering/class-construction.js +156 -0
  55. package/dist/frontend/lowering/class-construction.js.map +1 -0
  56. package/dist/frontend/lowering/class-descriptors.d.ts +1 -0
  57. package/dist/frontend/lowering/class-descriptors.js +46 -5
  58. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  59. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +11 -1
  60. package/dist/frontend/lowering/class-dynamic-dispatch.js +403 -48
  61. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  62. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +2 -1
  63. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  64. package/dist/frontend/lowering/class-instance-constructor.js +4 -1
  65. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  66. package/dist/frontend/lowering/class-method-values.d.ts +4 -1
  67. package/dist/frontend/lowering/class-method-values.js +72 -7
  68. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  69. package/dist/frontend/lowering/class-prototypes.d.ts +5 -2
  70. package/dist/frontend/lowering/class-prototypes.js +121 -13
  71. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  72. package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
  73. package/dist/frontend/lowering/class-runtime-statics.js +66 -0
  74. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
  75. package/dist/frontend/lowering/class-static-data.js +2 -2
  76. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  77. package/dist/frontend/lowering/containers/bytes.js +49 -13
  78. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  79. package/dist/frontend/lowering/containers/string-and-regexp.js +19 -47
  80. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  81. package/dist/frontend/lowering/error-methods.d.ts +4 -1
  82. package/dist/frontend/lowering/error-methods.js +100 -1
  83. package/dist/frontend/lowering/error-methods.js.map +1 -1
  84. package/dist/frontend/lowering/expressions/native-proxy.js +3 -1
  85. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
  86. package/dist/frontend/lowering/expressions/nullish-assignment.js +19 -11
  87. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  88. package/dist/frontend/lowering/expressions/object-literals.js +38 -7
  89. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  90. package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
  91. package/dist/frontend/lowering/expressions/optional-chains.js +69 -17
  92. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  93. package/dist/frontend/lowering/function-context.d.ts +11 -3
  94. package/dist/frontend/lowering/function-context.js +11 -5
  95. package/dist/frontend/lowering/function-context.js.map +1 -1
  96. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -0
  97. package/dist/frontend/lowering/generator-dynamic-dispatch.js +39 -1
  98. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  99. package/dist/frontend/lowering/lib-boundary.d.ts +2 -0
  100. package/dist/frontend/lowering/lib-boundary.js +54 -1
  101. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  102. package/dist/frontend/lowering/lower-builtin-values.d.ts +7 -1
  103. package/dist/frontend/lowering/lower-builtin-values.js +113 -3
  104. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  105. package/dist/frontend/lowering/lower-builtins.d.ts +6 -5
  106. package/dist/frontend/lowering/lower-builtins.js +156 -41
  107. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  108. package/dist/frontend/lowering/lower-calls.d.ts +8 -5
  109. package/dist/frontend/lowering/lower-calls.js +448 -83
  110. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  111. package/dist/frontend/lowering/lower-classes.d.ts +13 -13
  112. package/dist/frontend/lowering/lower-classes.js +650 -176
  113. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  114. package/dist/frontend/lowering/lower-containers.d.ts +9 -0
  115. package/dist/frontend/lowering/lower-containers.js +135 -36
  116. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  117. package/dist/frontend/lowering/lower-dgram.js +3 -2
  118. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  119. package/dist/frontend/lowering/lower-exprs.d.ts +2 -2
  120. package/dist/frontend/lowering/lower-exprs.js +531 -126
  121. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  122. package/dist/frontend/lowering/lower-generators.js +12 -1
  123. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  124. package/dist/frontend/lowering/lower-island.d.ts +2 -0
  125. package/dist/frontend/lowering/lower-island.js +32 -10
  126. package/dist/frontend/lowering/lower-island.js.map +1 -1
  127. package/dist/frontend/lowering/lower-modules.js +220 -17
  128. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  129. package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
  130. package/dist/frontend/lowering/lower-modules.test.js +39 -0
  131. package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
  132. package/dist/frontend/lowering/lower-stmts.d.ts +7 -3
  133. package/dist/frontend/lowering/lower-stmts.js +135 -26
  134. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  135. package/dist/frontend/lowering/lower-stream.js +1 -1
  136. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  137. package/dist/frontend/lowering/lowerer.d.ts +27 -1
  138. package/dist/frontend/lowering/lowerer.js +172 -50
  139. package/dist/frontend/lowering/lowerer.js.map +1 -1
  140. package/dist/frontend/lowering/lowerer.test.js +149 -3
  141. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  142. package/dist/frontend/lowering/surfaces.d.ts +2 -0
  143. package/dist/frontend/lowering/surfaces.js +25 -8
  144. package/dist/frontend/lowering/surfaces.js.map +1 -1
  145. package/dist/frontend/lowering/text-decoder-encoding.d.ts +2 -0
  146. package/dist/frontend/lowering/text-decoder-encoding.js +5 -0
  147. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
  148. package/dist/frontend/lowering/unregistered-class-types.test.js +3 -3
  149. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
  150. package/dist/frontend/npm-static-prune.js +116 -34
  151. package/dist/frontend/npm-static-prune.js.map +1 -1
  152. package/dist/frontend/npm-static-prune.test.js +8 -0
  153. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  154. package/dist/frontend/program.d.ts +1 -1
  155. package/dist/frontend/program.js +53 -24
  156. package/dist/frontend/program.js.map +1 -1
  157. package/dist/frontend/program.test.js +18 -0
  158. package/dist/frontend/program.test.js.map +1 -1
  159. package/dist/frontend/ts7/ast.js +4 -3
  160. package/dist/frontend/ts7/ast.js.map +1 -1
  161. package/dist/frontend/ts7/semantic-json.js +5 -10
  162. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  163. package/dist/frontend/type-mapper.d.ts +9 -1
  164. package/dist/frontend/type-mapper.js +90 -13
  165. package/dist/frontend/type-mapper.js.map +1 -1
  166. package/dist/frontend/type-mapper.test.js +23 -0
  167. package/dist/frontend/type-mapper.test.js.map +1 -1
  168. package/dist/frontend/union-discriminants.d.ts +1 -1
  169. package/dist/frontend/union-discriminants.js +2 -2
  170. package/dist/frontend/union-discriminants.js.map +1 -1
  171. package/dist/ir/analysis.js +2 -0
  172. package/dist/ir/analysis.js.map +1 -1
  173. package/dist/ir/ir.d.ts +52 -33
  174. package/dist/ir/ir.js +142 -42
  175. package/dist/ir/ir.js.map +1 -1
  176. package/dist/ir/ir.test.js +35 -0
  177. package/dist/ir/ir.test.js.map +1 -1
  178. package/dist/ir/serialize.js +15 -3
  179. package/dist/ir/serialize.js.map +1 -1
  180. package/dist/ir/serialize.test.js +5 -1
  181. package/dist/ir/serialize.test.js.map +1 -1
  182. package/dist/ir/validate.js +80 -11
  183. package/dist/ir/validate.js.map +1 -1
  184. package/dist/ir/validate.test.js +61 -1
  185. package/dist/ir/validate.test.js.map +1 -1
  186. package/dist/native/sanitizer.js +3 -1
  187. package/dist/native/sanitizer.js.map +1 -1
  188. package/dist/native/toolchain.d.ts +1 -1
  189. package/dist/native/toolchain.js +26 -6
  190. package/dist/native/toolchain.js.map +1 -1
  191. package/dist/native/toolchain.test.js +53 -1
  192. package/dist/native/toolchain.test.js.map +1 -1
  193. package/package.json +20 -20
  194. package/surface-manifest.json +56 -81
@@ -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";
@@ -23,7 +24,8 @@ 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 { 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";
@@ -424,13 +426,16 @@ export function lowerStmts(lowerer, stmts) {
424
426
  // fence — inside this statement's poison window, so a JS fence
425
427
  // becomes the statement's runtimeFence exactly like every other
426
428
  // deferred rejection.
427
- if (lowered)
428
- enforceLibBoundary(lowerer, lowered);
429
- if (!appended) {
429
+ if (lowered) {
430
+ const body = [];
430
431
  if (Array.isArray(lowered))
431
- out.push(...lowered);
432
- else if (lowered)
433
- out.push(lowered);
432
+ body.push(...lowered);
433
+ else
434
+ body.push(lowered);
435
+ const rewritten = lowerSurplusCalls(lowerer, body);
436
+ enforceLibBoundary(lowerer, rewritten);
437
+ if (!appended)
438
+ out.push(...rewritten);
434
439
  }
435
440
  // Island accounting (--dynamic coverage): a statement that lowered
436
441
  // but carries island constructs compiles DYNAMICALLY — its work
@@ -1562,8 +1567,11 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
1562
1567
  * bound name, recursing through hidden temps for nested patterns. */
1563
1568
  export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, out, dynSpell, allowDynObject = false) {
1564
1569
  if (ts.isObjectBindingPattern(pattern)) {
1565
- const patternSymbol = lowerer.typeOf(pattern).getSymbol();
1570
+ const patternType = lowerer.typeOf(pattern);
1571
+ const patternSymbol = patternType.getSymbol();
1566
1572
  allowDynObject ||= patternSymbol?.name === "SegmentData" && lowerer.isStdlibSymbol(patternSymbol);
1573
+ allowDynObject ||= (patternType.flags & ts.TypeFlags.Object) !== 0 && lowerer.mapTypeOf(patternType)?.kind === "dyn";
1574
+ allowDynObject ||= (patternType.flags & ts.TypeFlags.Any) !== 0;
1567
1575
  }
1568
1576
  const present = patternSourceValue(lowerer, srcRef(), ts.isArrayBindingPattern(pattern), out, locOf(pattern), dynSpell);
1569
1577
  if (!typeEquals(present.type, srcType)) {
@@ -1724,13 +1732,13 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
1724
1732
  out.push({
1725
1733
  kind: "varDecl",
1726
1734
  localId: pack.id,
1727
- init: {
1735
+ init: pattern.elements.some((element) => ts.isBindingElement(element) && element.dotDotDotToken) ? {
1728
1736
  kind: "libCall",
1729
1737
  fn: "dyn.iterPack",
1730
1738
  args: [srcRef(), { kind: "strLit", value: dynSpell ?? "", type: STRING, loc }],
1731
1739
  type: DYN,
1732
1740
  loc,
1733
- },
1741
+ } : { kind: "dynIterN", value: srcRef(), count: pattern.elements.length, ...(dynSpell ? { notIterableMessage: dynSpell } : {}), type: DYN, loc },
1734
1742
  loc,
1735
1743
  });
1736
1744
  pattern.elements.forEach((el, i) => {
@@ -1738,7 +1746,9 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
1738
1746
  return; // hole: the position skips
1739
1747
  const elLoc = locOf(el);
1740
1748
  if (el.dotDotDotToken) {
1741
- lowerer.unsupported("SC1031", el, "rest elements over checked-dynamic sources");
1749
+ lowerer.bindPatternTarget(el.name, { kind: "dynInvoke", recv: varRef(pack.id, DYN, elLoc),
1750
+ method: "slice", calleeName: "Array.prototype.slice", args: [lowerer.coerceToExpected(numLit(i, elLoc), DYN)], type: DYN, loc: elLoc }, isLet, out);
1751
+ return;
1742
1752
  }
1743
1753
  let value = {
1744
1754
  kind: "dynKeyGet",
@@ -1752,7 +1762,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
1752
1762
  // its value converting into the checked-dynamic tree like any dyn-slot value.
1753
1763
  const rl = lowerer.declareHiddenLocal("%delem", DYN);
1754
1764
  out.push({ kind: "varDecl", localId: rl.id, init: value, loc: elLoc });
1755
- const dflt = lowerer.coerceToExpected(lowerer.lowerExpr(el.initializer), DYN);
1765
+ const dflt = lowerer.coerceInto(el.initializer, lowerer.lowerExpr(el.initializer), DYN);
1756
1766
  if (dflt.type.kind !== "dyn") {
1757
1767
  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
1768
  }
@@ -1875,14 +1885,26 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
1875
1885
  // scoped TypeScript exception: its declared result/token types are
1876
1886
  // deliberately carried by the checked-dynamic tree, so their ordinary
1877
1887
  // object patterns use the same exact keyed-read desugar.
1878
- if (srcType.kind === "dyn" &&
1879
- (isJsSourceFile(pattern.getSourceFile()) || allowDynObject)) {
1888
+ if (srcType.kind === "dyn") {
1880
1889
  for (const el of pattern.elements) {
1881
1890
  if (el.name === undefined)
1882
1891
  continue;
1883
1892
  const loc = locOf(el);
1884
1893
  if (el.dotDotDotToken) {
1885
- lowerer.unsupported("SC1031", el, "rest elements over checked-dynamic sources (the remaining-fields object has no lowering yet)");
1894
+ const keys = [];
1895
+ for (const sibling of pattern.elements) {
1896
+ if (sibling === el || sibling.dotDotDotToken)
1897
+ continue;
1898
+ const key = sibling.propertyName ?? sibling.name;
1899
+ const name = ts.isIdentifier(key) || ts.isStringLiteralLike(key) || ts.isNumericLiteral(key) || ts.isComputedPropertyName(key)
1900
+ ? patternKeyNameOf(lowerer, key) : null;
1901
+ if (name === null)
1902
+ lowerer.unsupported("SC1031", sibling, "rest bindings beside runtime computed keys");
1903
+ keys.push({ kind: "dynFrom", value: { kind: "strLit", value: name, type: STRING, loc }, type: DYN, loc });
1904
+ }
1905
+ lowerer.bindPatternTarget(el.name, { kind: "libCall", fn: "dyn.objectRest", args: [srcRef(),
1906
+ { kind: "dynArrLit", elems: keys, type: DYN, loc }], type: DYN, loc }, isLet, out, allowDynObject);
1907
+ continue;
1886
1908
  }
1887
1909
  const prop = el.propertyName ?? el.name;
1888
1910
  const propName = ts.isIdentifier(prop) || ts.isComputedPropertyName(prop) || ts.isStringLiteralLike(prop) || ts.isNumericLiteral(prop)
@@ -2117,6 +2139,17 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
2117
2139
  lowerer.bindPatternTarget(el.name, value, isLet, out);
2118
2140
  continue;
2119
2141
  }
2142
+ if (!fieldType && isJsSourceFile(el.getSourceFile())) {
2143
+ // Inferred JavaScript shapes can omit optional own properties and
2144
+ // inherit values from their prototype. Read the live checked view.
2145
+ const loc = locOf(el);
2146
+ let value = { kind: "dynKeyGet", value: lowerer.coerceToExpected(srcRef(), DYN),
2147
+ key: { kind: "strLit", value: propName, type: STRING, loc }, type: DYN, loc };
2148
+ if (el.initializer)
2149
+ value = applyBindingDefault(lowerer, el, value);
2150
+ lowerer.bindPatternTarget(el.name, value, isLet, out);
2151
+ continue;
2152
+ }
2120
2153
  if (!fieldType) {
2121
2154
  // The pattern names a field the source SHAPE does not carry —
2122
2155
  // `for (let {x = 1} of [{}])` (signature 08): tsc types the binding
@@ -2437,6 +2470,14 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
2437
2470
  * alike (the caller's bindPatternTarget recurses through the latter). */
2438
2471
  function applyBindingDefault(lowerer, el, value) {
2439
2472
  const name = el.name; // callers skip nameless elisions
2473
+ if (value.type.kind === "dyn") {
2474
+ const loc = value.loc;
2475
+ const local = lowerer.declareHiddenLocal("%bindingDefault", DYN);
2476
+ const ref = varRef(local.id, DYN, loc);
2477
+ const result = { kind: "ternary", cond: { kind: "dynTest", test: "undefined", value: ref, type: BOOL, loc },
2478
+ then: lowerer.lowerExprExpecting(el.initializer, DYN), else_: ref, type: DYN, loc };
2479
+ return { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: local.id, init: value, loc }], result, type: DYN, loc };
2480
+ }
2440
2481
  if (value.type.kind !== "union")
2441
2482
  return value; // no undefined arm: dead default
2442
2483
  if (lowerer.armTag(value.type.unionId, UNDEFINED_T) < 0)
@@ -3537,7 +3578,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3537
3578
  return null;
3538
3579
  }
3539
3580
  const raw = lowerVariableInitializer(lowerer, decl.initializer, g.type.kind === "dyn" && (isNativeBuiltinValueInitializer(lowerer, decl.initializer) ||
3540
- ts.isArrayLiteralExpression(decl.initializer)) ? DYN : undefined);
3581
+ ts.isArrayLiteralExpression(decl.initializer) || ts.isObjectLiteralExpression(decl.initializer)) ? DYN : undefined);
3541
3582
  const arithmetic = raw.type.kind === "union"
3542
3583
  ? lowerer.unions.get(raw.type.unionId)?.arms
3543
3584
  : undefined;
@@ -3606,7 +3647,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3606
3647
  // poisons, still declare the local when its type is representable, so
3607
3648
  // later references to this name don't produce cascading errors.
3608
3649
  const inferredObjectType = isJsSourceFile(decl.getSourceFile()) ? lowerer.mapTypeOf(lowerer.typeOf(decl.name)) : null;
3609
- const expandsObject = inferredObjectType?.kind === "record" && jsObjectBindingExpands(lowerer, decl, inferredObjectType);
3650
+ const inferredObjectArms = inferredObjectType?.kind === "union"
3651
+ ? lowerer.unions.get(inferredObjectType.unionId)?.arms ?? [] : inferredObjectType ? [inferredObjectType] : [];
3652
+ const expandsObject = !decl.type && !hasJsTypeAnnotation(decl) && inferredObjectType !== null &&
3653
+ jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn" ||
3654
+ inferredObjectArms.some((arm) => arm.kind === "record" && jsObjectBindingExpands(lowerer, decl, arm));
3610
3655
  let init;
3611
3656
  try {
3612
3657
  init = expandsObject || (isJsSourceFile(decl.getSourceFile()) && !decl.type &&
@@ -3661,6 +3706,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3661
3706
  staticImportNamespaceType(lowerer, decl.initializer) ??
3662
3707
  (init.type.kind === "moduleNs" ? init.type : null) ??
3663
3708
  (init.type.kind === "dyn" ? DYN : null);
3709
+ if (isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) && init.type.kind === "func")
3710
+ type = init.type;
3664
3711
  if (lowerer.implicitParamTypes !== null &&
3665
3712
  init.type.kind === "dyn" &&
3666
3713
  isJsSourceFile(decl.getSourceFile()) &&
@@ -3669,10 +3716,12 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3669
3716
  }
3670
3717
  const preservesObjectIdentity = init.type.kind === "dyn" &&
3671
3718
  (inferredObjectType?.kind === "record" || inferredObjectType?.kind === "array" ||
3719
+ (isJsSourceFile(decl.getSourceFile()) && inferredObjectArms.some((arm) => arm.kind === "record") &&
3720
+ inferredObjectArms.every((arm) => isUnitType(arm) || arm.kind === "record")) ||
3672
3721
  (isJsSourceFile(decl.getSourceFile()) && inferredObjectType !== null &&
3673
- (inferredObjectType.kind === "date" || inferredObjectType.kind === "func" || jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn")) ||
3722
+ (inferredObjectType.kind === "date" || inferredObjectType.kind === "func" || inferredObjectType.kind === "object" || jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn")) ||
3674
3723
  (isJsSourceFile(decl.getSourceFile()) && inferredObjectType !== null &&
3675
- (isUnitType(inferredObjectType) || inferredObjectType.kind === "union" && lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType)))) &&
3724
+ (inferredObjectType.kind === "void" || isUnitType(inferredObjectType) || inferredObjectType.kind === "union" && lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType)))) &&
3676
3725
  !decl.type && !hasJsTypeAnnotation(decl);
3677
3726
  if (expandsObject || preservesObjectIdentity || (isJsSourceFile(decl.getSourceFile()) &&
3678
3727
  !decl.type && isNativeBuiltinValueInitializer(lowerer, decl.initializer))) {
@@ -3694,6 +3743,10 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3694
3743
  if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
3695
3744
  type = DYN;
3696
3745
  }
3746
+ if (isLet && type !== null && isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) &&
3747
+ (type.kind === "object" || type.kind === "symbol" || jsBindingHasOpenWrites(lowerer, decl))) {
3748
+ type = DYN;
3749
+ }
3697
3750
  const returnedEmptyArrayType = npmStaticReturnedEmptyArrayType(lowerer, decl);
3698
3751
  if (returnedEmptyArrayType !== null) {
3699
3752
  type = returnedEmptyArrayType;
@@ -3799,7 +3852,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
3799
3852
  lowerer.badType(decl.name, lowerer.typeOf(decl.name));
3800
3853
  let settledType = type;
3801
3854
  if (!isLet && isJsSourceFile(decl.getSourceFile()) && !hasJsTypeAnnotation(decl) && decl.initializer && ts.isNewExpression(decl.initializer)) {
3802
- settledType = objectFactorySignature(lowerer, decl.initializer)?.returnType ?? settledType;
3855
+ settledType = init.type.kind === "dyn" ? DYN : objectFactorySignature(lowerer, decl.initializer)?.returnType ?? settledType;
3803
3856
  }
3804
3857
  const arithmeticType = decl.initializer ? lowerer.runtimeOptionalArithmeticTypes.get(decl.initializer) : undefined;
3805
3858
  const isStringArithmeticUnion = (t) => {
@@ -3954,6 +4007,8 @@ function lowerVariableInitializer(lowerer, node, expected) {
3954
4007
  return ts.isArrayLiteralExpression(value) || ts.isConditionalExpression(value)
3955
4008
  ? lowerer.lowerExprExpecting(node, expected) : lowerer.lowerExpr(node);
3956
4009
  }
4010
+ if (expected?.kind === "dyn")
4011
+ return lowerDynObjectLiteral(lowerer, value);
3957
4012
  const previous = new Map();
3958
4013
  for (const property of value.properties) {
3959
4014
  if (!ts.isPropertyAssignment(property) || !ts.isComputedPropertyName(property.name))
@@ -3987,7 +4042,7 @@ function jsObjectBindingExpands(lowerer, decl, type) {
3987
4042
  let initializer = decl.initializer;
3988
4043
  while (ts.isParenthesizedExpression(initializer))
3989
4044
  initializer = initializer.expression;
3990
- if (!ts.isObjectLiteralExpression(initializer))
4045
+ if (!ts.isObjectLiteralExpression(initializer) && !ts.isCallExpression(initializer))
3991
4046
  return false;
3992
4047
  if (hasJsTypeAnnotation(decl))
3993
4048
  return false;
@@ -4050,6 +4105,13 @@ function jsObjectBindingExpands(lowerer, decl, type) {
4050
4105
  }
4051
4106
  if (ts.isDeleteExpression(node) && property(node.expression) !== undefined)
4052
4107
  expands = true;
4108
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "setPrototypeOf" &&
4109
+ lowerer.isStdlibGlobal(node.expression.expression, "Object")) {
4110
+ const target = node.arguments[0];
4111
+ const sym = target && ts.isIdentifier(target) ? lowerer.resolveValueSymbol(target) : undefined;
4112
+ if (sym && aliases.has(sym))
4113
+ expands = true;
4114
+ }
4053
4115
  ts.forEachChild(node, visit);
4054
4116
  };
4055
4117
  visit(scope);
@@ -4059,6 +4121,30 @@ export function hasJsTypeAnnotation(decl) {
4059
4121
  const statement = decl.parent?.parent;
4060
4122
  return !!statement && /@type\b/.test(decl.getSourceFile().text.slice(statement.pos, decl.getStart()));
4061
4123
  }
4124
+ /** Inferred JS scalar initializers do not constrain later writes through
4125
+ * an any-valued callback. Keep those bindings open, including captured writes. */
4126
+ export function jsBindingHasOpenWrites(lowerer, decl) {
4127
+ if (!isJsSourceFile(decl.getSourceFile()) || decl.type || hasJsTypeAnnotation(decl) || !ts.isIdentifier(decl.name))
4128
+ return false;
4129
+ const symbol = lowerer.resolveValueSymbol(decl.name);
4130
+ if (!symbol)
4131
+ return false;
4132
+ let owner = decl;
4133
+ while (owner.parent && !ts.isFunctionLike(owner) && !ts.isSourceFile(owner))
4134
+ owner = owner.parent;
4135
+ let open = false;
4136
+ ts.walkPreorder(owner, (node) => {
4137
+ if (ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
4138
+ node.operatorToken.kind <= ts.SyntaxKind.LastAssignment && ts.isIdentifier(node.left) &&
4139
+ lowerer.resolveValueSymbol(node.left) === symbol &&
4140
+ (lowerer.typeOf(node.right).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0) {
4141
+ open = true;
4142
+ return "stop";
4143
+ }
4144
+ return undefined;
4145
+ });
4146
+ return open;
4147
+ }
4062
4148
  function immediatelyGuardedAbsenceProbe(lowerer, decl) {
4063
4149
  if (decl.type || !ts.isIdentifier(decl.name) || !decl.initializer)
4064
4150
  return false;
@@ -4228,9 +4314,10 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
4228
4314
  * narrowing tests (`e instanceof C` over hierarchy classes, `typeof e
4229
4315
  * === "string"/"number"/"boolean"`), reads under a proven narrow
4230
4316
  * (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
4317
+ * unionNarrow), and rethrow (`throw e`). Unsupported raw uses and
4318
+ * assignments are fenced (SC1063 and friends); destructuring patterns
4319
+ * are SC1062. Captures retain the snapshot beyond the catch scope.
4320
+ * The `: any` / `: unknown` annotations tsc admits both
4234
4321
  * lower the same way (tsc narrows either through the tests).
4235
4322
  * - `finally` runs on normal completion, exception paths, and every
4236
4323
  * abrupt completion that crosses it. Return values are snapshotted
@@ -4343,6 +4430,16 @@ function lowerDeleteStatement(lowerer, expr) {
4343
4430
  };
4344
4431
  }
4345
4432
  let obj = lowerer.lowerExpr(target.expression);
4433
+ if (isJsSourceFile(expr.getSourceFile()) && obj.type.kind === "object") {
4434
+ const info = lowerer.classes.get(obj.type.className);
4435
+ const keyType = ts.isElementAccessExpression(target) ? lowerer.typeOf(target.argumentExpression) : null;
4436
+ const name = ts.isPropertyAccessExpression(target) ? target.name.text
4437
+ : keyType?.isStringLiteralType() ? keyType.value : null;
4438
+ if (info && name !== null && isClassCallback(lowerer, info, name)) {
4439
+ obj = { kind: "call", callee: classPropertiesHelper(lowerer, loc).name,
4440
+ args: [lowerer.coerceToExpected(obj, DYN)], type: DYN, loc };
4441
+ }
4442
+ }
4346
4443
  if (isJsSourceFile(expr.getSourceFile()) && obj.type.kind === "func" && lowerer.dynConvertible(obj.type)) {
4347
4444
  obj = lowerer.coerceToExpected(obj, DYN);
4348
4445
  }
@@ -4650,7 +4747,7 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
4650
4747
  const exportSym = lowerer.checker.getSymbolAtLocation(expr.left);
4651
4748
  if (exportSym && !lowerer.classBySymbol.has(exportSym))
4652
4749
  lowerer.classBySymbol.set(exportSym, info);
4653
- return { kind: "block", body: [], loc };
4750
+ return { kind: "exprStmt", expr: lowerer.lowerClassExpression(rhs), loc };
4654
4751
  }
4655
4752
  const g = lowerer.globalsByDeclNode.get(expr);
4656
4753
  if (!g)
@@ -5092,6 +5189,11 @@ export function lowerExprStatement(lowerer, expr) {
5092
5189
  if (viaStream)
5093
5190
  return viaStream;
5094
5191
  }
5192
+ if (expr.left.name.text === "lastIndex" && lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression))?.kind === "regex") {
5193
+ const loc = locOf(expr);
5194
+ return { kind: "exprStmt", expr: { kind: "libCall", fn: "regex.resetLastIndex",
5195
+ args: [lowerer.lowerExpr(expr.left.expression), lowerer.lowerExprExpecting(expr.right, F64)], type: VOID, loc }, loc };
5196
+ }
5095
5197
  const unionWrite = lowerUnionFieldWrite(lowerer, expr.left, expr.right);
5096
5198
  if (unionWrite)
5097
5199
  return unionWrite;
@@ -5111,6 +5213,13 @@ export function lowerExprStatement(lowerer, expr) {
5111
5213
  }
5112
5214
  if (!expr.left.questionDotToken) {
5113
5215
  const recv = tryLowerExpression(lowerer, expr.left.expression);
5216
+ if (recv?.type.kind === "object" && recv.type.className === "%Error") {
5217
+ const loc = locOf(expr);
5218
+ return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keySet", args: [
5219
+ lowerer.coerceToExpected(recv, DYN), { kind: "strLit", value: expr.left.name.text, type: STRING, loc },
5220
+ lowerer.lowerExprExpecting(expr.right, DYN),
5221
+ ], type: VOID, loc }, loc };
5222
+ }
5114
5223
  if (recv && isDynTypedRefType(recv.type)) {
5115
5224
  const info = lowerer.classes.get(recv.type.className);
5116
5225
  if (info && !info.def.runtime && !info.builtinError && !info.builtinEmitter && !info.builtinStream &&