@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 { pathModuleValue } from "./lower-builtin-values.js";
1
2
  import { everyExprChild, everyStmtChild } from "../../ir/traverse.js";
2
3
  import { RuntimeOptionalLocals } from "./runtime-optional-locals.js";
3
4
  import { sanitizeUnregisteredClassTypes } from "./sanitize-class-types.js";
@@ -29,7 +30,7 @@ import { bindingSource } from "../binding-source.js";
29
30
  import { tsgoPath } from "../dts-paths.js";
30
31
  import * as ts from "../ts7/adapter.js";
31
32
  import { literalValues } from "../literal-values.js";
32
- import { literalUnionArm } from "../union-discriminants.js";
33
+ import { discriminantOwners, literalUnionArm } from "../union-discriminants.js";
33
34
  import { anyOpRequiresDynamicDiag, blockedBindingUseDiag, checkerPanicDiag, componentTypeDiag, isCheckerPanic, genericSignatureTypeDiag, indexSignatureTypeDiag, intersectionTypeDiag, noLoweringDiag, overloadedSignatureTypeDiag, recordShapeMismatchDiag, requiresDynamicApiDiag, requiresDynamicPackageDiag, requiresDynamicTypeDiag, unionMismatchDiag, UNSUPPORTED, unsupportedDiag, unsupportedTypeDiag, } from "../../diagnostics/diagnostic.js";
34
35
  import { arrayOf, BOOL, canAdaptDynFuncTo, canDynCheckTo, canConvertToDyn, canCrossIslandBoundary, canExitIslandToType, canMarshalTypedFuncIntoIsland, DYN, DYN_HANDLE_KINDS, F64, isDynTypedRefType, isJsonSafeType, isJsonStringifySafeType, isSupportedMapKey, isSupportedMapValue, isUndefinedArmedUnion, isUnitType, JSVAL, NULL_T, RUNTIME_ERROR_CLASSES, STRING, typeEquals, UNDEFINED_T, VOID } from "../../ir/ir.js";
35
36
  import {} from "../npm.js";
@@ -50,7 +51,7 @@ import { lowerRegexMethodCall, lowerStringMethodCall } from "./containers/string
50
51
  import { lowerStreamModuleCall } from "./lower-stream.js";
51
52
  import { lowerEmitOverrideSpec } from "./lower-event-emitter.js";
52
53
  import { builtinImportOf, createRequireBindingDecl, createRequireNamespaceDecl, createRequireProgramModuleOf, createRequireSpecOf, stripTypeCasts, lowerBuiltinModuleCall, lowerNodeModuleCall, lowerTimersPromisesSetInterval, lowerFsToUnixTimestampCall, lowerFsLadderCall, lowerChildArgsArg, lowerSpawnSyncCall, lowerSpawnCall, lowerExecFileCall, lowerExecSyncCall, recordToEnvPairs, lowerJsonMethodCall, fencedBuiltinImportOf, lowerCryptoComposedCall, lowerUrlMethodCall, lowerSearchParamsMethodCall, lowerStatsMethodCall, lowerChildMethodCall, lowerAtomicsCall, lowerBuiltinExtraProperty, registerPromisifiedBuiltinDecl, lowerExecFileAsyncCall, execFileAsyncHelper, lowerStringDecoderMethodCall, strdecHelper, lowerReadlineMethodCall, lowerDcChannelMethodCall, lowerDcChannelProperty, lowerAlsMethodCall, lowerDcTracingChannelMethodCall, lowerDcTracingChannelProperty, lowerJsonProperty, lowerErrorCodeProperty, lowerProcessProperty, isProcessEnv, envValueType, lowerProcessEnvGet, lowerProcessMethodCall, lowerProcessOptionalMethodCall, lowerTimeoutMethodCall, envSnapshotHelper, isConsoleLog, consoleCallMember, lowerNumberStaticCall, lowerNumberStaticProperty, lowerDateCall, lowerTextCodecCall, lowerCryptoModuleCall, lowerFsConstantsProperty, lowerBuiltinConstantsProperty, builtinConstantBindingOf, builtinConstantsDestructureDecl, lowerProcessStreamProperty, lowerStringStaticCall, lowerStringLastIndexOfCall, lowerPromiseStaticCall } from "./lower-builtins.js";
53
- import { fenceFetchObjectAssignment, fenceFetchObjectBinding, fenceStaticAbortControllerMemberRead, fenceStaticHeadersIteration, fenceStaticHeadersMember, fenceStaticReadableStreamMember, fenceStaticResponseMember, fenceUnsupportedFetchConstructorMember, isIslandExpr, islandFuncValueFence, islandRegexpOf, jsvalIn, requireDynamicApi, islandGlobalFnOf, lowerAbortControllerNew, lowerDynamicHeadersIteratorCall, lowerDynamicHeadersSpread, lowerDynamicImportCall, lowerFetchCall, lowerFetchElementMethodCall, lowerResponseNew, lowerStaticFetchCompanionCall, lowerStaticAbortControllerCall, lowerStaticAbortSignalListenerCall, lowerStaticReadableStreamCancelCall, lowerStaticReadableStreamControllerCall, lowerStaticReadableStreamNew, lowerStaticReadableStreamReaderCall, lowerStaticResponseCall, lowerIslandMethodCall, lowerMathProperty, npmPackageOf, npmMemberFence, npmPackageOfSymbol } from "./lower-island.js";
54
+ import { fenceFetchObjectAssignment, fenceFetchObjectBinding, fenceStaticAbortControllerMemberRead, fenceStaticHeadersIteration, fenceStaticHeadersMember, fenceStaticReadableStreamMember, fenceStaticResponseMember, fenceUnsupportedFetchConstructorMember, isIslandExpr, islandFuncValueFence, islandRegexpOf, jsvalIn, requireDynamicApi, islandGlobalFnOf, lowerAbortControllerNew, lowerDynamicHeadersIteratorCall, lowerDynamicHeadersSpread, lowerDynamicImportCall, lowerFetchCall, lowerFetchElementMethodCall, lowerResponseNew, lowerFetchWebNew, lowerStaticFetchCompanionCall, lowerStaticAbortControllerCall, lowerStaticAbortSignalListenerCall, lowerStaticReadableStreamCancelCall, lowerStaticReadableStreamControllerCall, lowerStaticReadableStreamNew, lowerStaticReadableStreamReaderCall, lowerStaticResponseCall, lowerIslandMethodCall, lowerMathProperty, npmPackageOf, npmMemberFence, npmPackageOfSymbol } from "./lower-island.js";
54
55
  import { lowerHttpHeadersElement, lowerNetModuleCall, lowerServerMethodCall, lowerServerProperty, lowerTlsRootCertificates } from "./lower-server.js";
55
56
  import { lowerDgramDnsModuleCall, lowerDgramMethodCall } from "./lower-dgram.js";
56
57
  import { lowerNodeTestModuleCall, lowerTestDirectCall, lowerTestMethodCall, lowerTestCtxProperty } from "./lower-test.js";
@@ -514,6 +515,14 @@ export function dynFallbackType(lowerer, node, t) {
514
515
  if (!isJsSourceFile(node.getSourceFile())) {
515
516
  if (t.flags & ts.TypeFlags.Any)
516
517
  return DYN;
518
+ const symbol = t.getSymbol();
519
+ const args = symbol && lowerer.isStdlibSymbol(symbol) ? lowerer.checker.getTypeArguments(t) : [];
520
+ if (symbol?.name === "Promise" && args[0] && args[0].flags & ts.TypeFlags.Any)
521
+ return jsFallbackPromiseType(lowerer, t);
522
+ if (symbol && ["Generator", "AsyncGenerator", "IterableIterator"].includes(symbol.name) && args.some((arg) => arg.flags & ts.TypeFlags.Any))
523
+ return jsFallbackGeneratorType(lowerer, t);
524
+ if (lowerer.checker.isArrayType(t) && ((lowerer.checker.getTypeArguments(t)[0]?.flags ?? 0) & ts.TypeFlags.Any) !== 0)
525
+ return DYN;
517
526
  // TS single-call-signature function types: per-piece fallback, but
518
527
  // ONLY `any` pieces fall to dyn — any other unmappable piece keeps
519
528
  // the whole type's own fence.
@@ -765,6 +774,9 @@ export function jsFuncNameOf(node) {
765
774
  if (p && ts.isVariableDeclaration(p) && p.initializer === n && ts.isIdentifier(p.name)) {
766
775
  return p.name.text;
767
776
  }
777
+ if (p && ts.isBindingElement(p) && p.initializer === n && ts.isIdentifier(p.name)) {
778
+ return p.name.text;
779
+ }
768
780
  if (p && ts.isPropertyAssignment(p) && p.initializer === n && ts.isIdentifier(p.name)) {
769
781
  return p.name.text;
770
782
  }
@@ -1331,6 +1343,15 @@ export class Lowerer {
1331
1343
  /** Union re-tag helpers (%union.retag.N), interned per (from, to)
1332
1344
  * unionId pair — see unionRetagHelper. */
1333
1345
  retagHelpers = new Map();
1346
+ /** Copy-only routes depend on the two union contracts and discriminator
1347
+ * layouts, without recursive width assumptions or evolving class members. */
1348
+ copyRetagHelpers = new Map();
1349
+ unionLiteralOwners = new Map();
1350
+ strippedUndefinedArms = new Map();
1351
+ stdlibSymbols = new Map();
1352
+ /** Method adapter names are owned by class-method-values. Looking them
1353
+ * up must not scan and retain every unrelated lifted function. */
1354
+ classMethodValueHelpers = new Set();
1334
1355
  /** Callee names of every interned coercion helper whose CALL mints a
1335
1356
  * FRESH closure per evaluation (%fn.width.*, %fn.adapt.*,
1336
1357
  * %fnval.spawnres.*). Registered at the mint site — NOT recovered by
@@ -1415,6 +1436,9 @@ export class Lowerer {
1415
1436
  /** Keyed by program-wide qualified class name (what IR object types carry). */
1416
1437
  classes = new Map();
1417
1438
  classBySymbol = new Map();
1439
+ /** Named method slots observed before class collection need a callable
1440
+ * ABI and shared prototype descriptors instead of call-site specialization. */
1441
+ prototypeMethodAccesses = new Map();
1418
1442
  /** Inferred JS methods participating in an override chain keep a vtable
1419
1443
  * ABI instead of call-site specialization. Filled before class collection. */
1420
1444
  virtualJsMethods = new Set();
@@ -1566,7 +1590,10 @@ export class Lowerer {
1566
1590
  /** One Error-method helper belongs to this lowering session. Its cached
1567
1591
  * dispatch revision needs no weak-key identity or process-global state. */
1568
1592
  errorMethodDispatchRevision = null;
1593
+ errorPropertyDispatchRevision = null;
1569
1594
  lambdaCounter = 0;
1595
+ preparedClassFactories = new Map();
1596
+ preparingClassFactories = new Set();
1570
1597
  /** Statement lists currently mid-lowering, innermost last: the forward-
1571
1598
  * capture machinery needs to know which later statements of an OPEN list
1572
1599
  * a symbol's declaration sits in, which scope frame list-level declarations
@@ -1703,6 +1730,27 @@ export class Lowerer {
1703
1730
  ? { kind: "object", className: this.mixinTypeContext.className }
1704
1731
  : null,
1705
1732
  localClassInstance: (decl) => {
1733
+ // Computed heritage can close over parameters of its factory.
1734
+ // A speculative checker query outside that factory must not lower
1735
+ // the extends expression in the caller's lexical scope.
1736
+ if (!this.classes.has(this.classNamer(decl)) && !this.collectingExprClasses.has(decl) &&
1737
+ decl.heritageClauses?.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword && clause.types.some((base) => {
1738
+ const expression = base.expression;
1739
+ if (ts.isCallExpression(expression))
1740
+ return true;
1741
+ if (ts.isIdentifier(expression) && this.isStdlibGlobal(expression, expression.text))
1742
+ return false;
1743
+ const symbol = this.checker.getSymbolAtLocation(ts.isPropertyAccessExpression(expression) ? expression.name : expression);
1744
+ const resolved = symbol && symbol.flags & ts.SymbolFlags.Alias ? this.checker.getAliasedSymbol(symbol) : symbol;
1745
+ if (ts.isPropertyAccessExpression(expression) && this.isStdlibGlobal(expression.expression, "globalThis") &&
1746
+ this.builtinErrorInfoOf(resolved))
1747
+ return false;
1748
+ if (resolved && this.classBySymbol.has(resolved))
1749
+ return false;
1750
+ const mapped = this.mapTypeOf(this.typeOf(expression));
1751
+ return mapped?.kind !== "classval" || !this.classes.has(mapped.className);
1752
+ })))
1753
+ return null;
1706
1754
  for (let parent = decl.parent; parent && !ts.isSourceFile(parent); parent = parent.parent) {
1707
1755
  if (!ts.isFunctionDeclaration(parent) && !ts.isFunctionExpression(parent) &&
1708
1756
  !ts.isArrowFunction(parent) && !ts.isMethodDeclaration(parent))
@@ -2266,7 +2314,7 @@ export class Lowerer {
2266
2314
  return null;
2267
2315
  const directSpec = requireSpecOf(decl.initializer);
2268
2316
  if (directSpec !== null) {
2269
- return resolveImport(this.program, decl.getSourceFile(), directSpec) ??
2317
+ return resolveImport(this.program, decl.getSourceFile(), directSpec, "require") ??
2270
2318
  npmStaticDepSf7(this.program, decl.getSourceFile(), directSpec, "require");
2271
2319
  }
2272
2320
  return createRequireProgramModuleOf(this, decl.initializer)?.dep ?? null;
@@ -2586,7 +2634,7 @@ export class Lowerer {
2586
2634
  // Without the guarded %init call at this position
2587
2635
  // those globals stay uninitialized: the dep's module body would never
2588
2636
  // run.
2589
- const dep = resolveImport(this.program, node.getSourceFile(), spec) ??
2637
+ const dep = resolveImport(this.program, node.getSourceFile(), spec, "require") ??
2590
2638
  npmStaticDepSf7(this.program, node.getSourceFile(), spec, "require");
2591
2639
  if (!dep || dep.fileName.endsWith(".json"))
2592
2640
  return null;
@@ -3832,6 +3880,8 @@ export class Lowerer {
3832
3880
  // before collectProgram visits them one by one; reached body lowering
3833
3881
  // will reuse the same answers later.
3834
3882
  this.prefetchClassCollection(parts.flatMap((fp) => fp.classDecls));
3883
+ const collectionEdges = new Set();
3884
+ this.onEdge = (name) => { collectionEdges.add(name); };
3835
3885
  this.collectProgram(parts);
3836
3886
  this.analyzeRuntimeOptionalArrayReads(parts);
3837
3887
  // Decorated classes analyze post-collection here too: the %init seeds
@@ -3894,13 +3944,13 @@ export class Lowerer {
3894
3944
  units.set(`%${cName}.constructor`, {
3895
3945
  order: unitOrder++,
3896
3946
  roots: classCtorRoots(info),
3897
- lower: () => this.lowerClassCtor(info),
3947
+ lower: () => info.localClass && !info.localClass.ready ? null : this.lowerClassCtor(info),
3898
3948
  });
3899
3949
  for (const { mName, member } of this.classMethodMembers(info)) {
3900
3950
  units.set(`%${cName}.${mName}`, {
3901
3951
  order: unitOrder++,
3902
3952
  roots: functionRoots(member),
3903
- lower: () => this.lowerClassMethodMember(info, member),
3953
+ lower: () => info.localClass && !info.localClass.ready ? null : this.lowerClassMethodMember(info, member),
3904
3954
  });
3905
3955
  }
3906
3956
  for (const prop of info.throwingSetters) {
@@ -3996,11 +4046,13 @@ export class Lowerer {
3996
4046
  const cName = info.def.name;
3997
4047
  const register = (name, roots, lower) => {
3998
4048
  units.set(name, { order: unitOrder++, roots, lower });
4049
+ if (reachable.has(name))
4050
+ queue.push(name);
3999
4051
  metadataPriority.set(name, [3, expressionMetadataOrder++]);
4000
4052
  };
4001
- register(`%${cName}.constructor`, classCtorRoots(info), () => this.lowerClassCtor(info));
4053
+ register(`%${cName}.constructor`, classCtorRoots(info), () => info.localClass && !info.localClass.ready ? null : this.lowerClassCtor(info));
4002
4054
  for (const { mName, member } of this.classMethodMembers(info)) {
4003
- register(`%${cName}.${mName}`, functionRoots(member), () => this.lowerClassMethodMember(info, member));
4055
+ register(`%${cName}.${mName}`, functionRoots(member), () => info.localClass && !info.localClass.ready ? null : this.lowerClassMethodMember(info, member));
4004
4056
  }
4005
4057
  if (info.staticMethods)
4006
4058
  for (const [name, entry] of info.staticMethods) {
@@ -4010,6 +4062,8 @@ export class Lowerer {
4010
4062
  register(`%${cName}.set:${prop}`, [], () => this.throwingSetterFn(info, prop));
4011
4063
  }
4012
4064
  };
4065
+ for (const name of collectionEdges)
4066
+ this.onEdge(name);
4013
4067
  // Generic instances queued by the bodies above lower here (an instance
4014
4068
  // body fires edges of its own and can queue further instances of
4015
4069
  // either kind — function instances and class instantiations drain to
@@ -4477,7 +4531,7 @@ export class Lowerer {
4477
4531
  Segmenter: intlHint,
4478
4532
  DisplayNames: intlHint,
4479
4533
  TextEncoder: "TextEncoder instances support encode(string) and encode(); other codec operations require a dedicated lowering",
4480
- TextDecoder: "TextDecoder instances support recognized literal labels with default options and whole-buffer decode(Uint8Array); runtime labels and options remain unsupported",
4534
+ TextDecoder: "TextDecoder instances support recognized labels, fatal/ignoreBOM option literals, and streaming UTF-8/UTF-16/single-byte decode; runtime option objects remain unsupported",
4481
4535
  };
4482
4536
  this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node), typeHints[stdlibOwnSym?.name ?? ""]));
4483
4537
  throw new PoisonError();
@@ -4533,6 +4587,12 @@ export class Lowerer {
4533
4587
  return fenceStaticReadableStreamMember(this, access, use);
4534
4588
  }
4535
4589
  typeOf(node) {
4590
+ // A checked JS method receives its actual call-site receiver. Its
4591
+ // declaration's inferred class type must not turn property reads back
4592
+ // into native field loads when the method is borrowed by another object.
4593
+ if (node.kind === ts.SyntaxKind.ThisKeyword && isJsSourceFile(node.getSourceFile()) &&
4594
+ this.fnStack.length > 0 && this.resolveThis()?.type.kind === "dyn")
4595
+ return this.checker.getUnknownType();
4536
4596
  // Inside an optional-chain body the guarded receiver is typed by its
4537
4597
  // NON-NULLISH type (the chain's tag test proved it), so every
4538
4598
  // receiver-kind check downstream sees the narrowed arm.
@@ -4887,8 +4947,20 @@ export class Lowerer {
4887
4947
  * this is THE tag for that (union, arm) pair program-wide — every wrap,
4888
4948
  * narrow, and tag test agrees by construction. */
4889
4949
  armTag(unionId, arm) {
4950
+ return this.unions.armTag(unionId, arm);
4951
+ }
4952
+ /** Literal ownership depends only on the union contract and record layouts.
4953
+ * Recheck it when recursive placeholders close, not for every literal. */
4954
+ literalUnionArm(unionId, values) {
4890
4955
  const def = this.unions.get(unionId);
4891
- return def ? def.arms.findIndex((a) => typeEquals(a, arm)) : -1;
4956
+ if (!def || values.length === 0)
4957
+ return null;
4958
+ let cached = this.unionLiteralOwners.get(unionId);
4959
+ if (!cached || cached.shapes !== this.shapes.revision || cached.unions !== this.unions.revision) {
4960
+ cached = { owners: discriminantOwners(def, (id) => this.shapes.get(id)), shapes: this.shapes.revision, unions: this.unions.revision };
4961
+ this.unionLiteralOwners.set(unionId, cached);
4962
+ }
4963
+ return literalUnionArm(def, values, (id) => this.shapes.get(id), cached.owners);
4892
4964
  }
4893
4965
  /** Implicit union construction. Wherever a value flows into a typed slot
4894
4966
  * (initializer, assignment, call argument, return, field write, record
@@ -5009,23 +5081,22 @@ export class Lowerer {
5009
5081
  return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr, loc: expr.loc }],
5010
5082
  result: dynUndefinedExpr(expr.loc), type: DYN, loc: expr.loc };
5011
5083
  }
5012
- // An error-HIERARCHY object (builtin subclass or user `extends
5013
- // Error` class) upcasts to the %Error root first — the caughtToDyn
5014
- // encoding (scr_dyn_from_error) carries name/message/code and the
5015
- // runtime CACHES the identity edge, so `instanceof TypeError` on
5016
- // the dyn side still answers exactly (dyn.errInstanceof). Only the
5017
- // root spelling was convertible before; the harness passes typed
5018
- // errors into untyped helpers constantly.
5084
+ // Preserve the concrete class so checked property/method dispatch
5085
+ // discovers user Error subclasses. Runtime boxing selects the live
5086
+ // view by vtable even when an error first crosses through its base.
5019
5087
  if (expr.type.kind === "object" && this.errorHierarchyClassOf(expr.type.className)) {
5020
5088
  return {
5021
5089
  kind: "dynFrom",
5022
- value: this.upcastTo(expr, "%Error"),
5090
+ value: expr,
5023
5091
  type: DYN,
5024
5092
  loc: expr.loc,
5025
5093
  };
5026
5094
  }
5027
5095
  if (expr.kind === "unitLit" || this.dynConvertible(expr.type)) {
5028
- return { kind: "dynFrom", value: expr, type: DYN, loc: expr.loc };
5096
+ const shape = expr.type.kind === "record" ? this.shapes.get(expr.type.shapeId) : undefined;
5097
+ const liveRef = expr.type.kind === "array" || !!shape && (shape.fields.length > 0 || shape.indexValue !== undefined);
5098
+ return { kind: "dynFrom", value: expr, type: DYN, loc: expr.loc,
5099
+ ...(liveRef ? { liveRef: true } : {}) };
5029
5100
  }
5030
5101
  return expr;
5031
5102
  }
@@ -5447,6 +5518,7 @@ export class Lowerer {
5447
5518
  return;
5448
5519
  const sameFamily = (src.kind === "record" && arm.kind === "record") ||
5449
5520
  (src.kind === "array" && arm.kind === "array") ||
5521
+ (src.kind === "func" && arm.kind === "func") ||
5450
5522
  (src.kind === "object" && arm.kind === "object") ||
5451
5523
  // Tuples already lift into ordinary array slots. Consider that
5452
5524
  // same conversion when the array is an arm of a union too.
@@ -5456,9 +5528,30 @@ export class Lowerer {
5456
5528
  if (sameFamily && this.widthLiftPlan(src, arm) !== null)
5457
5529
  candidates.push({ tag: i, arm });
5458
5530
  });
5459
- if (candidates.length !== 1)
5531
+ let selected = candidates;
5532
+ if (selected.length > 1 && src.kind === "record") {
5533
+ const source = this.shapes.get(src.shapeId);
5534
+ // An inferred JS union may widen its tag while retaining variants
5535
+ // with and without a value. Prefer the unique layout whose omitted
5536
+ // fields are explicitly undefined, rather than filling an optional
5537
+ // unknown slot and making both variants look equally compatible.
5538
+ const absentOnly = selected.filter(({ arm }) => {
5539
+ if (!source || arm.kind !== "record")
5540
+ return false;
5541
+ const target = this.shapes.get(arm.shapeId);
5542
+ return target !== undefined && target.fields.every((field) => {
5543
+ if (source.fields.some((present) => present.name === field.name))
5544
+ return true;
5545
+ return isUnitType(field.type) || field.type.kind === "union" &&
5546
+ this.unions.get(field.type.unionId)?.arms.every(isUnitType) === true;
5547
+ });
5548
+ });
5549
+ if (absentOnly.length === 1)
5550
+ selected = absentOnly;
5551
+ }
5552
+ if (selected.length !== 1)
5460
5553
  return null;
5461
- return { how: "liftWrap", tag: candidates[0].tag, arm: candidates[0].arm };
5554
+ return { how: "liftWrap", tag: selected[0].tag, arm: selected[0].arm };
5462
5555
  }
5463
5556
  // A UNION source into a slot that is ONE of its arms (a width copy
5464
5557
  // whose target field narrowed — the option-table choices shape:
@@ -7100,6 +7193,10 @@ export class Lowerer {
7100
7193
  const to = this.unions.get(toId);
7101
7194
  if (!from || !to)
7102
7195
  return null;
7196
+ const request = `${fromId}:${toId}:${trappable === undefined ? "" : [...trappable].sort((a, b) => a - b).join(".")}`;
7197
+ const cached = this.copyRetagHelpers.get(request);
7198
+ if (cached && cached.shapes === this.shapes.revision && cached.unions === this.unions.revision)
7199
+ return cached.name;
7103
7200
  const plan = planUnionRetag(from, to, (id) => this.shapes.get(id), (src, dst) => this.widthLiftPlan(src, dst), trappable);
7104
7201
  if (plan === null)
7105
7202
  return null;
@@ -7111,11 +7208,17 @@ export class Lowerer {
7111
7208
  stranded.push(tag); });
7112
7209
  const key = `${fromId}:${toId}:${stranded.join(".")}`;
7113
7210
  const existing = this.retagHelpers.get(key);
7114
- if (existing)
7115
- return existing;
7116
- const name = `%union.retag.${this.retagHelpers.size}`;
7117
- this.retagHelpers.set(key, name);
7118
- this.liftedFns.push(buildUnionRetag(name, from, to, plan, loc, (lift, value, dst) => this.applyWidthLift(lift, value, dst, loc), (type) => this.fmt(type)));
7211
+ const name = existing ?? `%union.retag.${this.retagHelpers.size}`;
7212
+ if (!existing) {
7213
+ this.retagHelpers.set(key, name);
7214
+ this.liftedFns.push(buildUnionRetag(name, from, to, plan, loc, (lift, value, dst) => this.applyWidthLift(lift, value, dst, loc), (type) => this.fmt(type)));
7215
+ }
7216
+ // Width routes still revalidate on every request. Only a complete plan
7217
+ // of exact payload copies and site-proven traps can bypass planning.
7218
+ if (plan.every((arm) => arm.kind === "trap" || (arm.kind === "direct"
7219
+ ? arm.route.lift.how === "copy" : arm.routes.every((route) => route.lift.how === "copy")))) {
7220
+ this.copyRetagHelpers.set(request, { name, shapes: this.shapes.revision, unions: this.unions.revision });
7221
+ }
7119
7222
  return name;
7120
7223
  }
7121
7224
  /** Interned `%union.narrow.<n>(u)` — the CHECKED single-arm extraction
@@ -7588,7 +7691,7 @@ export class Lowerer {
7588
7691
  const property = this.checker.getPropertyOfType(this.typeOf(literal), def.discriminant.field);
7589
7692
  if (property && !(property.flags & (ts.SymbolFlags.Optional | ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor))) {
7590
7693
  const values = literalValues(this.checker.getTypeOfSymbol(property));
7591
- const arm = values && literalUnionArm(def, values, (id) => this.shapes.get(id));
7694
+ const arm = values && this.literalUnionArm(def.id, values);
7592
7695
  if (arm)
7593
7696
  expr = this.coerceInto(node, expr, arm);
7594
7697
  }
@@ -7611,7 +7714,9 @@ export class Lowerer {
7611
7714
  }
7612
7715
  }
7613
7716
  }
7614
- let e = this.coerceToExpected(expr, expected);
7717
+ let e = this.dynamic && expr.type.kind === "dyn" && expected.kind === "array" && expected.elem.kind === "jsval"
7718
+ ? { kind: "jsExit", value: this.jsvalIn(expr, node), type: expected, loc: expr.loc }
7719
+ : this.coerceToExpected(expr, expected);
7615
7720
  // Existing JavaScript arrays retain mutations and identity across checked
7616
7721
  // slots. Fresh literals have no prior identity and use checked storage
7617
7722
  // directly, so later writes can change their inferred element type.
@@ -7857,7 +7962,7 @@ export class Lowerer {
7857
7962
  const property = this.checker.getPropertyOfType(this.typeOf(node), def.discriminant.field);
7858
7963
  if (property && !(property.flags & (ts.SymbolFlags.Optional | ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor))) {
7859
7964
  const values = literalValues(this.checker.getTypeOfSymbol(property));
7860
- const arm = values && literalUnionArm(def, values, (id) => this.shapes.get(id));
7965
+ const arm = values && this.literalUnionArm(def.id, values);
7861
7966
  if (arm)
7862
7967
  return this.coerceInto(node, this.lowerObjectLiteral(node, arm), expected);
7863
7968
  }
@@ -7865,7 +7970,7 @@ export class Lowerer {
7865
7970
  }
7866
7971
  // An OBJECT LITERAL against a checked-dynamic slot in a JS file (the
7867
7972
  // getSupportInfo options argument — a dyn-ABI param), or against the
7868
- // standard RequestInit/ErrorOptions types in TypeScript: the value's world IS the
7973
+ // standard native option-bag types in TypeScript: the value's world IS the
7869
7974
  // checked-dynamic tree — build the dyn literal directly.
7870
7975
  if (expected?.kind === "dyn") {
7871
7976
  let x = node;
@@ -7885,7 +7990,8 @@ export class Lowerer {
7885
7990
  return sym?.name === name && this.isStdlibSymbol(sym);
7886
7991
  });
7887
7992
  if (ts.isObjectLiteralExpression(x)) {
7888
- if (isJsSourceFile(x.getSourceFile()) || builtinOption("RequestInit") || builtinOption("ErrorOptions")) {
7993
+ if (isJsSourceFile(x.getSourceFile()) || builtinOption("RequestInit") || builtinOption("ErrorOptions") || builtinOption("SpawnOptions") ||
7994
+ !this.mapTypeOf(this.typeOf(x))) {
7889
7995
  return lowerDynObjectLiteral(this, x);
7890
7996
  }
7891
7997
  }
@@ -8096,14 +8202,17 @@ export class Lowerer {
8096
8202
  stripUndefinedArm(t) {
8097
8203
  if (t.kind !== "union")
8098
8204
  return t;
8205
+ const cached = this.strippedUndefinedArms.get(t.unionId);
8206
+ if (cached && cached.unions === this.unions.revision)
8207
+ return cached.type;
8099
8208
  const def = this.unions.get(t.unionId);
8100
- if (!def || !def.arms.some((a) => a.kind === "undefinedT"))
8209
+ if (!def || this.armTag(t.unionId, UNDEFINED_T) < 0)
8101
8210
  return t;
8102
8211
  const rest = def.arms.filter((a) => a.kind !== "undefinedT");
8103
- if (rest.length === 1)
8104
- return rest[0];
8105
8212
  // Removing an arm keeps canonical (typeKey-sorted) order.
8106
- return { kind: "union", unionId: this.unions.transform(def, rest) };
8213
+ const type = rest.length === 1 ? rest[0] : { kind: "union", unionId: this.unions.transform(def, rest) };
8214
+ this.strippedUndefinedArms.set(t.unionId, { type, unions: this.unions.revision });
8215
+ return type;
8107
8216
  }
8108
8217
  /** The interned `T | undefined` union over a non-union arm type — the ABI
8109
8218
  * type of a defaulted parameter, and the result type of lookups that may
@@ -8164,13 +8273,14 @@ export class Lowerer {
8164
8273
  * symbol reports eagerly (nothing could ever reference it). */
8165
8274
  collectDeferring(symbolOf, collect) {
8166
8275
  const sink = [];
8276
+ const previousSink = this.diagSink;
8167
8277
  this.diagSink = sink;
8168
8278
  try {
8169
8279
  collect();
8170
8280
  return null;
8171
8281
  }
8172
8282
  catch (e) {
8173
- this.diagSink = null;
8283
+ this.diagSink = previousSink;
8174
8284
  const symbol = (() => {
8175
8285
  // symbolOf queries the checker too — a second panic must not
8176
8286
  // escape the fence that is handling the first.
@@ -8203,7 +8313,7 @@ export class Lowerer {
8203
8313
  return symbol;
8204
8314
  }
8205
8315
  finally {
8206
- this.diagSink = null;
8316
+ this.diagSink = previousSink;
8207
8317
  }
8208
8318
  }
8209
8319
  /** Pushes a symbol's deferred collection diagnostics: lowering resolved
@@ -8384,6 +8494,8 @@ export class Lowerer {
8384
8494
  * BEFORE that statement (JS's order for the supported whole-initializer
8385
8495
  * positions). */
8386
8496
  pendingClassExprInits = [];
8497
+ computedClassBases = new Map();
8498
+ computedCallableBases = new Map();
8387
8499
  /** Discovery hook: registers a just-collected expression class's member
8388
8500
  * bodies as worklist units (the units map is otherwise built before
8389
8501
  * lowering starts). Null in the emit pass. */
@@ -8472,11 +8584,7 @@ export class Lowerer {
8472
8584
  // Computed method names resolve exactly like collection did
8473
8585
  // (classMemberNameOf — folded keys and the sym:iterator slot);
8474
8586
  // unresolvable ones never collected, so they skip here too.
8475
- const baseName = ts.isMethodDeclaration(fnLike)
8476
- ? classMemberNameOf(this, fnLike.name)
8477
- : ts.isIdentifier(fnLike.name) || ts.isPrivateIdentifier(fnLike.name)
8478
- ? fnLike.name.text
8479
- : null;
8587
+ const baseName = classMemberNameOf(this, fnLike.name);
8480
8588
  if (baseName === null)
8481
8589
  continue;
8482
8590
  const mName = ts.isMethodDeclaration(fnLike) ? baseName : `${ts.isGetAccessor(fnLike) ? "get" : "set"}:${baseName}`;
@@ -8847,9 +8955,7 @@ export class Lowerer {
8847
8955
  });
8848
8956
  if (resolved.error !== null) {
8849
8957
  const location = blame ?? (symbol === undefined ? undefined : this.checker.declarationsOf(symbol)[0]) ?? this.entry;
8850
- const message = resolved.error === "caught"
8851
- ? "closures capturing catch bindings (narrow into a typed local first)"
8852
- : `the binding '${resolved.origin.name}' captured through a plain nested function (the declaration has no static storage a capture can thread — bind the value through a typed const, or read it in the declaring scope)`;
8958
+ const message = `the binding '${resolved.origin.name}' captured through a plain nested function (the declaration has no static storage a capture can thread — bind the value through a typed const, or read it in the declaring scope)`;
8853
8959
  this.unsupported("SC1090", location, message);
8854
8960
  }
8855
8961
  if (resolved.local !== null)
@@ -9238,7 +9344,16 @@ export class Lowerer {
9238
9344
  return isStdlibMember(this, access);
9239
9345
  }
9240
9346
  isStdlibSymbol(symbol) {
9241
- return isStdlibSymbol(this, symbol);
9347
+ if (!symbol)
9348
+ return false;
9349
+ const cached = this.stdlibSymbols.get(symbol);
9350
+ if (cached !== undefined)
9351
+ return cached;
9352
+ // A compilation's checker declarations and library provenance are fixed.
9353
+ // Global alias and narrowing state remain outside this symbol-only cache.
9354
+ const result = isStdlibSymbol(this, symbol);
9355
+ this.stdlibSymbols.set(symbol, result);
9356
+ return result;
9242
9357
  }
9243
9358
  isStdlibGlobal(expr, name) {
9244
9359
  return isStdlibGlobal(this, expr, name);
@@ -9580,7 +9695,7 @@ export class Lowerer {
9580
9695
  const arg = this.lowerExpr(expr.arguments[0]);
9581
9696
  return { kind: "jsOp", op: "construct", args: [ctor, arg], type: JSVAL, loc };
9582
9697
  }
9583
- const builtin = lowerAbortControllerNew(this, expr) ?? lowerResponseNew(this, expr) ?? lowerStaticReadableStreamNew(this, expr);
9698
+ const builtin = lowerAbortControllerNew(this, expr) ?? lowerFetchWebNew(this, expr) ?? lowerResponseNew(this, expr) ?? lowerStaticReadableStreamNew(this, expr);
9584
9699
  return builtin ?? this.withRuntimeOptionalClassValue(expr.expression, () => lowerNew(this, expr));
9585
9700
  }
9586
9701
  lowerFieldRead(expr) {
@@ -9862,10 +9977,10 @@ export class Lowerer {
9862
9977
  if (!expr.questionDotToken && ts.isPropertyAccessExpression(expr.expression)) {
9863
9978
  const inner = this.builtinMemberOf(expr.expression);
9864
9979
  if (inner && inner.module === "fs" && inner.member === "constants") {
9865
- const MODES = { F_OK: 0, X_OK: 1, W_OK: 2, R_OK: 4 };
9980
+ const MODES = { F_OK: 0, X_OK: 1, W_OK: 2, R_OK: 4, COPYFILE_EXCL: 1, COPYFILE_FICLONE: 2, COPYFILE_FICLONE_FORCE: 4 };
9866
9981
  const value = own(MODES, expr.name.text);
9867
9982
  if (value === undefined) {
9868
- this.noLowering(`fs.constants.${expr.name.text}`, expr, "F_OK, R_OK, W_OK, and X_OK are the lowered constants");
9983
+ this.noLowering(`fs.constants.${expr.name.text}`, expr, "F_OK, R_OK, W_OK, X_OK, and COPYFILE_* are the lowered constants");
9869
9984
  }
9870
9985
  return { kind: "numLit", value, type: F64, loc };
9871
9986
  }
@@ -9873,6 +9988,10 @@ export class Lowerer {
9873
9988
  const bi = this.builtinMemberOf(expr);
9874
9989
  if (!bi)
9875
9990
  return null;
9991
+ if ((bi.module === "path" || bi.module === "path/posix" || bi.module === "path/win32") &&
9992
+ (bi.member === "posix" || bi.member === "win32")) {
9993
+ return pathModuleValue(this, `path/${bi.member}`, loc);
9994
+ }
9876
9995
  // events.defaultMaxListeners READS the process-wide default (its
9877
9996
  // write twin routes through emitter.setDefaultMaxChk).
9878
9997
  if (bi.module === "events" && bi.member === "defaultMaxListeners") {
@@ -9908,7 +10027,7 @@ export class Lowerer {
9908
10027
  }
9909
10028
  if (bi.member === "constants" && bi.module === "fs") {
9910
10029
  // A bare `fs.constants` read (not one of the baked bits above).
9911
- this.noLowering(`fs.constants`, expr, "F_OK, R_OK, W_OK, and X_OK are the lowered constants");
10030
+ this.noLowering(`fs.constants`, expr, "F_OK, R_OK, W_OK, X_OK, and COPYFILE_* are the lowered constants");
9912
10031
  }
9913
10032
  if (builtinModuleFnOf(this, bi.module, bi.member)) {
9914
10033
  this.unsupported("SC1090", expr, `library functions as values (call '${expr.getText()}' directly)`);
@@ -9921,6 +10040,9 @@ export class Lowerer {
9921
10040
  * deliberately narrower than table membership because many table rows
9922
10041
  * are only dispatch sentinels for call-site-specific lowering. */
9923
10042
  lowerBuiltinCallableValue(bi, loc) {
10043
+ if (bi.module === "fs" && builtinModuleFnOf(this, bi.module, bi.member)?.fn === "fs.callbackCall") {
10044
+ return { kind: "libCall", fn: "fs.callbackValue", args: [{ kind: "strLit", value: bi.member, type: STRING, loc }], type: DYN, loc };
10045
+ }
9924
10046
  const fn = builtinModuleFnOf(this, bi.module, bi.member);
9925
10047
  return fn ? this.lowerNativeCallableValue(fn, `${bi.module}.${bi.member}`, loc) : null;
9926
10048
  }