@scriptc/compiler 0.1.6 → 0.2.0
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.
- package/ambient/scriptc-node-fallback.d.ts +73 -25
- package/ambient/scriptc-overrides.d.ts +10 -6
- package/ambient/scriptc.d.ts +28 -5
- package/dist/backend/build-cache.d.ts +1 -3
- package/dist/backend/build-cache.js +3 -22
- package/dist/backend/build-cache.js.map +1 -1
- package/dist/backend/cache-root.d.ts +3 -0
- package/dist/backend/cache-root.js +23 -0
- package/dist/backend/cache-root.js.map +1 -0
- package/dist/backend/cycle-analysis.d.ts +15 -0
- package/dist/backend/cycle-analysis.js +107 -0
- package/dist/backend/cycle-analysis.js.map +1 -0
- package/dist/backend/cycle-analysis.test.js +124 -0
- package/dist/backend/cycle-analysis.test.js.map +1 -0
- package/dist/backend/debug-symbols.d.ts +8 -0
- package/dist/backend/debug-symbols.js +52 -0
- package/dist/backend/debug-symbols.js.map +1 -0
- package/dist/backend/executable-features.d.ts +4 -0
- package/dist/backend/executable-features.js +42 -0
- package/dist/backend/executable-features.js.map +1 -0
- package/dist/backend/external-c.d.ts +5 -27
- package/dist/backend/external-c.js +5 -40
- package/dist/backend/external-c.js.map +1 -1
- package/dist/backend/ffi-callbacks.d.ts +2 -3
- package/dist/backend/ffi-callbacks.js +2 -3
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/library-identity-markers.d.ts +4 -9
- package/dist/backend/library-identity-markers.js +11 -49
- package/dist/backend/library-identity-markers.js.map +1 -1
- package/dist/backend/library-pack.d.ts +5 -0
- package/dist/backend/library-pack.js +123 -0
- package/dist/backend/library-pack.js.map +1 -0
- package/dist/backend/link-plan-core.d.ts +20 -0
- package/dist/backend/link-plan-core.js +18 -0
- package/dist/backend/link-plan-core.js.map +1 -0
- package/dist/backend/link-plan.d.ts +2 -1
- package/dist/backend/link-plan.js +18 -17
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/link-trace.d.ts +2 -0
- package/dist/backend/link-trace.js +24 -0
- package/dist/backend/link-trace.js.map +1 -0
- package/dist/backend/linker.js +9 -1
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/literals.d.ts +9 -0
- package/dist/backend/literals.js +35 -0
- package/dist/backend/literals.js.map +1 -0
- package/dist/backend/literals.test.d.ts +1 -0
- package/dist/backend/literals.test.js +53 -0
- package/dist/backend/literals.test.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +4 -0
- package/dist/backend/llvm/blocks.js +25 -4
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.d.ts +1 -0
- package/dist/backend/llvm/blocks.test.js +91 -0
- package/dist/backend/llvm/blocks.test.js.map +1 -0
- package/dist/backend/llvm/classes.d.ts +14 -8
- package/dist/backend/llvm/classes.js +70 -28
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +5 -1
- package/dist/backend/llvm/common.js +45 -4
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/debug-info.d.ts +32 -0
- package/dist/backend/llvm/debug-info.js +198 -0
- package/dist/backend/llvm/debug-info.js.map +1 -0
- package/dist/backend/llvm/debug-info.test.d.ts +1 -0
- package/dist/backend/llvm/debug-info.test.js +110 -0
- package/dist/backend/llvm/debug-info.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +16 -2
- package/dist/backend/llvm/dyn.js +498 -175
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +598 -1
- package/dist/backend/llvm/emitter.js +739 -409
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.d.ts +1 -0
- package/dist/backend/llvm/emitter.test.js +179 -0
- package/dist/backend/llvm/emitter.test.js.map +1 -0
- package/dist/backend/llvm/expr-async.js +23 -14
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -1
- package/dist/backend/llvm/expr-bytes.js +32 -14
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
- package/dist/backend/llvm/expr-callbacks.js +25 -22
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +136 -35
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +1 -1
- package/dist/backend/llvm/expr-containers.js +43 -14
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +5 -260
- package/dist/backend/llvm/expr-control.js +9 -5
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.d.ts +1 -1
- package/dist/backend/llvm/expr-dispatch.js +2 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +72 -74
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.d.ts +1 -1
- package/dist/backend/llvm/expr-island.js +11 -7
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +51 -30
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +1 -1
- package/dist/backend/llvm/expr-records.d.ts +5 -1
- package/dist/backend/llvm/expr-records.js +43 -4
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +4 -4
- package/dist/backend/llvm/expr-stream-bridges.js +102 -121
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.d.ts +1 -0
- package/dist/backend/llvm/expr-stream-bridges.test.js +55 -0
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.js +12 -12
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/layouts.d.ts +19 -0
- package/dist/backend/llvm/layouts.js +12 -0
- package/dist/backend/llvm/layouts.js.map +1 -0
- package/dist/backend/llvm/lib-abi.d.ts +19 -0
- package/dist/backend/llvm/lib-abi.js +82 -0
- package/dist/backend/llvm/lib-abi.js.map +1 -0
- package/dist/backend/llvm/lib-connect.d.ts +2 -0
- package/dist/backend/llvm/lib-connect.js +51 -0
- package/dist/backend/llvm/lib-connect.js.map +1 -0
- package/dist/backend/llvm/lib-datagram.d.ts +2 -0
- package/dist/backend/llvm/lib-datagram.js +135 -0
- package/dist/backend/llvm/lib-datagram.js.map +1 -0
- package/dist/backend/llvm/lib-dispatch.js +50 -6
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +59 -18
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.d.ts +2 -0
- package/dist/backend/llvm/lib-http2.js +215 -0
- package/dist/backend/llvm/lib-http2.js.map +1 -0
- package/dist/backend/llvm/lib-lookup.d.ts +2 -0
- package/dist/backend/llvm/lib-lookup.js +39 -0
- package/dist/backend/llvm/lib-lookup.js.map +1 -0
- package/dist/backend/llvm/lib-network.js +25 -2
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +21 -16
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +125 -1
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +3 -2
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.d.ts +2 -0
- package/dist/backend/llvm/lib-test.js +34 -0
- package/dist/backend/llvm/lib-test.js.map +1 -0
- package/dist/backend/llvm/lib-tls.d.ts +2 -0
- package/dist/backend/llvm/lib-tls.js +82 -0
- package/dist/backend/llvm/lib-tls.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +10 -9
- package/dist/backend/llvm/shapes.js +35 -130
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/split.js +4 -1
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/split.test.js +26 -1
- package/dist/backend/llvm/split.test.js.map +1 -1
- package/dist/backend/llvm/unsupported.d.ts +1 -0
- package/dist/backend/llvm/unsupported.js +1 -2
- package/dist/backend/llvm/unsupported.js.map +1 -1
- package/dist/backend/llvm/walkers.js +1 -7
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/mangle.d.ts +2 -2
- package/dist/backend/mangle.js +16 -5
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/{c/may-throw.d.ts → may-throw.d.ts} +1 -1
- package/dist/backend/{c/may-throw.js → may-throw.js} +51 -46
- package/dist/backend/may-throw.js.map +1 -0
- package/dist/backend/may-throw.test.d.ts +1 -0
- package/dist/backend/may-throw.test.js +58 -0
- package/dist/backend/may-throw.test.js.map +1 -0
- package/dist/backend/native-codegen-core.d.ts +22 -0
- package/dist/backend/native-codegen-core.js +44 -0
- package/dist/backend/native-codegen-core.js.map +1 -0
- package/dist/backend/native-codegen.d.ts +3 -19
- package/dist/backend/native-codegen.js +5 -44
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +2 -2
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +94 -0
- package/dist/backend/native-link-info-core.js +62 -0
- package/dist/backend/native-link-info-core.js.map +1 -0
- package/dist/backend/native-link-info.d.ts +3 -88
- package/dist/backend/native-link-info.js +12 -243
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-link-info.test.js +41 -146
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +10 -25
- package/dist/backend/native-toolchain.js +89 -219
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +15 -5
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/native-tools.d.ts +24 -0
- package/dist/backend/native-tools.js +33 -0
- package/dist/backend/native-tools.js.map +1 -0
- package/dist/backend/object-localize.js +19 -8
- package/dist/backend/object-localize.js.map +1 -1
- package/dist/backend/object-localize.test.js +22 -0
- package/dist/backend/object-localize.test.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +101 -0
- package/dist/backend/runtime-pack-core.js +172 -0
- package/dist/backend/runtime-pack-core.js.map +1 -0
- package/dist/backend/runtime-pack-native.d.ts +21 -0
- package/dist/backend/runtime-pack-native.js +70 -0
- package/dist/backend/runtime-pack-native.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.d.ts +3 -83
- package/dist/backend/runtime-pack.js +8 -151
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +24 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/source-locations.d.ts +12 -0
- package/dist/backend/source-locations.js +32 -0
- package/dist/backend/source-locations.js.map +1 -0
- package/dist/backend/source-locations.test.d.ts +1 -0
- package/dist/backend/source-locations.test.js +16 -0
- package/dist/backend/source-locations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.d.ts +22 -0
- package/dist/backend/target-diagnostics.js +108 -0
- package/dist/backend/target-diagnostics.js.map +1 -0
- package/dist/backend/target-platform.d.ts +15 -0
- package/dist/backend/target-platform.js +72 -0
- package/dist/backend/target-platform.js.map +1 -0
- package/dist/backend/targets.d.ts +13 -4
- package/dist/backend/targets.js +95 -30
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +65 -4
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/backend/toolchain-environment.d.ts +6 -0
- package/dist/backend/toolchain-environment.js +99 -0
- package/dist/backend/toolchain-environment.js.map +1 -0
- package/dist/backend/vendor-archives.d.ts +1 -9
- package/dist/backend/vendor-archives.js +2 -9
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +9 -0
- package/dist/backend/vendor-inputs.js +10 -0
- package/dist/backend/vendor-inputs.js.map +1 -0
- package/dist/backend/warm-cache.d.ts +3 -0
- package/dist/backend/warm-cache.js +41 -0
- package/dist/backend/warm-cache.js.map +1 -0
- package/dist/cli/command.d.ts +3 -0
- package/dist/cli/command.js +328 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/host.d.ts +24 -0
- package/dist/cli/host.js +2 -0
- package/dist/cli/host.js.map +1 -0
- package/dist/cli/output-options.d.ts +26 -0
- package/dist/cli/output-options.js +60 -0
- package/dist/cli/output-options.js.map +1 -0
- package/dist/cli/paths.d.ts +12 -0
- package/dist/cli/paths.js +42 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/usage.d.ts +74 -0
- package/dist/cli/usage.js +86 -0
- package/dist/cli/usage.js.map +1 -0
- package/dist/cli/wasi-paths.d.ts +8 -0
- package/dist/cli/wasi-paths.js +41 -0
- package/dist/cli/wasi-paths.js.map +1 -0
- package/dist/cli/wasi-runner.d.ts +2 -0
- package/dist/cli/wasi-runner.js +28 -0
- package/dist/cli/wasi-runner.js.map +1 -0
- package/dist/compat/fetch-profile.js +3 -3
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +162 -0
- package/dist/compile-types.js +2 -0
- package/dist/compile-types.js.map +1 -0
- package/dist/coverage/report.js +11 -5
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +5 -2
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +4 -0
- package/dist/diagnostics/diagnostic.js +15 -3
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +3 -4
- package/dist/executable/executable-cache.js +33 -10
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +38 -16
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.d.ts +14 -0
- package/dist/executable/prepare.js +66 -0
- package/dist/executable/prepare.js.map +1 -0
- package/dist/ffi/ffi-manifest.d.ts +11 -4
- package/dist/ffi/ffi-manifest.js +170 -58
- package/dist/ffi/ffi-manifest.js.map +1 -1
- package/dist/ffi/ffi-manifest.test.d.ts +1 -0
- package/dist/ffi/ffi-manifest.test.js +111 -0
- package/dist/ffi/ffi-manifest.test.js.map +1 -0
- package/dist/format-integer.d.ts +3 -0
- package/dist/format-integer.js +14 -0
- package/dist/format-integer.js.map +1 -0
- package/dist/frontend/analysis.d.ts +5 -0
- package/dist/frontend/analysis.js +88 -0
- package/dist/frontend/analysis.js.map +1 -0
- package/dist/frontend/arguments-usage.d.ts +4 -0
- package/dist/frontend/arguments-usage.js +40 -0
- package/dist/frontend/arguments-usage.js.map +1 -0
- package/dist/frontend/binding-source.d.ts +4 -0
- package/dist/frontend/binding-source.js +18 -0
- package/dist/frontend/binding-source.js.map +1 -0
- package/dist/frontend/builtin-modules.d.ts +1 -1
- package/dist/frontend/builtin-modules.js +1 -1
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-lexer.d.ts +4 -25
- package/dist/frontend/cjs-lexer.js +6 -806
- package/dist/frontend/cjs-lexer.js.map +1 -1
- package/dist/frontend/cjs-resolve.d.ts +5 -0
- package/dist/frontend/cjs-resolve.js +429 -0
- package/dist/frontend/cjs-resolve.js.map +1 -0
- package/dist/frontend/cjs-syntax.d.ts +26 -0
- package/dist/frontend/cjs-syntax.js +806 -0
- package/dist/frontend/cjs-syntax.js.map +1 -0
- package/dist/frontend/comptime-node.d.ts +4 -0
- package/dist/frontend/comptime-node.js +16 -0
- package/dist/frontend/comptime-node.js.map +1 -0
- package/dist/frontend/comptime-node.test.d.ts +1 -0
- package/dist/frontend/comptime-node.test.js +37 -0
- package/dist/frontend/comptime-node.test.js.map +1 -0
- package/dist/frontend/dts-paths.d.ts +3 -4
- package/dist/frontend/dts-paths.js +15 -8
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/fork-target.js +2 -2
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/helper-tokens.d.ts +1 -0
- package/dist/frontend/helper-tokens.js +147 -0
- package/dist/frontend/helper-tokens.js.map +1 -0
- package/dist/frontend/helper-tokens.test.d.ts +1 -0
- package/dist/frontend/helper-tokens.test.js +35 -0
- package/dist/frontend/helper-tokens.test.js.map +1 -0
- package/dist/frontend/inferred-js-diagnostics.d.ts +5 -0
- package/dist/frontend/inferred-js-diagnostics.js +69 -0
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -0
- package/dist/frontend/inferred-js-diagnostics.test.d.ts +1 -0
- package/dist/frontend/inferred-js-diagnostics.test.js +58 -0
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -0
- package/dist/frontend/input-tracker.d.ts +5 -2
- package/dist/frontend/input-tracker.js +24 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +23 -0
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lib-contract.js +32 -24
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/literal-values.d.ts +4 -0
- package/dist/frontend/literal-values.js +21 -0
- package/dist/frontend/literal-values.js.map +1 -0
- package/dist/frontend/literal-values.test.d.ts +1 -0
- package/dist/frontend/literal-values.test.js +91 -0
- package/dist/frontend/literal-values.test.js.map +1 -0
- package/dist/frontend/lowering/abstract-equality.d.ts +1 -1
- package/dist/frontend/lowering/abstract-equality.js +3 -0
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-indexed-mutation.js +11 -6
- package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +4 -1
- package/dist/frontend/lowering/array-values.js +43 -1
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/callback-arg.js +1 -0
- package/dist/frontend/lowering/callback-arg.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +12 -0
- package/dist/frontend/lowering/class-callbacks.js +63 -0
- package/dist/frontend/lowering/class-callbacks.js.map +1 -0
- package/dist/frontend/lowering/class-descriptors.d.ts +9 -0
- package/dist/frontend/lowering/class-descriptors.js +73 -0
- package/dist/frontend/lowering/class-descriptors.js.map +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +41 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +803 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.d.ts +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +92 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -0
- package/dist/frontend/lowering/class-instance-constructor.d.ts +7 -0
- package/dist/frontend/lowering/class-instance-constructor.js +64 -0
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -0
- package/dist/frontend/lowering/class-method-values.d.ts +10 -0
- package/dist/frontend/lowering/class-method-values.js +170 -0
- package/dist/frontend/lowering/class-method-values.js.map +1 -0
- package/dist/frontend/lowering/class-prototypes.d.ts +16 -0
- package/dist/frontend/lowering/class-prototypes.js +134 -0
- package/dist/frontend/lowering/class-prototypes.js.map +1 -0
- package/dist/frontend/lowering/class-static-data.d.ts +6 -0
- package/dist/frontend/lowering/class-static-data.js +56 -0
- package/dist/frontend/lowering/class-static-data.js.map +1 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.d.ts +4 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.js +26 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.d.ts +11 -7
- package/dist/frontend/lowering/containers/bytes.js +164 -155
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +2 -2
- package/dist/frontend/lowering/containers/string-and-regexp.js +39 -16
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.d.ts +7 -0
- package/dist/frontend/lowering/containers/string-replacement.js +217 -0
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -0
- package/dist/frontend/lowering/error-methods.d.ts +11 -0
- package/dist/frontend/lowering/error-methods.js +78 -0
- package/dist/frontend/lowering/error-methods.js.map +1 -0
- package/dist/frontend/lowering/expressions/global-symbols.d.ts +6 -0
- package/dist/frontend/lowering/expressions/global-symbols.js +11 -0
- package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.d.ts +7 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +49 -0
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.d.ts +6 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js +124 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -0
- package/dist/frontend/lowering/expressions/object-literals.d.ts +8 -8
- package/dist/frontend/lowering/expressions/object-literals.js +485 -185
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +5 -6
- package/dist/frontend/lowering/expressions/optional-chains.js +27 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/try-lower-expression.js +1 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-field-write.d.ts +8 -0
- package/dist/frontend/lowering/expressions/union-field-write.js +71 -0
- package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +93 -0
- package/dist/frontend/lowering/function-context.js +103 -0
- package/dist/frontend/lowering/function-context.js.map +1 -0
- package/dist/frontend/lowering/generator-delegation.d.ts +7 -0
- package/dist/frontend/lowering/generator-delegation.js +85 -0
- package/dist/frontend/lowering/generator-delegation.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +10 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +105 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.d.ts +2 -1
- package/dist/frontend/lowering/lib-boundary.js +59 -20
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.test.d.ts +1 -0
- package/dist/frontend/lowering/lib-boundary.test.js +45 -0
- package/dist/frontend/lowering/lib-boundary.test.js.map +1 -0
- package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
- package/dist/frontend/lowering/lower-assert.d.ts +1 -1
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +12 -0
- package/dist/frontend/lowering/lower-builtin-values.js +139 -0
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.d.ts +27 -41
- package/dist/frontend/lowering/lower-builtins.js +553 -346
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +22 -26
- package/dist/frontend/lowering/lower-calls.js +1373 -380
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +83 -45
- package/dist/frontend/lowering/lower-classes.js +952 -339
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
- package/dist/frontend/lowering/lower-comptime.js +23 -32
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +27 -32
- package/dist/frontend/lowering/lower-containers.js +796 -151
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +1 -1
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.d.ts +1 -1
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +30 -1
- package/dist/frontend/lowering/lower-event-emitter.js +58 -26
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.d.ts +7 -1
- package/dist/frontend/lowering/lower-expando.js +14 -6
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +35 -11
- package/dist/frontend/lowering/lower-exprs.js +1785 -790
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +2 -5
- package/dist/frontend/lowering/lower-generators.js +77 -46
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.d.ts +7 -0
- package/dist/frontend/lowering/lower-global-value.js +17 -0
- package/dist/frontend/lowering/lower-global-value.js.map +1 -0
- package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
- package/dist/frontend/lowering/lower-inspect.js +17 -8
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +5 -8
- package/dist/frontend/lowering/lower-island.js +34 -23
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.d.ts +2 -2
- package/dist/frontend/lowering/lower-mixins.js +5 -3
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +1 -1
- package/dist/frontend/lowering/lower-modules.js +252 -38
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +1 -1
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +1 -1
- package/dist/frontend/lowering/lower-node-module.js +13 -10
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +1 -1
- package/dist/frontend/lowering/lower-server.js +6 -10
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +10 -14
- package/dist/frontend/lowering/lower-stmts.js +731 -532
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +1 -1
- package/dist/frontend/lowering/lower-stream.js +19 -10
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +1 -1
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-url.d.ts +6 -0
- package/dist/frontend/lowering/lower-url.js +77 -0
- package/dist/frontend/lowering/lower-url.js.map +1 -0
- package/dist/frontend/lowering/lowerer.d.ts +113 -189
- package/dist/frontend/lowering/lowerer.js +1033 -663
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.d.ts +1 -0
- package/dist/frontend/lowering/lowerer.test.js +26 -0
- package/dist/frontend/lowering/lowerer.test.js.map +1 -0
- package/dist/frontend/lowering/native-ffi.d.ts +5 -0
- package/dist/frontend/lowering/native-ffi.js +40 -0
- package/dist/frontend/lowering/native-ffi.js.map +1 -0
- package/dist/frontend/lowering/object-enumeration-receiver.d.ts +7 -0
- package/dist/frontend/lowering/object-enumeration-receiver.js +33 -0
- package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.d.ts +8 -0
- package/dist/frontend/lowering/object-factory-new.js +68 -0
- package/dist/frontend/lowering/object-factory-new.js.map +1 -0
- package/dist/frontend/lowering/optional-arguments.js +6 -1
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.js +2 -1
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-locals.d.ts +14 -0
- package/dist/frontend/lowering/runtime-optional-locals.js +41 -0
- package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.d.ts +1 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.js +85 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -0
- package/dist/frontend/lowering/sanitize-class-types.d.ts +8 -0
- package/dist/frontend/lowering/sanitize-class-types.js +79 -0
- package/dist/frontend/lowering/sanitize-class-types.js.map +1 -0
- package/dist/frontend/lowering/sanitize-class-types.test.d.ts +1 -0
- package/dist/frontend/lowering/sanitize-class-types.test.js +60 -0
- package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -0
- package/dist/frontend/lowering/static-this.d.ts +5 -1
- package/dist/frontend/lowering/static-this.js +28 -2
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +7 -0
- package/dist/frontend/lowering/string-index.js +39 -0
- package/dist/frontend/lowering/string-index.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +9 -4
- package/dist/frontend/lowering/surfaces.js +98 -35
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +22 -0
- package/dist/frontend/lowering/symbol-fields.js +183 -0
- package/dist/frontend/lowering/symbol-fields.js.map +1 -0
- package/dist/frontend/lowering/symbol-methods.d.ts +7 -0
- package/dist/frontend/lowering/symbol-methods.js +30 -0
- package/dist/frontend/lowering/symbol-methods.js.map +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.d.ts +10 -0
- package/dist/frontend/lowering/text-decoder-encoding.js +77 -0
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.d.ts +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.js +38 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -0
- package/dist/frontend/lowering/union-narrow.d.ts +9 -0
- package/dist/frontend/lowering/union-narrow.js +59 -0
- package/dist/frontend/lowering/union-narrow.js.map +1 -0
- package/dist/frontend/lowering/union-narrow.test.d.ts +1 -0
- package/dist/frontend/lowering/union-narrow.test.js +72 -0
- package/dist/frontend/lowering/union-narrow.test.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +43 -0
- package/dist/frontend/lowering/union-retag.js +259 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -0
- package/dist/frontend/lowering/union-retag.test.d.ts +1 -0
- package/dist/frontend/lowering/union-retag.test.js +405 -0
- package/dist/frontend/lowering/union-retag.test.js.map +1 -0
- package/dist/frontend/lowering/unregistered-class-types.d.ts +14 -0
- package/dist/frontend/lowering/unregistered-class-types.js +94 -0
- package/dist/frontend/lowering/unregistered-class-types.js.map +1 -0
- package/dist/frontend/lowering/unregistered-class-types.test.d.ts +1 -0
- package/dist/frontend/lowering/unregistered-class-types.test.js +65 -0
- package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -0
- package/dist/frontend/lowering/width-lift.d.ts +40 -0
- package/dist/frontend/lowering/width-lift.js +2 -0
- package/dist/frontend/lowering/width-lift.js.map +1 -0
- package/dist/frontend/module-syntax.d.ts +58 -0
- package/dist/frontend/module-syntax.js +123 -0
- package/dist/frontend/module-syntax.js.map +1 -0
- package/dist/frontend/module-syntax.test.d.ts +1 -0
- package/dist/frontend/module-syntax.test.js +78 -0
- package/dist/frontend/module-syntax.test.js.map +1 -0
- package/dist/frontend/npm-fetch-analysis.d.ts +17 -0
- package/dist/frontend/npm-fetch-analysis.js +100 -0
- package/dist/frontend/npm-fetch-analysis.js.map +1 -0
- package/dist/frontend/npm-fetch-analysis.test.d.ts +1 -0
- package/dist/frontend/npm-fetch-analysis.test.js +107 -0
- package/dist/frontend/npm-fetch-analysis.test.js.map +1 -0
- package/dist/frontend/npm-fetch-node.d.ts +2 -0
- package/dist/frontend/npm-fetch-node.js +12 -0
- package/dist/frontend/npm-fetch-node.js.map +1 -0
- package/dist/frontend/npm-fetch-syntax.d.ts +6 -0
- package/dist/frontend/npm-fetch-syntax.js +207 -0
- package/dist/frontend/npm-fetch-syntax.js.map +1 -0
- package/dist/frontend/npm-node.d.ts +10 -0
- package/dist/frontend/npm-node.js +14 -0
- package/dist/frontend/npm-node.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.d.ts +8 -0
- package/dist/frontend/npm-static-bundled-cjs.js +236 -0
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-cjs.test.js +69 -0
- package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.d.ts +57 -0
- package/dist/frontend/npm-static-declaration-syntax.js +944 -0
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -0
- package/dist/frontend/npm-static-declarations.d.ts +11 -39
- package/dist/frontend/npm-static-declarations.js +22 -561
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +245 -6
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.d.ts +1 -1
- package/dist/frontend/npm-static-prune.js +5 -4
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-prune.test.js +1 -1
- package/dist/frontend/npm-static-prune.test.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -0
- package/dist/frontend/npm-static-rewrite-host.js +179 -0
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -0
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +16 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +905 -0
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -0
- package/dist/frontend/npm-static-rewrite.d.ts +0 -5
- package/dist/frontend/npm-static-rewrite.js +2 -1079
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.d.ts +5 -0
- package/dist/frontend/npm-static-subtyping.js +55 -0
- package/dist/frontend/npm-static-subtyping.js.map +1 -0
- package/dist/frontend/npm-static-subtyping.test.d.ts +1 -0
- package/dist/frontend/npm-static-subtyping.test.js +58 -0
- package/dist/frontend/npm-static-subtyping.test.js.map +1 -0
- package/dist/frontend/npm-static.d.ts +7 -15
- package/dist/frontend/npm-static.js +19 -28
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +8 -69
- package/dist/frontend/npm.js +21 -361
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +2 -2
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.d.ts +6 -0
- package/dist/frontend/pipeline-native.js +32 -0
- package/dist/frontend/pipeline-native.js.map +1 -0
- package/dist/frontend/pipeline.d.ts +54 -0
- package/dist/frontend/pipeline.js +382 -0
- package/dist/frontend/pipeline.js.map +1 -0
- package/dist/frontend/pipeline.test.d.ts +1 -0
- package/dist/frontend/pipeline.test.js +77 -0
- package/dist/frontend/pipeline.test.js.map +1 -0
- package/dist/frontend/program-analysis.d.ts +10 -0
- package/dist/frontend/program-analysis.js +14 -0
- package/dist/frontend/program-analysis.js.map +1 -0
- package/dist/frontend/program-node.d.ts +9 -0
- package/dist/frontend/program-node.js +48 -0
- package/dist/frontend/program-node.js.map +1 -0
- package/dist/frontend/program.d.ts +43 -19
- package/dist/frontend/program.js +556 -197
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.d.ts +1 -0
- package/dist/frontend/program.test.js +202 -0
- package/dist/frontend/program.test.js.map +1 -0
- package/dist/frontend/provenance-core.d.ts +9 -0
- package/dist/frontend/provenance-core.js +435 -0
- package/dist/frontend/provenance-core.js.map +1 -0
- package/dist/frontend/provenance.d.ts +0 -4
- package/dist/frontend/provenance.js +4 -459
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/resolve.d.ts +3 -1
- package/dist/frontend/resolve.js +6 -3
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.d.ts +4 -3
- package/dist/frontend/runtime-resolve.js +22 -18
- package/dist/frontend/runtime-resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.test.js +53 -0
- package/dist/frontend/runtime-resolve.test.js.map +1 -1
- package/dist/frontend/services-node.d.ts +5 -0
- package/dist/frontend/services-node.js +19 -0
- package/dist/frontend/services-node.js.map +1 -0
- package/dist/frontend/services-node.test.d.ts +1 -0
- package/dist/frontend/services-node.test.js +70 -0
- package/dist/frontend/services-node.test.js.map +1 -0
- package/dist/frontend/services.d.ts +44 -0
- package/dist/frontend/services.js +90 -0
- package/dist/frontend/services.js.map +1 -0
- package/dist/frontend/services.test.d.ts +1 -0
- package/dist/frontend/services.test.js +174 -0
- package/dist/frontend/services.test.js.map +1 -0
- package/dist/frontend/ts7/adapter.d.ts +3 -3
- package/dist/frontend/ts7/adapter.js +14 -31
- package/dist/frontend/ts7/adapter.js.map +1 -1
- package/dist/frontend/ts7/api.d.ts +16 -0
- package/dist/frontend/ts7/api.js +24 -0
- package/dist/frontend/ts7/api.js.map +1 -0
- package/dist/frontend/ts7/ast-bytes.d.ts +31 -0
- package/dist/frontend/ts7/ast-bytes.js +137 -0
- package/dist/frontend/ts7/ast-bytes.js.map +1 -0
- package/dist/frontend/ts7/ast-bytes.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-bytes.test.js +73 -0
- package/dist/frontend/ts7/ast-bytes.test.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.d.ts +353 -0
- package/dist/frontend/ts7/ast-guards.generated.js +1951 -0
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-guards.test.js +43 -0
- package/dist/frontend/ts7/ast-guards.test.js.map +1 -0
- package/dist/frontend/ts7/ast-node.d.ts +194 -0
- package/dist/frontend/ts7/ast-node.js +448 -0
- package/dist/frontend/ts7/ast-node.js.map +1 -0
- package/dist/frontend/ts7/ast-node.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-node.test.js +266 -0
- package/dist/frontend/ts7/ast-node.test.js.map +1 -0
- package/dist/frontend/ts7/ast-schema.generated.d.ts +503 -0
- package/dist/frontend/ts7/ast-schema.generated.js +1446 -0
- package/dist/frontend/ts7/ast-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-text.d.ts +6 -0
- package/dist/frontend/ts7/ast-text.js +124 -0
- package/dist/frontend/ts7/ast-text.js.map +1 -0
- package/dist/frontend/ts7/ast-text.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-text.test.js +38 -0
- package/dist/frontend/ts7/ast-text.test.js.map +1 -0
- package/dist/frontend/ts7/ast-tokens.generated.d.ts +2 -0
- package/dist/frontend/ts7/ast-tokens.generated.js +155 -0
- package/dist/frontend/ts7/ast-tokens.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-types.d.ts +42 -0
- package/dist/frontend/ts7/ast-types.generated.d.ts +1615 -0
- package/dist/frontend/ts7/ast-types.generated.js +5 -0
- package/dist/frontend/ts7/ast-types.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-types.js +3 -0
- package/dist/frontend/ts7/ast-types.js.map +1 -0
- package/dist/frontend/ts7/ast-wire.d.ts +58 -0
- package/dist/frontend/ts7/ast-wire.js +267 -0
- package/dist/frontend/ts7/ast-wire.js.map +1 -0
- package/dist/frontend/ts7/ast-wire.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-wire.test.js +151 -0
- package/dist/frontend/ts7/ast-wire.test.js.map +1 -0
- package/dist/frontend/ts7/ast.d.ts +14 -14
- package/dist/frontend/ts7/ast.js +21 -15
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/census-check.js +1 -0
- package/dist/frontend/ts7/census-check.js.map +1 -1
- package/dist/frontend/ts7/checker-cache.d.ts +48 -0
- package/dist/frontend/ts7/checker-cache.js +92 -0
- package/dist/frontend/ts7/checker-cache.js.map +1 -0
- package/dist/frontend/ts7/checker.d.ts +19 -46
- package/dist/frontend/ts7/checker.js +231 -161
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.d.ts +1 -0
- package/dist/frontend/ts7/checker.test.js +335 -0
- package/dist/frontend/ts7/checker.test.js.map +1 -0
- package/dist/frontend/ts7/enums.d.ts +4 -27
- package/dist/frontend/ts7/enums.generated.d.ts +878 -0
- package/dist/frontend/ts7/enums.generated.js +1313 -0
- package/dist/frontend/ts7/enums.generated.js.map +1 -0
- package/dist/frontend/ts7/enums.js +4 -45
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/enums.test.d.ts +1 -0
- package/dist/frontend/ts7/enums.test.js +48 -0
- package/dist/frontend/ts7/enums.test.js.map +1 -0
- package/dist/frontend/ts7/native-api.d.ts +10 -0
- package/dist/frontend/ts7/native-api.js +10 -0
- package/dist/frontend/ts7/native-api.js.map +1 -0
- package/dist/frontend/ts7/native-host.d.ts +2 -0
- package/dist/frontend/ts7/native-host.js +11 -0
- package/dist/frontend/ts7/native-host.js.map +1 -0
- package/dist/frontend/ts7/native-process.d.ts +14 -0
- package/dist/frontend/ts7/native-process.js +62 -0
- package/dist/frontend/ts7/native-process.js.map +1 -0
- package/dist/frontend/ts7/program-adapter.d.ts +10 -98
- package/dist/frontend/ts7/program-adapter.js +16 -310
- package/dist/frontend/ts7/program-adapter.js.map +1 -1
- package/dist/frontend/ts7/program-host.d.ts +115 -0
- package/dist/frontend/ts7/program-host.js +347 -0
- package/dist/frontend/ts7/program-host.js.map +1 -0
- package/dist/frontend/ts7/program-host.test.d.ts +1 -0
- package/dist/frontend/ts7/program-host.test.js +207 -0
- package/dist/frontend/ts7/program-host.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-api.d.ts +12 -0
- package/dist/frontend/ts7/rpc-api.js +23 -0
- package/dist/frontend/ts7/rpc-api.js.map +1 -0
- package/dist/frontend/ts7/rpc-client.d.ts +27 -0
- package/dist/frontend/ts7/rpc-client.js +102 -0
- package/dist/frontend/ts7/rpc-client.js.map +1 -0
- package/dist/frontend/ts7/rpc-client.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-client.test.js +133 -0
- package/dist/frontend/ts7/rpc-client.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-filesystem.d.ts +16 -0
- package/dist/frontend/ts7/rpc-filesystem.js +42 -0
- package/dist/frontend/ts7/rpc-filesystem.js.map +1 -0
- package/dist/frontend/ts7/rpc-filesystem.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-filesystem.test.js +89 -0
- package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-process.d.ts +2 -0
- package/dist/frontend/ts7/rpc-process.js +148 -0
- package/dist/frontend/ts7/rpc-process.js.map +1 -0
- package/dist/frontend/ts7/rpc-process.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-process.test.js +29 -0
- package/dist/frontend/ts7/rpc-process.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-wire.d.ts +46 -0
- package/dist/frontend/ts7/rpc-wire.js +195 -0
- package/dist/frontend/ts7/rpc-wire.js.map +1 -0
- package/dist/frontend/ts7/rpc-wire.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-wire.test.js +168 -0
- package/dist/frontend/ts7/rpc-wire.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-checker.d.ts +137 -0
- package/dist/frontend/ts7/semantic-checker.js +221 -0
- package/dist/frontend/ts7/semantic-checker.js.map +1 -0
- package/dist/frontend/ts7/semantic-checker.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-checker.test.js +119 -0
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-json.d.ts +5 -0
- package/dist/frontend/ts7/semantic-json.js +52 -0
- package/dist/frontend/ts7/semantic-json.js.map +1 -0
- package/dist/frontend/ts7/semantic-json.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-json.test.js +42 -0
- package/dist/frontend/ts7/semantic-json.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-model.d.ts +222 -0
- package/dist/frontend/ts7/semantic-model.js +423 -0
- package/dist/frontend/ts7/semantic-model.js.map +1 -0
- package/dist/frontend/ts7/semantic-model.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-model.test.js +322 -0
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-schema.generated.d.ts +283 -0
- package/dist/frontend/ts7/semantic-schema.generated.js +222 -0
- package/dist/frontend/ts7/semantic-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/semantic-types.d.ts +5 -0
- package/dist/frontend/ts7/semantic-types.js +2 -0
- package/dist/frontend/ts7/semantic-types.js.map +1 -0
- package/dist/frontend/ts7/session-cache.d.ts +17 -0
- package/dist/frontend/ts7/session-cache.js +97 -0
- package/dist/frontend/ts7/session-cache.js.map +1 -0
- package/dist/frontend/ts7/session-cache.test.d.ts +1 -0
- package/dist/frontend/ts7/session-cache.test.js +87 -0
- package/dist/frontend/ts7/session-cache.test.js.map +1 -0
- package/dist/frontend/ts7/session-path.d.ts +18 -0
- package/dist/frontend/ts7/session-path.js +203 -0
- package/dist/frontend/ts7/session-path.js.map +1 -0
- package/dist/frontend/ts7/session-path.test.d.ts +1 -0
- package/dist/frontend/ts7/session-path.test.js +34 -0
- package/dist/frontend/ts7/session-path.test.js.map +1 -0
- package/dist/frontend/ts7/session-schema.generated.d.ts +167 -0
- package/dist/frontend/ts7/session-schema.generated.js +5 -0
- package/dist/frontend/ts7/session-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/session-timing.d.ts +50 -0
- package/dist/frontend/ts7/session-timing.js +61 -0
- package/dist/frontend/ts7/session-timing.js.map +1 -0
- package/dist/frontend/ts7/session-timing.test.d.ts +1 -0
- package/dist/frontend/ts7/session-timing.test.js +52 -0
- package/dist/frontend/ts7/session-timing.test.js.map +1 -0
- package/dist/frontend/ts7/session.d.ts +105 -0
- package/dist/frontend/ts7/session.js +233 -0
- package/dist/frontend/ts7/session.js.map +1 -0
- package/dist/frontend/ts7/session.test.d.ts +1 -0
- package/dist/frontend/ts7/session.test.js +215 -0
- package/dist/frontend/ts7/session.test.js.map +1 -0
- package/dist/frontend/ts7/source-parser-node.d.ts +6 -0
- package/dist/frontend/ts7/source-parser-node.js +15 -0
- package/dist/frontend/ts7/source-parser-node.js.map +1 -0
- package/dist/frontend/ts7/source-parser.d.ts +25 -0
- package/dist/frontend/ts7/source-parser.js +96 -0
- package/dist/frontend/ts7/source-parser.js.map +1 -0
- package/dist/frontend/ts7/source-parser.test.d.ts +1 -0
- package/dist/frontend/ts7/source-parser.test.js +151 -0
- package/dist/frontend/ts7/source-parser.test.js.map +1 -0
- package/dist/frontend/ts7/syntax.d.ts +3 -0
- package/dist/frontend/ts7/syntax.js +4 -0
- package/dist/frontend/ts7/syntax.js.map +1 -0
- package/dist/frontend/tsc-codes.js +3 -0
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +29 -19
- package/dist/frontend/type-mapper.js +713 -306
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.d.ts +1 -0
- package/dist/frontend/type-mapper.test.js +207 -0
- package/dist/frontend/type-mapper.test.js.map +1 -0
- package/dist/frontend/union-discriminants.d.ts +16 -0
- package/dist/frontend/union-discriminants.js +98 -0
- package/dist/frontend/union-discriminants.js.map +1 -0
- package/dist/frontend/union-discriminants.test.d.ts +1 -0
- package/dist/frontend/union-discriminants.test.js +182 -0
- package/dist/frontend/union-discriminants.test.js.map +1 -0
- package/dist/index.d.ts +7 -197
- package/dist/index.js +369 -1567
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +16 -4
- package/dist/ir/analysis.js +25 -6
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +15 -2
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/constant-tables.js +67 -49
- package/dist/ir/constant-tables.js.map +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/control-flow.d.ts +6 -0
- package/dist/ir/control-flow.js +142 -0
- package/dist/ir/control-flow.js.map +1 -0
- package/dist/ir/control-flow.test.d.ts +1 -0
- package/dist/ir/control-flow.test.js +113 -0
- package/dist/ir/control-flow.test.js.map +1 -0
- package/dist/ir/integer-loops.js +7 -18
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-ranges.js +53 -27
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/ir.d.ts +309 -164
- package/dist/ir/ir.js +588 -879
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +127 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/scalar-records.js +165 -134
- package/dist/ir/scalar-records.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/serialize.d.ts +4 -2
- package/dist/ir/serialize.js +19 -12
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.d.ts +1 -0
- package/dist/ir/serialize.test.js +53 -0
- package/dist/ir/serialize.test.js.map +1 -0
- package/dist/ir/traverse.d.ts +41 -0
- package/dist/ir/traverse.js +660 -0
- package/dist/ir/traverse.js.map +1 -0
- package/dist/ir/traverse.test.d.ts +1 -0
- package/dist/ir/traverse.test.js +242 -0
- package/dist/ir/traverse.test.js.map +1 -0
- package/dist/ir/validate.js +1956 -1496
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +476 -2
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/cache-primitives.d.ts +2 -3
- package/dist/library/cache-primitives.js +4 -6
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/compiler-self-identity.d.ts +1 -1
- package/dist/library/compiler-self-identity.js +31 -15
- package/dist/library/compiler-self-identity.js.map +1 -1
- package/dist/library/compiler-self-identity.test.d.ts +1 -0
- package/dist/library/compiler-self-identity.test.js +93 -0
- package/dist/library/compiler-self-identity.test.js.map +1 -0
- package/dist/library/fence-eval.js +2 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.js +7 -6
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/library-cache.d.ts +3 -2
- package/dist/library/library-cache.js +5 -17
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +54 -41
- package/dist/library/library-cache.test.js.map +1 -1
- package/dist/library/library-profile.d.ts +3 -1
- package/dist/library/library-profile.js +15 -6
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.d.ts +15 -0
- package/dist/library/prepare.js +584 -0
- package/dist/library/prepare.js.map +1 -0
- package/dist/library/semantic-source.d.ts +1 -1
- package/dist/library/semantic-source.js +8 -6
- package/dist/library/semantic-source.js.map +1 -1
- package/dist/library/sidecar-validate.js +4 -4
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +2 -0
- package/dist/library/sidecar.js +10 -3
- package/dist/library/sidecar.js.map +1 -1
- package/dist/native/cache.d.ts +11 -0
- package/dist/native/cache.js +113 -0
- package/dist/native/cache.js.map +1 -0
- package/dist/native/cache.test.d.ts +1 -0
- package/dist/native/cache.test.js +66 -0
- package/dist/native/cache.test.js.map +1 -0
- package/dist/native/cli.d.ts +1 -0
- package/dist/native/cli.js +112 -0
- package/dist/native/cli.js.map +1 -0
- package/dist/native/compiler.d.ts +15 -0
- package/dist/native/compiler.js +336 -0
- package/dist/native/compiler.js.map +1 -0
- package/dist/native/compiler.test.d.ts +1 -0
- package/dist/native/compiler.test.js +174 -0
- package/dist/native/compiler.test.js.map +1 -0
- package/dist/native/comptime.d.ts +5 -0
- package/dist/native/comptime.js +73 -0
- package/dist/native/comptime.js.map +1 -0
- package/dist/native/comptime.test.d.ts +1 -0
- package/dist/native/comptime.test.js +65 -0
- package/dist/native/comptime.test.js.map +1 -0
- package/dist/native/executable-cache.d.ts +26 -0
- package/dist/native/executable-cache.js +228 -0
- package/dist/native/executable-cache.js.map +1 -0
- package/dist/native/executable-cache.test.d.ts +1 -0
- package/dist/native/executable-cache.test.js +151 -0
- package/dist/native/executable-cache.test.js.map +1 -0
- package/dist/native/file-identity.d.ts +4 -0
- package/dist/native/file-identity.js +14 -0
- package/dist/native/file-identity.js.map +1 -0
- package/dist/native/file-identity.test.d.ts +1 -0
- package/dist/native/file-identity.test.js +43 -0
- package/dist/native/file-identity.test.js.map +1 -0
- package/dist/native/library.d.ts +22 -0
- package/dist/native/library.js +83 -0
- package/dist/native/library.js.map +1 -0
- package/dist/native/prepare.d.ts +21 -0
- package/dist/native/prepare.js +174 -0
- package/dist/native/prepare.js.map +1 -0
- package/dist/native/prepare.test.d.ts +1 -0
- package/dist/native/prepare.test.js +70 -0
- package/dist/native/prepare.test.js.map +1 -0
- package/dist/native/sanitizer.d.ts +11 -0
- package/dist/native/sanitizer.js +135 -0
- package/dist/native/sanitizer.js.map +1 -0
- package/dist/native/sanitizer.test.d.ts +1 -0
- package/dist/native/sanitizer.test.js +58 -0
- package/dist/native/sanitizer.test.js.map +1 -0
- package/dist/native/task.d.ts +4 -0
- package/dist/native/task.js +16 -0
- package/dist/native/task.js.map +1 -0
- package/dist/native/task.test.d.ts +1 -0
- package/dist/native/task.test.js +17 -0
- package/dist/native/task.test.js.map +1 -0
- package/dist/native/toolchain.d.ts +45 -0
- package/dist/native/toolchain.js +74 -0
- package/dist/native/toolchain.js.map +1 -0
- package/dist/native/toolchain.test.d.ts +1 -0
- package/dist/native/toolchain.test.js +33 -0
- package/dist/native/toolchain.test.js.map +1 -0
- package/dist/startup-cache.d.ts +1 -1
- package/dist/startup-cache.js +2 -5
- package/dist/startup-cache.js.map +1 -1
- package/dist/timing.d.ts +4 -0
- package/dist/timing.js +19 -0
- package/dist/timing.js.map +1 -0
- package/dist/wasi-paths.js +10 -7
- package/dist/wasi-paths.js.map +1 -1
- package/package.json +28 -19
- package/surface-manifest.json +171 -18
- package/dist/backend/c/async.d.ts +0 -171
- package/dist/backend/c/async.js +0 -1317
- package/dist/backend/c/async.js.map +0 -1
- package/dist/backend/c/c-emitter.d.ts +0 -531
- package/dist/backend/c/c-emitter.js +0 -1917
- package/dist/backend/c/c-emitter.js.map +0 -1
- package/dist/backend/c/exprs.d.ts +0 -15
- package/dist/backend/c/exprs.js +0 -8803
- package/dist/backend/c/exprs.js.map +0 -1
- package/dist/backend/c/island.d.ts +0 -45
- package/dist/backend/c/island.js +0 -281
- package/dist/backend/c/island.js.map +0 -1
- package/dist/backend/c/may-throw.js.map +0 -1
- package/dist/backend/c/shapes.d.ts +0 -142
- package/dist/backend/c/shapes.js +0 -603
- package/dist/backend/c/shapes.js.map +0 -1
- package/dist/backend/c/stmts.d.ts +0 -76
- package/dist/backend/c/stmts.js +0 -1084
- package/dist/backend/c/stmts.js.map +0 -1
- package/dist/backend/c/types.d.ts +0 -71
- package/dist/backend/c/types.js +0 -459
- package/dist/backend/c/types.js.map +0 -1
- package/dist/backend/c/types.test.js +0 -32
- package/dist/backend/c/types.test.js.map +0 -1
- package/dist/backend/c/walkers.d.ts +0 -134
- package/dist/backend/c/walkers.js +0 -1773
- package/dist/backend/c/walkers.js.map +0 -1
- /package/dist/backend/{c/types.test.d.ts → cycle-analysis.test.d.ts} +0 -0
|
@@ -1,4 +1,15 @@
|
|
|
1
|
+
import { everyExprChild, everyStmtChild } from "../../ir/traverse.js";
|
|
2
|
+
import { RuntimeOptionalLocals } from "./runtime-optional-locals.js";
|
|
3
|
+
import { sanitizeUnregisteredClassTypes } from "./sanitize-class-types.js";
|
|
4
|
+
import { UnregisteredClassTypes } from "./unregistered-class-types.js";
|
|
5
|
+
import { buildUnionNarrow } from "./union-narrow.js";
|
|
6
|
+
import { planUnionRetag, buildUnionRetag, planRecordUnionWrap, buildRecordUnionWrap } from "./union-retag.js";
|
|
7
|
+
import { bindingInContext, captureContextBinding, declareContextLocal, declareContextThis } from "./function-context.js";
|
|
8
|
+
export { newFnCtx } from "./function-context.js";
|
|
1
9
|
import { InternalCompilerError } from "../../errors.js";
|
|
10
|
+
import { defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "./optional-arguments.js";
|
|
11
|
+
import { ClassDynamicDispatch } from "./class-dynamic-dispatch.js";
|
|
12
|
+
import { finalizeClassMethodValues } from "./class-method-values.js";
|
|
2
13
|
/* AST + checker → IR.
|
|
3
14
|
*
|
|
4
15
|
* Invariants:
|
|
@@ -14,25 +25,31 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
14
25
|
* ("x.0", "x.1" for shadowing); the IR is scope-flat.
|
|
15
26
|
*/
|
|
16
27
|
import { resolve } from "node:path";
|
|
28
|
+
import { bindingSource } from "../binding-source.js";
|
|
17
29
|
import { tsgoPath } from "../dts-paths.js";
|
|
18
30
|
import * as ts from "../ts7/adapter.js";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
31
|
+
import { literalValues } from "../literal-values.js";
|
|
32
|
+
import { literalUnionArm } from "../union-discriminants.js";
|
|
33
|
+
import { anyOpRequiresDynamicDiag, blockedBindingUseDiag, checkerPanicDiag, componentTypeDiag, isCheckerPanic, genericSignatureTypeDiag, indexSignatureTypeDiag, intersectionTypeDiag, noLoweringDiag, overloadedSignatureTypeDiag, recordShapeMismatchDiag, requiresDynamicApiDiag, requiresDynamicPackageDiag, requiresDynamicTypeDiag, unionMismatchDiag, UNSUPPORTED, unsupportedDiag, unsupportedTypeDiag, } from "../../diagnostics/diagnostic.js";
|
|
34
|
+
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
|
+
import {} from "../npm.js";
|
|
21
36
|
import { provenanceActive } from "../provenance-registry.js";
|
|
22
37
|
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
23
|
-
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, ISLAND_AMBIENT_TYPES, isUnitOnlyTsType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
38
|
+
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, ISLAND_AMBIENT_TYPES, isUnitOnlyTsType, jsOpenObjectType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
24
39
|
import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
|
|
25
40
|
import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules, appendForkModules } from "./lower-modules.js";
|
|
26
41
|
import { prepareCjsModuleGraph } from "./lower-node-module.js";
|
|
27
|
-
import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, findGenericMethodOn, findGenericStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor,
|
|
42
|
+
import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, findGenericMethodOn, findGenericStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorConstructorArgs, lowerNew, accessorCall } from "./lower-classes.js";
|
|
28
43
|
import { mixinCallClassInfoOf, mixinIntersectionInstanceType } from "./lower-mixins.js";
|
|
44
|
+
import { implicitAnyParamSymbolsOf } from "./lower-calls.js";
|
|
45
|
+
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
29
46
|
import { bindingNeverReassigned, bodyReadsArguments, funcTypeFromParamShapes, implicitMonoFile, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, completeArgs, wrappedUndefined, undefinedArgFor, requireExactArityValue, bodyReturnType, declaredReturnType, collectSignature, collectSignatureInner, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, lowerCall, lowerFfiCall, lowerTimersMemberCall, lowerPromiseMethodCall, lowerFilterNarrowCall, isTopLevelFnSymbol, lowerNestedFunctionDecl, lambdaSignature, lowerLambda, lowerFunction, validateFfiImports } from "./lower-calls.js";
|
|
30
47
|
import { lowerArrayMethodCall, lowerMapMethodCall, lowerMapForEachCall, buildMapForEachFn, lowerRecordOvfCaptureHelper, lowerEnvToPairsHelper, lowerSetMethodCall, lowerSetForEachCall, buildSetForEachFn } from "./lower-containers.js";
|
|
31
48
|
import { lowerBufferStaticCall, lowerBytesMethodCall, lowerBytesNew } from "./containers/bytes.js";
|
|
32
49
|
import { lowerRegexMethodCall, lowerStringMethodCall } from "./containers/string-and-regexp.js";
|
|
33
50
|
import { lowerStreamModuleCall } from "./lower-stream.js";
|
|
34
51
|
import { lowerEmitOverrideSpec } from "./lower-event-emitter.js";
|
|
35
|
-
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
|
|
52
|
+
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";
|
|
36
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";
|
|
37
54
|
import { lowerHttpHeadersElement, lowerNetModuleCall, lowerServerMethodCall, lowerServerProperty, lowerTlsRootCertificates } from "./lower-server.js";
|
|
38
55
|
import { lowerDgramDnsModuleCall, lowerDgramMethodCall } from "./lower-dgram.js";
|
|
@@ -42,12 +59,13 @@ import { lowerUtilModuleCall } from "./lower-inspect.js";
|
|
|
42
59
|
import { lowerComptime, comptimeBakeable, rejectComptimeCaptures, comptimeValueToIr } from "./lower-comptime.js";
|
|
43
60
|
import { lowerStmts, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, lowerJsvalBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement } from "./lower-stmts.js";
|
|
44
61
|
import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf } from "./lower-exprs.js";
|
|
45
|
-
import { finishOptionalChain, lowerOptionalChain } from "./expressions/optional-chains.js";
|
|
62
|
+
import { finishOptionalChain, isOptionalChainTail, lowerOptionalChain } from "./expressions/optional-chains.js";
|
|
46
63
|
import { foldedStringKeyOf, lowerDynObjectLiteral, lowerObjectLiteral, lowerShorthandValue, rejectThisInObjectMethod } from "./expressions/object-literals.js";
|
|
47
64
|
import { lowerRecordFieldCall, lowerObjectMethodCall } from "./lower-calls.js";
|
|
48
65
|
import { fenceCrossBlockNsRef, nsPathPrefix } from "./lower-namespaces.js";
|
|
49
66
|
import { numLit, varRef } from "../../ir/build.js";
|
|
50
67
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
68
|
+
import { lowerTernary } from "./lower-exprs.js";
|
|
51
69
|
/** Entry function name. '%' cannot appear in a TS identifier, so a user
|
|
52
70
|
* function can never collide with it (mangling is injective per prefix). */
|
|
53
71
|
export const ENTRY_NAME = "%main";
|
|
@@ -61,24 +79,6 @@ export class PoisonError extends Error {
|
|
|
61
79
|
export function own(table, key) {
|
|
62
80
|
return Object.hasOwn(table, key) ? table[key] : undefined;
|
|
63
81
|
}
|
|
64
|
-
/** Sentinel binding key for `this` (which has no ts.Symbol): a stable
|
|
65
|
-
* object identity used in the same scope/capture maps as real symbols, so
|
|
66
|
-
* arrows capturing `this` ride the ordinary capture machinery. */
|
|
67
|
-
const THIS_BINDING = { escapedName: "%this" };
|
|
68
|
-
export function newFnCtx(lifted, selfSymbol, selfType, returnType) {
|
|
69
|
-
return {
|
|
70
|
-
locals: [],
|
|
71
|
-
scopes: [new Map()],
|
|
72
|
-
localCounters: new Map(),
|
|
73
|
-
captures: lifted ? [] : null,
|
|
74
|
-
captureSources: [],
|
|
75
|
-
captureBySymbol: new Map(),
|
|
76
|
-
selfSymbol,
|
|
77
|
-
selfType,
|
|
78
|
-
returnType,
|
|
79
|
-
ctl: [],
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
82
|
/** IrStmt discriminants — the island walk below must not descend into
|
|
83
83
|
* NESTED statements (each is counted individually by its own lowerStmts
|
|
84
84
|
* visit; descending would attribute a nested island statement to every
|
|
@@ -89,10 +89,6 @@ const IR_STMT_KINDS = new Set([
|
|
|
89
89
|
"arraySet", "arraySetLength", "arraySetUndefined", "arrayDelete", "forOf", "return", "fieldSet", "recordSet", "break",
|
|
90
90
|
"continue", "block", "tryCatch", "throw", "rethrow", "runtimeFence",
|
|
91
91
|
]);
|
|
92
|
-
/** True when a lowered statement's OWN expressions contain island
|
|
93
|
-
* constructs — a generic JSON walk (like moduleUsesRegex): `kind`
|
|
94
|
-
* discriminants live only on IR objects, so user string values can never
|
|
95
|
-
* false-positive. Nested statements are skipped (counted separately). */
|
|
96
92
|
/** Every identifier a binding name binds: the identifier itself, or all
|
|
97
93
|
* identifiers of a (possibly nested) destructuring pattern in source
|
|
98
94
|
* order. */
|
|
@@ -109,31 +105,22 @@ export function boundIdentifiersOf(name) {
|
|
|
109
105
|
}
|
|
110
106
|
return out;
|
|
111
107
|
}
|
|
108
|
+
/** Inspect executable children directly, without boxing the statement tree
|
|
109
|
+
* into checked-dynamic storage just to calculate coverage. */
|
|
112
110
|
export function stmtUsesIsland(stmts) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return;
|
|
121
|
-
|
|
122
|
-
const kind = v.kind;
|
|
123
|
-
if (!root && typeof kind === "string" && IR_STMT_KINDS.has(kind))
|
|
124
|
-
return;
|
|
125
|
-
const fn = v.fn;
|
|
126
|
-
if (kind === "jsOp" || kind === "jsExit" || kind === "jsBridgePromise" ||
|
|
127
|
-
fn === "island.eval" || fn === "island.import" || fn === "island.importDyn" ||
|
|
128
|
-
fn === "island.castFail") {
|
|
129
|
-
found = true;
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
for (const value of Object.values(v))
|
|
133
|
-
visit(value, false);
|
|
111
|
+
// Keep the accounting boundary at the source statement: nested statement
|
|
112
|
+
// lists are counted by their own lowerStmts invocation.
|
|
113
|
+
const nested = (stmt) => IR_STMT_KINDS.has(stmt.kind) || everyStmtChild(stmt, expr, nested);
|
|
114
|
+
const expr = (node) => {
|
|
115
|
+
if (node.kind === "jsOp" || node.kind === "jsExit" || node.kind === "jsBridgePromise" ||
|
|
116
|
+
(node.kind === "libCall" && (node.fn === "island.eval" || node.fn === "island.import" ||
|
|
117
|
+
node.fn === "island.importDyn" || node.fn === "island.castFail")))
|
|
118
|
+
return false;
|
|
119
|
+
return everyExprChild(node, expr, nested);
|
|
134
120
|
};
|
|
135
|
-
|
|
136
|
-
|
|
121
|
+
if (Array.isArray(stmts))
|
|
122
|
+
return !stmts.every((stmt) => everyStmtChild(stmt, expr, nested));
|
|
123
|
+
return !everyStmtChild(stmts, expr, nested);
|
|
137
124
|
}
|
|
138
125
|
function directExternalTypeSpecifiersByFile(externalTypes) {
|
|
139
126
|
const out = new Map();
|
|
@@ -172,12 +159,14 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
172
159
|
if (!phaseTiming)
|
|
173
160
|
return;
|
|
174
161
|
const now = performance.now();
|
|
175
|
-
|
|
162
|
+
const event = {
|
|
176
163
|
phase,
|
|
177
164
|
phase_ms: Math.round((now - phaseLast) * 10) / 10,
|
|
178
165
|
total_ms: Math.round((now - phaseStarted) * 10) / 10,
|
|
179
|
-
|
|
180
|
-
|
|
166
|
+
};
|
|
167
|
+
for (const key of Object.keys(detail))
|
|
168
|
+
event[key] = detail[key];
|
|
169
|
+
process.stderr.write(`scriptc lowering ${JSON.stringify(event)}\n`);
|
|
181
170
|
phaseLast = now;
|
|
182
171
|
};
|
|
183
172
|
const dynamic = options.dynamic ?? false;
|
|
@@ -215,6 +204,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
215
204
|
const externalTypeSpecifiersByFile = options.externalTypeSpecifiersByFile ??
|
|
216
205
|
directExternalTypeSpecifiersByFile(externalTypes);
|
|
217
206
|
const validation = new Lowerer(program, entry, moduleOrder, dynamic, {
|
|
207
|
+
frontendServices: options.frontendServices,
|
|
218
208
|
targetPlatform,
|
|
219
209
|
startupCrash,
|
|
220
210
|
ffiImports,
|
|
@@ -233,6 +223,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
233
223
|
const reachableEmit = ffiImports.length === 0
|
|
234
224
|
? validation
|
|
235
225
|
: new Lowerer(program, entry, moduleOrder, dynamic, {
|
|
226
|
+
frontendServices: options.frontendServices,
|
|
236
227
|
targetPlatform,
|
|
237
228
|
startupCrash,
|
|
238
229
|
ffiImports,
|
|
@@ -260,6 +251,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
260
251
|
// without such a settled fence retain checker-backed IR exactly once.
|
|
261
252
|
if (reachableEmit.requiresHistoricalOrderRelower) {
|
|
262
253
|
const emit = new Lowerer(program, entry, moduleOrder, dynamic, {
|
|
254
|
+
frontendServices: options.frontendServices,
|
|
263
255
|
reachable,
|
|
264
256
|
targetPlatform,
|
|
265
257
|
startupCrash,
|
|
@@ -281,6 +273,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
281
273
|
if (options.coverage !== true)
|
|
282
274
|
return result;
|
|
283
275
|
const remainder = new Lowerer(program, entry, moduleOrder, dynamic, {
|
|
276
|
+
frontendServices: options.frontendServices,
|
|
284
277
|
reachable,
|
|
285
278
|
remainder: true,
|
|
286
279
|
alreadyFlushed: resultLowerer.flushedSymbols,
|
|
@@ -352,7 +345,7 @@ export function staticImportNamespaceType(lowerer, expr) {
|
|
|
352
345
|
if (moduleId === null) {
|
|
353
346
|
const symbol = lowerer.checker.getSymbolAtLocation(arg);
|
|
354
347
|
const source = symbol && lowerer.checker.declarationsOf(symbol).find((decl) => ts.isSourceFile(decl) && !decl.isDeclarationFile);
|
|
355
|
-
if (source && !source.fileName.endsWith(".cts") && !isCjsJsFile(source) &&
|
|
348
|
+
if (source && !source.fileName.endsWith(".cts") && !isCjsJsFile(source, lowerer.program) &&
|
|
356
349
|
lowerer.moduleOrder.includes(source)) {
|
|
357
350
|
moduleId = `file:${tsgoPath(resolve(source.fileName))}`;
|
|
358
351
|
}
|
|
@@ -526,6 +519,25 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
526
519
|
// the whole type's own fence.
|
|
527
520
|
return anyPiecedFuncType(lowerer, node, t);
|
|
528
521
|
}
|
|
522
|
+
const promise = jsFallbackPromiseType(lowerer, t);
|
|
523
|
+
if (promise)
|
|
524
|
+
return promise;
|
|
525
|
+
const generator = jsFallbackGeneratorType(lowerer, t);
|
|
526
|
+
if (generator)
|
|
527
|
+
return generator;
|
|
528
|
+
const symbol = t.getSymbol();
|
|
529
|
+
if ((symbol?.name === "Map" || symbol?.name === "ReadonlyMap") && lowerer.isStdlibSymbol(symbol)) {
|
|
530
|
+
const args = lowerer.checker.getTypeArguments(t);
|
|
531
|
+
if (args.length === 2) {
|
|
532
|
+
const key = lowerer.mapTypeOf(args[0]);
|
|
533
|
+
const value = lowerer.mapTypeOf(args[1]);
|
|
534
|
+
return {
|
|
535
|
+
kind: "map",
|
|
536
|
+
key: key && isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined) ? key : DYN,
|
|
537
|
+
value: value && isSupportedMapValue(value) ? value : DYN,
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
}
|
|
529
541
|
// JS inference commonly spells a callback field initialized to null as
|
|
530
542
|
// `((value: any) => any) | null`. Preserve the callable arm and its
|
|
531
543
|
// checked-dynamic pieces instead of collapsing the whole slot to dyn.
|
|
@@ -587,6 +599,32 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
587
599
|
return fallbackFunction;
|
|
588
600
|
return DYN;
|
|
589
601
|
}
|
|
602
|
+
/** An inferred JS promise keeps its asynchronous ABI even when its payload
|
|
603
|
+
* has no fixed shape. The settled value crosses the checked native boundary. */
|
|
604
|
+
function jsFallbackPromiseType(lowerer, t) {
|
|
605
|
+
const symbol = t.getSymbol();
|
|
606
|
+
if (symbol?.name !== "Promise" || !lowerer.isStdlibSymbol(symbol))
|
|
607
|
+
return null;
|
|
608
|
+
const inner = lowerer.checker.getTypeArguments(t)[0];
|
|
609
|
+
return inner ? { kind: "promise", inner: lowerer.mapTypeOf(inner) ?? DYN } : null;
|
|
610
|
+
}
|
|
611
|
+
/** An inferred generator with channels outside the typed result union
|
|
612
|
+
* keeps its fiber ABI and carries yielded/resumed values as checked values. */
|
|
613
|
+
function jsFallbackGeneratorType(lowerer, t) {
|
|
614
|
+
const symbol = t.getSymbol();
|
|
615
|
+
if (!symbol || !["Generator", "AsyncGenerator", "IterableIterator"].includes(symbol.name) ||
|
|
616
|
+
!lowerer.isStdlibSymbol(symbol))
|
|
617
|
+
return null;
|
|
618
|
+
const [yielded, returned, resumed] = lowerer.checker.getTypeArguments(t);
|
|
619
|
+
const unit = ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Never;
|
|
620
|
+
return {
|
|
621
|
+
kind: "generator",
|
|
622
|
+
...(symbol.name === "AsyncGenerator" ? { async: true } : {}),
|
|
623
|
+
yieldT: yielded && yielded.flags & ts.TypeFlags.Never ? VOID : DYN,
|
|
624
|
+
retT: !returned || returned.flags & unit ? VOID : DYN,
|
|
625
|
+
nextT: !resumed || resumed.flags & unit ? UNDEFINED_T : DYN,
|
|
626
|
+
};
|
|
627
|
+
}
|
|
590
628
|
function jsFallbackFunctionType(lowerer, node, t) {
|
|
591
629
|
const sig = pureSingleCallSignatureOf(lowerer, t);
|
|
592
630
|
if (!sig)
|
|
@@ -601,6 +639,7 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
601
639
|
// `enabled = true`) rather than that call-site type, so recover the
|
|
602
640
|
// syntactic optionality from the parameter declaration.
|
|
603
641
|
const decl = lowerer.checker.valueDeclarationOf(p);
|
|
642
|
+
mapped = jsOpenObjectType(decl, mapped, lowerer.shapes, lowerer.unions);
|
|
604
643
|
const optional = decl !== undefined &&
|
|
605
644
|
ts.isParameter(decl) &&
|
|
606
645
|
(decl.questionToken !== undefined || decl.initializer !== undefined);
|
|
@@ -613,12 +652,16 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
613
652
|
return mapped;
|
|
614
653
|
});
|
|
615
654
|
const retT = lowerer.checker.getReturnTypeOfSignature(sig);
|
|
616
|
-
const
|
|
655
|
+
const sigDecl = lowerer.checker.signatureDeclaration(sig);
|
|
656
|
+
const jsUnitReturn = sigDecl !== undefined && isJsSourceFile(sigDecl.getSourceFile()) &&
|
|
657
|
+
(retT.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0;
|
|
658
|
+
const ret = jsUnitReturn ? DYN : retT.flags & ts.TypeFlags.Void ? VOID
|
|
659
|
+
: lowerer.mapTypeOf(retT) ?? jsFallbackPromiseType(lowerer, retT) ?? jsFallbackGeneratorType(lowerer, retT) ?? DYN;
|
|
617
660
|
return { kind: "func", params, ret };
|
|
618
661
|
}
|
|
619
|
-
/**
|
|
620
|
-
*
|
|
621
|
-
*
|
|
662
|
+
/** Recover a JavaScript variadic callable's native ABI from its declaration.
|
|
663
|
+
* Rest parameters and an implicit `arguments` array must keep their packing
|
|
664
|
+
* convention when the function flows through a value or an export. */
|
|
622
665
|
function jsArgumentsFunctionType(lowerer, t) {
|
|
623
666
|
if (!(t.flags & ts.TypeFlags.Object))
|
|
624
667
|
return null;
|
|
@@ -626,16 +669,19 @@ function jsArgumentsFunctionType(lowerer, t) {
|
|
|
626
669
|
if (sigs.length !== 1 || sigs[0].getTypeParameters().length !== 0 || lowerer.checker.getConstructSignatures(t).length !== 0 || lowerer.checker.getPropertiesOfType(t).length !== 0)
|
|
627
670
|
return null;
|
|
628
671
|
const decl = lowerer.checker.signatureDeclaration(sigs[0]);
|
|
629
|
-
if (decl === undefined || !(ts.isFunctionDeclaration(decl) || ts.isFunctionExpression(decl)) ||
|
|
630
|
-
!isJsSourceFile(decl.getSourceFile())
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
672
|
+
if (decl === undefined || !(ts.isFunctionDeclaration(decl) || ts.isFunctionExpression(decl) || ts.isArrowFunction(decl)) ||
|
|
673
|
+
!isJsSourceFile(decl.getSourceFile()))
|
|
674
|
+
return null;
|
|
675
|
+
const hasRest = decl.parameters.some((p) => p.dotDotDotToken !== undefined);
|
|
676
|
+
if (!hasRest && (ts.isArrowFunction(decl) || !bodyReadsArguments(decl) ||
|
|
677
|
+
decl.parameters.length > 0 && !isNodeEsmFile(decl.getSourceFile(), lowerer.program)))
|
|
634
678
|
return null;
|
|
635
679
|
const shapes = paramShapes(lowerer, decl.parameters);
|
|
636
680
|
const retType = lowerer.checker.getReturnTypeOfSignature(sigs[0]);
|
|
637
|
-
const ret = retType.flags & ts.TypeFlags.
|
|
638
|
-
|
|
681
|
+
const ret = retType.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)
|
|
682
|
+
? DYN
|
|
683
|
+
: retType.flags & ts.TypeFlags.Void ? VOID : lowerer.mapTypeOf(retType) ?? DYN;
|
|
684
|
+
return funcTypeFromParamShapes(hasRest ? shapes : [...shapes, { type: DYN, mode: "arguments" }], ret);
|
|
639
685
|
}
|
|
640
686
|
/** The one call signature of a PURE function type — single signature, no
|
|
641
687
|
* properties, no construct signatures, no type parameters, no rest params
|
|
@@ -730,6 +776,7 @@ export class Lowerer {
|
|
|
730
776
|
entry;
|
|
731
777
|
moduleOrder;
|
|
732
778
|
dynamic;
|
|
779
|
+
frontendServices;
|
|
733
780
|
checker;
|
|
734
781
|
diags = [];
|
|
735
782
|
fnSigsBySymbol = new Map();
|
|
@@ -934,6 +981,7 @@ export class Lowerer {
|
|
|
934
981
|
/** Non-null while an instance body lowers: type-parameter symbol →
|
|
935
982
|
* concrete IR type, consulted inside mapType's recursion. */
|
|
936
983
|
typeParamBindings = null;
|
|
984
|
+
localClassInstantiations = [];
|
|
937
985
|
/** The ts-level twin of typeParamBindings, non-null while a CALL-keyed
|
|
938
986
|
* instance body lowers: type-parameter symbol → the bound CHECKER type,
|
|
939
987
|
* consulted where the mapped IrType has already widened away information
|
|
@@ -958,10 +1006,23 @@ export class Lowerer {
|
|
|
958
1006
|
* aliases, so this carries the var/let form the checker cannot.
|
|
959
1007
|
* Scoped strictly by narrowingAliases (lowerIf / lowerCondition). */
|
|
960
1008
|
aliasNarrowTypes = new Map();
|
|
1009
|
+
/** These caches belong to this lowering pass. The program already owns
|
|
1010
|
+
* their symbol/node keys; no module-level cache should retain a pass. */
|
|
1011
|
+
classSymbolKeys = new Map();
|
|
1012
|
+
registeredClassSymbols = new Map();
|
|
1013
|
+
httpClientFnBindings = new Map();
|
|
1014
|
+
streamPropMutatedSyms = null;
|
|
1015
|
+
requestInitPropMutatedSyms = null;
|
|
1016
|
+
emitterEventTable = null;
|
|
1017
|
+
emitterComputedPatterns = [];
|
|
961
1018
|
/** Locals widened beyond the checker's type because an inferred indexed
|
|
962
1019
|
* read can be absent at runtime. Bare reads preserve that union until a
|
|
963
1020
|
* surrounding JavaScript guard/default consumes it. */
|
|
964
|
-
runtimeOptionalLocals = new
|
|
1021
|
+
runtimeOptionalLocals = new RuntimeOptionalLocals();
|
|
1022
|
+
/** An effectful switch test can change the original binding after the
|
|
1023
|
+
* discriminant was captured. A case match narrows the captured value,
|
|
1024
|
+
* not that mutable binding; preserve its tagged representation on reads. */
|
|
1025
|
+
unstableSwitchBindings = new Set();
|
|
965
1026
|
/** All storage slots widened for runtime absence, including slots whose
|
|
966
1027
|
* current control-flow branch has temporarily narrowed the value. */
|
|
967
1028
|
runtimeOptionalStorageLocals = new Set();
|
|
@@ -980,18 +1041,21 @@ export class Lowerer {
|
|
|
980
1041
|
runtimeOptionalBindingTypes = new Map();
|
|
981
1042
|
/** Concise callback/lambda returns promoted by the HOF callback prepass;
|
|
982
1043
|
* arrows have no declaration symbol to key in fnSigsBySymbol. */
|
|
983
|
-
runtimeOptionalFunctionReturns = new
|
|
1044
|
+
runtimeOptionalFunctionReturns = new Map();
|
|
1045
|
+
/** Intrinsic callback slots can supply a destination for fresh return
|
|
1046
|
+
* literals, such as a reduce accumulator with recursive union fields. */
|
|
1047
|
+
contextualFunctionReturns = new Map();
|
|
984
1048
|
/** Arithmetic over an unchecked string read can answer either NaN or a
|
|
985
1049
|
* string. Bindings and returns use this marker to retain that result union
|
|
986
1050
|
* through checker-bare string annotations. */
|
|
987
|
-
runtimeOptionalArithmeticTypes = new
|
|
1051
|
+
runtimeOptionalArithmeticTypes = new Map();
|
|
988
1052
|
/** Record fields promoted to an undefined-armed union by an indexed-read
|
|
989
1053
|
* value. The key is the concrete emitted shape and field name. */
|
|
990
1054
|
runtimeOptionalFields = new Set();
|
|
991
1055
|
/** Callback pattern parameters carry an optional source without making
|
|
992
1056
|
* every name destructured from a present source optional. */
|
|
993
|
-
runtimeOptionalPatternTypes = new
|
|
994
|
-
runtimeOptionalReduceTypes = new
|
|
1057
|
+
runtimeOptionalPatternTypes = new Map();
|
|
1058
|
+
runtimeOptionalReduceTypes = new Map();
|
|
995
1059
|
/** Capture entries and their origin share one mutable box. Normalize each
|
|
996
1060
|
* entry to the origin so writes and flow proofs stay synchronized. */
|
|
997
1061
|
runtimeOptionalRoots = new Map();
|
|
@@ -1351,6 +1415,12 @@ export class Lowerer {
|
|
|
1351
1415
|
/** Keyed by program-wide qualified class name (what IR object types carry). */
|
|
1352
1416
|
classes = new Map();
|
|
1353
1417
|
classBySymbol = new Map();
|
|
1418
|
+
/** Inferred JS methods participating in an override chain keep a vtable
|
|
1419
|
+
* ABI instead of call-site specialization. Filled before class collection. */
|
|
1420
|
+
virtualJsMethods = new Set();
|
|
1421
|
+
/** Largest fixed argument list below a JS method, discovered before any
|
|
1422
|
+
* base vtable signature is collected. Unused checked slots carry undefined. */
|
|
1423
|
+
virtualJsMethodArity = new Map();
|
|
1354
1424
|
/** The class whose members are lowering — `super` binds lexically to it
|
|
1355
1425
|
* (arrows inside methods lower within this window, so they see it too). */
|
|
1356
1426
|
currentClass = null;
|
|
@@ -1403,6 +1473,7 @@ export class Lowerer {
|
|
|
1403
1473
|
* engine handle (a dynamic import's namespace object) — paramShape's
|
|
1404
1474
|
* early-out. */
|
|
1405
1475
|
jsvalParamOverrides = new Set();
|
|
1476
|
+
checkedCallbackParams = new Set();
|
|
1406
1477
|
/** Inline Promise.then parameters whose contextual type is a builtin
|
|
1407
1478
|
* module namespace anonymous object. The settled native token is the
|
|
1408
1479
|
* ABI truth even when the checker type has no stable module symbol. */
|
|
@@ -1492,6 +1563,9 @@ export class Lowerer {
|
|
|
1492
1563
|
// top level, top = the innermost nested function currently lowering).
|
|
1493
1564
|
fnStack = [];
|
|
1494
1565
|
liftedFns = [];
|
|
1566
|
+
/** One Error-method helper belongs to this lowering session. Its cached
|
|
1567
|
+
* dispatch revision needs no weak-key identity or process-global state. */
|
|
1568
|
+
errorMethodDispatchRevision = null;
|
|
1495
1569
|
lambdaCounter = 0;
|
|
1496
1570
|
/** Statement lists currently mid-lowering, innermost last: the forward-
|
|
1497
1571
|
* capture machinery needs to know which later statements of an OPEN list
|
|
@@ -1499,20 +1573,6 @@ export class Lowerer {
|
|
|
1499
1573
|
* register into, and where to insert predeclarations before closures or
|
|
1500
1574
|
* earlier source statements need them. */
|
|
1501
1575
|
activeStmtLists = [];
|
|
1502
|
-
/** Forward-captured consts pre-declared as TDZ boxes, keyed by symbol:
|
|
1503
|
-
* lowerVarDecl consumes the entry when the source declaration arrives and
|
|
1504
|
-
* emits the initializing `assign` instead of a fresh declaration. */
|
|
1505
|
-
tdzPredeclared = new Map();
|
|
1506
|
-
/** Nested function DECLARATIONS lowered eagerly by the forward-hoisting
|
|
1507
|
-
* machinery (predeclareForwardFnDecl — a reference above the declaration
|
|
1508
|
-
* in the same function, JS's function hoisting): the statement loop skips
|
|
1509
|
-
* the source statement when it arrives. */
|
|
1510
|
-
hoistedFnDecls = new Set();
|
|
1511
|
-
/** `var` bindings hoisted to their function root (hoistVarBinding), keyed
|
|
1512
|
-
* by the checker's merged symbol — every same-name `var` in one function
|
|
1513
|
-
* is one symbol, so one slot. Module-scope vars live in globalsBySymbol
|
|
1514
|
-
* instead. */
|
|
1515
|
-
hoistedVars = new Map();
|
|
1516
1576
|
/** Per-file `var` module globals whose type carries an undefined arm:
|
|
1517
1577
|
* lowerFileInit assigns them the interned undefined right after the
|
|
1518
1578
|
* run-once guard — JS hoists module vars to `undefined` at entry, so a
|
|
@@ -1601,13 +1661,19 @@ export class Lowerer {
|
|
|
1601
1661
|
let s = this.statsByFile.get(file);
|
|
1602
1662
|
if (!s)
|
|
1603
1663
|
this.statsByFile.set(file, (s = { total: 0, failed: 0, island: 0 }));
|
|
1604
|
-
|
|
1664
|
+
if (kind === "total")
|
|
1665
|
+
s.total += 1;
|
|
1666
|
+
else if (kind === "failed")
|
|
1667
|
+
s.failed += 1;
|
|
1668
|
+
else
|
|
1669
|
+
s.island += 1;
|
|
1605
1670
|
}
|
|
1606
1671
|
constructor(program, entry, moduleOrder, dynamic, mode = {}) {
|
|
1607
1672
|
this.program = program;
|
|
1608
1673
|
this.entry = entry;
|
|
1609
1674
|
this.moduleOrder = moduleOrder;
|
|
1610
1675
|
this.dynamic = dynamic;
|
|
1676
|
+
this.frontendServices = mode.frontendServices;
|
|
1611
1677
|
this.reachable = mode.reachable ?? null;
|
|
1612
1678
|
this.remainder = mode.remainder ?? false;
|
|
1613
1679
|
this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
|
|
@@ -1632,10 +1698,25 @@ export class Lowerer {
|
|
|
1632
1698
|
classNamer: this.classNamer,
|
|
1633
1699
|
resolveTypeParam: this.typeParamResolver,
|
|
1634
1700
|
resolveTypeParamTs: this.typeParamTsResolver,
|
|
1635
|
-
genericClassInstance: (decl, ref) => this.genericClassInstanceType(decl, ref),
|
|
1701
|
+
genericClassInstance: (decl, ref, mapArgument) => this.genericClassInstanceType(decl, ref, mapArgument),
|
|
1636
1702
|
mixinClassInstance: (decl) => this.mixinTypeContext && this.mixinTypeContext.classNode === decl
|
|
1637
1703
|
? { kind: "object", className: this.mixinTypeContext.className }
|
|
1638
1704
|
: null,
|
|
1705
|
+
localClassInstance: (decl) => {
|
|
1706
|
+
for (let parent = decl.parent; parent && !ts.isSourceFile(parent); parent = parent.parent) {
|
|
1707
|
+
if (!ts.isFunctionDeclaration(parent) && !ts.isFunctionExpression(parent) &&
|
|
1708
|
+
!ts.isArrowFunction(parent) && !ts.isMethodDeclaration(parent))
|
|
1709
|
+
continue;
|
|
1710
|
+
if (this.localClassInstantiations.some((entry) => entry.owner === parent))
|
|
1711
|
+
break;
|
|
1712
|
+
if (parent.typeParameters?.length || (implicitMonoFile(parent.getSourceFile()) && implicitAnyParamSymbolsOf(this, parent)))
|
|
1713
|
+
return null;
|
|
1714
|
+
}
|
|
1715
|
+
const className = this.classNamer(decl);
|
|
1716
|
+
if (!this.collectingExprClasses.has(decl))
|
|
1717
|
+
this.lowerClassExpressionInfo(decl);
|
|
1718
|
+
return { kind: "object", className };
|
|
1719
|
+
},
|
|
1639
1720
|
mixinIntersectionInstance: (widened) => mixinIntersectionInstanceType(this, widened),
|
|
1640
1721
|
isStdlibFile: this.isStdlibFile,
|
|
1641
1722
|
isNpmFile: this.isNpmFile,
|
|
@@ -1677,7 +1758,7 @@ export class Lowerer {
|
|
|
1677
1758
|
sym = this.checker.getAliasedSymbol(sym);
|
|
1678
1759
|
for (const decl of this.checker.declarationsOf(sym)) {
|
|
1679
1760
|
if (ts.isSourceFile(decl) && !decl.isDeclarationFile &&
|
|
1680
|
-
!decl.fileName.endsWith(".cts") && !isCjsJsFile(decl) &&
|
|
1761
|
+
!decl.fileName.endsWith(".cts") && !isCjsJsFile(decl, this.program) &&
|
|
1681
1762
|
this.moduleOrder.includes(decl)) {
|
|
1682
1763
|
return `file:${tsgoPath(resolve(decl.fileName))}`;
|
|
1683
1764
|
}
|
|
@@ -1716,9 +1797,25 @@ export class Lowerer {
|
|
|
1716
1797
|
* builds (no counter can drift between invocations),
|
|
1717
1798
|
* program-unique through the file qualifier, and collision-free with
|
|
1718
1799
|
* user identifiers ('%'). */
|
|
1719
|
-
classNamer = (decl) =>
|
|
1720
|
-
|
|
1721
|
-
|
|
1800
|
+
classNamer = (decl) => {
|
|
1801
|
+
const name = ts.isClassExpression(decl) || (() => {
|
|
1802
|
+
for (let parent = decl.parent; parent && !ts.isSourceFile(parent); parent = parent.parent) {
|
|
1803
|
+
if (ts.isFunctionLike(parent))
|
|
1804
|
+
return true;
|
|
1805
|
+
}
|
|
1806
|
+
return false;
|
|
1807
|
+
})()
|
|
1808
|
+
? this.qualify(decl.getSourceFile(), `%cx${decl.getStart()}.${decl.name?.text ?? ""}`)
|
|
1809
|
+
: this.qualify(decl.getSourceFile(), nsPathPrefix(decl) + (decl.name ? decl.name.text : "%anon"));
|
|
1810
|
+
for (let index = this.localClassInstantiations.length - 1; index >= 0; index--) {
|
|
1811
|
+
const entry = this.localClassInstantiations[index];
|
|
1812
|
+
for (let parent = decl.parent; parent && !ts.isSourceFile(parent); parent = parent.parent) {
|
|
1813
|
+
if (parent === entry.owner)
|
|
1814
|
+
return `${name}%${entry.name}`;
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
return name;
|
|
1818
|
+
};
|
|
1722
1819
|
/** Follows import aliases to the original declaration's symbol. Every
|
|
1723
1820
|
* value reference resolves through here, so it doubles as the flush
|
|
1724
1821
|
* point for deferred collection diagnostics: resolving a reference to a
|
|
@@ -1930,7 +2027,7 @@ export class Lowerer {
|
|
|
1930
2027
|
: undefined;
|
|
1931
2028
|
if (namespaceDecl === undefined)
|
|
1932
2029
|
return null;
|
|
1933
|
-
const importDecl = namespaceDecl.parent
|
|
2030
|
+
const importDecl = namespaceDecl.parent?.parent;
|
|
1934
2031
|
if (!ts.isImportDeclaration(importDecl) || !ts.isStringLiteral(importDecl.moduleSpecifier))
|
|
1935
2032
|
return null;
|
|
1936
2033
|
if (this.externalTypes.has(importDecl.moduleSpecifier.text))
|
|
@@ -1952,7 +2049,7 @@ export class Lowerer {
|
|
|
1952
2049
|
let specNode;
|
|
1953
2050
|
let importedName = null;
|
|
1954
2051
|
if (ts.isImportSpecifier(decl)) {
|
|
1955
|
-
const importDecl = decl.parent
|
|
2052
|
+
const importDecl = decl.parent?.parent?.parent;
|
|
1956
2053
|
if (ts.isImportDeclaration(importDecl))
|
|
1957
2054
|
specNode = importDecl.moduleSpecifier;
|
|
1958
2055
|
importedName = (decl.propertyName ?? decl.name).text;
|
|
@@ -1963,13 +2060,13 @@ export class Lowerer {
|
|
|
1963
2060
|
importedName = "default";
|
|
1964
2061
|
}
|
|
1965
2062
|
else if (ts.isNamespaceImport(decl)) {
|
|
1966
|
-
const importDecl = decl.parent
|
|
2063
|
+
const importDecl = decl.parent?.parent;
|
|
1967
2064
|
if (ts.isImportDeclaration(importDecl))
|
|
1968
2065
|
specNode = importDecl.moduleSpecifier;
|
|
1969
2066
|
importedName = null;
|
|
1970
2067
|
}
|
|
1971
2068
|
else if (ts.isExportSpecifier(decl)) {
|
|
1972
|
-
const exportDecl = decl.parent
|
|
2069
|
+
const exportDecl = decl.parent?.parent;
|
|
1973
2070
|
if (ts.isExportDeclaration(exportDecl))
|
|
1974
2071
|
specNode = exportDecl.moduleSpecifier;
|
|
1975
2072
|
importedName = (decl.propertyName ?? decl.name).text;
|
|
@@ -2030,13 +2127,13 @@ export class Lowerer {
|
|
|
2030
2127
|
name = "default";
|
|
2031
2128
|
}
|
|
2032
2129
|
else if (d && ts.isImportSpecifier(d)) {
|
|
2033
|
-
const idecl = d.parent
|
|
2130
|
+
const idecl = d.parent?.parent?.parent;
|
|
2034
2131
|
if (ts.isImportDeclaration(idecl))
|
|
2035
2132
|
spec = idecl.moduleSpecifier;
|
|
2036
2133
|
name = (d.propertyName ?? d.name).text;
|
|
2037
2134
|
}
|
|
2038
2135
|
else if (d && ts.isExportSpecifier(d)) {
|
|
2039
|
-
const edecl = d.parent
|
|
2136
|
+
const edecl = d.parent?.parent;
|
|
2040
2137
|
if (ts.isExportDeclaration(edecl))
|
|
2041
2138
|
spec = edecl.moduleSpecifier;
|
|
2042
2139
|
name = (d.propertyName ?? d.name).text;
|
|
@@ -2149,7 +2246,7 @@ export class Lowerer {
|
|
|
2149
2246
|
// relative imports; an opted-in --npm-static package is the fallback.
|
|
2150
2247
|
const dep = resolveImport(this.program, importDecl.getSourceFile(), spec) ??
|
|
2151
2248
|
npmStaticDepSf7(this.program, importDecl.getSourceFile(), spec);
|
|
2152
|
-
if (!dep || !isJsSourceFile(dep) || isNodeEsmFile(dep))
|
|
2249
|
+
if (!dep || !isJsSourceFile(dep) || isNodeEsmFile(dep, this.program))
|
|
2153
2250
|
return null;
|
|
2154
2251
|
return dep;
|
|
2155
2252
|
}
|
|
@@ -2170,7 +2267,7 @@ export class Lowerer {
|
|
|
2170
2267
|
const directSpec = requireSpecOf(decl.initializer);
|
|
2171
2268
|
if (directSpec !== null) {
|
|
2172
2269
|
return resolveImport(this.program, decl.getSourceFile(), directSpec) ??
|
|
2173
|
-
npmStaticDepSf7(this.program, decl.getSourceFile(), directSpec);
|
|
2270
|
+
npmStaticDepSf7(this.program, decl.getSourceFile(), directSpec, "require");
|
|
2174
2271
|
}
|
|
2175
2272
|
return createRequireProgramModuleOf(this, decl.initializer)?.dep ?? null;
|
|
2176
2273
|
}
|
|
@@ -2381,7 +2478,7 @@ export class Lowerer {
|
|
|
2381
2478
|
while (changed) {
|
|
2382
2479
|
changed = false;
|
|
2383
2480
|
for (const fp of parts) {
|
|
2384
|
-
if (this.asyncInitFiles.has(fp.sf) || !isNodeEsmFile(fp.sf))
|
|
2481
|
+
if (this.asyncInitFiles.has(fp.sf) || !isNodeEsmFile(fp.sf, this.program))
|
|
2385
2482
|
continue;
|
|
2386
2483
|
if (orderedImportsOf(this.program, fp.sf).some(({ dep }) => dep !== null && this.asyncInitFiles.has(dep))) {
|
|
2387
2484
|
this.asyncInitFiles.add(fp.sf);
|
|
@@ -2405,9 +2502,14 @@ export class Lowerer {
|
|
|
2405
2502
|
}
|
|
2406
2503
|
const orderIndex = new Map(parts.map((fp, i) => [fp.sf, i]));
|
|
2407
2504
|
const partSet = new Set(parts.map((fp) => fp.sf));
|
|
2408
|
-
const staticDeps = (sf) =>
|
|
2409
|
-
|
|
2410
|
-
|
|
2505
|
+
const staticDeps = (sf) => {
|
|
2506
|
+
const dependencies = [];
|
|
2507
|
+
for (const { dep } of orderedImportsOf(this.program, sf)) {
|
|
2508
|
+
if (dep !== null && dep !== sf && partSet.has(dep))
|
|
2509
|
+
dependencies.push(dep);
|
|
2510
|
+
}
|
|
2511
|
+
return dependencies;
|
|
2512
|
+
};
|
|
2411
2513
|
// Tarjan SCCs over the same static graph. The last postorder member is
|
|
2412
2514
|
// a deterministic COMPONENT representative for internal-edge tests
|
|
2413
2515
|
// and global naming. The runtime evaluation root can differ: a cycle
|
|
@@ -2485,7 +2587,7 @@ export class Lowerer {
|
|
|
2485
2587
|
// those globals stay uninitialized: the dep's module body would never
|
|
2486
2588
|
// run.
|
|
2487
2589
|
const dep = resolveImport(this.program, node.getSourceFile(), spec) ??
|
|
2488
|
-
npmStaticDepSf7(this.program, node.getSourceFile(), spec);
|
|
2590
|
+
npmStaticDepSf7(this.program, node.getSourceFile(), spec, "require");
|
|
2489
2591
|
if (!dep || dep.fileName.endsWith(".json"))
|
|
2490
2592
|
return null;
|
|
2491
2593
|
if (this.asyncInitFiles.has(dep)) {
|
|
@@ -2565,6 +2667,9 @@ export class Lowerer {
|
|
|
2565
2667
|
};
|
|
2566
2668
|
const functionDeclBySymbol = new Map();
|
|
2567
2669
|
const signatureBySymbol = new Map();
|
|
2670
|
+
const methodFamilies = new Map();
|
|
2671
|
+
const familyBySymbol = new Map();
|
|
2672
|
+
const optionalMethodFamilies = new Set();
|
|
2568
2673
|
for (const [symbol, sig] of this.fnSigsBySymbol)
|
|
2569
2674
|
signatureBySymbol.set(symbol, { params: sig.params, returnType: sig.returnType, top: sig });
|
|
2570
2675
|
for (const decl of fnDecls) {
|
|
@@ -2588,8 +2693,18 @@ export class Lowerer {
|
|
|
2588
2693
|
continue;
|
|
2589
2694
|
const symbol = symbolOf(member.name);
|
|
2590
2695
|
const sig = info.methods.get(mName);
|
|
2591
|
-
if (symbol && sig)
|
|
2696
|
+
if (symbol && sig) {
|
|
2592
2697
|
signatureBySymbol.set(symbol, { params: sig.params, returnType: sig.ret, method: sig });
|
|
2698
|
+
let root = info;
|
|
2699
|
+
for (let base = info.base; base; base = base.base)
|
|
2700
|
+
if (base.methods.has(mName))
|
|
2701
|
+
root = base;
|
|
2702
|
+
const key = `${root.def.name}:${mName}`;
|
|
2703
|
+
const family = methodFamilies.get(key) ?? [];
|
|
2704
|
+
family.push(symbol);
|
|
2705
|
+
methodFamilies.set(key, family);
|
|
2706
|
+
familyBySymbol.set(symbol, family);
|
|
2707
|
+
}
|
|
2593
2708
|
}
|
|
2594
2709
|
}
|
|
2595
2710
|
const peel = (node) => {
|
|
@@ -2599,6 +2714,32 @@ export class Lowerer {
|
|
|
2599
2714
|
}
|
|
2600
2715
|
return e;
|
|
2601
2716
|
};
|
|
2717
|
+
const callableSymbols = new Map();
|
|
2718
|
+
const callableSymbolOf = (node) => {
|
|
2719
|
+
const cached = callableSymbols.get(node);
|
|
2720
|
+
if (cached !== undefined)
|
|
2721
|
+
return cached;
|
|
2722
|
+
let symbol = symbolOf(ts.isPropertyAccessExpression(node) ? node.name : node);
|
|
2723
|
+
if (symbol === null || signatureBySymbol.has(symbol)) {
|
|
2724
|
+
callableSymbols.set(node, symbol);
|
|
2725
|
+
return symbol;
|
|
2726
|
+
}
|
|
2727
|
+
const seen = new Set();
|
|
2728
|
+
while (symbol && !signatureBySymbol.has(symbol) && !seen.has(symbol)) {
|
|
2729
|
+
seen.add(symbol);
|
|
2730
|
+
const declaration = this.checker.valueDeclarationOf(symbol);
|
|
2731
|
+
if (declaration && ts.isMethodDeclaration(declaration)) {
|
|
2732
|
+
symbol = symbolOf(declaration.name);
|
|
2733
|
+
}
|
|
2734
|
+
else if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer && ts.isIdentifier(peel(declaration.initializer))) {
|
|
2735
|
+
symbol = symbolOf(peel(declaration.initializer));
|
|
2736
|
+
}
|
|
2737
|
+
else
|
|
2738
|
+
break;
|
|
2739
|
+
}
|
|
2740
|
+
callableSymbols.set(node, symbol);
|
|
2741
|
+
return symbol;
|
|
2742
|
+
};
|
|
2602
2743
|
const explicitlyNonNull = (node) => {
|
|
2603
2744
|
let e = node;
|
|
2604
2745
|
while (ts.isParenthesizedExpression(e) || ts.isAsExpression(e) || ts.isTypeAssertion(e) || ts.isNonNullExpression(e)) {
|
|
@@ -2660,13 +2801,17 @@ export class Lowerer {
|
|
|
2660
2801
|
this.mapTypeOf(this.typeOf(e))?.kind === "union" &&
|
|
2661
2802
|
this.armTag(this.mapTypeOf(this.typeOf(e)).unionId, UNDEFINED_T) >= 0)
|
|
2662
2803
|
return true;
|
|
2663
|
-
if (ts.isIdentifier(e))
|
|
2664
|
-
|
|
2804
|
+
if (ts.isIdentifier(e)) {
|
|
2805
|
+
const symbol = symbolOf(e);
|
|
2806
|
+
return symbol !== null && optionalSymbols.has(symbol);
|
|
2807
|
+
}
|
|
2665
2808
|
if (ts.isCallExpression(e) && ts.isIdentifier(e.expression)) {
|
|
2666
|
-
|
|
2809
|
+
const symbol = callableSymbolOf(e.expression);
|
|
2810
|
+
return symbol !== null && optionalReturns.has(symbol);
|
|
2667
2811
|
}
|
|
2668
2812
|
if (ts.isCallExpression(e) && ts.isPropertyAccessExpression(e.expression)) {
|
|
2669
|
-
|
|
2813
|
+
const symbol = callableSymbolOf(e.expression);
|
|
2814
|
+
return symbol !== null && optionalReturns.has(symbol);
|
|
2670
2815
|
}
|
|
2671
2816
|
if (ts.isConditionalExpression(e)) {
|
|
2672
2817
|
return mayBeOptional(e.whenTrue) || mayBeOptional(e.whenFalse);
|
|
@@ -2679,7 +2824,8 @@ export class Lowerer {
|
|
|
2679
2824
|
return mayBeOptional(e.left) || mayBeOptional(e.right);
|
|
2680
2825
|
}
|
|
2681
2826
|
if (ts.isPropertyAccessExpression(e) && ts.isIdentifier(e.expression)) {
|
|
2682
|
-
const
|
|
2827
|
+
const symbol = symbolOf(e.expression);
|
|
2828
|
+
const fields = symbol === null ? undefined : optionalFields.get(symbol);
|
|
2683
2829
|
return fields?.has(fieldName(e)) ?? false;
|
|
2684
2830
|
}
|
|
2685
2831
|
return false;
|
|
@@ -2689,9 +2835,11 @@ export class Lowerer {
|
|
|
2689
2835
|
if (!ts.isBinaryExpression(e) || e.operatorToken.kind !== ts.SyntaxKind.PlusToken)
|
|
2690
2836
|
return null;
|
|
2691
2837
|
const stringArrayRead = (part) => {
|
|
2692
|
-
const t = this.mapTypeOf(this.typeOf(part));
|
|
2693
2838
|
const p = peel(part);
|
|
2694
|
-
if (
|
|
2839
|
+
if (!ts.isElementAccessExpression(p))
|
|
2840
|
+
return false;
|
|
2841
|
+
const t = this.mapTypeOf(this.typeOf(part));
|
|
2842
|
+
if (t?.kind !== "string")
|
|
2695
2843
|
return false;
|
|
2696
2844
|
const recv = this.mapTypeOf(this.typeOf(p.expression));
|
|
2697
2845
|
return recv?.kind === "array" && recv.elem.kind === "string";
|
|
@@ -2766,19 +2914,36 @@ export class Lowerer {
|
|
|
2766
2914
|
return [0];
|
|
2767
2915
|
return null;
|
|
2768
2916
|
};
|
|
2769
|
-
|
|
2917
|
+
// Syntax does not change during the fixed point. Reuse its return sites
|
|
2918
|
+
// while recomputing their optionality from each pass's current bindings.
|
|
2919
|
+
const returnSites = new Map();
|
|
2920
|
+
const returnsOf = (fn) => {
|
|
2921
|
+
const cached = returnSites.get(fn);
|
|
2922
|
+
if (cached !== undefined)
|
|
2923
|
+
return cached;
|
|
2924
|
+
const expressions = [];
|
|
2925
|
+
returnSites.set(fn, expressions);
|
|
2770
2926
|
if (!fn.body)
|
|
2771
|
-
return
|
|
2772
|
-
if (!ts.isBlock(fn.body))
|
|
2773
|
-
|
|
2774
|
-
|
|
2927
|
+
return expressions;
|
|
2928
|
+
if (!ts.isBlock(fn.body)) {
|
|
2929
|
+
expressions.push(fn.body);
|
|
2930
|
+
}
|
|
2775
2931
|
ts.walkPreorder(fn.body, (node) => {
|
|
2776
2932
|
if (node !== fn.body && (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node)))
|
|
2777
2933
|
return "skip";
|
|
2778
|
-
if (ts.isReturnStatement(node) && node.expression
|
|
2779
|
-
|
|
2934
|
+
if (ts.isReturnStatement(node) && node.expression)
|
|
2935
|
+
expressions.push(node.expression);
|
|
2780
2936
|
return undefined;
|
|
2781
2937
|
});
|
|
2938
|
+
return expressions;
|
|
2939
|
+
};
|
|
2940
|
+
const bodyReturnsOptional = (fn) => {
|
|
2941
|
+
if (fn.body && !ts.isBlock(fn.body))
|
|
2942
|
+
return mayBeOptional(fn.body);
|
|
2943
|
+
let found = false;
|
|
2944
|
+
for (const expression of returnsOf(fn))
|
|
2945
|
+
if (mayBeOptional(expression))
|
|
2946
|
+
found = true;
|
|
2782
2947
|
return found;
|
|
2783
2948
|
};
|
|
2784
2949
|
const promoteHofCallback = (callback, parameterIndices, seen = new Set()) => {
|
|
@@ -2790,6 +2955,8 @@ export class Lowerer {
|
|
|
2790
2955
|
};
|
|
2791
2956
|
const promoteNode = (fn) => {
|
|
2792
2957
|
for (const parameterIndex of parameterIndices) {
|
|
2958
|
+
if (parameterIndex === undefined)
|
|
2959
|
+
continue;
|
|
2793
2960
|
const parameter = fn.parameters[parameterIndex];
|
|
2794
2961
|
if (!parameter)
|
|
2795
2962
|
continue;
|
|
@@ -2862,6 +3029,8 @@ export class Lowerer {
|
|
|
2862
3029
|
const sig = signatureBySymbol.get(symbol);
|
|
2863
3030
|
if (sig) {
|
|
2864
3031
|
for (const parameterIndex of parameterIndices) {
|
|
3032
|
+
if (parameterIndex === undefined)
|
|
3033
|
+
continue;
|
|
2865
3034
|
if (!sig.params[parameterIndex])
|
|
2866
3035
|
continue;
|
|
2867
3036
|
const before = sig.params[parameterIndex].type;
|
|
@@ -2877,6 +3046,8 @@ export class Lowerer {
|
|
|
2877
3046
|
if (valueType?.kind === "func") {
|
|
2878
3047
|
const params = valueType.params.slice();
|
|
2879
3048
|
for (const parameterIndex of parameterIndices) {
|
|
3049
|
+
if (parameterIndex === undefined)
|
|
3050
|
+
continue;
|
|
2880
3051
|
if (params[parameterIndex])
|
|
2881
3052
|
params[parameterIndex] = this.runtimeOptionalType(params[parameterIndex]);
|
|
2882
3053
|
}
|
|
@@ -2927,9 +3098,22 @@ export class Lowerer {
|
|
|
2927
3098
|
const decl = this.checker.valueDeclarationOf(symbol);
|
|
2928
3099
|
return !!decl && ts.isVariableDeclaration(decl) && !!decl.initializer && callbackReturnsOptional(decl.initializer, seen);
|
|
2929
3100
|
};
|
|
3101
|
+
const scanSites = new Map();
|
|
3102
|
+
const sitesOf = (sf) => {
|
|
3103
|
+
const cached = scanSites.get(sf);
|
|
3104
|
+
if (cached !== undefined)
|
|
3105
|
+
return cached;
|
|
3106
|
+
const nodes = [];
|
|
3107
|
+
ts.walkPreorder(sf, (node) => {
|
|
3108
|
+
if (ts.isVariableDeclaration(node) || ts.isBinaryExpression(node) || ts.isCallExpression(node))
|
|
3109
|
+
nodes.push(node);
|
|
3110
|
+
});
|
|
3111
|
+
scanSites.set(sf, nodes);
|
|
3112
|
+
return nodes;
|
|
3113
|
+
};
|
|
2930
3114
|
const scanFile = (sf) => {
|
|
2931
3115
|
let changed = false;
|
|
2932
|
-
|
|
3116
|
+
const scan = (node) => {
|
|
2933
3117
|
if (ts.isVariableDeclaration(node)) {
|
|
2934
3118
|
if (node.initializer) {
|
|
2935
3119
|
if (ts.isIdentifier(node.name) && isDynamicObjectEntryRead(node.initializer)) {
|
|
@@ -3020,93 +3204,137 @@ export class Lowerer {
|
|
|
3020
3204
|
}
|
|
3021
3205
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
3022
3206
|
const callbackIndices = hofCallbackIndices(node.expression.name.text, node.arguments.length >= 2);
|
|
3023
|
-
const
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
const
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3207
|
+
const callback = node.arguments[0];
|
|
3208
|
+
if (callbackIndices !== null && callback !== undefined && !ts.isSpreadElement(callback)) {
|
|
3209
|
+
const receiverNode = node.expression.expression;
|
|
3210
|
+
const receiverTs = this.typeOf(receiverNode);
|
|
3211
|
+
let receiver = this.mapTypeOf(receiverTs);
|
|
3212
|
+
// An array method after an optional-chain guard only runs on the
|
|
3213
|
+
// present receiver. The checker includes the chain's short-circuit
|
|
3214
|
+
// undefined in intermediate call types, so use the same narrowed
|
|
3215
|
+
// receiver the method lowerer sees when promoting HOF callbacks.
|
|
3216
|
+
if (receiver?.kind === "union" &&
|
|
3217
|
+
(node.expression.questionDotToken !== undefined || isOptionalChainTail(this, node))) {
|
|
3218
|
+
receiver = this.mapTypeOf(this.checker.getNonNullableType(receiverTs));
|
|
3219
|
+
}
|
|
3220
|
+
const tuple = receiver?.kind === "record" && this.shapes.get(receiver.shapeId)?.tuple === true;
|
|
3221
|
+
// A JS/evolving-any array may have acquired a precise FLOW type
|
|
3222
|
+
// at this call while its actual binding remains a checked-dynamic
|
|
3223
|
+
// array. Its callback consumes DYN values through runtime method
|
|
3224
|
+
// dispatch, so widening that callback to the native array value
|
|
3225
|
+
// ABI makes it impossible to box back into DYN. Judge a simple
|
|
3226
|
+
// binding by its declaration type, the same storage fact local
|
|
3227
|
+
// declaration lowering uses.
|
|
3228
|
+
let nativeArrayReceiver = receiver?.kind === "array" || tuple;
|
|
3229
|
+
if (nativeArrayReceiver && ts.isIdentifier(receiverNode)) {
|
|
3230
|
+
const receiverSymbol = symbolOf(receiverNode);
|
|
3231
|
+
const declaration = receiverSymbol ? this.checker.valueDeclarationOf(receiverSymbol) : undefined;
|
|
3232
|
+
if (declaration && ts.isVariableDeclaration(declaration)) {
|
|
3233
|
+
const declared = this.mapTypeOf(this.typeOf(declaration.name));
|
|
3234
|
+
if (declared?.kind !== "array" && !(declared?.kind === "record" && this.shapes.get(declared.shapeId)?.tuple === true)) {
|
|
3235
|
+
nativeArrayReceiver = false;
|
|
3236
|
+
}
|
|
3042
3237
|
}
|
|
3043
3238
|
}
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
if (promoteHofCallback(callback, callbackIndices))
|
|
3047
|
-
changed = true;
|
|
3048
|
-
const method = node.expression.name.text;
|
|
3049
|
-
if ((method === "reduce" || method === "reduceRight") &&
|
|
3050
|
-
(node.arguments.length < 2 || callbackReturnsOptional(callback))) {
|
|
3051
|
-
if (promoteHofCallback(callback, [0, 1]))
|
|
3052
|
-
changed = true;
|
|
3053
|
-
const result = this.runtimeOptionalType(this.irTypeOf(node));
|
|
3054
|
-
const previous = this.runtimeOptionalReduceTypes.get(node);
|
|
3055
|
-
if (!previous || !typeEquals(previous, result)) {
|
|
3056
|
-
this.runtimeOptionalReduceTypes.set(node, result);
|
|
3239
|
+
if (nativeArrayReceiver) {
|
|
3240
|
+
if (promoteHofCallback(callback, callbackIndices))
|
|
3057
3241
|
changed = true;
|
|
3242
|
+
const method = node.expression.name.text;
|
|
3243
|
+
if ((method === "reduce" || method === "reduceRight") &&
|
|
3244
|
+
(node.arguments.length < 2 || callbackReturnsOptional(callback))) {
|
|
3245
|
+
if (promoteHofCallback(callback, [0, 1]))
|
|
3246
|
+
changed = true;
|
|
3247
|
+
const result = this.runtimeOptionalType(this.irTypeOf(node));
|
|
3248
|
+
const previous = this.runtimeOptionalReduceTypes.get(node);
|
|
3249
|
+
if (!previous || !typeEquals(previous, result)) {
|
|
3250
|
+
this.runtimeOptionalReduceTypes.set(node, result);
|
|
3251
|
+
changed = true;
|
|
3252
|
+
}
|
|
3058
3253
|
}
|
|
3059
3254
|
}
|
|
3060
3255
|
}
|
|
3061
3256
|
}
|
|
3062
3257
|
if (ts.isCallExpression(node) &&
|
|
3063
3258
|
(ts.isIdentifier(node.expression) || ts.isPropertyAccessExpression(node.expression))) {
|
|
3064
|
-
const
|
|
3065
|
-
const symbol = symbolOf(calleeNode);
|
|
3259
|
+
const symbol = callableSymbolOf(node.expression);
|
|
3066
3260
|
if (!symbol)
|
|
3067
3261
|
return;
|
|
3068
3262
|
const sig = signatureBySymbol.get(symbol);
|
|
3069
|
-
if (!sig)
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3263
|
+
if (!sig)
|
|
3264
|
+
return;
|
|
3265
|
+
// JSDoc describes the usual value, not a runtime arity check.
|
|
3266
|
+
// A short JavaScript call still passes undefined. Widen only the
|
|
3267
|
+
// observed slots before bodies lower so both caller and callee
|
|
3268
|
+
// agree on that value's representation.
|
|
3269
|
+
const callee = functionDeclBySymbol.get(symbol);
|
|
3270
|
+
if (callee && isJsSourceFile(callee.getSourceFile()) && !node.arguments.some(ts.isSpreadElement)) {
|
|
3271
|
+
for (let i = 0; i < sig.params.length; i++) {
|
|
3272
|
+
const arg = node.arguments[i];
|
|
3273
|
+
if (arg && (this.typeOf(arg).flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) === 0)
|
|
3274
|
+
continue;
|
|
3275
|
+
const family = familyBySymbol.get(symbol);
|
|
3276
|
+
if (family)
|
|
3277
|
+
optionalMethodFamilies.add(family);
|
|
3278
|
+
for (const target of familyBySymbol.get(symbol) ?? [symbol]) {
|
|
3279
|
+
const shape = signatureBySymbol.get(target)?.params[i];
|
|
3280
|
+
if (!shape || shape.mode !== "required")
|
|
3281
|
+
continue;
|
|
3282
|
+
const widened = addUndefined(shape.type);
|
|
3283
|
+
if (typeEquals(shape.type, widened))
|
|
3284
|
+
continue;
|
|
3285
|
+
shape.type = widened;
|
|
3286
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
3287
|
+
if (parameter) {
|
|
3288
|
+
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
3289
|
+
const boundSymbol = symbolOf(bound);
|
|
3290
|
+
if (boundSymbol) {
|
|
3291
|
+
optionalSymbols.add(boundSymbol);
|
|
3292
|
+
if (ts.isIdentifier(parameter.name))
|
|
3293
|
+
this.runtimeOptionalBindingTypes.set(boundSymbol, shape.type);
|
|
3092
3294
|
}
|
|
3093
3295
|
}
|
|
3094
|
-
}
|
|
3296
|
+
}
|
|
3297
|
+
changed = true;
|
|
3095
3298
|
}
|
|
3096
3299
|
}
|
|
3097
|
-
return;
|
|
3098
3300
|
}
|
|
3099
|
-
|
|
3100
|
-
|
|
3301
|
+
const restAt = sig.params.findIndex((shape) => shape.mode === "rest" || shape.mode === "dynRest" || shape.mode === "islandRest" || shape.mode === "arguments");
|
|
3302
|
+
node.arguments.forEach((arg, argumentIndex) => {
|
|
3303
|
+
const i = restAt >= 0 && argumentIndex >= restAt ? restAt : argumentIndex;
|
|
3304
|
+
const shape = sig.params[i];
|
|
3305
|
+
const callbackSlot = shape?.type;
|
|
3101
3306
|
if (callbackSlot?.kind === "func" && !ts.isSpreadElement(arg)) {
|
|
3102
3307
|
const optionalCallbackParams = callbackSlot.params.flatMap((type, index) => type.kind === "union" && this.armTag(type.unionId, UNDEFINED_T) >= 0 ? [index] : []);
|
|
3103
3308
|
if (optionalCallbackParams.length > 0 && promoteHofCallback(arg, optionalCallbackParams)) {
|
|
3104
3309
|
changed = true;
|
|
3105
3310
|
}
|
|
3106
3311
|
}
|
|
3107
|
-
if (ts.isSpreadElement(arg) || !mayBeOptional(arg) || !
|
|
3312
|
+
if (ts.isSpreadElement(arg) || !mayBeOptional(arg) || !shape)
|
|
3108
3313
|
return;
|
|
3314
|
+
if (i === restAt) {
|
|
3315
|
+
// A rest binding always receives an array. An unchecked
|
|
3316
|
+
// argument can make its elements undefined, not the pack.
|
|
3317
|
+
// Keep every virtual implementation on the same array ABI.
|
|
3318
|
+
for (const target of familyBySymbol.get(symbol) ?? [symbol]) {
|
|
3319
|
+
const rest = signatureBySymbol.get(target)?.params[i];
|
|
3320
|
+
if (rest?.mode !== "rest" || rest.type.kind !== "array")
|
|
3321
|
+
continue;
|
|
3322
|
+
const widened = arrayOf(addUndefined(rest.type.elem));
|
|
3323
|
+
if (typeEquals(rest.type, widened))
|
|
3324
|
+
continue;
|
|
3325
|
+
rest.type = widened;
|
|
3326
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
3327
|
+
if (parameter && ts.isIdentifier(parameter.name)) {
|
|
3328
|
+
const bound = symbolOf(parameter.name);
|
|
3329
|
+
if (bound)
|
|
3330
|
+
this.runtimeOptionalBindingTypes.set(bound, widened);
|
|
3331
|
+
}
|
|
3332
|
+
changed = true;
|
|
3333
|
+
}
|
|
3334
|
+
return;
|
|
3335
|
+
}
|
|
3109
3336
|
const set = optionalParams.get(symbol) ?? new Set();
|
|
3337
|
+
shape.type = addUndefined(shape.type);
|
|
3110
3338
|
const before = set.size;
|
|
3111
3339
|
set.add(i);
|
|
3112
3340
|
optionalParams.set(symbol, set);
|
|
@@ -3126,40 +3354,24 @@ export class Lowerer {
|
|
|
3126
3354
|
}
|
|
3127
3355
|
});
|
|
3128
3356
|
}
|
|
3129
|
-
}
|
|
3357
|
+
};
|
|
3358
|
+
for (const node of sitesOf(sf))
|
|
3359
|
+
scan(node);
|
|
3130
3360
|
return changed;
|
|
3131
3361
|
};
|
|
3132
3362
|
const scanReturns = (symbol, decl) => {
|
|
3133
|
-
if (!decl.body)
|
|
3134
|
-
return false;
|
|
3135
3363
|
let changed = false;
|
|
3136
|
-
|
|
3137
|
-
optionalReturns.
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
const arithmetic = optionalStringArithmeticType(
|
|
3364
|
+
for (const expression of returnsOf(decl)) {
|
|
3365
|
+
if (mayBeOptional(expression) && !optionalReturns.has(symbol)) {
|
|
3366
|
+
optionalReturns.add(symbol);
|
|
3367
|
+
changed = true;
|
|
3368
|
+
}
|
|
3369
|
+
const arithmetic = optionalStringArithmeticType(expression);
|
|
3142
3370
|
if (arithmetic && !arithmeticReturns.has(symbol)) {
|
|
3143
3371
|
arithmeticReturns.set(symbol, arithmetic);
|
|
3144
3372
|
changed = true;
|
|
3145
3373
|
}
|
|
3146
3374
|
}
|
|
3147
|
-
ts.walkPreorder(decl.body, (node) => {
|
|
3148
|
-
if (node !== decl.body && (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node)))
|
|
3149
|
-
return "skip";
|
|
3150
|
-
if (ts.isReturnStatement(node) && node.expression && mayBeOptional(node.expression) && !optionalReturns.has(symbol)) {
|
|
3151
|
-
optionalReturns.add(symbol);
|
|
3152
|
-
changed = true;
|
|
3153
|
-
}
|
|
3154
|
-
if (ts.isReturnStatement(node) && node.expression) {
|
|
3155
|
-
const arithmetic = optionalStringArithmeticType(node.expression);
|
|
3156
|
-
if (arithmetic && !arithmeticReturns.has(symbol)) {
|
|
3157
|
-
arithmeticReturns.set(symbol, arithmetic);
|
|
3158
|
-
changed = true;
|
|
3159
|
-
}
|
|
3160
|
-
}
|
|
3161
|
-
return undefined;
|
|
3162
|
-
});
|
|
3163
3375
|
return changed;
|
|
3164
3376
|
};
|
|
3165
3377
|
let changed = true;
|
|
@@ -3171,6 +3383,18 @@ export class Lowerer {
|
|
|
3171
3383
|
for (const [symbol, decl] of functionDeclBySymbol)
|
|
3172
3384
|
if (scanReturns(symbol, decl))
|
|
3173
3385
|
changed = true;
|
|
3386
|
+
// Every implementation of a virtual slot must retain the same ABI,
|
|
3387
|
+
// including when just one body forwards an omitted parameter.
|
|
3388
|
+
for (const family of optionalMethodFamilies) {
|
|
3389
|
+
if (!family.some((symbol) => optionalReturns.has(symbol)))
|
|
3390
|
+
continue;
|
|
3391
|
+
for (const symbol of family) {
|
|
3392
|
+
if (!optionalReturns.has(symbol)) {
|
|
3393
|
+
optionalReturns.add(symbol);
|
|
3394
|
+
changed = true;
|
|
3395
|
+
}
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3174
3398
|
}
|
|
3175
3399
|
for (const [symbol, sig] of signatureBySymbol) {
|
|
3176
3400
|
const params = optionalParams.get(symbol);
|
|
@@ -3296,7 +3520,7 @@ export class Lowerer {
|
|
|
3296
3520
|
continue;
|
|
3297
3521
|
const sig = declSymbol ? this.fnSigsBySymbol.get(declSymbol) : undefined;
|
|
3298
3522
|
// A body nothing reaches never lowers: its constructs can't fail
|
|
3299
|
-
// the build and it leaves no trace in the emitted
|
|
3523
|
+
// the build and it leaves no trace in the emitted LLVM.
|
|
3300
3524
|
if (sig && !this.wantBody(sig.name))
|
|
3301
3525
|
continue;
|
|
3302
3526
|
const fn = this.lowerFunction(decl);
|
|
@@ -3342,7 +3566,10 @@ export class Lowerer {
|
|
|
3342
3566
|
let gc = 0;
|
|
3343
3567
|
let gi = 0;
|
|
3344
3568
|
let es = 0;
|
|
3345
|
-
|
|
3569
|
+
const classDispatch = new ClassDynamicDispatch();
|
|
3570
|
+
let dispatchChanged = !this.remainder;
|
|
3571
|
+
while (dispatchChanged ||
|
|
3572
|
+
ec < this.exprClasses.length ||
|
|
3346
3573
|
gc < this.genericClassInstances.length ||
|
|
3347
3574
|
gi < this.instantiationQueue.length ||
|
|
3348
3575
|
es < this.emitSpecQueue.length) {
|
|
@@ -3380,6 +3607,9 @@ export class Lowerer {
|
|
|
3380
3607
|
throw e;
|
|
3381
3608
|
}
|
|
3382
3609
|
}
|
|
3610
|
+
dispatchChanged = !this.remainder && classDispatch.process(this, [
|
|
3611
|
+
...functions, ...this.liftedFns, ...this.implicitFns,
|
|
3612
|
+
]);
|
|
3383
3613
|
}
|
|
3384
3614
|
}
|
|
3385
3615
|
// Lambdas lifted while lowering any of the above (plus synthetic
|
|
@@ -3413,6 +3643,7 @@ export class Lowerer {
|
|
|
3413
3643
|
/** Final retention, pruning, and module assembly shared by ordinary emit
|
|
3414
3644
|
* and the retained reachability worklist. */
|
|
3415
3645
|
finishModule(functions) {
|
|
3646
|
+
finalizeClassMethodValues(this, functions);
|
|
3416
3647
|
// Globals typed by a class that never REGISTERED (a JS class whose
|
|
3417
3648
|
// collection fenced — Symbol-keyed fields, an unsupported base): the
|
|
3418
3649
|
// declaration statement and every use compiled to runtime fences, but
|
|
@@ -3423,8 +3654,9 @@ export class Lowerer {
|
|
|
3423
3654
|
// fences), so drop it — guarded by a reference scan, with the
|
|
3424
3655
|
// validator's registration check as the backstop for anything that
|
|
3425
3656
|
// does slip through with a live reference.
|
|
3426
|
-
const
|
|
3427
|
-
const
|
|
3657
|
+
const unregistered = new UnregisteredClassTypes((id) => this.shapes.get(id), (id) => this.unions.get(id), (name) => this.classes.has(name));
|
|
3658
|
+
const brokenGlobals = this.globalsList.filter((g) => unregistered.has(g.type));
|
|
3659
|
+
const brokenLocalFns = functions.filter((fn) => fn.locals.some((l) => unregistered.has(l.type)));
|
|
3428
3660
|
if (brokenGlobals.length > 0 || brokenLocalFns.length > 0) {
|
|
3429
3661
|
const referencedIn = (root) => {
|
|
3430
3662
|
const referenced = new Set();
|
|
@@ -3445,7 +3677,7 @@ export class Lowerer {
|
|
|
3445
3677
|
referenced.add(catchId);
|
|
3446
3678
|
// Closure captures name their source locals as PLAIN STRINGS
|
|
3447
3679
|
// (captures: string[]) — a captured broken-class local is live.
|
|
3448
|
-
if (rec["kind"] === "closure" && Array.isArray(rec["captures"])) {
|
|
3680
|
+
if ((rec["kind"] === "closure" || rec["kind"] === "classRef") && Array.isArray(rec["captures"])) {
|
|
3449
3681
|
for (const c of rec["captures"])
|
|
3450
3682
|
if (typeof c === "string")
|
|
3451
3683
|
referenced.add(c);
|
|
@@ -3473,8 +3705,8 @@ export class Lowerer {
|
|
|
3473
3705
|
for (const fn of brokenLocalFns) {
|
|
3474
3706
|
// Params and captures list their locals by id too — never prune
|
|
3475
3707
|
// those out from under them.
|
|
3476
|
-
const referenced = referencedIn([fn.body, fn.params, fn.captures ?? []]);
|
|
3477
|
-
fn.locals = fn.locals.filter((l) => referenced.has(l.id) || !
|
|
3708
|
+
const referenced = referencedIn([fn.body, fn.params, fn.captures ?? [], fn.classCaptures ?? []]);
|
|
3709
|
+
fn.locals = fn.locals.filter((l) => referenced.has(l.id) || !unregistered.has(l.type));
|
|
3478
3710
|
}
|
|
3479
3711
|
}
|
|
3480
3712
|
// Computed before the module gate: retention resolves every class name
|
|
@@ -3492,13 +3724,10 @@ export class Lowerer {
|
|
|
3492
3724
|
// slots), uniformly across params/locals/globals/fields/body types so
|
|
3493
3725
|
// every producer and consumer agrees. Programs with no unregistered
|
|
3494
3726
|
// reference are untouched — byte-stability holds.
|
|
3495
|
-
if (this.diags.length === 0) {
|
|
3496
|
-
this.sanitizeUnregisteredClassTypes([functions, this.globalsList, artifacts.classes, artifacts.records, artifacts.unions]);
|
|
3497
|
-
}
|
|
3498
3727
|
const module = this.diags.length > 0
|
|
3499
3728
|
? null
|
|
3500
3729
|
: {
|
|
3501
|
-
irVersion:
|
|
3730
|
+
irVersion: 13,
|
|
3502
3731
|
sourceFile: this.entry.fileName,
|
|
3503
3732
|
functions,
|
|
3504
3733
|
classes: artifacts.classes,
|
|
@@ -3509,6 +3738,8 @@ export class Lowerer {
|
|
|
3509
3738
|
entry: ENTRY_NAME,
|
|
3510
3739
|
...(this.ffiImports.length > 0 ? { ffiImports: [...this.ffiImports] } : {}),
|
|
3511
3740
|
};
|
|
3741
|
+
if (module)
|
|
3742
|
+
sanitizeUnregisteredClassTypes(module, (name) => this.classes.has(name));
|
|
3512
3743
|
return {
|
|
3513
3744
|
module,
|
|
3514
3745
|
diagnostics: this.diags,
|
|
@@ -3520,45 +3751,6 @@ export class Lowerer {
|
|
|
3520
3751
|
...(this.npmLazyTraps ? { npmLazyTraps: this.npmLazyTraps } : {}),
|
|
3521
3752
|
};
|
|
3522
3753
|
}
|
|
3523
|
-
/** The unregistered-class type sweep (run()'s last step before the
|
|
3524
|
-
* module assembles): every `{kind:"object"}` TYPE naming a class with
|
|
3525
|
-
* no registered ClassInfo is rewritten IN PLACE to the f64 dummy.
|
|
3526
|
-
* classval types are exempt (they emit the class-independent
|
|
3527
|
-
* `ScrClassObj *` — inert-but-valid storage, the validator's own
|
|
3528
|
-
* stance), and only type objects rewrite — node-level classNames
|
|
3529
|
-
* (`new`, upcasts) cannot reach here (their lowerings fence without a
|
|
3530
|
-
* registered class), so the validator still backstops those. */
|
|
3531
|
-
sanitizeUnregisteredClassTypes(roots) {
|
|
3532
|
-
const isUnregisteredObjectType = (v) => typeof v === "object" && v !== null &&
|
|
3533
|
-
v.kind === "object" &&
|
|
3534
|
-
typeof v.className === "string" &&
|
|
3535
|
-
!this.classes.has(v.className);
|
|
3536
|
-
const sweep = (node) => {
|
|
3537
|
-
if (node === null || typeof node !== "object")
|
|
3538
|
-
return;
|
|
3539
|
-
if (Array.isArray(node)) {
|
|
3540
|
-
node.forEach((item, i) => {
|
|
3541
|
-
if (isUnregisteredObjectType(item))
|
|
3542
|
-
node[i] = F64;
|
|
3543
|
-
else
|
|
3544
|
-
sweep(item);
|
|
3545
|
-
});
|
|
3546
|
-
return;
|
|
3547
|
-
}
|
|
3548
|
-
const rec = node;
|
|
3549
|
-
for (const key of Object.keys(rec)) {
|
|
3550
|
-
if (key === "loc")
|
|
3551
|
-
continue;
|
|
3552
|
-
const v = rec[key];
|
|
3553
|
-
if (isUnregisteredObjectType(v))
|
|
3554
|
-
rec[key] = F64;
|
|
3555
|
-
else
|
|
3556
|
-
sweep(v);
|
|
3557
|
-
}
|
|
3558
|
-
};
|
|
3559
|
-
for (const root of roots)
|
|
3560
|
-
sweep(root);
|
|
3561
|
-
}
|
|
3562
3754
|
/** True when `t` (recursively) names a class instance type with no
|
|
3563
3755
|
* registered ClassInfo — the shape of a JS class whose collection fenced.
|
|
3564
3756
|
* Used by run()'s global pruning; shapes/unions recurse with a seen-set
|
|
@@ -3656,11 +3848,16 @@ export class Lowerer {
|
|
|
3656
3848
|
const bodyRoots = (...roots) => roots.filter((root) => root !== undefined && root !== null);
|
|
3657
3849
|
const functionRoots = (decl) => bodyRoots(...decl.parameters.map((param) => param.initializer), decl.body);
|
|
3658
3850
|
const classCtorRoots = (info) => bodyRoots(...(info.ctor?.parameters ?? []).map((param) => param.initializer), info.ctor?.body, ...info.fieldOrder.map((field) => field.initializer));
|
|
3659
|
-
const classMemberRoots = (info) =>
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3851
|
+
const classMemberRoots = (info) => {
|
|
3852
|
+
const roots = classCtorRoots(info);
|
|
3853
|
+
for (const { member } of this.classMethodMembers(info))
|
|
3854
|
+
roots.push(...functionRoots(member));
|
|
3855
|
+
if (info.staticMethods) {
|
|
3856
|
+
for (const { member } of info.staticMethods.values())
|
|
3857
|
+
roots.push(...functionRoots(member));
|
|
3858
|
+
}
|
|
3859
|
+
return roots;
|
|
3860
|
+
};
|
|
3664
3861
|
let unitOrder = 0;
|
|
3665
3862
|
for (const fp of parts) {
|
|
3666
3863
|
for (const decl of fp.fnDecls) {
|
|
@@ -3714,12 +3911,14 @@ export class Lowerer {
|
|
|
3714
3911
|
});
|
|
3715
3912
|
}
|
|
3716
3913
|
}
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3914
|
+
if (info.staticMethods) {
|
|
3915
|
+
for (const [name, entry] of info.staticMethods) {
|
|
3916
|
+
units.set(`%${cName}.static:${name}`, {
|
|
3917
|
+
order: unitOrder++,
|
|
3918
|
+
roots: functionRoots(entry.member),
|
|
3919
|
+
lower: () => lowerStaticMethod(this, info, name),
|
|
3920
|
+
});
|
|
3921
|
+
}
|
|
3723
3922
|
}
|
|
3724
3923
|
}
|
|
3725
3924
|
// The old emit pass visited each file's functions and then its classes,
|
|
@@ -3754,8 +3953,10 @@ export class Lowerer {
|
|
|
3754
3953
|
rank(`%${cName}.constructor`);
|
|
3755
3954
|
for (const { mName } of this.classMethodMembers(info))
|
|
3756
3955
|
rank(`%${cName}.${mName}`);
|
|
3757
|
-
|
|
3758
|
-
|
|
3956
|
+
if (info.staticMethods) {
|
|
3957
|
+
for (const name of info.staticMethods.keys())
|
|
3958
|
+
rank(`%${cName}.static:${name}`);
|
|
3959
|
+
}
|
|
3759
3960
|
for (const prop of info.throwingSetters)
|
|
3760
3961
|
rank(`%${cName}.set:${prop}`);
|
|
3761
3962
|
}
|
|
@@ -3801,9 +4002,10 @@ export class Lowerer {
|
|
|
3801
4002
|
for (const { mName, member } of this.classMethodMembers(info)) {
|
|
3802
4003
|
register(`%${cName}.${mName}`, functionRoots(member), () => this.lowerClassMethodMember(info, member));
|
|
3803
4004
|
}
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
4005
|
+
if (info.staticMethods)
|
|
4006
|
+
for (const [name, entry] of info.staticMethods) {
|
|
4007
|
+
register(`%${cName}.static:${name}`, functionRoots(entry.member), () => lowerStaticMethod(this, info, name));
|
|
4008
|
+
}
|
|
3807
4009
|
for (const prop of info.throwingSetters) {
|
|
3808
4010
|
register(`%${cName}.set:${prop}`, [], () => this.throwingSetterFn(info, prop));
|
|
3809
4011
|
}
|
|
@@ -3929,9 +4131,13 @@ export class Lowerer {
|
|
|
3929
4131
|
// turn queue more instances. Continue to the joint fixpoint; the initial
|
|
3930
4132
|
// queue above is the only portion whose discovery order differed from
|
|
3931
4133
|
// historical emit order.
|
|
4134
|
+
const classDispatch = new ClassDynamicDispatch(extraRoots !== undefined);
|
|
3932
4135
|
for (;;) {
|
|
3933
4136
|
drainInstances();
|
|
3934
|
-
|
|
4137
|
+
const dispatchChanged = classDispatch.process(this, [
|
|
4138
|
+
...loweredUnits.values(), ...initFunctions, ...instanceFunctions, ...this.liftedFns, ...this.implicitFns,
|
|
4139
|
+
]);
|
|
4140
|
+
if (queue.length === 0 && !dispatchChanged)
|
|
3935
4141
|
break;
|
|
3936
4142
|
drainUnits();
|
|
3937
4143
|
this.restoreGenericInstanceOrder(instLowered);
|
|
@@ -4017,7 +4223,8 @@ export class Lowerer {
|
|
|
4017
4223
|
if (target.kind === "statement")
|
|
4018
4224
|
return fence;
|
|
4019
4225
|
const params = target.params ?? [];
|
|
4020
|
-
const
|
|
4226
|
+
const targetName = target.name;
|
|
4227
|
+
const name = typeof targetName === "function" ? targetName() : targetName;
|
|
4021
4228
|
const fn = {
|
|
4022
4229
|
name,
|
|
4023
4230
|
params,
|
|
@@ -4188,7 +4395,7 @@ export class Lowerer {
|
|
|
4188
4395
|
// package-declared generic signature stays the package's story.
|
|
4189
4396
|
{
|
|
4190
4397
|
const parts = widened.isUnionType() ? ts.constituentTypes(widened) : [widened];
|
|
4191
|
-
if (parts.some((p) => this.checker.getCallSignatures(p).some((s) =>
|
|
4398
|
+
if (parts.some((p) => this.checker.getCallSignatures(p).some((s) => s.getTypeParameters().length > 0))) {
|
|
4192
4399
|
this.pushDiag(genericSignatureTypeDiag(this.checker.typeToString(type), locOf(node)));
|
|
4193
4400
|
throw new PoisonError();
|
|
4194
4401
|
}
|
|
@@ -4269,8 +4476,8 @@ export class Lowerer {
|
|
|
4269
4476
|
RelativeTimeFormat: intlHint,
|
|
4270
4477
|
Segmenter: intlHint,
|
|
4271
4478
|
DisplayNames: intlHint,
|
|
4272
|
-
TextEncoder: "TextEncoder
|
|
4273
|
-
TextDecoder: "TextDecoder
|
|
4479
|
+
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",
|
|
4274
4481
|
};
|
|
4275
4482
|
this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node), typeHints[stdlibOwnSym?.name ?? ""]));
|
|
4276
4483
|
throw new PoisonError();
|
|
@@ -4367,6 +4574,11 @@ export class Lowerer {
|
|
|
4367
4574
|
return bound;
|
|
4368
4575
|
if (typeEquals(narrowedIr, boundIr))
|
|
4369
4576
|
return t;
|
|
4577
|
+
// A checked value can contain any runtime kind. A checker-proven
|
|
4578
|
+
// branch narrow therefore cannot contradict this specialization;
|
|
4579
|
+
// reads still validate the payload through maybeNarrow.
|
|
4580
|
+
if (boundIr.kind === "dyn")
|
|
4581
|
+
return t;
|
|
4370
4582
|
// A union binding narrowed to one of its arms (typeof/equality
|
|
4371
4583
|
// guards over string|number bindings) — the narrow is truth.
|
|
4372
4584
|
if (boundIr.kind === "union") {
|
|
@@ -4387,10 +4599,11 @@ export class Lowerer {
|
|
|
4387
4599
|
return t;
|
|
4388
4600
|
}
|
|
4389
4601
|
/** mapType with this Lowerer's registries and (while a generic instance
|
|
4390
|
-
* body lowers) type-parameter bindings threaded through.
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4602
|
+
* body lowers) type-parameter bindings threaded through. A supplied mapper
|
|
4603
|
+
* retains interface-view substitutions while sharing ABI normalization. */
|
|
4604
|
+
mapTypeOf(t, mapper) {
|
|
4605
|
+
const mapped = mapper ? mapper(t) : mapType(t, this.typeCtx);
|
|
4606
|
+
return mapped === null || mapped.kind === "func" ? jsArgumentsFunctionType(this, t) ?? mapped : mapped;
|
|
4394
4607
|
}
|
|
4395
4608
|
/** The one position where a contextual UNION must not be adopted over the
|
|
4396
4609
|
* expression's own: the LEFT operand of `&&`, `||`, or `??`. Adopting a
|
|
@@ -4545,6 +4758,11 @@ export class Lowerer {
|
|
|
4545
4758
|
};
|
|
4546
4759
|
irTypeOf(node) {
|
|
4547
4760
|
const t = this.typeOf(node);
|
|
4761
|
+
// JS inference can leave mutable fields, accessor parameters and
|
|
4762
|
+
// locals at null/undefined despite later writes. Keep mutable native
|
|
4763
|
+
// storage instead of a slot restricted to the initializer's unit value.
|
|
4764
|
+
if (isJsSourceFile(node.getSourceFile()) && (t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0)
|
|
4765
|
+
return DYN;
|
|
4548
4766
|
// A never-tainted JS type (neverTaintedJsType) maps — never rides as
|
|
4549
4767
|
// f64 — but must not: pre-empt the mapping so the JS fallback below
|
|
4550
4768
|
// answers instead.
|
|
@@ -4567,7 +4785,7 @@ export class Lowerer {
|
|
|
4567
4785
|
return dyn;
|
|
4568
4786
|
this.badType(node, t);
|
|
4569
4787
|
}
|
|
4570
|
-
return mapped;
|
|
4788
|
+
return jsOpenObjectType(node, mapped, this.shapes, this.unions);
|
|
4571
4789
|
}
|
|
4572
4790
|
/** Exact-shape enforcement (SC2002). Records are monomorphic structs, so
|
|
4573
4791
|
* everywhere a value flows into a typed slot (call arg, initializer,
|
|
@@ -4785,8 +5003,11 @@ export class Lowerer {
|
|
|
4785
5003
|
return { kind: "promiseVoidWiden", value: expr, type: expected, loc: expr.loc };
|
|
4786
5004
|
}
|
|
4787
5005
|
if (expected.kind === "dyn" && expr.type.kind !== "dyn") {
|
|
4788
|
-
|
|
4789
|
-
|
|
5006
|
+
// Native void calls still have a JavaScript value: undefined. Keep
|
|
5007
|
+
// the call's effects before exposing that value to checked JS code.
|
|
5008
|
+
if (expr.type.kind === "void") {
|
|
5009
|
+
return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr, loc: expr.loc }],
|
|
5010
|
+
result: dynUndefinedExpr(expr.loc), type: DYN, loc: expr.loc };
|
|
4790
5011
|
}
|
|
4791
5012
|
// An error-HIERARCHY object (builtin subclass or user `extends
|
|
4792
5013
|
// Error` class) upcasts to the %Error root first — the caughtToDyn
|
|
@@ -4803,6 +5024,9 @@ export class Lowerer {
|
|
|
4803
5024
|
loc: expr.loc,
|
|
4804
5025
|
};
|
|
4805
5026
|
}
|
|
5027
|
+
if (expr.kind === "unitLit" || this.dynConvertible(expr.type)) {
|
|
5028
|
+
return { kind: "dynFrom", value: expr, type: DYN, loc: expr.loc };
|
|
5029
|
+
}
|
|
4806
5030
|
return expr;
|
|
4807
5031
|
}
|
|
4808
5032
|
// A dyn ('unknown') ACTUAL flowing into a typed slot the checker
|
|
@@ -4838,7 +5062,7 @@ export class Lowerer {
|
|
|
4838
5062
|
const funcOk = expected.kind === "func" &&
|
|
4839
5063
|
canAdaptDynFuncTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id));
|
|
4840
5064
|
const handleOk = DYN_HANDLE_KINDS.has(expected.kind);
|
|
4841
|
-
if (this.
|
|
5065
|
+
if (canDynCheckTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id)) || undefArmedOk || bytesOk || errorOk || classOk || funcOk || handleOk) {
|
|
4842
5066
|
return { kind: "dynCheck", value: expr, type: expected, loc: expr.loc };
|
|
4843
5067
|
}
|
|
4844
5068
|
return expr;
|
|
@@ -4995,6 +5219,11 @@ export class Lowerer {
|
|
|
4995
5219
|
return expr;
|
|
4996
5220
|
}
|
|
4997
5221
|
const tag = this.armTag(expected.unionId, expr.type);
|
|
5222
|
+
if (tag >= 0 && expr.type.kind === "record" && expr.kind !== "recordLit") {
|
|
5223
|
+
const helper = this.recordUnionWrapHelper(expr.type, expected.unionId, expr.loc);
|
|
5224
|
+
if (helper)
|
|
5225
|
+
return { kind: "call", callee: helper, args: [expr], type: expected, loc: expr.loc };
|
|
5226
|
+
}
|
|
4998
5227
|
if (tag < 0) {
|
|
4999
5228
|
// A derived class flowing into a union with a base-class arm widens
|
|
5000
5229
|
// first (nearest ancestor arm wins), then wraps like any arm value.
|
|
@@ -5164,9 +5393,11 @@ export class Lowerer {
|
|
|
5164
5393
|
* before any helper exists. The cases, in order:
|
|
5165
5394
|
* copy — exact same type (typeEquals), the field/element moves as is
|
|
5166
5395
|
* retag — union into union, every arm mapped (unionRetagMappable —
|
|
5167
|
-
* identity arms
|
|
5168
|
-
*
|
|
5396
|
+
* identity arms and compatible payload conversions; a shared
|
|
5397
|
+
* discriminant may select different record destinations)
|
|
5169
5398
|
* wrap — a non-unit arm value into a union that contains it
|
|
5399
|
+
* discriminantWrap — identical recursive layouts distinguished by
|
|
5400
|
+
* their literal field value rather than their storage id
|
|
5170
5401
|
* liftWrap — a record/array value into a union with NO identical arm
|
|
5171
5402
|
* but exactly ONE arm it width-lifts into (the findRoute
|
|
5172
5403
|
* rule applied at every level; several candidates are
|
|
@@ -5201,17 +5432,25 @@ export class Lowerer {
|
|
|
5201
5432
|
if (isUnitType(src))
|
|
5202
5433
|
return null;
|
|
5203
5434
|
const tag = this.armTag(dst.unionId, src);
|
|
5204
|
-
if (tag >= 0)
|
|
5205
|
-
return { how: "wrap", tag };
|
|
5206
5435
|
const def = this.unions.get(dst.unionId);
|
|
5207
5436
|
if (!def)
|
|
5208
5437
|
return null;
|
|
5438
|
+
if (tag >= 0) {
|
|
5439
|
+
const shape = src.kind === "record" ? this.shapes.get(src.shapeId) : undefined;
|
|
5440
|
+
if (shape && planRecordUnionWrap(shape, def, (id) => this.shapes.get(id)))
|
|
5441
|
+
return { how: "discriminantWrap" };
|
|
5442
|
+
return { how: "wrap", tag };
|
|
5443
|
+
}
|
|
5209
5444
|
const candidates = [];
|
|
5210
5445
|
def.arms.forEach((arm, i) => {
|
|
5211
5446
|
if (isUnitType(arm))
|
|
5212
5447
|
return;
|
|
5213
5448
|
const sameFamily = (src.kind === "record" && arm.kind === "record") ||
|
|
5214
5449
|
(src.kind === "array" && arm.kind === "array") ||
|
|
5450
|
+
(src.kind === "object" && arm.kind === "object") ||
|
|
5451
|
+
// Tuples already lift into ordinary array slots. Consider that
|
|
5452
|
+
// same conversion when the array is an arm of a union too.
|
|
5453
|
+
(src.kind === "record" && this.shapes.get(src.shapeId)?.tuple === true && arm.kind === "array") ||
|
|
5215
5454
|
(src.kind === "object" && arm.kind === "record") ||
|
|
5216
5455
|
(src.kind === "record" && arm.kind === "object");
|
|
5217
5456
|
if (sameFamily && this.widthLiftPlan(src, arm) !== null)
|
|
@@ -5250,6 +5489,25 @@ export class Lowerer {
|
|
|
5250
5489
|
if (dst.kind === "record" && src.kind === "record") {
|
|
5251
5490
|
return this.recordWidthPlan(src.shapeId, dst.shapeId) !== null ? { how: "width" } : null;
|
|
5252
5491
|
}
|
|
5492
|
+
if (dst.kind === "record" && src.kind === "union") {
|
|
5493
|
+
// A union of records can share a structural destination without
|
|
5494
|
+
// choosing one payload layout in advance. Plan every arm: omitted
|
|
5495
|
+
// destination fields need the ordinary optional-field completion,
|
|
5496
|
+
// and a required field missing from any arm still rejects the pair.
|
|
5497
|
+
const from = this.unions.get(src.unionId);
|
|
5498
|
+
if (!from || from.arms.length === 0 || !from.arms.every((arm) => arm.kind === "record"))
|
|
5499
|
+
return null;
|
|
5500
|
+
const key = `unionWidth:${src.unionId}:${dst.shapeId}`;
|
|
5501
|
+
if (this.widthPlanning.has(key))
|
|
5502
|
+
return { how: "unionWidth" };
|
|
5503
|
+
this.widthPlanning.add(key);
|
|
5504
|
+
try {
|
|
5505
|
+
return from.arms.every((arm) => this.widthLiftPlan(arm, dst) !== null) ? { how: "unionWidth" } : null;
|
|
5506
|
+
}
|
|
5507
|
+
finally {
|
|
5508
|
+
this.widthPlanning.delete(key);
|
|
5509
|
+
}
|
|
5510
|
+
}
|
|
5253
5511
|
if (dst.kind === "record" && src.kind === "object") {
|
|
5254
5512
|
return this.objToRecordPlan(src.className, dst.shapeId) !== null ? { how: "objWidth" } : null;
|
|
5255
5513
|
}
|
|
@@ -5303,6 +5561,14 @@ export class Lowerer {
|
|
|
5303
5561
|
throw new InternalCompilerError("lowerer bug: wrap lift against a non-union");
|
|
5304
5562
|
return { kind: "unionWrap", unionId: dst.unionId, tag: lift.tag, value, type: dst, loc };
|
|
5305
5563
|
}
|
|
5564
|
+
case "discriminantWrap": {
|
|
5565
|
+
if (dst.kind !== "union" || value.type.kind !== "record")
|
|
5566
|
+
throw new InternalCompilerError("lowerer bug: record discriminator lift shape");
|
|
5567
|
+
const helper = this.recordUnionWrapHelper(value.type, dst.unionId, loc);
|
|
5568
|
+
if (!helper)
|
|
5569
|
+
throw new InternalCompilerError("lowerer bug: planned record discriminator lift failed to intern");
|
|
5570
|
+
return { kind: "call", callee: helper, args: [value], type: dst, loc };
|
|
5571
|
+
}
|
|
5306
5572
|
case "retag": {
|
|
5307
5573
|
if (dst.kind !== "union" || value.type.kind !== "union")
|
|
5308
5574
|
throw new InternalCompilerError("lowerer bug: retag lift shape");
|
|
@@ -5328,6 +5594,12 @@ export class Lowerer {
|
|
|
5328
5594
|
throw new InternalCompilerError("lowerer bug: planned width lift failed to intern");
|
|
5329
5595
|
return { kind: "call", callee: helper, args: [value], type: dst, loc };
|
|
5330
5596
|
}
|
|
5597
|
+
case "unionWidth": {
|
|
5598
|
+
if (dst.kind !== "record" || value.type.kind !== "union")
|
|
5599
|
+
throw new InternalCompilerError("lowerer bug: union width lift shape");
|
|
5600
|
+
const helper = this.unionRecordWidthHelper(value.type.unionId, dst, loc);
|
|
5601
|
+
return { kind: "call", callee: helper, args: [value], type: dst, loc };
|
|
5602
|
+
}
|
|
5331
5603
|
case "arr": {
|
|
5332
5604
|
if (dst.kind !== "array" || value.type.kind !== "array")
|
|
5333
5605
|
throw new InternalCompilerError("lowerer bug: arr lift shape");
|
|
@@ -5399,6 +5671,50 @@ export class Lowerer {
|
|
|
5399
5671
|
}
|
|
5400
5672
|
}
|
|
5401
5673
|
}
|
|
5674
|
+
/** Dispatch a structural copy from its runtime union tag. Each record
|
|
5675
|
+
* payload has its own field offsets and optional-field completions;
|
|
5676
|
+
* interpreting all arms as the destination layout would corrupt memory.
|
|
5677
|
+
* Intern before descending so recursive record unions can reuse it. */
|
|
5678
|
+
unionRecordWidthHelper(fromId, target, loc) {
|
|
5679
|
+
const key = `unionWidth:${fromId}:${target.shapeId}`;
|
|
5680
|
+
const existing = this.widthHelpers.get(key);
|
|
5681
|
+
if (existing)
|
|
5682
|
+
return existing;
|
|
5683
|
+
const name = `%union.record.${this.widthHelpers.size}`;
|
|
5684
|
+
this.widthHelpers.set(key, name);
|
|
5685
|
+
const type = { kind: "union", unionId: fromId };
|
|
5686
|
+
const value = varRef("value.0", type, loc);
|
|
5687
|
+
const from = this.unions.get(fromId);
|
|
5688
|
+
if (!from)
|
|
5689
|
+
throw new InternalCompilerError("lowerer bug: missing record union");
|
|
5690
|
+
const body = [];
|
|
5691
|
+
from.arms.forEach((arm, tag) => {
|
|
5692
|
+
const lift = this.widthLiftPlan(arm, target);
|
|
5693
|
+
if (!lift || arm.kind !== "record")
|
|
5694
|
+
throw new InternalCompilerError("lowerer bug: invalid union record plan");
|
|
5695
|
+
const narrowed = { kind: "unionNarrow", unionId: fromId, tag, value, type: arm, loc };
|
|
5696
|
+
body.push({
|
|
5697
|
+
kind: "if",
|
|
5698
|
+
cond: { kind: "unionIsTag", unionId: fromId, tag, negated: false, value, type: BOOL, loc },
|
|
5699
|
+
then: [{ kind: "return", value: this.applyWidthLift(lift, narrowed, target, loc), loc }],
|
|
5700
|
+
else_: null, loc,
|
|
5701
|
+
});
|
|
5702
|
+
});
|
|
5703
|
+
body.push({
|
|
5704
|
+
kind: "throw",
|
|
5705
|
+
value: {
|
|
5706
|
+
kind: "libCall", fn: "error.new",
|
|
5707
|
+
args: [{ kind: "strLit", value: "invalid record union tag", type: STRING, loc }],
|
|
5708
|
+
type: { kind: "object", className: "%TypeError" }, loc,
|
|
5709
|
+
},
|
|
5710
|
+
loc,
|
|
5711
|
+
});
|
|
5712
|
+
this.liftedFns.push({
|
|
5713
|
+
name, params: [{ localId: "value.0", name: "value", type }], returnType: target,
|
|
5714
|
+
locals: [{ id: "value.0", name: "value", type, mutable: false }], body, loc,
|
|
5715
|
+
});
|
|
5716
|
+
return name;
|
|
5717
|
+
}
|
|
5402
5718
|
/** Interned `%rec.width.<n>(r)` — builds the target shape from a source
|
|
5403
5719
|
* record by copying fields: every target field must exist on the source
|
|
5404
5720
|
* with the EXACT same type, or with a type that LIFTS under
|
|
@@ -6147,6 +6463,7 @@ export class Lowerer {
|
|
|
6147
6463
|
{
|
|
6148
6464
|
kind: "callValue",
|
|
6149
6465
|
callee: { kind: "varRef", localId: "f.0", type: fromT, loc },
|
|
6466
|
+
receiver: { kind: "libCall", fn: "dyn.this", args: [], type: DYN, loc },
|
|
6150
6467
|
args: [],
|
|
6151
6468
|
type: fromT.ret,
|
|
6152
6469
|
loc,
|
|
@@ -6279,9 +6596,33 @@ export class Lowerer {
|
|
|
6279
6596
|
// value — the call runs (a `never` thrower never comes back, so the
|
|
6280
6597
|
// trap is unreachable there), then the stranded TypeError.
|
|
6281
6598
|
let strandParams = false;
|
|
6599
|
+
const narrowedParams = new Map();
|
|
6600
|
+
const partialDynParams = new Map();
|
|
6282
6601
|
for (let i = 0; i < fromT.params.length; i++) {
|
|
6283
|
-
|
|
6284
|
-
|
|
6602
|
+
const actual = toT.params[i];
|
|
6603
|
+
const expected = fromT.params[i];
|
|
6604
|
+
if (this.coercibleValue(actual, expected))
|
|
6605
|
+
continue;
|
|
6606
|
+
if (actual.kind === "union" && expected.kind === "dyn") {
|
|
6607
|
+
const arms = this.unions.get(actual.unionId)?.arms.filter((arm) => this.dynConvertible(arm)) ?? [];
|
|
6608
|
+
if (arms.length > 0) {
|
|
6609
|
+
partialDynParams.set(i, arms.length === 1 ? arms[0] : { kind: "union", unionId: this.unions.intern(arms) });
|
|
6610
|
+
continue;
|
|
6611
|
+
}
|
|
6612
|
+
}
|
|
6613
|
+
// A stored native builtin can have a narrower supported overload
|
|
6614
|
+
// than its public declaration. Preserve every supported union arm
|
|
6615
|
+
// and reject only an invocation carrying an unsupported arm. This
|
|
6616
|
+
// is the union counterpart of the checked single-arm extraction.
|
|
6617
|
+
if (actual.kind === "union" && expected.kind === "union") {
|
|
6618
|
+
const source = this.unions.get(actual.unionId);
|
|
6619
|
+
const target = this.unions.get(expected.unionId);
|
|
6620
|
+
if (source && target && target.arms.every((arm) => this.armTag(actual.unionId, arm) >= 0)) {
|
|
6621
|
+
narrowedParams.set(i, new Set(source.arms.flatMap((arm, tag) => this.armTag(expected.unionId, arm) < 0 ? [tag] : [])));
|
|
6622
|
+
continue;
|
|
6623
|
+
}
|
|
6624
|
+
}
|
|
6625
|
+
strandParams = true;
|
|
6285
6626
|
}
|
|
6286
6627
|
let voidRet = null;
|
|
6287
6628
|
let strandRet = false;
|
|
@@ -6329,7 +6670,25 @@ export class Lowerer {
|
|
|
6329
6670
|
else {
|
|
6330
6671
|
const args = fromT.params.map((pt, i) => {
|
|
6331
6672
|
const aRef = { kind: "varRef", localId: `a.${i}`, type: toT.params[i], loc };
|
|
6332
|
-
const
|
|
6673
|
+
const partial = partialDynParams.get(i);
|
|
6674
|
+
if (partial && aRef.type.kind === "union") {
|
|
6675
|
+
const source = this.unions.get(aRef.type.unionId);
|
|
6676
|
+
const supported = partial.kind === "union" ? this.unions.get(partial.unionId).arms : [partial];
|
|
6677
|
+
const rejected = new Set(source.arms.flatMap((arm, tag) => supported.some((accepted) => typeEquals(accepted, arm)) ? [] : [tag]));
|
|
6678
|
+
const narrow = partial.kind === "union"
|
|
6679
|
+
? this.unionRetagHelper(aRef.type.unionId, partial.unionId, loc, rejected)
|
|
6680
|
+
: this.narrowedArmHelper(aRef.type.unionId, partial, loc);
|
|
6681
|
+
if (!narrow)
|
|
6682
|
+
throw new InternalCompilerError("lowerer bug: partial callable parameter stopped narrowing");
|
|
6683
|
+
return this.coerceToExpected({ kind: "call", callee: narrow, args: [aRef], type: partial, loc }, pt);
|
|
6684
|
+
}
|
|
6685
|
+
const narrowed = narrowedParams.get(i);
|
|
6686
|
+
const helper = narrowed && aRef.type.kind === "union" && pt.kind === "union"
|
|
6687
|
+
? this.unionRetagHelper(aRef.type.unionId, pt.unionId, loc, narrowed)
|
|
6688
|
+
: null;
|
|
6689
|
+
const converted = helper
|
|
6690
|
+
? { kind: "call", callee: helper, args: [aRef], type: pt, loc }
|
|
6691
|
+
: this.coerceToExpected(aRef, pt);
|
|
6333
6692
|
if (!typeEquals(converted.type, pt))
|
|
6334
6693
|
throw new InternalCompilerError("lowerer bug: probed fn-adapter param stopped coercing");
|
|
6335
6694
|
return converted;
|
|
@@ -6337,6 +6696,7 @@ export class Lowerer {
|
|
|
6337
6696
|
const call = {
|
|
6338
6697
|
kind: "callValue",
|
|
6339
6698
|
callee: { kind: "varRef", localId: "f.0", type: fromT, loc },
|
|
6699
|
+
receiver: { kind: "libCall", fn: "dyn.this", args: [], type: DYN, loc },
|
|
6340
6700
|
args,
|
|
6341
6701
|
type: fromT.ret,
|
|
6342
6702
|
loc,
|
|
@@ -6498,6 +6858,7 @@ export class Lowerer {
|
|
|
6498
6858
|
init: {
|
|
6499
6859
|
kind: "callValue",
|
|
6500
6860
|
callee: { kind: "varRef", localId: "f.0", type: fromT, loc },
|
|
6861
|
+
receiver: { kind: "libCall", fn: "dyn.this", args: [], type: DYN, loc },
|
|
6501
6862
|
args: params.map((p) => ({ kind: "varRef", localId: p.localId, type: p.type, loc })),
|
|
6502
6863
|
type: fromT.ret,
|
|
6503
6864
|
loc,
|
|
@@ -6533,44 +6894,20 @@ export class Lowerer {
|
|
|
6533
6894
|
});
|
|
6534
6895
|
return name;
|
|
6535
6896
|
}
|
|
6536
|
-
/**
|
|
6537
|
-
*
|
|
6538
|
-
*
|
|
6539
|
-
* (unionNarrow + unionWrap — the payload pointer moves, no copy, so
|
|
6540
|
-
* ref-arm identity is preserved across the re-tag). Arms map by
|
|
6541
|
-
* canonical type (typeEquals): every non-unit source arm must exist in
|
|
6542
|
-
* the destination, or the pair isn't mappable (null — the caller keeps
|
|
6543
|
-
* the SC2003 fence). A stranded UNIT arm (undefined/null with no
|
|
6544
|
-
* destination arm) is different: it means tsc's picture at the site was
|
|
6545
|
-
* NARROWER than the IR type — control-flow narrowing to a sub-union, or
|
|
6546
|
-
* a non-null assertion, both of which erase at lowering — so the arm is
|
|
6547
|
-
* exactly the possibility the checker proved (or the source asserted)
|
|
6548
|
-
* away. It compiles to a runtime trap case throwing a catchable
|
|
6549
|
-
* TypeError-shaped string, the lying-cast stance (SEMANTICS.md): sound
|
|
6550
|
-
* narrowing never reaches it, a lying `!` throws instead of smuggling
|
|
6551
|
-
* an unrepresentable unit into the destination. */
|
|
6552
|
-
/** True when unionRetagHelper can bridge the pair — every non-unit
|
|
6553
|
-
* source arm exists (typeEquals) in the destination, or width-lifts
|
|
6554
|
-
* into exactly one destination arm (widthLiftPlan — record and array
|
|
6555
|
-
* arms compose the re-tag with the per-arm reshape). Pure: callers that
|
|
6556
|
-
* must validate a WHOLE plan before interning anything (recordWidthHelper)
|
|
6557
|
-
* probe with this so a failed later field never orphans a helper. */
|
|
6897
|
+
/** Validate the complete union conversion before interning helpers.
|
|
6898
|
+
* Recursive width plans close through the same in-progress pair guard;
|
|
6899
|
+
* no optimistic result is memoized after that planning stack unwinds. */
|
|
6558
6900
|
unionRetagMappable(fromId, toId) {
|
|
6559
6901
|
const from = this.unions.get(fromId);
|
|
6560
|
-
|
|
6902
|
+
const to = this.unions.get(toId);
|
|
6903
|
+
if (!from || !to)
|
|
6561
6904
|
return false;
|
|
6562
|
-
// The union-pair face of the widthPlanning cycle guard: recursive
|
|
6563
|
-
// aliases can close their cycle through a union without repeating a
|
|
6564
|
-
// record pair (`type Json = Json[] | undefined`) — an in-progress
|
|
6565
|
-
// pair re-entered answers "assume mappable", same greatest-fixed-point
|
|
6566
|
-
// reading as recordWidthPlan's.
|
|
6567
6905
|
const key = `u:${fromId}:${toId}`;
|
|
6568
6906
|
if (this.widthPlanning.has(key))
|
|
6569
6907
|
return true;
|
|
6570
6908
|
this.widthPlanning.add(key);
|
|
6571
6909
|
try {
|
|
6572
|
-
|
|
6573
|
-
return from.arms.every((arm) => isUnitType(arm) || this.widthLiftPlan(arm, toT) !== null);
|
|
6910
|
+
return planUnionRetag(from, to, (id) => this.shapes.get(id), (src, dst) => this.widthLiftPlan(src, dst)) !== null;
|
|
6574
6911
|
}
|
|
6575
6912
|
finally {
|
|
6576
6913
|
this.widthPlanning.delete(key);
|
|
@@ -6741,111 +7078,44 @@ export class Lowerer {
|
|
|
6741
7078
|
}
|
|
6742
7079
|
return { kind: "call", callee: name, args: isUnitType(src) ? [] : [expr], type: expected, loc };
|
|
6743
7080
|
}
|
|
7081
|
+
recordUnionWrapHelper(source, toId, loc) {
|
|
7082
|
+
const shape = this.shapes.get(source.shapeId);
|
|
7083
|
+
const to = this.unions.get(toId);
|
|
7084
|
+
if (!shape || !to)
|
|
7085
|
+
return null;
|
|
7086
|
+
const plan = planRecordUnionWrap(shape, to, (id) => this.shapes.get(id));
|
|
7087
|
+
if (!plan)
|
|
7088
|
+
return null;
|
|
7089
|
+
const key = `recordWrap:${source.shapeId}:${toId}`;
|
|
7090
|
+
const existing = this.retagHelpers.get(key);
|
|
7091
|
+
if (existing)
|
|
7092
|
+
return existing;
|
|
7093
|
+
const name = `%record.wrap.${this.retagHelpers.size}`;
|
|
7094
|
+
this.retagHelpers.set(key, name);
|
|
7095
|
+
this.liftedFns.push(buildRecordUnionWrap(name, source, to, plan, loc, (lift, value, dst) => this.applyWidthLift(lift, value, dst, loc)));
|
|
7096
|
+
return name;
|
|
7097
|
+
}
|
|
6744
7098
|
unionRetagHelper(fromId, toId, loc, trappable) {
|
|
6745
7099
|
const from = this.unions.get(fromId);
|
|
6746
7100
|
const to = this.unions.get(toId);
|
|
6747
7101
|
if (!from || !to)
|
|
6748
7102
|
return null;
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
// (widthLiftPlan's liftWrap — the findRoute pattern: `{hostname, port,
|
|
6752
|
-
// tailscaleUrl?} | undefined` returning as `{hostname, port} |
|
|
6753
|
-
// undefined`; nested width and per-element array reshapes compose).
|
|
6754
|
-
// Planned PURELY first so a failing arm never orphans an interned
|
|
6755
|
-
// width helper; ambiguity (several liftable destination arms) declines
|
|
6756
|
-
// — no honest single mapping exists. A lifted arm is a COPY
|
|
6757
|
-
// (divergence 35's stance), unlike the identity-preserving plain
|
|
6758
|
-
// re-wrap.
|
|
6759
|
-
const toT = { kind: "union", unionId: toId };
|
|
6760
|
-
const lifts = new Map();
|
|
6761
|
-
from.arms.forEach((arm, i) => {
|
|
6762
|
-
if (this.armTag(toId, arm) >= 0 || isUnitType(arm) || (trappable?.has(i) ?? false))
|
|
6763
|
-
return;
|
|
6764
|
-
const lp = this.widthLiftPlan(arm, toT);
|
|
6765
|
-
if (lp && lp.how === "liftWrap")
|
|
6766
|
-
lifts.set(i, lp);
|
|
6767
|
-
});
|
|
6768
|
-
// `trappable` extends the unit-arm rule to arms the CHECKER proved
|
|
6769
|
-
// away at the coercion site (narrowedRetagHelper): those may trap too.
|
|
6770
|
-
const ok = from.arms.every((arm, i) => this.armTag(toId, arm) >= 0 || isUnitType(arm) || (trappable?.has(i) ?? false) || lifts.has(i));
|
|
6771
|
-
if (!ok)
|
|
7103
|
+
const plan = planUnionRetag(from, to, (id) => this.shapes.get(id), (src, dst) => this.widthLiftPlan(src, dst), trappable);
|
|
7104
|
+
if (plan === null)
|
|
6772
7105
|
return null;
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
// key stays sound for them; stranded arms depend on the SITE.
|
|
7106
|
+
// The registry pair determines every route; only checker-proven
|
|
7107
|
+
// stranded arms vary by site. Publish the name before building widths
|
|
7108
|
+
// so recursive records and arrays can call this same helper.
|
|
7109
|
+
const stranded = [];
|
|
7110
|
+
plan.forEach((arm, tag) => { if (arm.kind === "trap")
|
|
7111
|
+
stranded.push(tag); });
|
|
6780
7112
|
const key = `${fromId}:${toId}:${stranded.join(".")}`;
|
|
6781
7113
|
const existing = this.retagHelpers.get(key);
|
|
6782
7114
|
if (existing)
|
|
6783
7115
|
return existing;
|
|
6784
7116
|
const name = `%union.retag.${this.retagHelpers.size}`;
|
|
6785
7117
|
this.retagHelpers.set(key, name);
|
|
6786
|
-
|
|
6787
|
-
const u = { kind: "varRef", localId: "u.0", type: fromT, loc };
|
|
6788
|
-
const body = [];
|
|
6789
|
-
from.arms.forEach((arm, i) => {
|
|
6790
|
-
const tag = mapping[i];
|
|
6791
|
-
const cond = { kind: "unionIsTag", unionId: fromId, tag: i, negated: false, value: u, type: BOOL, loc };
|
|
6792
|
-
let then;
|
|
6793
|
-
if (tag < 0) {
|
|
6794
|
-
const what = isUnitType(arm)
|
|
6795
|
-
? (arm.kind === "undefinedT" ? "undefined" : "null")
|
|
6796
|
-
: `a '${this.fmt(arm)}' value`;
|
|
6797
|
-
then = [
|
|
6798
|
-
{
|
|
6799
|
-
kind: "throw",
|
|
6800
|
-
value: {
|
|
6801
|
-
kind: "libCall",
|
|
6802
|
-
fn: "error.new",
|
|
6803
|
-
args: [
|
|
6804
|
-
{
|
|
6805
|
-
kind: "strLit",
|
|
6806
|
-
value: `${what} is not representable in the target union (a value narrowed or asserted past it still held it)`,
|
|
6807
|
-
type: STRING,
|
|
6808
|
-
loc,
|
|
6809
|
-
},
|
|
6810
|
-
],
|
|
6811
|
-
type: { kind: "object", className: "%TypeError" },
|
|
6812
|
-
loc,
|
|
6813
|
-
},
|
|
6814
|
-
loc,
|
|
6815
|
-
},
|
|
6816
|
-
];
|
|
6817
|
-
}
|
|
6818
|
-
else {
|
|
6819
|
-
const value = isUnitType(arm)
|
|
6820
|
-
? { kind: "unitLit", unit: arm.kind === "undefinedT" ? "undefined" : "null", type: arm, loc }
|
|
6821
|
-
: { kind: "unionNarrow", unionId: fromId, tag: i, value: u, type: arm, loc };
|
|
6822
|
-
const lift = lifts.get(i);
|
|
6823
|
-
// Width-lifted arm: the narrowed payload reshapes into the
|
|
6824
|
-
// destination arm and wraps (applyWidthLift — planned above, so
|
|
6825
|
-
// the interns cannot fail here); identity arms re-wrap the same
|
|
6826
|
-
// payload pointer.
|
|
6827
|
-
const wrapped = lift
|
|
6828
|
-
? this.applyWidthLift(lift, value, toT, loc)
|
|
6829
|
-
: { kind: "unionWrap", unionId: toId, tag, value, type: toT, loc };
|
|
6830
|
-
then = [{ kind: "return", value: wrapped, loc }];
|
|
6831
|
-
}
|
|
6832
|
-
body.push({ kind: "if", cond, then, else_: null, loc });
|
|
6833
|
-
});
|
|
6834
|
-
// Unreachable when tags are exhaustive (they are, by construction);
|
|
6835
|
-
// satisfies the all-paths-return rule and keeps a corrupted tag loud.
|
|
6836
|
-
body.push({
|
|
6837
|
-
kind: "throw",
|
|
6838
|
-
value: { kind: "strLit", value: "scriptc: internal error: invalid union tag", type: STRING, loc },
|
|
6839
|
-
loc,
|
|
6840
|
-
});
|
|
6841
|
-
this.liftedFns.push({
|
|
6842
|
-
name,
|
|
6843
|
-
params: [{ localId: "u.0", name: "u", type: fromT }],
|
|
6844
|
-
returnType: toT,
|
|
6845
|
-
locals: [{ id: "u.0", name: "u", type: fromT, mutable: true }],
|
|
6846
|
-
body,
|
|
6847
|
-
loc,
|
|
6848
|
-
});
|
|
7118
|
+
this.liftedFns.push(buildUnionRetag(name, from, to, plan, loc, (lift, value, dst) => this.applyWidthLift(lift, value, dst, loc), (type) => this.fmt(type)));
|
|
6849
7119
|
return name;
|
|
6850
7120
|
}
|
|
6851
7121
|
/** Interned `%union.narrow.<n>(u)` — the CHECKED single-arm extraction
|
|
@@ -6871,55 +7141,10 @@ export class Lowerer {
|
|
|
6871
7141
|
const name = `%union.narrow.${this.narrowHelpers.size}`;
|
|
6872
7142
|
this.narrowHelpers.set(key, name);
|
|
6873
7143
|
this.checkedNarrowHelpers.add(name);
|
|
6874
|
-
const
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
if (i === tag)
|
|
6879
|
-
return; // the fall-through extraction below
|
|
6880
|
-
const what = isUnitType(arm)
|
|
6881
|
-
? (arm.kind === "undefinedT" ? "undefined" : "null")
|
|
6882
|
-
: `a '${this.fmt(arm)}' value`;
|
|
6883
|
-
body.push({
|
|
6884
|
-
kind: "if",
|
|
6885
|
-
cond: { kind: "unionIsTag", unionId: fromId, tag: i, negated: false, value: u, type: BOOL, loc },
|
|
6886
|
-
then: [
|
|
6887
|
-
{
|
|
6888
|
-
kind: "throw",
|
|
6889
|
-
value: {
|
|
6890
|
-
kind: "libCall",
|
|
6891
|
-
fn: "error.new",
|
|
6892
|
-
args: [
|
|
6893
|
-
{
|
|
6894
|
-
kind: "strLit",
|
|
6895
|
-
value: `${what} is not representable in the target union (a value narrowed or asserted past it still held it)`,
|
|
6896
|
-
type: STRING,
|
|
6897
|
-
loc,
|
|
6898
|
-
},
|
|
6899
|
-
],
|
|
6900
|
-
type: { kind: "object", className: "%TypeError" },
|
|
6901
|
-
loc,
|
|
6902
|
-
},
|
|
6903
|
-
loc,
|
|
6904
|
-
},
|
|
6905
|
-
],
|
|
6906
|
-
else_: null,
|
|
6907
|
-
loc,
|
|
6908
|
-
});
|
|
6909
|
-
});
|
|
6910
|
-
body.push({
|
|
6911
|
-
kind: "return",
|
|
6912
|
-
value: { kind: "unionNarrow", unionId: fromId, tag, value: u, type: target, loc },
|
|
6913
|
-
loc,
|
|
6914
|
-
});
|
|
6915
|
-
this.liftedFns.push({
|
|
6916
|
-
name,
|
|
6917
|
-
params: [{ localId: "u.0", name: "u", type: fromT }],
|
|
6918
|
-
returnType: target,
|
|
6919
|
-
locals: [{ id: "u.0", name: "u", type: fromT, mutable: true }],
|
|
6920
|
-
body,
|
|
6921
|
-
loc,
|
|
6922
|
-
});
|
|
7144
|
+
const fn = buildUnionNarrow(name, from, target, loc, (type) => this.fmt(type));
|
|
7145
|
+
if (!fn)
|
|
7146
|
+
throw new InternalCompilerError("lowerer bug: invalid checked union extraction");
|
|
7147
|
+
this.liftedFns.push(fn);
|
|
6923
7148
|
return name;
|
|
6924
7149
|
}
|
|
6925
7150
|
/** The DEFERRED-INIT field read (`stream!: T` assigned past the
|
|
@@ -6947,32 +7172,13 @@ export class Lowerer {
|
|
|
6947
7172
|
return existing;
|
|
6948
7173
|
const name = `%deferred.read.${this.narrowHelpers.size}`;
|
|
6949
7174
|
this.narrowHelpers.set(key, name);
|
|
6950
|
-
const fromT = { kind: "union", unionId: fromId };
|
|
6951
|
-
const u = { kind: "varRef", localId: "u.0", type: fromT, loc };
|
|
6952
7175
|
const dflt = target.kind === "bool"
|
|
6953
7176
|
? { kind: "boolLit", value: false, type: BOOL, loc }
|
|
6954
7177
|
: { kind: "numLit", value: NaN, type: F64, loc };
|
|
6955
|
-
this.
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
locals: [{ id: "u.0", name: "u", type: fromT, mutable: true }],
|
|
6960
|
-
body: [
|
|
6961
|
-
{
|
|
6962
|
-
kind: "if",
|
|
6963
|
-
cond: { kind: "unionIsTag", unionId: fromId, tag: utag, negated: false, value: u, type: BOOL, loc },
|
|
6964
|
-
then: [{ kind: "return", value: dflt, loc }],
|
|
6965
|
-
else_: null,
|
|
6966
|
-
loc,
|
|
6967
|
-
},
|
|
6968
|
-
{
|
|
6969
|
-
kind: "return",
|
|
6970
|
-
value: { kind: "unionNarrow", unionId: fromId, tag, value: u, type: target, loc },
|
|
6971
|
-
loc,
|
|
6972
|
-
},
|
|
6973
|
-
],
|
|
6974
|
-
loc,
|
|
6975
|
-
});
|
|
7178
|
+
const fn = buildUnionNarrow(name, from, target, loc, (type) => this.fmt(type), dflt);
|
|
7179
|
+
if (!fn)
|
|
7180
|
+
throw new InternalCompilerError("lowerer bug: invalid deferred union extraction");
|
|
7181
|
+
this.liftedFns.push(fn);
|
|
6976
7182
|
return name;
|
|
6977
7183
|
}
|
|
6978
7184
|
/** True when a static value can become ONE island value: jsval itself,
|
|
@@ -7356,7 +7562,66 @@ export class Lowerer {
|
|
|
7356
7562
|
* lowering goes through here (via lowerExprExpecting) or calls this
|
|
7357
7563
|
* directly when the expression was already lowered. */
|
|
7358
7564
|
coerceInto(node, expr, expected) {
|
|
7565
|
+
// A union destination can accept the binding's tagged storage directly.
|
|
7566
|
+
// The checker's single-arm flow type can be stale after a callback writes
|
|
7567
|
+
// the binding. Extracting that arm and wrapping it again would discard the
|
|
7568
|
+
// actual tag and could read a different record layout. Retag the stored
|
|
7569
|
+
// value instead; ordinary coercion checks any excluded destination arms.
|
|
7570
|
+
// Explicit assertions keep their own conversion and validation.
|
|
7571
|
+
if (expected.kind === "union" && expr.kind === "unionNarrow") {
|
|
7572
|
+
let source = node;
|
|
7573
|
+
while (ts.isParenthesizedExpression(source) || ts.isSatisfiesExpression(source))
|
|
7574
|
+
source = source.expression;
|
|
7575
|
+
if (ts.isIdentifier(source) || ts.isShorthandPropertyAssignment(source))
|
|
7576
|
+
expr = expr.value;
|
|
7577
|
+
}
|
|
7578
|
+
// A fresh literal can retain a wider runtime-optional field after its
|
|
7579
|
+
// initial contextual layout was chosen. Its known discriminator still
|
|
7580
|
+
// selects the destination arm; validate that payload before wrapping.
|
|
7581
|
+
// Work with the already lowered value so property effects run once.
|
|
7582
|
+
if (expr.type.kind === "record" && expected.kind === "union") {
|
|
7583
|
+
let literal = node;
|
|
7584
|
+
while (ts.isParenthesizedExpression(literal) || ts.isSatisfiesExpression(literal))
|
|
7585
|
+
literal = literal.expression;
|
|
7586
|
+
const def = this.unions.get(expected.unionId);
|
|
7587
|
+
if (def?.discriminant && ts.isObjectLiteralExpression(literal)) {
|
|
7588
|
+
const property = this.checker.getPropertyOfType(this.typeOf(literal), def.discriminant.field);
|
|
7589
|
+
if (property && !(property.flags & (ts.SymbolFlags.Optional | ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor))) {
|
|
7590
|
+
const values = literalValues(this.checker.getTypeOfSymbol(property));
|
|
7591
|
+
const arm = values && literalUnionArm(def, values, (id) => this.shapes.get(id));
|
|
7592
|
+
if (arm)
|
|
7593
|
+
expr = this.coerceInto(node, expr, arm);
|
|
7594
|
+
}
|
|
7595
|
+
}
|
|
7596
|
+
}
|
|
7597
|
+
if (expected.kind === "dyn") {
|
|
7598
|
+
const contextual = this.checker.getContextualType(node);
|
|
7599
|
+
const parts = contextual?.isUnionType() ? ts.constituentTypes(contextual) : contextual ? [contextual] : [];
|
|
7600
|
+
const errorOptions = parts.some((part) => {
|
|
7601
|
+
const sym = part.getAliasSymbol() ?? part.getSymbol();
|
|
7602
|
+
return sym?.name === "ErrorOptions" && this.isStdlibSymbol(sym);
|
|
7603
|
+
});
|
|
7604
|
+
if (errorOptions) {
|
|
7605
|
+
const actual = this.typeOf(node);
|
|
7606
|
+
for (const part of actual.isUnionType() ? ts.constituentTypes(actual) : [actual]) {
|
|
7607
|
+
const cause = this.checker.getPropertyOfType(part, "cause");
|
|
7608
|
+
if (cause && cause.flags & (ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) {
|
|
7609
|
+
this.unsupported("SC1090", node, "Error options with a cause accessor (use a data property)");
|
|
7610
|
+
}
|
|
7611
|
+
}
|
|
7612
|
+
}
|
|
7613
|
+
}
|
|
7359
7614
|
let e = this.coerceToExpected(expr, expected);
|
|
7615
|
+
// Existing JavaScript arrays retain mutations and identity across checked
|
|
7616
|
+
// slots. Fresh literals have no prior identity and use checked storage
|
|
7617
|
+
// directly, so later writes can change their inferred element type.
|
|
7618
|
+
let literal = node;
|
|
7619
|
+
while (ts.isParenthesizedExpression(literal))
|
|
7620
|
+
literal = literal.expression;
|
|
7621
|
+
if (isJsSourceFile(node.getSourceFile()) && !ts.isArrayLiteralExpression(literal) &&
|
|
7622
|
+
e.kind === "dynFrom" && e.value.type.kind === "array") {
|
|
7623
|
+
e = { ...e, liveRef: true };
|
|
7624
|
+
}
|
|
7360
7625
|
// An 'any' value PROVABLY null/undefined (the unit literal itself, or
|
|
7361
7626
|
// a read of a binding nothing ever assigns a non-unit value) flowing
|
|
7362
7627
|
// implicitly into a primitive slot: the validated exit refuses units
|
|
@@ -7391,6 +7656,20 @@ export class Lowerer {
|
|
|
7391
7656
|
if (helper) {
|
|
7392
7657
|
e = { kind: "call", callee: helper, args: [e], type: expected, loc: e.loc };
|
|
7393
7658
|
}
|
|
7659
|
+
// Shipped JavaScript can select overloads using runtime brand data
|
|
7660
|
+
// that its JSDoc union does not narrow. Preserve the numeric/string/
|
|
7661
|
+
// boolean destination check, just as for an unknown-typed argument;
|
|
7662
|
+
// never reinterpret an object payload as a scalar union arm.
|
|
7663
|
+
if (e.type.kind === "union" && !typeEquals(e.type, expected) && isJsSourceFile(node.getSourceFile()) &&
|
|
7664
|
+
this.dynConvertible(e.type)) {
|
|
7665
|
+
const sourceArms = this.unions.get(e.type.unionId)?.arms ?? [];
|
|
7666
|
+
const targetArms = this.unions.get(expected.unionId)?.arms ?? [];
|
|
7667
|
+
if (sourceArms.some(isDynTypedRefType) && targetArms.length > 0 &&
|
|
7668
|
+
targetArms.every((arm) => isUnitType(arm) || arm.kind === "f64" || arm.kind === "string" || arm.kind === "bool") &&
|
|
7669
|
+
targetArms.some((arm) => !isUnitType(arm) && sourceArms.some((source) => typeEquals(source, arm)))) {
|
|
7670
|
+
e = this.coerceToExpected(this.coerceToExpected(e, DYN), expected);
|
|
7671
|
+
}
|
|
7672
|
+
}
|
|
7394
7673
|
}
|
|
7395
7674
|
// A JS FUNC value outside the island marshal set flowing into a
|
|
7396
7675
|
// jsval slot (`withPlugins(getSupportInfoWithoutPlugins, 0)` — a
|
|
@@ -7404,7 +7683,9 @@ export class Lowerer {
|
|
|
7404
7683
|
this.requireExactShape(node, e.type, expected);
|
|
7405
7684
|
}
|
|
7406
7685
|
catch (err) {
|
|
7407
|
-
|
|
7686
|
+
if (!(err instanceof PoisonError))
|
|
7687
|
+
throw err;
|
|
7688
|
+
const fence = islandFuncValueFence(this, diagsBefore, node);
|
|
7408
7689
|
if (fence)
|
|
7409
7690
|
return fence;
|
|
7410
7691
|
throw err;
|
|
@@ -7482,53 +7763,145 @@ export class Lowerer {
|
|
|
7482
7763
|
return null;
|
|
7483
7764
|
return [...units].sort().join(" or ");
|
|
7484
7765
|
}
|
|
7485
|
-
/**
|
|
7486
|
-
*
|
|
7487
|
-
*
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7766
|
+
/** A key conversion may rebox or upcast a reference, but must never copy
|
|
7767
|
+
* its referent. Apply the ordinary checked narrowing to absent arms from
|
|
7768
|
+
* runtime-optional reads; only present reference arms participate here. */
|
|
7769
|
+
lowerCollectionKey(node, expected) {
|
|
7770
|
+
if (expected.kind === "dyn") {
|
|
7771
|
+
const value = this.lowerExprExpecting(node, expected);
|
|
7772
|
+
// An adapting promise changes identity, while the Error boundary
|
|
7773
|
+
// snapshots mutable fields. Neither is a live collection reference.
|
|
7774
|
+
const copiesReference = (type) => (type.kind === "promise" && type.inner.kind !== "dyn") ||
|
|
7775
|
+
(type.kind === "object" && (RUNTIME_ERROR_CLASSES.has(type.className) || this.isSubclassOf(type.className, "%Error"))) ||
|
|
7776
|
+
(type.kind === "union" && (this.unions.get(type.unionId)?.arms.some(copiesReference) ?? false));
|
|
7777
|
+
if (value.kind === "dynFrom" && copiesReference(value.value.type)) {
|
|
7778
|
+
this.noLowering("collection slot conversion requiring an Error snapshot or promise adapter", node, "use a collection with the original reference type; checked collection slots require identity-preserving conversions");
|
|
7779
|
+
}
|
|
7780
|
+
// Collections expose the stored reference again. Preserve records,
|
|
7781
|
+
// arrays and byte views rather than taking the ordinary dyn snapshot.
|
|
7782
|
+
const hasLiveReference = (type) => type.kind === "record" || type.kind === "array" || type.kind === "bytes" ||
|
|
7783
|
+
(type.kind === "union" && (this.unions.get(type.unionId)?.arms.some(hasLiveReference) ?? false));
|
|
7784
|
+
if (value.kind === "dynFrom" && hasLiveReference(value.value.type)) {
|
|
7785
|
+
return { ...value, liveRef: true };
|
|
7786
|
+
}
|
|
7787
|
+
return value;
|
|
7788
|
+
}
|
|
7789
|
+
let literal = node;
|
|
7790
|
+
while (ts.isParenthesizedExpression(literal))
|
|
7791
|
+
literal = literal.expression;
|
|
7792
|
+
// Fresh literals have no previous outer identity to preserve. Build them
|
|
7793
|
+
// for their storage layout, just as ordinary contextual literals do.
|
|
7794
|
+
if (ts.isObjectLiteralExpression(literal) || ts.isArrayLiteralExpression(literal) || expected.kind === "f64" || expected.kind === "string") {
|
|
7795
|
+
return this.lowerExprExpecting(node, expected);
|
|
7796
|
+
}
|
|
7797
|
+
// Assertions can perform their own conversion before slot coercion.
|
|
7798
|
+
// Inspect the assertion chain so a width copy cannot hide behind its
|
|
7799
|
+
// already-converted result type. Union-arm checks only unwrap a box.
|
|
7800
|
+
let asserted = literal;
|
|
7801
|
+
while (ts.isAsExpression(asserted) || ts.isTypeAssertion(asserted) || ts.isNonNullExpression(asserted) || ts.isParenthesizedExpression(asserted)) {
|
|
7802
|
+
if (ts.isAsExpression(asserted) || ts.isTypeAssertion(asserted)) {
|
|
7803
|
+
const from = this.mapTypeOf(this.typeOf(asserted.expression));
|
|
7804
|
+
const to = this.mapTypeOf(this.checker.getTypeFromTypeNode(asserted.type));
|
|
7805
|
+
if (from?.kind === "dyn" || from?.kind === "jsval" || (from?.kind === "record" && to?.kind === "record" && !typeEquals(from, to))) {
|
|
7806
|
+
this.noLowering("collection key assertion requiring a structural copy or dynamic conversion", asserted, "use the original reference with the same type as the collection key");
|
|
7807
|
+
}
|
|
7808
|
+
}
|
|
7809
|
+
asserted = asserted.expression;
|
|
7810
|
+
}
|
|
7811
|
+
const value = this.lowerExpr(node);
|
|
7812
|
+
const source = (value.type.kind === "union" ? this.unions.get(value.type.unionId)?.arms ?? [] : [value.type]).filter((type) => !isUnitType(type));
|
|
7813
|
+
const target = expected.kind === "union" ? this.unions.get(expected.unionId)?.arms ?? [] : [expected];
|
|
7814
|
+
const preservesIdentity = source.length > 0 && source.every((from) => target.some((to) => typeEquals(from, to) || (from.kind === "object" && to.kind === "object" && this.isSubclassOf(from.className, to.className))));
|
|
7815
|
+
if (!preservesIdentity || value.kind === "dynCheck" || value.kind === "jsExit") {
|
|
7816
|
+
this.noLowering(`collection key conversion from '${this.fmt(value.type)}' to '${this.fmt(expected)}' requiring a structural copy or dynamic conversion`, node, "use the same reference type for the key and collection; copying a key would change its identity");
|
|
7817
|
+
}
|
|
7818
|
+
return this.coerceInto(node, value, expected);
|
|
7819
|
+
}
|
|
7820
|
+
/** Lower for a known destination, then apply ordinary value coercion.
|
|
7821
|
+
* Fresh arrays and records use the destination layout directly. */
|
|
7491
7822
|
lowerExprExpecting(node, expected) {
|
|
7823
|
+
// These wrappers do not change the value or its inferred type. Keep a
|
|
7824
|
+
// fresh literal visible to destination-directed construction. Assertions
|
|
7825
|
+
// retain their own checked conversion and must not be erased here.
|
|
7826
|
+
while (ts.isParenthesizedExpression(node) || ts.isSatisfiesExpression(node))
|
|
7827
|
+
node = node.expression;
|
|
7828
|
+
if (expected) {
|
|
7829
|
+
if (ts.isConditionalExpression(node))
|
|
7830
|
+
return lowerTernary(this, node, expected);
|
|
7831
|
+
const fresh = this.emptyCollectionFor(node, expected);
|
|
7832
|
+
if (fresh)
|
|
7833
|
+
return this.coerceInto(node, fresh, expected);
|
|
7834
|
+
}
|
|
7492
7835
|
if (expected?.kind === "array") {
|
|
7493
7836
|
let x = node;
|
|
7494
7837
|
while (ts.isParenthesizedExpression(x))
|
|
7495
7838
|
x = x.expression;
|
|
7496
|
-
|
|
7839
|
+
// Fresh arrays are built for the actual destination, including
|
|
7840
|
+
// nested literals whose checker context names a wider recursive
|
|
7841
|
+
// union. Existing arrays still go through ordinary value coercion.
|
|
7842
|
+
if (ts.isArrayLiteralExpression(x)) {
|
|
7497
7843
|
return this.coerceInto(node, this.lowerArrayLiteral(x, expected), expected);
|
|
7498
7844
|
}
|
|
7499
7845
|
}
|
|
7846
|
+
if (expected?.kind === "record") {
|
|
7847
|
+
let x = node;
|
|
7848
|
+
while (ts.isParenthesizedExpression(x))
|
|
7849
|
+
x = x.expression;
|
|
7850
|
+
if (ts.isObjectLiteralExpression(x)) {
|
|
7851
|
+
return this.coerceInto(node, this.lowerObjectLiteral(x, expected), expected);
|
|
7852
|
+
}
|
|
7853
|
+
}
|
|
7854
|
+
if (expected?.kind === "union" && ts.isObjectLiteralExpression(node)) {
|
|
7855
|
+
const def = this.unions.get(expected.unionId);
|
|
7856
|
+
if (def?.discriminant) {
|
|
7857
|
+
const property = this.checker.getPropertyOfType(this.typeOf(node), def.discriminant.field);
|
|
7858
|
+
if (property && !(property.flags & (ts.SymbolFlags.Optional | ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor))) {
|
|
7859
|
+
const values = literalValues(this.checker.getTypeOfSymbol(property));
|
|
7860
|
+
const arm = values && literalUnionArm(def, values, (id) => this.shapes.get(id));
|
|
7861
|
+
if (arm)
|
|
7862
|
+
return this.coerceInto(node, this.lowerObjectLiteral(node, arm), expected);
|
|
7863
|
+
}
|
|
7864
|
+
}
|
|
7865
|
+
}
|
|
7500
7866
|
// An OBJECT LITERAL against a checked-dynamic slot in a JS file (the
|
|
7501
7867
|
// getSupportInfo options argument — a dyn-ABI param), or against the
|
|
7502
|
-
// standard RequestInit
|
|
7868
|
+
// standard RequestInit/ErrorOptions types in TypeScript: the value's world IS the
|
|
7503
7869
|
// checked-dynamic tree — build the dyn literal directly.
|
|
7504
7870
|
if (expected?.kind === "dyn") {
|
|
7505
7871
|
let x = node;
|
|
7506
7872
|
while (ts.isParenthesizedExpression(x))
|
|
7507
7873
|
x = x.expression;
|
|
7874
|
+
// A fresh dense array entering a checked slot has no typed aliases.
|
|
7875
|
+
// Construct its actual storage here so identity and WeakMap lifetime
|
|
7876
|
+
// belong to the array the program keeps, rather than a typed snapshot.
|
|
7877
|
+
if (ts.isArrayLiteralExpression(x) && x.elements.every((element) => !ts.isSpreadElement(element) && !ts.isOmittedExpression(element))) {
|
|
7878
|
+
return { kind: "dynArrLit", elems: x.elements.map((element) => this.lowerExprExpecting(element, DYN)), type: DYN, loc: locOf(x) };
|
|
7879
|
+
}
|
|
7880
|
+
const contextual = this.checker.getContextualType(x);
|
|
7881
|
+
const widened = contextual ? this.checker.getBaseTypeOfLiteralType(contextual) : undefined;
|
|
7882
|
+
const parts = widened?.isUnionType() ? ts.constituentTypes(widened) : widened ? [widened] : [];
|
|
7883
|
+
const builtinOption = (name) => parts.some((part) => {
|
|
7884
|
+
const sym = part.getAliasSymbol() ?? part.getSymbol();
|
|
7885
|
+
return sym?.name === name && this.isStdlibSymbol(sym);
|
|
7886
|
+
});
|
|
7508
7887
|
if (ts.isObjectLiteralExpression(x)) {
|
|
7509
|
-
|
|
7510
|
-
const widened = contextual
|
|
7511
|
-
? this.checker.getBaseTypeOfLiteralType(contextual)
|
|
7512
|
-
: undefined;
|
|
7513
|
-
const sym = widened?.getAliasSymbol() ?? widened?.getSymbol();
|
|
7514
|
-
const requestInit = sym?.name === "RequestInit" && this.isStdlibSymbol(sym);
|
|
7515
|
-
if (isJsSourceFile(x.getSourceFile()) || requestInit) {
|
|
7888
|
+
if (isJsSourceFile(x.getSourceFile()) || builtinOption("RequestInit") || builtinOption("ErrorOptions")) {
|
|
7516
7889
|
return lowerDynObjectLiteral(this, x);
|
|
7517
7890
|
}
|
|
7518
7891
|
}
|
|
7519
7892
|
}
|
|
7520
|
-
//
|
|
7521
|
-
//
|
|
7522
|
-
//
|
|
7523
|
-
//
|
|
7524
|
-
//
|
|
7525
|
-
//
|
|
7893
|
+
// A fresh array can use the unique array-family destination inside a
|
|
7894
|
+
// union too. In nullable recursive fields the checker can report the
|
|
7895
|
+
// whole union as context: an identity lift of that context does not
|
|
7896
|
+
// mean the literal's independently inferred element layout fits.
|
|
7897
|
+
// Construct the elements for the selected arm before wrapping it.
|
|
7898
|
+
// When several array arms fit a fresh literal, any complete element
|
|
7899
|
+
// layout is valid: the new array has no existing aliases to preserve.
|
|
7526
7900
|
if (expected?.kind === "union") {
|
|
7527
7901
|
let x = node;
|
|
7528
7902
|
while (ts.isParenthesizedExpression(x))
|
|
7529
7903
|
x = x.expression;
|
|
7530
7904
|
if (ts.isArrayLiteralExpression(x)) {
|
|
7531
|
-
const own = this.mapTypeOf(this.checker.getContextualType(x) ?? this.typeOf(x));
|
|
7532
7905
|
// Elements beyond bare null/undefined literals can never live in
|
|
7533
7906
|
// a unit-only-element array — a checker type that degraded to one
|
|
7534
7907
|
// (`[]`-flavored inference over a populated literal) carries no
|
|
@@ -7536,26 +7909,60 @@ export class Lowerer {
|
|
|
7536
7909
|
const nonUnitElems = x.elements.some((el) => !ts.isOmittedExpression(el) &&
|
|
7537
7910
|
el.kind !== ts.SyntaxKind.NullKeyword &&
|
|
7538
7911
|
!(ts.isIdentifier(el) && el.text === "undefined"));
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
(
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7912
|
+
const def = this.unions.get(expected.unionId);
|
|
7913
|
+
const arms = (def?.arms ?? []).filter((a) => (a.kind === "array" && !(nonUnitElems && this.unitOnlyElem(a.elem))) ||
|
|
7914
|
+
(a.kind === "record" &&
|
|
7915
|
+
!!this.shapes.get(a.shapeId)?.tuple &&
|
|
7916
|
+
this.shapes.get(a.shapeId).fields.length === x.elements.length &&
|
|
7917
|
+
!x.elements.some(ts.isSpreadElement)));
|
|
7918
|
+
let arm = arms.length === 1 ? arms[0] : undefined;
|
|
7919
|
+
if (!arm && arms.length > 1 && x.elements.length > 0 &&
|
|
7920
|
+
x.elements.every((el) => !ts.isSpreadElement(el) && !ts.isOmittedExpression(el))) {
|
|
7921
|
+
const ownType = this.mapTypeOf(this.typeOf(x));
|
|
7922
|
+
arm = arms.find((candidate) => ownType !== null && typeEquals(candidate, ownType));
|
|
7923
|
+
if (!arm) {
|
|
7924
|
+
const elements = x.elements.map((el) => tryLowerExpression(this, el));
|
|
7925
|
+
arm = arms.find((candidate) => candidate.kind === "array" &&
|
|
7926
|
+
elements.every((element) => element !== null && this.widthLiftPlan(element.type, candidate.elem) !== null));
|
|
7552
7927
|
}
|
|
7553
7928
|
}
|
|
7929
|
+
if (arm) {
|
|
7930
|
+
const built = this.lowerArrayLiteral(x, arm);
|
|
7931
|
+
return this.coerceInto(node, built, expected);
|
|
7932
|
+
}
|
|
7554
7933
|
}
|
|
7555
7934
|
}
|
|
7556
|
-
|
|
7935
|
+
let e = this.lowerExpr(node);
|
|
7936
|
+
if (expected?.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0) {
|
|
7937
|
+
// A destination that accepts undefined must retain an unchecked
|
|
7938
|
+
// read's storage value even when the checker still calls it present.
|
|
7939
|
+
e = this.runtimeOptionalSourceValue(node, e) ?? e;
|
|
7940
|
+
}
|
|
7557
7941
|
return expected ? this.coerceInto(node, e, expected) : e;
|
|
7558
7942
|
}
|
|
7943
|
+
/** An unannotated empty collection has no existing elements or aliases
|
|
7944
|
+
* that constrain its layout. An explicit type argument still wins. */
|
|
7945
|
+
emptyCollectionFor(node, expected) {
|
|
7946
|
+
let value = node;
|
|
7947
|
+
while (ts.isParenthesizedExpression(value))
|
|
7948
|
+
value = value.expression;
|
|
7949
|
+
if (!ts.isNewExpression(value) || !ts.isIdentifier(value.expression) || (value.arguments?.length ?? 0) !== 0 ||
|
|
7950
|
+
(value.typeArguments?.length ?? 0) !== 0)
|
|
7951
|
+
return null;
|
|
7952
|
+
const symbol = this.resolveValueSymbol(value.expression);
|
|
7953
|
+
if (!symbol || !this.isStdlibSymbol(symbol))
|
|
7954
|
+
return null;
|
|
7955
|
+
const kind = symbol.name === "Map" ? "map" : symbol.name === "Set" ? "set" : null;
|
|
7956
|
+
if (!kind)
|
|
7957
|
+
return null;
|
|
7958
|
+
const arms = expected.kind === "union" ? this.unions.get(expected.unionId)?.arms ?? [] : [expected];
|
|
7959
|
+
const candidates = arms.filter((arm) => arm.kind === kind);
|
|
7960
|
+
if (candidates.length !== 1)
|
|
7961
|
+
return null;
|
|
7962
|
+
const type = candidates[0];
|
|
7963
|
+
return type.kind === "map" ? { kind: "mapNew", type, loc: locOf(value) }
|
|
7964
|
+
: type.kind === "set" ? { kind: "setNew", type, loc: locOf(value) } : null;
|
|
7965
|
+
}
|
|
7559
7966
|
/** A value flowing into an index-signature VALUE slot (an overflow
|
|
7560
7967
|
* literal entry, a dynamic-keyed record write). dyn slots (`unknown`
|
|
7561
7968
|
* signatures — ModelPricing's) take a dyn conversion: dyn values pass
|
|
@@ -7613,6 +8020,22 @@ export class Lowerer {
|
|
|
7613
8020
|
* nothing evaluates; unit-typed non-literals keep the fences. */
|
|
7614
8021
|
lowerReturnValue(node) {
|
|
7615
8022
|
const expected = this.ctx.returnType;
|
|
8023
|
+
// A return slot supplies the same construction layout as an argument
|
|
8024
|
+
// or initializer. In particular, contextual callbacks can return fresh
|
|
8025
|
+
// arrays of recursive unions and nullable, unannotated collections.
|
|
8026
|
+
// Async returns still resolve a promise before converting its payload.
|
|
8027
|
+
if (!this.ctx.isAsync && expected.kind !== "void")
|
|
8028
|
+
return this.lowerExprExpecting(node, expected);
|
|
8029
|
+
// Fresh JS objects returned through a checked-native ABI use that
|
|
8030
|
+
// storage directly, just like arguments and variable initializers.
|
|
8031
|
+
// Contextual types (such as Proxy descriptors' symbol-valued fields)
|
|
8032
|
+
// must not force an intermediate record with incompatible field slots.
|
|
8033
|
+
let literal = node;
|
|
8034
|
+
while (ts.isParenthesizedExpression(literal))
|
|
8035
|
+
literal = literal.expression;
|
|
8036
|
+
if (expected.kind === "dyn" && isJsSourceFile(node.getSourceFile()) && ts.isObjectLiteralExpression(literal)) {
|
|
8037
|
+
return this.lowerExprExpecting(node, expected);
|
|
8038
|
+
}
|
|
7616
8039
|
const e = this.lowerExpr(node);
|
|
7617
8040
|
if (expected.kind === "void" && e.kind === "unitLit")
|
|
7618
8041
|
return null;
|
|
@@ -7680,7 +8103,7 @@ export class Lowerer {
|
|
|
7680
8103
|
if (rest.length === 1)
|
|
7681
8104
|
return rest[0];
|
|
7682
8105
|
// Removing an arm keeps canonical (typeKey-sorted) order.
|
|
7683
|
-
return { kind: "union", unionId: this.unions.
|
|
8106
|
+
return { kind: "union", unionId: this.unions.transform(def, rest) };
|
|
7684
8107
|
}
|
|
7685
8108
|
/** The interned `T | undefined` union over a non-union arm type — the ABI
|
|
7686
8109
|
* type of a defaulted parameter, and the result type of lookups that may
|
|
@@ -7952,7 +8375,7 @@ export class Lowerer {
|
|
|
7952
8375
|
* members ride fp.classDecls; expressions register only when their
|
|
7953
8376
|
* containing statement lowers). */
|
|
7954
8377
|
exprClasses = [];
|
|
7955
|
-
|
|
8378
|
+
exprClassInfoByName = new Map();
|
|
7956
8379
|
/** Class expressions whose collection is IN FLIGHT — the reentrancy
|
|
7957
8380
|
* guard for heritage-demanded collection (lowerClassExpressionInfo). */
|
|
7958
8381
|
collectingExprClasses = new Set();
|
|
@@ -8006,8 +8429,8 @@ export class Lowerer {
|
|
|
8006
8429
|
* onExprClassCollected should instantiations ever need eager
|
|
8007
8430
|
* registration. */
|
|
8008
8431
|
onLateClassCollected = null;
|
|
8009
|
-
genericClassInstanceType(decl, ref) {
|
|
8010
|
-
return genericClassInstanceType(this, decl, ref);
|
|
8432
|
+
genericClassInstanceType(decl, ref, mapArgument) {
|
|
8433
|
+
return genericClassInstanceType(this, decl, ref, mapArgument);
|
|
8011
8434
|
}
|
|
8012
8435
|
findStaticOn(info, name) {
|
|
8013
8436
|
return findStaticOn(this, info, name);
|
|
@@ -8080,14 +8503,10 @@ export class Lowerer {
|
|
|
8080
8503
|
superCallStmt(info, thisLocal, args, loc) {
|
|
8081
8504
|
return superCallStmt(this, info, thisLocal, args, loc);
|
|
8082
8505
|
}
|
|
8083
|
-
/** Declares the
|
|
8084
|
-
*
|
|
8506
|
+
/** Declares the this parameter in the function's dedicated binding slot.
|
|
8507
|
+
* Arrow captures use the same boxing and threading as named bindings. */
|
|
8085
8508
|
declareThis(type) {
|
|
8086
|
-
|
|
8087
|
-
const local = { id: "this.0", name: "this", type, mutable: false };
|
|
8088
|
-
ctx.locals.push(local);
|
|
8089
|
-
ctx.scopes[ctx.scopes.length - 1].set(THIS_BINDING, local);
|
|
8090
|
-
return local;
|
|
8509
|
+
return declareContextThis(this.ctx, type);
|
|
8091
8510
|
}
|
|
8092
8511
|
lowerFunction(decl) {
|
|
8093
8512
|
return lowerFunction(this, decl);
|
|
@@ -8106,26 +8525,13 @@ export class Lowerer {
|
|
|
8106
8525
|
}
|
|
8107
8526
|
/* ── scoping and captures ─────────────────────────────────────────── */
|
|
8108
8527
|
declareLocal(nameNode, name, type, mutable) {
|
|
8109
|
-
|
|
8110
|
-
const count = ctx.localCounters.get(name) ?? 0;
|
|
8111
|
-
ctx.localCounters.set(name, count + 1);
|
|
8112
|
-
const local = { id: `${name}.${count}`, name, type, mutable };
|
|
8113
|
-
ctx.locals.push(local);
|
|
8114
|
-
const symbol = this.checker.getSymbolAtLocation(nameNode);
|
|
8115
|
-
if (symbol)
|
|
8116
|
-
ctx.scopes[ctx.scopes.length - 1].set(symbol, local);
|
|
8117
|
-
return local;
|
|
8528
|
+
return declareContextLocal(this.ctx, name, type, mutable, this.checker.getSymbolAtLocation(nameNode), bindingSource(nameNode));
|
|
8118
8529
|
}
|
|
8119
8530
|
/** A function-scope local bound to NO ts.Symbol — the hidden ABI slot of a
|
|
8120
8531
|
* defaulted parameter (the parameter's symbol binds to the separately-
|
|
8121
8532
|
* declared body local; nothing in the source can name this one). */
|
|
8122
8533
|
declareHiddenLocal(name, type) {
|
|
8123
|
-
|
|
8124
|
-
const count = ctx.localCounters.get(name) ?? 0;
|
|
8125
|
-
ctx.localCounters.set(name, count + 1);
|
|
8126
|
-
const local = { id: `${name}.${count}`, name, type, mutable: false };
|
|
8127
|
-
ctx.locals.push(local);
|
|
8128
|
-
return local;
|
|
8534
|
+
return declareContextLocal(this.ctx, name, type, false, undefined, undefined);
|
|
8129
8535
|
}
|
|
8130
8536
|
/** Declares a callee's parameter locals from its ParamShapes and builds
|
|
8131
8537
|
* the DEFAULT-PARAM PROLOGUE. Required/optional/rest params bind their
|
|
@@ -8148,6 +8554,13 @@ export class Lowerer {
|
|
|
8148
8554
|
const decls = rawDecls.filter((p) => !isThisParameter(p));
|
|
8149
8555
|
const params = [];
|
|
8150
8556
|
const prologue = [];
|
|
8557
|
+
const defaultValue = (node, expected) => {
|
|
8558
|
+
const undefinedValue = lowerStaticallyUndefinedArgument(this, node);
|
|
8559
|
+
if (undefinedValue === null)
|
|
8560
|
+
return this.lowerExprExpecting(node, expected);
|
|
8561
|
+
const absent = { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc: locOf(node) };
|
|
8562
|
+
return defaultAfterUndefined(undefinedValue, this.coerceInto(node, absent, expected));
|
|
8563
|
+
};
|
|
8151
8564
|
decls.forEach((decl, i) => {
|
|
8152
8565
|
const shape = shapes[i];
|
|
8153
8566
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
@@ -8174,7 +8587,7 @@ export class Lowerer {
|
|
|
8174
8587
|
// dynamic dyn): the slot holds its tier's undefined directly,
|
|
8175
8588
|
// so the default test is the runtime undefined test — then
|
|
8176
8589
|
// the pattern destructures the picked value.
|
|
8177
|
-
const dflt =
|
|
8590
|
+
const dflt = defaultValue(decl.initializer, abi);
|
|
8178
8591
|
const src = this.declareHiddenLocal("%psrc", abi);
|
|
8179
8592
|
const inRef = () => ({ kind: "varRef", localId: slot.id, type: abi, loc });
|
|
8180
8593
|
const isUndef = abi.kind === "jsval"
|
|
@@ -8189,6 +8602,16 @@ export class Lowerer {
|
|
|
8189
8602
|
const pickedT = abi;
|
|
8190
8603
|
srcType = pickedT;
|
|
8191
8604
|
srcRef = () => ({ kind: "varRef", localId: src.id, type: pickedT, loc });
|
|
8605
|
+
// An empty object pattern still rejects null after applying
|
|
8606
|
+
// the default. With no property reads, nothing else performs
|
|
8607
|
+
// RequireObjectCoercible; use V8's default-expression spelling.
|
|
8608
|
+
if (abi.kind === "dyn" && ts.isObjectBindingPattern(decl.name) && decl.name.elements.length === 0) {
|
|
8609
|
+
prologue.push({
|
|
8610
|
+
kind: "exprStmt",
|
|
8611
|
+
expr: { kind: "dynDestrCheck", value: srcRef(), spelling: "(intermediate value)(intermediate value)(intermediate value)", type: DYN, loc },
|
|
8612
|
+
loc,
|
|
8613
|
+
});
|
|
8614
|
+
}
|
|
8192
8615
|
this.lowerBindingPattern(decl.name, srcRef, srcType, true, prologue);
|
|
8193
8616
|
return;
|
|
8194
8617
|
}
|
|
@@ -8218,7 +8641,7 @@ export class Lowerer {
|
|
|
8218
8641
|
}
|
|
8219
8642
|
if (!present)
|
|
8220
8643
|
this.unsupported("SC1090", decl, "this parameter form"); // defensive: abi = bodyType + undefined by construction
|
|
8221
|
-
const dflt =
|
|
8644
|
+
const dflt = defaultValue(decl.initializer, shape.bodyType);
|
|
8222
8645
|
const src = this.declareHiddenLocal("%psrc", shape.bodyType);
|
|
8223
8646
|
prologue.push({
|
|
8224
8647
|
kind: "varDecl",
|
|
@@ -8248,7 +8671,7 @@ export class Lowerer {
|
|
|
8248
8671
|
const isUndef = abi.kind === "jsval"
|
|
8249
8672
|
? { kind: "jsOp", op: "eq", args: [inRef(), { kind: "jsOp", op: "undefLit", args: [], type: JSVAL, loc }], type: BOOL, loc }
|
|
8250
8673
|
: { kind: "dynTest", test: "undefined", value: inRef(), type: BOOL, loc };
|
|
8251
|
-
const dflt =
|
|
8674
|
+
const dflt = defaultValue(decl.initializer, abi);
|
|
8252
8675
|
const body = this.declareLocal(decl.name, name, abi, true);
|
|
8253
8676
|
prologue.push({
|
|
8254
8677
|
kind: "varDecl",
|
|
@@ -8272,7 +8695,7 @@ export class Lowerer {
|
|
|
8272
8695
|
// the body keeps the full `T | undefined` union (tsc's type),
|
|
8273
8696
|
// so a present argument passes through unchanged and an omitted
|
|
8274
8697
|
// one takes the default AS IS — no narrow on either branch.
|
|
8275
|
-
const dflt =
|
|
8698
|
+
const dflt = defaultValue(decl.initializer, abi);
|
|
8276
8699
|
const body = this.declareLocal(decl.name, name, abi, true);
|
|
8277
8700
|
prologue.push({
|
|
8278
8701
|
kind: "varDecl",
|
|
@@ -8298,7 +8721,7 @@ export class Lowerer {
|
|
|
8298
8721
|
const retag = this.unionRetagHelper(abi.unionId, shape.bodyType.unionId, loc);
|
|
8299
8722
|
if (!retag)
|
|
8300
8723
|
this.unsupported("SC1090", decl, "this parameter form"); // defensive
|
|
8301
|
-
const dflt =
|
|
8724
|
+
const dflt = defaultValue(decl.initializer, shape.bodyType);
|
|
8302
8725
|
const body = this.declareLocal(decl.name, name, shape.bodyType, true);
|
|
8303
8726
|
prologue.push({
|
|
8304
8727
|
kind: "varDecl",
|
|
@@ -8321,7 +8744,7 @@ export class Lowerer {
|
|
|
8321
8744
|
// The default lowers BEFORE the body local binds, so a same-named
|
|
8322
8745
|
// outer binding referenced in it can never resolve to the fresh
|
|
8323
8746
|
// local (tsc separately rejects `x = x`).
|
|
8324
|
-
const dflt =
|
|
8747
|
+
const dflt = defaultValue(decl.initializer, shape.bodyType);
|
|
8325
8748
|
const body = this.declareLocal(decl.name, name, shape.bodyType, true);
|
|
8326
8749
|
prologue.push({
|
|
8327
8750
|
kind: "varDecl",
|
|
@@ -8354,12 +8777,7 @@ export class Lowerer {
|
|
|
8354
8777
|
/** The binding for `symbol` inside context `ctx` — a scoped local or an
|
|
8355
8778
|
* already-threaded capture entry. */
|
|
8356
8779
|
bindingIn(ctx, symbol) {
|
|
8357
|
-
|
|
8358
|
-
const local = ctx.scopes[i].get(symbol);
|
|
8359
|
-
if (local)
|
|
8360
|
-
return local;
|
|
8361
|
-
}
|
|
8362
|
-
return ctx.captureBySymbol.get(symbol) ?? null;
|
|
8780
|
+
return bindingInContext(ctx, symbol);
|
|
8363
8781
|
}
|
|
8364
8782
|
/** Resolves an identifier to a local of the CURRENT function, creating
|
|
8365
8783
|
* capture entries (and boxing the origin binding) when the name lives in
|
|
@@ -8398,7 +8816,7 @@ export class Lowerer {
|
|
|
8398
8816
|
* through arrows (function expressions/declarations reset `this` in JS;
|
|
8399
8817
|
* their bodies never see an enclosing method's binding). */
|
|
8400
8818
|
resolveThis() {
|
|
8401
|
-
return this.resolveKey(
|
|
8819
|
+
return this.resolveKey(undefined);
|
|
8402
8820
|
}
|
|
8403
8821
|
/** READ-ONLY twin of resolveLocal for PROBES (isIslandExpr): answers
|
|
8404
8822
|
* the nearest binding entry without boxing, threading, or predeclaring.
|
|
@@ -8422,74 +8840,23 @@ export class Lowerer {
|
|
|
8422
8840
|
return null;
|
|
8423
8841
|
}
|
|
8424
8842
|
resolveKey(symbol, blame) {
|
|
8425
|
-
const
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
|
|
8433
|
-
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
// the island's documented collection stance, not the box's.
|
|
8443
|
-
if (origin.type.kind === "caught") {
|
|
8444
|
-
// A catch binding never escapes its catch (KEEP NARROW): narrow it
|
|
8445
|
-
// into a typed local and capture THAT.
|
|
8446
|
-
this.unsupported("SC1090", blame ?? this.checker.declarationsOf(symbol)[0] ?? this.entry, "closures capturing catch bindings (narrow into a typed local first)");
|
|
8447
|
-
}
|
|
8448
|
-
// The binding escapes into a nested function: it must live in a box,
|
|
8449
|
-
// shared by everyone (that's what makes mutation visible everywhere).
|
|
8450
|
-
origin.boxed = true;
|
|
8451
|
-
// Thread a capture through every function between origin and here.
|
|
8452
|
-
let parentEntry = origin;
|
|
8453
|
-
for (let j = depth + 1; j < this.fnStack.length; j++) {
|
|
8454
|
-
const ctx = this.fnStack[j];
|
|
8455
|
-
let entry = ctx.captureBySymbol.get(symbol);
|
|
8456
|
-
if (!entry) {
|
|
8457
|
-
// A context that takes NO captures (a plain declared function —
|
|
8458
|
-
// monomorphized/implicit instances lower this way) cannot carry
|
|
8459
|
-
// the binding through: the shape is a module binding whose only
|
|
8460
|
-
// storage is the init function's LOCAL (a typed-but-unmappable
|
|
8461
|
-
// const — the file-scope `new Map()` ledger idiom) read from
|
|
8462
|
-
// inside a nested instance. Fence it — in JS the statement
|
|
8463
|
-
// defers to its runtime trap like every collection failure;
|
|
8464
|
-
// asserting here was an ICE on ordinary npm-static JS.
|
|
8465
|
-
if (ctx.captures === null) {
|
|
8466
|
-
this.unsupported("SC1090", blame ?? this.checker.declarationsOf(symbol)[0] ?? this.entry, `the binding '${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)`);
|
|
8467
|
-
}
|
|
8468
|
-
const count = ctx.localCounters.get(origin.name) ?? 0;
|
|
8469
|
-
ctx.localCounters.set(origin.name, count + 1);
|
|
8470
|
-
entry = {
|
|
8471
|
-
id: `${origin.name}.${count}`,
|
|
8472
|
-
name: origin.name,
|
|
8473
|
-
type: origin.type,
|
|
8474
|
-
mutable: origin.mutable,
|
|
8475
|
-
boxed: true,
|
|
8476
|
-
// TDZ travels with the binding: reads through ANY capture of a
|
|
8477
|
-
// forward-captured const must trap while the box is empty.
|
|
8478
|
-
...(origin.tdz ? { tdz: true } : {}),
|
|
8479
|
-
};
|
|
8480
|
-
ctx.locals.push(entry);
|
|
8481
|
-
ctx.captureBySymbol.set(symbol, entry);
|
|
8482
|
-
ctx.captures.push({ localId: entry.id, name: entry.name, type: entry.type });
|
|
8483
|
-
ctx.captureSources.push(parentEntry.id);
|
|
8484
|
-
const runtimeOptionalRoot = this.runtimeOptionalRootOf(parentEntry);
|
|
8485
|
-
if (this.runtimeOptionalStorageLocals.has(runtimeOptionalRoot)) {
|
|
8486
|
-
this.runtimeOptionalRoots.set(entry, runtimeOptionalRoot);
|
|
8487
|
-
}
|
|
8488
|
-
}
|
|
8489
|
-
parentEntry = entry;
|
|
8490
|
-
}
|
|
8491
|
-
return parentEntry;
|
|
8492
|
-
}
|
|
8843
|
+
const resolved = captureContextBinding(this.fnStack, symbol, (parentEntry, entry) => {
|
|
8844
|
+
const root = this.runtimeOptionalRootOf(parentEntry);
|
|
8845
|
+
if (this.runtimeOptionalStorageLocals.has(root))
|
|
8846
|
+
this.runtimeOptionalRoots.set(entry, root);
|
|
8847
|
+
});
|
|
8848
|
+
if (resolved.error !== null) {
|
|
8849
|
+
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)`;
|
|
8853
|
+
this.unsupported("SC1090", location, message);
|
|
8854
|
+
}
|
|
8855
|
+
if (resolved.local !== null)
|
|
8856
|
+
return resolved.local;
|
|
8857
|
+
// This cannot be forward-declared: its parameter must already exist.
|
|
8858
|
+
if (symbol === undefined)
|
|
8859
|
+
return null;
|
|
8493
8860
|
// Nothing declared yet anywhere on the stack: the hoisted-handler shape
|
|
8494
8861
|
// — a function declared BEFORE a const it captures (`const cleanup =
|
|
8495
8862
|
// () => onSigInt; ...; const onSigInt = ...`). Pre-declare the const as
|
|
@@ -8555,21 +8922,10 @@ export class Lowerer {
|
|
|
8555
8922
|
// binding-form text.
|
|
8556
8923
|
if (symbol) {
|
|
8557
8924
|
const d = this.checker.valueDeclarationOf(symbol);
|
|
8558
|
-
if (d && ts.isVariableDeclaration(d) && ts.isVariableDeclarationList(d.parent) &&
|
|
8559
|
-
(d.parent.flags & ts.NodeFlags.Const) !== 0) {
|
|
8560
|
-
const codec = textCodecBindingClassOf(this, d.name, d.initializer);
|
|
8561
|
-
if (codec !== null) {
|
|
8562
|
-
const call = codec === "TextEncoder" ? `${name}.encode(s)` : `${name}.decode(bytes)`;
|
|
8563
|
-
const composed = codec === "TextEncoder"
|
|
8564
|
-
? "new TextEncoder().encode(s)"
|
|
8565
|
-
: "new TextDecoder().decode(bytes)";
|
|
8566
|
-
this.noLowering(`${codec} instance stored in ${name}`, node, `${call} compiles through this const; the codec object itself has no representation (the composed ${composed} form also compiles)`);
|
|
8567
|
-
}
|
|
8568
|
-
}
|
|
8569
8925
|
if (d && ts.isVariableDeclaration(d) && d.initializer === undefined) {
|
|
8570
8926
|
const t = this.checker.getTypeOfSymbol(symbol);
|
|
8571
8927
|
const parts = t.isUnionType() ? ts.constituentTypes(t) : [t];
|
|
8572
|
-
if (parts.some((p) => this.checker.getCallSignatures(p).some((s) =>
|
|
8928
|
+
if (parts.some((p) => this.checker.getCallSignatures(p).some((s) => s.getTypeParameters().length > 0))) {
|
|
8573
8929
|
this.unsupported("SC1030", node, `the generic-signature binding '${name}' (its type keeps type parameters and the declaration has no initializer — no function body exists to monomorphize, so nothing can pin a concrete signature)`);
|
|
8574
8930
|
}
|
|
8575
8931
|
}
|
|
@@ -8893,8 +9249,8 @@ export class Lowerer {
|
|
|
8893
9249
|
lowerArrayLiteral(expr, expected) {
|
|
8894
9250
|
return lowerArrayLiteral(this, expr, expected);
|
|
8895
9251
|
}
|
|
8896
|
-
lowerObjectLiteral(expr) {
|
|
8897
|
-
return lowerObjectLiteral(this, expr);
|
|
9252
|
+
lowerObjectLiteral(expr, expected) {
|
|
9253
|
+
return lowerObjectLiteral(this, expr, expected);
|
|
8898
9254
|
}
|
|
8899
9255
|
lowerShorthandValue(prop) {
|
|
8900
9256
|
return lowerShorthandValue(this, prop);
|
|
@@ -9192,8 +9548,8 @@ export class Lowerer {
|
|
|
9192
9548
|
lowerFieldCompound(access, op, rhsNode, loc) {
|
|
9193
9549
|
return lowerFieldCompound(this, access, op, rhsNode, loc);
|
|
9194
9550
|
}
|
|
9195
|
-
|
|
9196
|
-
return
|
|
9551
|
+
errorConstructorArgs(args, loc, blame) {
|
|
9552
|
+
return errorConstructorArgs(this, args, loc, blame);
|
|
9197
9553
|
}
|
|
9198
9554
|
inheritsBuiltinErrorCtor(info) {
|
|
9199
9555
|
return inheritsBuiltinErrorCtor(this, info);
|
|
@@ -9373,7 +9729,7 @@ export class Lowerer {
|
|
|
9373
9729
|
}
|
|
9374
9730
|
if (!ts.isNamespaceImport(decl))
|
|
9375
9731
|
return null;
|
|
9376
|
-
const importDecl = decl.parent
|
|
9732
|
+
const importDecl = decl.parent?.parent;
|
|
9377
9733
|
if (!ts.isImportDeclaration(importDecl) || !ts.isStringLiteral(importDecl.moduleSpecifier))
|
|
9378
9734
|
return null;
|
|
9379
9735
|
return canonicalBuiltinModule(importDecl.moduleSpecifier.text);
|
|
@@ -9393,6 +9749,16 @@ export class Lowerer {
|
|
|
9393
9749
|
builtinMemberOf(access) {
|
|
9394
9750
|
if (access.questionDotToken)
|
|
9395
9751
|
return null;
|
|
9752
|
+
// Function-owned builtin members still require import provenance. A
|
|
9753
|
+
// user object named realpathSync must retain its ordinary method call.
|
|
9754
|
+
if (access.name.text === "native") {
|
|
9755
|
+
const owner = access.expression;
|
|
9756
|
+
const imported = ts.isIdentifier(owner) ? this.builtinImportOf(owner)
|
|
9757
|
+
: ts.isPropertyAccessExpression(owner) ? this.builtinMemberOf(owner) : null;
|
|
9758
|
+
if (imported?.module === "fs" && imported.member === "realpathSync") {
|
|
9759
|
+
return { module: "fs", member: "realpathSync.native" };
|
|
9760
|
+
}
|
|
9761
|
+
}
|
|
9396
9762
|
const module = this.builtinNamespaceModuleOf(access.expression);
|
|
9397
9763
|
if (module !== null)
|
|
9398
9764
|
return { module, member: access.name.text };
|
|
@@ -9533,10 +9899,9 @@ export class Lowerer {
|
|
|
9533
9899
|
if (roots)
|
|
9534
9900
|
return roots;
|
|
9535
9901
|
}
|
|
9536
|
-
//
|
|
9537
|
-
//
|
|
9538
|
-
|
|
9539
|
-
if (!isJsSourceFile(expr.getSourceFile())) {
|
|
9902
|
+
// Builtin values admitted by an explicit surface-table contract use
|
|
9903
|
+
// the same interned native closures in TypeScript and JavaScript.
|
|
9904
|
+
{
|
|
9540
9905
|
const callable = this.lowerBuiltinCallableValue(bi, loc);
|
|
9541
9906
|
if (callable)
|
|
9542
9907
|
return callable;
|
|
@@ -9557,8 +9922,11 @@ export class Lowerer {
|
|
|
9557
9922
|
* are only dispatch sentinels for call-site-specific lowering. */
|
|
9558
9923
|
lowerBuiltinCallableValue(bi, loc) {
|
|
9559
9924
|
const fn = builtinModuleFnOf(this, bi.module, bi.member);
|
|
9560
|
-
|
|
9561
|
-
|
|
9925
|
+
return fn ? this.lowerNativeCallableValue(fn, `${bi.module}.${bi.member}`, loc) : null;
|
|
9926
|
+
}
|
|
9927
|
+
lowerNativeCallableValue(fn, display, loc) {
|
|
9928
|
+
const valueParams = fn.valueParams;
|
|
9929
|
+
if (!valueParams)
|
|
9562
9930
|
return null;
|
|
9563
9931
|
const shapes = valueParams.map((param) => {
|
|
9564
9932
|
if (param.mode === "rest")
|
|
@@ -9582,10 +9950,10 @@ export class Lowerer {
|
|
|
9582
9950
|
name: `arg${index}`,
|
|
9583
9951
|
type,
|
|
9584
9952
|
}));
|
|
9585
|
-
const args =
|
|
9586
|
-
const
|
|
9587
|
-
if (!valueParam) {
|
|
9588
|
-
throw new InternalCompilerError(`builtin callable value '${
|
|
9953
|
+
const args = valueParams.map((valueParam, index) => {
|
|
9954
|
+
const param = params[index];
|
|
9955
|
+
if (!param || !valueParam) {
|
|
9956
|
+
throw new InternalCompilerError(`builtin callable value '${display}' has a missing value parameter`);
|
|
9589
9957
|
}
|
|
9590
9958
|
const ref = {
|
|
9591
9959
|
kind: "varRef",
|
|
@@ -9595,13 +9963,13 @@ export class Lowerer {
|
|
|
9595
9963
|
};
|
|
9596
9964
|
if (valueParam.mode !== "optional")
|
|
9597
9965
|
return ref;
|
|
9598
|
-
if (valueParam.type.kind !== "string" || param.type.kind !== "union") {
|
|
9599
|
-
throw new InternalCompilerError(`builtin callable value '${
|
|
9966
|
+
if ((valueParam.type.kind !== "string" && valueParam.type.kind !== "f64") || param.type.kind !== "union") {
|
|
9967
|
+
throw new InternalCompilerError(`builtin callable value '${display}' has an unsupported optional default`);
|
|
9600
9968
|
}
|
|
9601
9969
|
const undefTag = this.armTag(param.type.unionId, UNDEFINED_T);
|
|
9602
9970
|
const valueTag = this.armTag(param.type.unionId, valueParam.type);
|
|
9603
9971
|
if (undefTag < 0 || valueTag < 0) {
|
|
9604
|
-
throw new InternalCompilerError(`builtin callable value '${
|
|
9972
|
+
throw new InternalCompilerError(`builtin callable value '${display}' has an invalid optional ABI`);
|
|
9605
9973
|
}
|
|
9606
9974
|
return {
|
|
9607
9975
|
kind: "ternary",
|
|
@@ -9614,7 +9982,9 @@ export class Lowerer {
|
|
|
9614
9982
|
type: BOOL,
|
|
9615
9983
|
loc,
|
|
9616
9984
|
},
|
|
9617
|
-
then:
|
|
9985
|
+
then: typeof valueParam.defaultValue === "string"
|
|
9986
|
+
? { kind: "strLit", value: valueParam.defaultValue, type: STRING, loc }
|
|
9987
|
+
: { kind: "numLit", value: valueParam.defaultValue, type: F64, loc },
|
|
9618
9988
|
else_: {
|
|
9619
9989
|
kind: "unionNarrow",
|
|
9620
9990
|
unionId: param.type.unionId,
|