@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
|
@@ -4,30 +4,41 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
4
4
|
* flow (if/while/for/for-of/do, switch, try/catch, abrupt completions),
|
|
5
5
|
* explicit resource management, and blocked-binding poisoning. */
|
|
6
6
|
import * as ts from "../ts7/adapter.js";
|
|
7
|
-
import {
|
|
7
|
+
import { bindingSource } from "../binding-source.js";
|
|
8
|
+
import { arrayValueRead, arrayValueStore, arrayValueType, unionArrayValueRead } from "./array-values.js";
|
|
8
9
|
import { lowerForAwaitGenerator, lowerForOfGenerator, lowerYieldStarStatement } from "./lower-generators.js";
|
|
9
10
|
import { lowerForAwaitBuiltin } from "./lower-async-iteration.js";
|
|
10
|
-
import { BOOL, BYTES_U8, CAUGHT, DYN, F64, JSVAL, STRING, UNDEFINED_T, VOID, arrayOf, isUnitType, shapeHasAccessorSlots, typeEquals } from "../../ir/ir.js";
|
|
11
|
+
import { BOOL, BYTES_U8, CAUGHT, DYN, F64, JSVAL, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals } from "../../ir/ir.js";
|
|
11
12
|
import { PoisonError, boundIdentifiersOf, dynFallbackType, dynUndefinedExpr, importCallHandleType, neverTaintedJsType, staticImportNamespaceType, stmtUsesIsland, uncheckedOverloadHandleCall } from "./lowerer.js";
|
|
12
13
|
import { enforceLibBoundary } from "./lib-boundary.js";
|
|
13
|
-
import { cjsExportAssignmentOf, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isJsSourceFile, locOf, requireSpecOf } from "../program.js";
|
|
14
|
+
import { cjsExportAssignmentOf, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile, isNodeEsmFile, locOf, requireSpecOf } from "../program.js";
|
|
14
15
|
import { COMPOUND_ASSIGN_OPS, STR_METHODS, UNSUPPORTED_STMT, isStdlibMember, sideEffectFreeOptionValue, stdlibGlobalAliasDecl, stdlibGlobalAliasNameOf, stdlibGlobalNameOf } from "./surfaces.js";
|
|
16
|
+
import { isNativeBuiltinValueInitializer } from "./lower-builtin-values.js";
|
|
15
17
|
import { isProvenanceSourceFile } from "../provenance-registry.js";
|
|
16
18
|
import { ambientUndefVarRootOf, lowerImportEquals, nsUndefRead, nsWritableTarget, trapDeclRootOf } from "./lower-namespaces.js";
|
|
17
19
|
import { expandoWritableTarget, lowerExpandoAssignStmt } from "./lower-expando.js";
|
|
18
20
|
import { lowerForOfArrayIter, lowerForOfMap, lowerForOfSearchParams, lowerForOfSet, lowerSafeIndexRead, objectIterOverIndexShape, strCharsCall } from "./lower-containers.js";
|
|
19
21
|
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, bindingNeverReassigned, deadUnmappableBinding, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, nullishExprUnitOf, nullishGenericBindingUnitOf, recordKeysArrayCall, registerOverloadedCallableAlias } from "./lower-calls.js";
|
|
20
22
|
import { isMixinFnBinding, mixinResultBindingClassOf } from "./lower-mixins.js";
|
|
21
|
-
import {
|
|
23
|
+
import { isCompiledPrototypeMember } from "./class-prototypes.js";
|
|
24
|
+
import { classStaticDataFor } from "./class-static-data.js";
|
|
25
|
+
import { objectFactorySignature } from "./object-factory-new.js";
|
|
26
|
+
import { lowerClassCallbackAssign } from "./class-callbacks.js";
|
|
27
|
+
import { genericIfaceBindingKeepsClass, staticFieldWriteTarget } from "./lower-classes.js";
|
|
22
28
|
import { lowerStreamUnderscoreAssign, streamClassAliasDecl } from "./lower-stream.js";
|
|
23
29
|
import { lowerHttpResPropertyAssignment, lowerHttpServerTimeoutAssignment, lowerServerCloseOverrideAssignment } from "./lower-server.js";
|
|
24
|
-
import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, lowerNodeModuleCall, registerBuiltinCallableAlias
|
|
30
|
+
import { isNativeFfiRequire, builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, lowerNodeModuleCall, registerBuiltinCallableAlias } from "./lower-builtins.js";
|
|
25
31
|
import { lowerEnumDeclaration } from "./lower-enums.js";
|
|
26
|
-
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerElementCompound, lowerGroupsProjection,
|
|
32
|
+
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerCompoundValueToTarget, lowerElementCompound, lowerGroupsProjection, matchResultNamedGroupsOf, runtimeOptionalGuardIds, runtimeOptionalTrueIds, symbolFieldInfo, withRuntimeOptionalNarrowed } from "./lower-exprs.js";
|
|
27
33
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
34
|
+
import { globalSymbolKey } from "./expressions/global-symbols.js";
|
|
35
|
+
import { lowerShortCircuitAssignment } from "./expressions/nullish-assignment.js";
|
|
36
|
+
import { lowerEnvironmentKey, lowerNativeFunctionAssignment } from "./lower-exprs.js";
|
|
37
|
+
import { isNativeProxyInitializer } from "./expressions/native-proxy.js";
|
|
28
38
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
39
|
+
import { lowerUnionFieldWrite } from "./expressions/union-field-write.js";
|
|
40
|
+
import { UNSUPPORTED, checkerPanicDiag, isCheckerPanic, requiresDynamicDiag } from "../../diagnostics/diagnostic.js";
|
|
41
|
+
import { isParseArgsDynTypeName, isUnitOnlyTsType, jsOpenObjectType, unitOnlyUnion } from "../type-mapper.js";
|
|
31
42
|
import { canonicalBuiltinModule } from "../builtin-modules.js";
|
|
32
43
|
import { isRelativeSpecifier } from "../workspace-registry.js";
|
|
33
44
|
import { probeNodeRequireRefusal } from "../npm.js";
|
|
@@ -55,7 +66,7 @@ function npmStaticReturnedEmptyArrayType(lowerer, decl) {
|
|
|
55
66
|
let owner = decl.parent;
|
|
56
67
|
while (owner !== undefined && !ts.isFunctionLike(owner))
|
|
57
68
|
owner = owner.parent;
|
|
58
|
-
const ownerBody = owner !== undefined &&
|
|
69
|
+
const ownerBody = owner !== undefined && ts.isFunctionLike(owner) ? owner.body : undefined;
|
|
59
70
|
if (ownerBody === undefined || !ts.isBlock(ownerBody))
|
|
60
71
|
return null;
|
|
61
72
|
let returned = false;
|
|
@@ -92,7 +103,7 @@ function npmStaticOptionalSelfWriteType(lowerer, decl, initial) {
|
|
|
92
103
|
let owner = decl.parent;
|
|
93
104
|
while (owner !== undefined && !ts.isFunctionLike(owner))
|
|
94
105
|
owner = owner.parent;
|
|
95
|
-
const ownerBody = owner !== undefined &&
|
|
106
|
+
const ownerBody = owner !== undefined && ts.isFunctionLike(owner) ? owner.body : undefined;
|
|
96
107
|
if (ownerBody === undefined || !ts.isBlock(ownerBody))
|
|
97
108
|
return null;
|
|
98
109
|
let candidate = null;
|
|
@@ -319,7 +330,7 @@ export function provenanceElidedConstDecl(lowerer, decl) {
|
|
|
319
330
|
const sf = decl.getSourceFile();
|
|
320
331
|
if (!isProvenanceSourceFile(sf.fileName))
|
|
321
332
|
return false;
|
|
322
|
-
const stmt = decl.parent
|
|
333
|
+
const stmt = decl.parent?.parent;
|
|
323
334
|
if (!ts.isVariableStatement(stmt) || !pureAnnotatedDeadConst(stmt, sf))
|
|
324
335
|
return false;
|
|
325
336
|
const diagsBefore = lowerer.diags.length;
|
|
@@ -508,11 +519,13 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
508
519
|
* empty-slot sentinel still works (a scalar slot has no spare state:
|
|
509
520
|
* every bit pattern is a legal value — the setTimeout-handle shape,
|
|
510
521
|
* `clearTimeout(timer)` captured above `const timer = setTimeout(...)`).
|
|
511
|
-
*
|
|
522
|
+
* Checked-dynamic values use ref boxes with their own retain/release;
|
|
523
|
+
* a NULL payload remains distinct from the allocated undefined value.
|
|
524
|
+
* caught/jsval keep their existing capture fences. Unit-only types
|
|
512
525
|
* never carry a useful forward capture. */
|
|
513
526
|
const TDZ_KINDS = new Set([
|
|
514
527
|
"func", "string", "array", "record", "object", "union", "map", "set", "regex", "bytes",
|
|
515
|
-
"f64", "bool",
|
|
528
|
+
"f64", "bool", "dyn",
|
|
516
529
|
// The runtime HANDLE kinds — heap, refcounted, pointer-backed like
|
|
517
530
|
// `object`, so the box's NULL sentinel works unchanged. The canonical
|
|
518
531
|
// shape is the const's own initializer capturing the const:
|
|
@@ -540,26 +553,25 @@ const TDZ_KINDS = new Set([
|
|
|
540
553
|
* threads captures normally. The source declaration later becomes the
|
|
541
554
|
* initializing `assign` (lowerVarDecl consumes tdzPredeclared). Reads
|
|
542
555
|
* test the box and throw Node's exact catchable ReferenceError while it
|
|
543
|
-
* is empty.
|
|
544
|
-
*
|
|
556
|
+
* is empty. Mutable bindings also guard writes; only the declaration's
|
|
557
|
+
* initializing assignment may leave the temporal dead zone. */
|
|
545
558
|
export function predeclareForwardCapture(lowerer, symbol) {
|
|
546
559
|
const decl = lowerer.checker.valueDeclarationOf(symbol);
|
|
547
560
|
if (!decl || !ts.isVariableDeclaration(decl) || decl.name === undefined || !ts.isIdentifier(decl.name))
|
|
548
561
|
return false;
|
|
549
562
|
if (!decl.initializer)
|
|
550
563
|
return false;
|
|
551
|
-
|
|
564
|
+
const flags = ts.getCombinedNodeFlags(decl);
|
|
565
|
+
if ((flags & ts.NodeFlags.BlockScoped) === 0 || (flags & ts.NodeFlags.Using) !== 0)
|
|
552
566
|
return false;
|
|
553
|
-
|
|
554
|
-
return false; // defensive: never twice
|
|
555
|
-
// MODULE-scope consts are pre-registered globals (collectGlobals):
|
|
567
|
+
// MODULE-scope bindings are pre-registered globals (collectGlobals):
|
|
556
568
|
// references resolve through globalOf after the local search fails, so
|
|
557
569
|
// a TDZ box here would SHADOW the global and never fill (the top-level
|
|
558
570
|
// `const id = setInterval(cb)` self-capture — the global slot is the
|
|
559
571
|
// binding). Function-scope declarations have no global; they predeclare.
|
|
560
572
|
if (lowerer.globalsBySymbol.has(symbol))
|
|
561
573
|
return false;
|
|
562
|
-
const varStmt = decl.parent
|
|
574
|
+
const varStmt = decl.parent?.parent;
|
|
563
575
|
if (!ts.isVariableStatement(varStmt))
|
|
564
576
|
return false; // for-initializers stay out
|
|
565
577
|
for (let i = lowerer.activeStmtLists.length - 1; i >= 0; i--) {
|
|
@@ -574,7 +586,7 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
574
586
|
// const's own initializer capturing the const (`const server =
|
|
575
587
|
// createServer(h).listen(0, go)` with `go` reading `server`) is a
|
|
576
588
|
// TDZ read until the initializing assign completes — JS exactly.
|
|
577
|
-
if (idx < entry.index || entry.ctx === lowerer.ctx)
|
|
589
|
+
if (idx < entry.index || entry.ctx === lowerer.ctx || entry.ctx.tdzPredeclared.has(symbol))
|
|
578
590
|
return false;
|
|
579
591
|
const type = lowerer.irTypeOf(decl.name);
|
|
580
592
|
if (!TDZ_KINDS.has(type.kind) || isUnitType(type))
|
|
@@ -582,11 +594,14 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
582
594
|
const name = decl.name.text;
|
|
583
595
|
const count = entry.ctx.localCounters.get(name) ?? 0;
|
|
584
596
|
entry.ctx.localCounters.set(name, count + 1);
|
|
585
|
-
const local = {
|
|
597
|
+
const local = {
|
|
598
|
+
id: `${name}.${count}`, name, type,
|
|
599
|
+
mutable: (flags & ts.NodeFlags.Const) === 0, boxed: true, tdz: true,
|
|
600
|
+
};
|
|
586
601
|
entry.ctx.locals.push(local);
|
|
587
602
|
entry.frame.set(symbol, local);
|
|
588
603
|
entry.out.push({ kind: "varDecl", localId: local.id, init: null, loc: locOf(decl) });
|
|
589
|
-
|
|
604
|
+
entry.ctx.tdzPredeclared.set(symbol, local);
|
|
590
605
|
return true;
|
|
591
606
|
}
|
|
592
607
|
return false;
|
|
@@ -598,23 +613,20 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
598
613
|
* declaration and initializing assignment are pushed before the current
|
|
599
614
|
* statement's IR, registered in the list's scope frame) and the statement
|
|
600
615
|
* loop skips the source statement when it arrives
|
|
601
|
-
* (
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
* ctx than the one currently open — that shape keeps the honest fence. */
|
|
616
|
+
* (the owner's hoistedFnDecls). Forward references from nested functions
|
|
617
|
+
* lower the declaration under the owning statement list's context, then
|
|
618
|
+
* resume the caller and thread its captures normally. */
|
|
605
619
|
export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
606
620
|
const decl = lowerer.checker.valueDeclarationOf(symbol);
|
|
607
621
|
if (!decl || !ts.isFunctionDeclaration(decl) || !decl.body || decl.typeParameters)
|
|
608
622
|
return false;
|
|
609
|
-
if (lowerer.hoistedFnDecls.has(decl))
|
|
610
|
-
return false; // defensive: never twice
|
|
611
623
|
for (let i = lowerer.activeStmtLists.length - 1; i >= 0; i--) {
|
|
612
624
|
const entry = lowerer.activeStmtLists[i];
|
|
613
625
|
const idx = entry.stmts.indexOf(decl);
|
|
614
626
|
if (idx < 0)
|
|
615
627
|
continue;
|
|
616
628
|
// Not forward — already lowered; resolution would have found it.
|
|
617
|
-
if (idx <= entry.index)
|
|
629
|
+
if (idx <= entry.index || entry.ctx.hoistedFnDecls.has(decl))
|
|
618
630
|
return false;
|
|
619
631
|
// The declaration may live in an ENCLOSING function's open list (a
|
|
620
632
|
// sibling hoisted function calling a later one — mutual recursion):
|
|
@@ -628,14 +640,14 @@ export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
|
628
640
|
const frameIdx = entry.ctx.scopes.indexOf(entry.frame);
|
|
629
641
|
if (depth < 0 || frameIdx < 0)
|
|
630
642
|
return false;
|
|
631
|
-
|
|
643
|
+
entry.ctx.hoistedFnDecls.add(decl);
|
|
632
644
|
const fnTail = lowerer.fnStack.splice(depth + 1);
|
|
633
645
|
const scopeTail = entry.ctx.scopes.splice(frameIdx + 1);
|
|
634
646
|
try {
|
|
635
647
|
entry.out.push(lowerer.lowerNestedFunctionDecl(decl));
|
|
636
648
|
}
|
|
637
649
|
catch (e) {
|
|
638
|
-
|
|
650
|
+
entry.ctx.hoistedFnDecls.delete(decl);
|
|
639
651
|
throw e;
|
|
640
652
|
}
|
|
641
653
|
finally {
|
|
@@ -650,7 +662,8 @@ export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
|
650
662
|
* was declared with `var` — no const/let/using flag anywhere on its
|
|
651
663
|
* binding chain. */
|
|
652
664
|
export function isVarDeclared(decl) {
|
|
653
|
-
|
|
665
|
+
const host = ts.isIdentifier(decl) ? hostVariableDeclarationOf(decl) : decl;
|
|
666
|
+
return host !== null && (ts.getCombinedNodeFlags(host) & ts.NodeFlags.BlockScoped) === 0;
|
|
654
667
|
}
|
|
655
668
|
/** The VariableDeclaration hosting a binding name (walking out of any
|
|
656
669
|
* enclosing binding patterns), or null when the name belongs to some
|
|
@@ -687,6 +700,11 @@ export function forOfVarTarget(lowerer, decl) {
|
|
|
687
700
|
* file rides the dyn fallback). Null when no static type can hold the
|
|
688
701
|
* binding. */
|
|
689
702
|
function varBindingType(lowerer, nameNode) {
|
|
703
|
+
if (ts.isVariableDeclaration(nameNode.parent) && isNativeProxyInitializer(lowerer, nameNode.parent.initializer))
|
|
704
|
+
return DYN;
|
|
705
|
+
if (isJsSourceFile(nameNode.getSourceFile()) && ts.isVariableDeclaration(nameNode.parent) &&
|
|
706
|
+
isNativeBuiltinValueInitializer(lowerer, nameNode.parent.initializer))
|
|
707
|
+
return DYN;
|
|
690
708
|
let type = lowerer.mapTypeOf(lowerer.typeOf(nameNode));
|
|
691
709
|
if (type?.kind === "record" && isJsSourceFile(nameNode.getSourceFile())) {
|
|
692
710
|
const shape = lowerer.shapes.get(type.shapeId);
|
|
@@ -735,13 +753,13 @@ function varBindingType(lowerer, nameNode) {
|
|
|
735
753
|
* classic capture semantics fall out: closures made in a loop share the
|
|
736
754
|
* single boxed binding, where `let` gets a fresh box per iteration. */
|
|
737
755
|
function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
738
|
-
const existing = lowerer.hoistedVars.get(symbol);
|
|
756
|
+
const existing = lowerer.ctx.hoistedVars.get(symbol);
|
|
739
757
|
if (existing)
|
|
740
758
|
return existing;
|
|
741
759
|
// The parameter merge: the symbol already binds a function-root local.
|
|
742
760
|
const bound = lowerer.bindingIn(lowerer.ctx, symbol);
|
|
743
761
|
if (bound) {
|
|
744
|
-
lowerer.hoistedVars.set(symbol, bound);
|
|
762
|
+
lowerer.ctx.hoistedVars.set(symbol, bound);
|
|
745
763
|
return bound;
|
|
746
764
|
}
|
|
747
765
|
const type = varBindingType(lowerer, nameNode);
|
|
@@ -753,7 +771,7 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
753
771
|
const name = nameNode.text;
|
|
754
772
|
const count = lowerer.ctx.localCounters.get(name) ?? 0;
|
|
755
773
|
lowerer.ctx.localCounters.set(name, count + 1);
|
|
756
|
-
const local = { id: `${name}.${count}`, name, type, mutable: true };
|
|
774
|
+
const local = { id: `${name}.${count}`, name, type, mutable: true, source: bindingSource(nameNode) };
|
|
757
775
|
lowerer.ctx.locals.push(local);
|
|
758
776
|
lowerer.ctx.scopes[0].set(symbol, local);
|
|
759
777
|
// A checked-dynamic slot holds the dyn undefined (a NULL dyn is a
|
|
@@ -761,7 +779,7 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
761
779
|
// engine undefined for jsval).
|
|
762
780
|
const wrapped = type.kind === "dyn" ? dynUndefinedExpr(locOf(nameNode)) : lowerer.unassignedSlotInit(type, locOf(nameNode));
|
|
763
781
|
root.out.push({ kind: "varDecl", localId: local.id, init: wrapped, loc: locOf(nameNode) });
|
|
764
|
-
lowerer.hoistedVars.set(symbol, local);
|
|
782
|
+
lowerer.ctx.hoistedVars.set(symbol, local);
|
|
765
783
|
return local;
|
|
766
784
|
}
|
|
767
785
|
/** The forward twin of hoistVarBinding, entered from resolution failure: a
|
|
@@ -778,8 +796,6 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
778
796
|
* would yield if the capture ran early, and guessing "it won't" is the
|
|
779
797
|
* silent-wrong-output sin. */
|
|
780
798
|
export function predeclareForwardVar(lowerer, symbol) {
|
|
781
|
-
if (lowerer.hoistedVars.has(symbol))
|
|
782
|
-
return false; // would have resolved
|
|
783
799
|
const decl = lowerer.checker.valueDeclarationOf(symbol);
|
|
784
800
|
if (!decl || !ts.isVariableDeclaration(decl) || !isVarDeclared(decl))
|
|
785
801
|
return false;
|
|
@@ -804,6 +820,8 @@ export function predeclareForwardVar(lowerer, symbol) {
|
|
|
804
820
|
if (!owner)
|
|
805
821
|
return false;
|
|
806
822
|
const ctx = owner.ctx;
|
|
823
|
+
if (ctx.hoistedVars.has(symbol))
|
|
824
|
+
return false; // would have resolved
|
|
807
825
|
// Only a slot that can hold `undefined` can carry the pre-
|
|
808
826
|
// initialization reads: an undefined-armed union (the interned arm),
|
|
809
827
|
// a checked-dynamic binding (the dyn undefined), or a jsval 'any'
|
|
@@ -818,11 +836,11 @@ export function predeclareForwardVar(lowerer, symbol) {
|
|
|
818
836
|
const name = nameNode.text;
|
|
819
837
|
const count = ctx.localCounters.get(name) ?? 0;
|
|
820
838
|
ctx.localCounters.set(name, count + 1);
|
|
821
|
-
const local = { id: `${name}.${count}`, name, type, mutable: true };
|
|
839
|
+
const local = { id: `${name}.${count}`, name, type, mutable: true, source: bindingSource(decl.name) };
|
|
822
840
|
ctx.locals.push(local);
|
|
823
841
|
ctx.scopes[0].set(symbol, local);
|
|
824
842
|
root.out.push({ kind: "varDecl", localId: local.id, init: wrapped, loc: locOf(decl) });
|
|
825
|
-
|
|
843
|
+
ctx.hoistedVars.set(symbol, local);
|
|
826
844
|
return true;
|
|
827
845
|
}
|
|
828
846
|
/** Records the symbols a poisoned DECLARATION statement would have bound
|
|
@@ -867,13 +885,24 @@ export function isBlockedBinding(lowerer, symbol) {
|
|
|
867
885
|
export function lowerScopedBlock(lowerer, stmt) {
|
|
868
886
|
lowerer.scopes.push(new Map());
|
|
869
887
|
try {
|
|
870
|
-
|
|
871
|
-
return stmts;
|
|
888
|
+
return withRuntimeOptionalScope(lowerer, () => ts.isBlock(stmt) ? lowerer.lowerStmts(stmt.statements) : lowerer.lowerStmts([stmt]));
|
|
872
889
|
}
|
|
873
890
|
finally {
|
|
874
891
|
lowerer.scopes.pop();
|
|
875
892
|
}
|
|
876
893
|
}
|
|
894
|
+
function withRuntimeOptionalScope(lowerer, lower) {
|
|
895
|
+
lowerer.runtimeOptionalLocals.beginScope();
|
|
896
|
+
try {
|
|
897
|
+
return lower();
|
|
898
|
+
}
|
|
899
|
+
finally {
|
|
900
|
+
// A guard inside one branch or loop body proves presence only for
|
|
901
|
+
// its remaining statements. Keep assignments that reactivated a
|
|
902
|
+
// slot, and restore every absence possibility from the outer scope.
|
|
903
|
+
lowerer.runtimeOptionalLocals.endScope();
|
|
904
|
+
}
|
|
905
|
+
}
|
|
877
906
|
/** `lbl: stmt` — labeled statements. A label chain collapses to one name
|
|
878
907
|
* list (`a: b: while ...` — both names target the same loop, JS-exact).
|
|
879
908
|
* Loops and switches take the labels DIRECTLY (a labeled continue needs
|
|
@@ -915,6 +944,15 @@ function lowerLabeled(lowerer, stmt) {
|
|
|
915
944
|
return { kind: "block", body, labels, loc: locOf(stmt) };
|
|
916
945
|
}
|
|
917
946
|
export function lowerStmt(lowerer, stmt) {
|
|
947
|
+
if (ts.isClassDeclaration(stmt)) {
|
|
948
|
+
if (!stmt.name)
|
|
949
|
+
lowerer.unsupported("SC1090", stmt, "anonymous local class declarations");
|
|
950
|
+
const info = lowerer.lowerClassExpressionInfo(stmt);
|
|
951
|
+
const type = { kind: "classval", className: info.def.name };
|
|
952
|
+
const local = lowerer.declareLocal(stmt.name, stmt.name.text, type, true);
|
|
953
|
+
const init = lowerer.lowerClassExpression(stmt);
|
|
954
|
+
return { kind: "varDecl", localId: local.id, init, loc: locOf(stmt) };
|
|
955
|
+
}
|
|
918
956
|
if (ts.isVariableStatement(stmt)) {
|
|
919
957
|
// `declare const` — ambient: no storage, no init (collectGlobals
|
|
920
958
|
// skipped it; reads throw Node's ReferenceError at the access).
|
|
@@ -938,11 +976,11 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
938
976
|
// checker only performs for consts (aliasTypeofNarrows).
|
|
939
977
|
const then = lowerer.narrowingAliases(aliasTypeofNarrows(lowerer, stmt.expression, true), () => withRuntimeOptionalNarrowed(lowerer, runtimeOptionalTrueIds(lowerer, stmt.expression), () => lowerer.lowerScopedBlock(stmt.thenStatement)));
|
|
940
978
|
const else_ = stmt.elseStatement
|
|
941
|
-
? lowerer.narrowingAliases(aliasTypeofNarrows(lowerer, stmt.expression, false), () => lowerer.lowerScopedBlock(stmt.elseStatement))
|
|
979
|
+
? lowerer.narrowingAliases(aliasTypeofNarrows(lowerer, stmt.expression, false), () => withRuntimeOptionalNarrowed(lowerer, runtimeOptionalGuardIds(lowerer, stmt.expression, false), () => lowerer.lowerScopedBlock(stmt.elseStatement)))
|
|
942
980
|
: null;
|
|
943
|
-
const
|
|
944
|
-
|
|
945
|
-
|
|
981
|
+
for (const local of falsyExitRuntimeOptionalLocals(lowerer, stmt)) {
|
|
982
|
+
lowerer.runtimeOptionalLocals.delete(lowerer.runtimeOptionalRootOf(local));
|
|
983
|
+
}
|
|
946
984
|
return { kind: "if", cond, then, else_, loc: locOf(stmt) };
|
|
947
985
|
}
|
|
948
986
|
if (ts.isWhileStatement(stmt)) {
|
|
@@ -1092,7 +1130,7 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1092
1130
|
// Already lowered eagerly by the forward-hoisting machinery
|
|
1093
1131
|
// (predeclareForwardFnDecl) — its declaration and assignment are in
|
|
1094
1132
|
// the list's output.
|
|
1095
|
-
if (lowerer.hoistedFnDecls.has(stmt))
|
|
1133
|
+
if (lowerer.ctx.hoistedFnDecls.has(stmt))
|
|
1096
1134
|
return null;
|
|
1097
1135
|
return lowerer.lowerNestedFunctionDecl(stmt);
|
|
1098
1136
|
}
|
|
@@ -1110,7 +1148,7 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1110
1148
|
const entry = UNSUPPORTED_STMT[stmt.kind];
|
|
1111
1149
|
if (entry)
|
|
1112
1150
|
lowerer.unsupported(entry.code, stmt, entry.feature);
|
|
1113
|
-
lowerer.unsupported("SC1090", stmt, `syntax '${ts.
|
|
1151
|
+
lowerer.unsupported("SC1090", stmt, `syntax '${ts.syntaxKindName(stmt.kind)}'`);
|
|
1114
1152
|
}
|
|
1115
1153
|
/** A variable statement may carry several declarators (`let a = 1,
|
|
1116
1154
|
* b = a + 1;`): each lowers to its own varDecl IN ORDER, so later
|
|
@@ -1149,6 +1187,7 @@ export function lowerVarStatement(lowerer, stmt) {
|
|
|
1149
1187
|
// fence.
|
|
1150
1188
|
if (decl.initializer !== undefined &&
|
|
1151
1189
|
requireSpecOf(decl.initializer) !== null &&
|
|
1190
|
+
!isNativeFfiRequire(lowerer, decl.initializer) &&
|
|
1152
1191
|
isJsSourceFile(decl.getSourceFile())) {
|
|
1153
1192
|
const spec = requireSpecOf(decl.initializer);
|
|
1154
1193
|
if (lowerer.externalTypes.has(spec))
|
|
@@ -1252,7 +1291,7 @@ function lowerNumericIteratorDecl(lowerer, decl, isConst) {
|
|
|
1252
1291
|
if (sourceNode === null)
|
|
1253
1292
|
return null;
|
|
1254
1293
|
const sym = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
1255
|
-
if (!sym || lowerer.tdzPredeclared.has(sym))
|
|
1294
|
+
if (!sym || lowerer.ctx.tdzPredeclared.has(sym))
|
|
1256
1295
|
return null;
|
|
1257
1296
|
const source = lowerer.lowerExpr(sourceNode);
|
|
1258
1297
|
if (!((source.type.kind === "array" && source.type.elem.kind === "f64") ||
|
|
@@ -1290,7 +1329,7 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1290
1329
|
if (!call)
|
|
1291
1330
|
return null;
|
|
1292
1331
|
const sym = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
1293
|
-
if (!sym || lowerer.globalsBySymbol.has(sym) || lowerer.tdzPredeclared.has(sym))
|
|
1332
|
+
if (!sym || lowerer.globalsBySymbol.has(sym) || lowerer.ctx.tdzPredeclared.has(sym))
|
|
1294
1333
|
return null;
|
|
1295
1334
|
const rowsT = arrayOf(arrayOf(STRING));
|
|
1296
1335
|
const declared = lowerer.mapTypeOf(lowerer.typeOf(decl.name));
|
|
@@ -1522,6 +1561,10 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1522
1561
|
/** One pattern level: emits a declaration (or global assignment) per
|
|
1523
1562
|
* bound name, recursing through hidden temps for nested patterns. */
|
|
1524
1563
|
export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, out, dynSpell, allowDynObject = false) {
|
|
1564
|
+
if (ts.isObjectBindingPattern(pattern)) {
|
|
1565
|
+
const patternSymbol = lowerer.typeOf(pattern).getSymbol();
|
|
1566
|
+
allowDynObject ||= patternSymbol?.name === "SegmentData" && lowerer.isStdlibSymbol(patternSymbol);
|
|
1567
|
+
}
|
|
1525
1568
|
const present = patternSourceValue(lowerer, srcRef(), ts.isArrayBindingPattern(pattern), out, locOf(pattern), dynSpell);
|
|
1526
1569
|
if (!typeEquals(present.type, srcType)) {
|
|
1527
1570
|
lowerer.lowerBindingPattern(pattern, () => present, present.type, isLet, out, dynSpell, allowDynObject);
|
|
@@ -1529,6 +1572,23 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1529
1572
|
}
|
|
1530
1573
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
1531
1574
|
lowerer.fenceStaticHeadersIteration(pattern);
|
|
1575
|
+
if (srcType.kind === "union" && lowerer.unions.get(srcType.unionId)?.arms.every((arm) => arm.kind === "array")) {
|
|
1576
|
+
for (let i = 0; i < pattern.elements.length; i++) {
|
|
1577
|
+
const el = pattern.elements[i];
|
|
1578
|
+
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1579
|
+
continue;
|
|
1580
|
+
if (el.dotDotDotToken)
|
|
1581
|
+
lowerer.unsupported("SC1031", el, "rest elements over a union of array layouts");
|
|
1582
|
+
const loc = locOf(el);
|
|
1583
|
+
let value = unionArrayValueRead(lowerer, srcRef(), numLit(i, loc), loc);
|
|
1584
|
+
if (!value)
|
|
1585
|
+
lowerer.unsupported("SC1031", el, "array union elements without a common native representation");
|
|
1586
|
+
if (el.initializer)
|
|
1587
|
+
value = applyBindingDefault(lowerer, el, value);
|
|
1588
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
1589
|
+
}
|
|
1590
|
+
return;
|
|
1591
|
+
}
|
|
1532
1592
|
// Tuple sources: each position is a field read of the tuple's record
|
|
1533
1593
|
// shape — the positional twin of object destructuring below.
|
|
1534
1594
|
const tupleShape = srcType.kind === "record" ? lowerer.shapes.get(srcType.shapeId) : undefined;
|
|
@@ -2107,7 +2167,8 @@ function patternSourceValue(lowerer, value, arrayPattern, out, loc, spelling) {
|
|
|
2107
2167
|
const unionId = value.type.unionId;
|
|
2108
2168
|
const arms = lowerer.unions.get(unionId)?.arms;
|
|
2109
2169
|
const present = arms?.filter((arm) => !isUnitType(arm));
|
|
2110
|
-
if (!arms || present?.length
|
|
2170
|
+
if (!arms || !present?.length || present.length === arms.length ||
|
|
2171
|
+
(present.length > 1 && !(arrayPattern && present.every((arm) => arm.kind === "array"))))
|
|
2111
2172
|
return value;
|
|
2112
2173
|
for (const [tag, arm] of arms.entries()) {
|
|
2113
2174
|
if (!isUnitType(arm))
|
|
@@ -2123,13 +2184,18 @@ function patternSourceValue(lowerer, value, arrayPattern, out, loc, spelling) {
|
|
|
2123
2184
|
else_: null, loc,
|
|
2124
2185
|
});
|
|
2125
2186
|
}
|
|
2126
|
-
|
|
2187
|
+
if (present.length === 1) {
|
|
2188
|
+
return { kind: "unionNarrow", unionId, tag: lowerer.armTag(unionId, present[0]), value, type: present[0], loc };
|
|
2189
|
+
}
|
|
2190
|
+
const type = { kind: "union", unionId: lowerer.unions.intern(present) };
|
|
2191
|
+
return lowerer.coerceToExpected(value, type);
|
|
2127
2192
|
}
|
|
2128
2193
|
/** The type a pattern element binds at — the checker's type of the bound
|
|
2129
2194
|
* identifier, or of the nested pattern itself (its implied type). Null
|
|
2130
|
-
* when the type has no static mapping
|
|
2195
|
+
* when the type has no static mapping or checked JS fallback. */
|
|
2131
2196
|
function patternBindingType(lowerer, name) {
|
|
2132
|
-
|
|
2197
|
+
const type = lowerer.typeOf(name);
|
|
2198
|
+
return lowerer.mapTypeOf(type) ?? (isJsSourceFile(name.getSourceFile()) ? dynFallbackType(lowerer, name, type) : null);
|
|
2133
2199
|
}
|
|
2134
2200
|
/** The STATIC property name of a destructuring key: identifiers spell
|
|
2135
2201
|
* themselves, string/numeric-literal keys and COMPUTED keys fold through
|
|
@@ -2333,7 +2399,7 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2333
2399
|
lowerer.unsupported("SC1031", el, `destructuring the member '${propName}' of the builtin global '${globalName}' (a detached member loses its receiver-keyed lowering — call it through the global)`);
|
|
2334
2400
|
}
|
|
2335
2401
|
const symbol = lowerer.checker.getSymbolAtLocation(el.name);
|
|
2336
|
-
if (!symbol || lowerer.tdzPredeclared.has(symbol)) {
|
|
2402
|
+
if (!symbol || lowerer.ctx.tdzPredeclared.has(symbol)) {
|
|
2337
2403
|
lowerer.unsupported("SC1031", el, `bindings with predeclared slots over the builtin global '${globalName}'`);
|
|
2338
2404
|
}
|
|
2339
2405
|
const g = lowerer.globalsBySymbol.get(symbol);
|
|
@@ -2352,7 +2418,7 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2352
2418
|
lowerer.stdlibGlobalAliases.set(symbol, b.alias);
|
|
2353
2419
|
}
|
|
2354
2420
|
if (b.g !== undefined) {
|
|
2355
|
-
out.push({ kind: "assign", localId: b.g.id, value: lowerer.coerceInto(b.name, token, b.g.type), loc });
|
|
2421
|
+
out.push({ kind: "assign", localId: b.g.id, value: lowerer.coerceInto(b.name, token, b.g.type), ...(b.g.tdz ? { initializes: true } : {}), loc });
|
|
2356
2422
|
}
|
|
2357
2423
|
else {
|
|
2358
2424
|
const local = lowerer.declareLocal(b.name, b.name.text, STRING, isLet);
|
|
@@ -2400,7 +2466,12 @@ function undefArmDefault(lowerer, blame, init, value, bodyT) {
|
|
|
2400
2466
|
return { kind: "ternary", cond: isUndef, then: dflt, else_: value, type: bodyT, loc };
|
|
2401
2467
|
}
|
|
2402
2468
|
let present = null;
|
|
2403
|
-
if (bodyT.kind === "
|
|
2469
|
+
if (bodyT.kind === "dyn" && lowerer.dynConvertible(fieldType)) {
|
|
2470
|
+
// The undefined arm is handled by the ternary. A present JSON-safe
|
|
2471
|
+
// union can cross into the binding's checked-dynamic slot.
|
|
2472
|
+
present = lowerer.coerceInto(blame, value, bodyT);
|
|
2473
|
+
}
|
|
2474
|
+
else if (bodyT.kind === "union") {
|
|
2404
2475
|
const retag = lowerer.unionRetagHelper(fieldType.unionId, bodyT.unionId, loc);
|
|
2405
2476
|
if (retag)
|
|
2406
2477
|
present = { kind: "call", callee: retag, args: [value], type: bodyT, loc };
|
|
@@ -2643,6 +2714,9 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
|
|
|
2643
2714
|
* JS skips them and so does the packing. */
|
|
2644
2715
|
function classInstanceRestValue(lowerer, blame, srcRef, srcType, info, consumed, restT) {
|
|
2645
2716
|
const loc = locOf(blame);
|
|
2717
|
+
if (info.symbolFields?.size) {
|
|
2718
|
+
lowerer.unsupported("SC1031", blame, "rest bindings over class instances with symbol-keyed fields (the copied symbols have no record form)");
|
|
2719
|
+
}
|
|
2646
2720
|
for (let c = info; c; c = c.base) {
|
|
2647
2721
|
if (c.builtinError || c.builtinEmitter || c.builtinStream) {
|
|
2648
2722
|
lowerer.unsupported("SC1031", blame, "rest bindings over runtime-provided class instances (Error/EventEmitter/stream internals have no record form)");
|
|
@@ -2904,7 +2978,7 @@ function enginePatternSpec(lowerer, pattern) {
|
|
|
2904
2978
|
const d = exprText(el.initializer, boundBefore);
|
|
2905
2979
|
if (d === null)
|
|
2906
2980
|
return null;
|
|
2907
|
-
sub
|
|
2981
|
+
sub = sub + `=${d}`;
|
|
2908
2982
|
}
|
|
2909
2983
|
parts.push(el.dotDotDotToken ? `...${sub}` : sub);
|
|
2910
2984
|
}
|
|
@@ -2949,7 +3023,7 @@ function enginePatternSpec(lowerer, pattern) {
|
|
|
2949
3023
|
const d = exprText(el.initializer, boundBefore);
|
|
2950
3024
|
if (d === null)
|
|
2951
3025
|
return null;
|
|
2952
|
-
sub
|
|
3026
|
+
sub = sub + `=${d}`;
|
|
2953
3027
|
}
|
|
2954
3028
|
parts.push(`[${key}]:${sub}`);
|
|
2955
3029
|
}
|
|
@@ -3025,7 +3099,7 @@ export function lowerJsvalBindingPattern(lowerer, pattern, srcRef, isLet, out) {
|
|
|
3025
3099
|
const symbol = lowerer.checker.getSymbolAtLocation(name);
|
|
3026
3100
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
3027
3101
|
if (g) {
|
|
3028
|
-
out.push({ kind: "assign", localId: g.id, value: lowerer.coerceInto(name, value, g.type), loc: bindLoc });
|
|
3102
|
+
out.push({ kind: "assign", localId: g.id, value: lowerer.coerceInto(name, value, g.type), ...(g.tdz ? { initializes: true } : {}), loc: bindLoc });
|
|
3029
3103
|
return;
|
|
3030
3104
|
}
|
|
3031
3105
|
if (symbol && hostVariableDeclarationOf(name) !== null && isVarDeclared(name)) {
|
|
@@ -3055,7 +3129,7 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3055
3129
|
const symbol = lowerer.checker.getSymbolAtLocation(name);
|
|
3056
3130
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
3057
3131
|
if (g) {
|
|
3058
|
-
out.push({ kind: "assign", localId: g.id, value: lowerer.coerceInto(name, value, g.type), loc });
|
|
3132
|
+
out.push({ kind: "assign", localId: g.id, value: lowerer.coerceInto(name, value, g.type), ...(g.tdz ? { initializes: true } : {}), loc });
|
|
3059
3133
|
return;
|
|
3060
3134
|
}
|
|
3061
3135
|
// A `var`-declared pattern name assigns its function-scoped hoisted
|
|
@@ -3114,13 +3188,9 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3114
3188
|
out.push({ kind: "varDecl", localId: tmp.id, init: value, loc });
|
|
3115
3189
|
lowerer.lowerBindingPattern(name, () => ({ kind: "varRef", localId: tmp.id, type: value.type, loc }), value.type, isLet, out, undefined, allowDynObject);
|
|
3116
3190
|
}
|
|
3117
|
-
/** For-loop initializers
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
* function-scoped binding with no per-iteration copies to model, so
|
|
3121
|
-
* `for (var i = 0, n = xs.length; ...)` is just two hoisted-slot
|
|
3122
|
-
* assignments (wrapped in a block when several). Statement position goes
|
|
3123
|
-
* through lowerVarStatement. */
|
|
3191
|
+
/** For-loop initializers evaluate declarators from left to right. The LLVM
|
|
3192
|
+
* loop emitter keeps their scope alive and freshens every captured let
|
|
3193
|
+
* binding before the first condition and each subsequent update. */
|
|
3124
3194
|
export function lowerVarDeclList(lowerer, list) {
|
|
3125
3195
|
if ((list.flags & ts.NodeFlags.Using) !== 0) {
|
|
3126
3196
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
@@ -3143,23 +3213,19 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3143
3213
|
return out[0];
|
|
3144
3214
|
return { kind: "block", body: out, loc: locOf(list) };
|
|
3145
3215
|
}
|
|
3146
|
-
|
|
3147
|
-
|
|
3216
|
+
const out = [];
|
|
3217
|
+
for (const decl of list.declarations) {
|
|
3218
|
+
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
3219
|
+
// Destructuring produces nested initialization blocks; copying
|
|
3220
|
+
// their captured bindings still needs a distinct head-scope plan.
|
|
3221
|
+
lowerer.unsupported("SC1031", decl.name, "let/const destructuring in for-loop initializers (declare the pattern before the loop, or use var)");
|
|
3222
|
+
}
|
|
3223
|
+
const lowered = lowerer.lowerVarDecl(decl, isLet);
|
|
3224
|
+
if (!lowered)
|
|
3225
|
+
throw new InternalCompilerError("lowerer bug: for-init declarator resolved to a global");
|
|
3226
|
+
out.push(lowered);
|
|
3148
3227
|
}
|
|
3149
|
-
|
|
3150
|
-
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
3151
|
-
// `for (let [x] = init; ...)`: the desugar is a multi-statement
|
|
3152
|
-
// block, and the backend's per-iteration fresh-binding copy (what
|
|
3153
|
-
// makes closures in iteration k see iteration k's let) keys off a
|
|
3154
|
-
// single varDecl init — a captured destructured head would silently
|
|
3155
|
-
// share one binding. `var` heads above have no per-iteration story
|
|
3156
|
-
// and lower; let/const keep an honest fence.
|
|
3157
|
-
lowerer.unsupported("SC1031", decl.name, "let/const destructuring in for-loop initializers (declare the pattern before the loop, or use var)");
|
|
3158
|
-
}
|
|
3159
|
-
const lowered = lowerer.lowerVarDecl(decl, isLet);
|
|
3160
|
-
if (!lowered)
|
|
3161
|
-
throw new InternalCompilerError("lowerer bug: for-init declarator resolved to a global");
|
|
3162
|
-
return lowered;
|
|
3228
|
+
return out.length === 1 ? out[0] : { kind: "block", body: out, loc: locOf(list) };
|
|
3163
3229
|
}
|
|
3164
3230
|
/** A single static type for an initializer-less JavaScript `let` whose
|
|
3165
3231
|
* later plain writes all agree. An evolving JS local reads as `undefined`
|
|
@@ -3172,7 +3238,7 @@ function inferredEvolvingLetType(lowerer, decl) {
|
|
|
3172
3238
|
if (!ts.isIdentifier(decl.name))
|
|
3173
3239
|
return null;
|
|
3174
3240
|
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
3175
|
-
const scope = decl.parent
|
|
3241
|
+
const scope = decl.parent?.parent?.parent;
|
|
3176
3242
|
if (symbol === undefined || (!ts.isBlock(scope) && !ts.isSourceFile(scope)))
|
|
3177
3243
|
return null;
|
|
3178
3244
|
const isPlainAssignmentTarget = (node) => {
|
|
@@ -3312,8 +3378,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3312
3378
|
// and keep the plain-variable lowering.
|
|
3313
3379
|
if (!decl.initializer &&
|
|
3314
3380
|
(decl.name.text === "module" || decl.name.text === "exports") &&
|
|
3315
|
-
ts.isVariableStatement(decl.parent
|
|
3316
|
-
ts.isSourceFile(decl.parent
|
|
3381
|
+
ts.isVariableStatement(decl.parent?.parent) &&
|
|
3382
|
+
ts.isSourceFile(decl.parent?.parent?.parent) &&
|
|
3317
3383
|
!isJsSourceFile(decl.getSourceFile()) &&
|
|
3318
3384
|
!decl.getSourceFile().statements.some((s) => ts.isImportDeclaration(s) || ts.isExportDeclaration(s) || ts.isExportAssignment(s) ||
|
|
3319
3385
|
(ts.canHaveModifiers(s) && ts.getModifiers(s)?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) === true))) {
|
|
@@ -3334,7 +3400,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3334
3400
|
// plumbing: each call through the binding resolves per site
|
|
3335
3401
|
// (lowerCreateRequireCall); no storage, no code (collectGlobals
|
|
3336
3402
|
// skipped its global by the same test).
|
|
3337
|
-
if (
|
|
3403
|
+
if (createRequireBindingDecl(lowerer, decl.name, decl.initializer))
|
|
3338
3404
|
return null;
|
|
3339
3405
|
// `const fs = require("node:fs")` through that binding — a builtin
|
|
3340
3406
|
// namespace import in const clothing: alias plumbing, no storage
|
|
@@ -3365,13 +3431,6 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3365
3431
|
})());
|
|
3366
3432
|
if (stableStdlibAlias && stdlibGlobalAliasDecl(lowerer, decl.name, decl.initializer))
|
|
3367
3433
|
return null;
|
|
3368
|
-
// `const encoder = new TextEncoder()` and a statically-labelled
|
|
3369
|
-
// TextDecoder twin: the codec has no general value representation, but calls
|
|
3370
|
-
// through this stable binding resolve back to the initializer. The
|
|
3371
|
-
// supported constructors are effect-free, so the declaration itself
|
|
3372
|
-
// is compile-time alias plumbing with no storage or code.
|
|
3373
|
-
if (!isLet && textCodecBindingDecl(lowerer, decl.name, decl.initializer))
|
|
3374
|
-
return null;
|
|
3375
3434
|
// `const f = <T>(x: T) => x` — a generic function value binding: the
|
|
3376
3435
|
// initializer monomorphizes per call-site-resolved signature exactly
|
|
3377
3436
|
// like a generic function declaration (bindingGenericFnInfoOf —
|
|
@@ -3477,7 +3536,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3477
3536
|
return { kind: "assign", localId: g.id, value: wrapped, loc: locOf(decl) };
|
|
3478
3537
|
return null;
|
|
3479
3538
|
}
|
|
3480
|
-
const raw = lowerVariableInitializer(lowerer, decl.initializer)
|
|
3539
|
+
const raw = lowerVariableInitializer(lowerer, decl.initializer, g.type.kind === "dyn" && (isNativeBuiltinValueInitializer(lowerer, decl.initializer) ||
|
|
3540
|
+
ts.isArrayLiteralExpression(decl.initializer)) ? DYN : undefined);
|
|
3481
3541
|
const arithmetic = raw.type.kind === "union"
|
|
3482
3542
|
? lowerer.unions.get(raw.type.unionId)?.arms
|
|
3483
3543
|
: undefined;
|
|
@@ -3487,17 +3547,17 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3487
3547
|
lowerer.runtimeOptionalArithmeticGlobals.add(g);
|
|
3488
3548
|
}
|
|
3489
3549
|
const init = lowerer.coerceInto(decl.initializer, raw, g.type);
|
|
3490
|
-
return { kind: "assign", localId: g.id, value: init, loc: locOf(decl) };
|
|
3550
|
+
return { kind: "assign", localId: g.id, value: init, ...(g.tdz ? { initializes: true } : {}), loc: locOf(decl) };
|
|
3491
3551
|
}
|
|
3492
|
-
// A forward-captured
|
|
3552
|
+
// A forward-captured binding pre-declared as a TDZ box (an earlier
|
|
3493
3553
|
// function in this scope captured it — predeclareForwardCapture): the
|
|
3494
3554
|
// binding and its scope-entry varDecl already exist; the source
|
|
3495
3555
|
// declaration is the one initializing `assign` into the shared box.
|
|
3496
|
-
const pre = declSymbol ? lowerer.tdzPredeclared.get(declSymbol) : undefined;
|
|
3556
|
+
const pre = declSymbol ? lowerer.ctx.tdzPredeclared.get(declSymbol) : undefined;
|
|
3497
3557
|
if (pre && decl.initializer) {
|
|
3498
|
-
lowerer.tdzPredeclared.delete(declSymbol);
|
|
3558
|
+
lowerer.ctx.tdzPredeclared.delete(declSymbol);
|
|
3499
3559
|
const init = lowerer.lowerExprExpecting(decl.initializer, pre.type);
|
|
3500
|
-
return { kind: "assign", localId: pre.id, value: init, loc: locOf(decl) };
|
|
3560
|
+
return { kind: "assign", localId: pre.id, value: init, initializes: true, loc: locOf(decl) };
|
|
3501
3561
|
}
|
|
3502
3562
|
// `var x = e` — an ASSIGNMENT into the function-scoped hoisted slot
|
|
3503
3563
|
// (hoistVarBinding mints it on first encounter and pushes its varDecl
|
|
@@ -3528,7 +3588,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3528
3588
|
// `var v: void;` / `let x: undefined;` — a unit-only binding rides
|
|
3529
3589
|
// the unit-only union (its undefined arm is the unassigned state,
|
|
3530
3590
|
// which is also the only state).
|
|
3531
|
-
if (type.kind === "void" && isUnitOnlyTsType(lowerer.typeOf(decl.name))) {
|
|
3591
|
+
if (type.kind === "void" && isUnitOnlyTsType(lowerer.typeOf(decl.name), lowerer.typeParamResolver)) {
|
|
3532
3592
|
type = unitOnlyUnion(lowerer.unions);
|
|
3533
3593
|
}
|
|
3534
3594
|
if (type.kind === "void")
|
|
@@ -3545,11 +3605,15 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3545
3605
|
// function (with its hint), not the unmappable declared type. If it
|
|
3546
3606
|
// poisons, still declare the local when its type is representable, so
|
|
3547
3607
|
// later references to this name don't produce cascading errors.
|
|
3608
|
+
const inferredObjectType = isJsSourceFile(decl.getSourceFile()) ? lowerer.mapTypeOf(lowerer.typeOf(decl.name)) : null;
|
|
3609
|
+
const expandsObject = inferredObjectType?.kind === "record" && jsObjectBindingExpands(lowerer, decl, inferredObjectType);
|
|
3548
3610
|
let init;
|
|
3549
3611
|
try {
|
|
3550
|
-
init =
|
|
3612
|
+
init = expandsObject || (isJsSourceFile(decl.getSourceFile()) && !decl.type &&
|
|
3613
|
+
isNativeBuiltinValueInitializer(lowerer, decl.initializer)) ? lowerer.lowerExprExpecting(decl.initializer, DYN) : immediatelyGuardedAbsenceProbe(lowerer, decl)
|
|
3551
3614
|
? (lowerAbsenceProbe(lowerer, decl.initializer) ?? lowerer.lowerExpr(decl.initializer))
|
|
3552
|
-
: lowerVariableInitializer(lowerer, decl.initializer)
|
|
3615
|
+
: lowerVariableInitializer(lowerer, decl.initializer, decl.type && (lowerer.typeOf(decl.name).flags & ts.TypeFlags.Never) === 0
|
|
3616
|
+
? lowerer.mapTypeOf(lowerer.typeOf(decl.name)) ?? undefined : undefined);
|
|
3553
3617
|
}
|
|
3554
3618
|
catch (e) {
|
|
3555
3619
|
if (e instanceof PoisonError) {
|
|
@@ -3603,6 +3667,21 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3603
3667
|
npmStaticPackageOfPath(decl.getSourceFile().fileName) !== null) {
|
|
3604
3668
|
type = DYN;
|
|
3605
3669
|
}
|
|
3670
|
+
const preservesObjectIdentity = init.type.kind === "dyn" &&
|
|
3671
|
+
(inferredObjectType?.kind === "record" || inferredObjectType?.kind === "array" ||
|
|
3672
|
+
(isJsSourceFile(decl.getSourceFile()) && inferredObjectType !== null &&
|
|
3673
|
+
(inferredObjectType.kind === "date" || inferredObjectType.kind === "func" || jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn")) ||
|
|
3674
|
+
(isJsSourceFile(decl.getSourceFile()) && inferredObjectType !== null &&
|
|
3675
|
+
(isUnitType(inferredObjectType) || inferredObjectType.kind === "union" && lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType)))) &&
|
|
3676
|
+
!decl.type && !hasJsTypeAnnotation(decl);
|
|
3677
|
+
if (expandsObject || preservesObjectIdentity || (isJsSourceFile(decl.getSourceFile()) &&
|
|
3678
|
+
!decl.type && isNativeBuiltinValueInitializer(lowerer, decl.initializer))) {
|
|
3679
|
+
type = DYN;
|
|
3680
|
+
}
|
|
3681
|
+
if (isJsSourceFile(decl.getSourceFile()) && !decl.type && init.type.kind === "array" && init.type.elem.kind === "dyn" &&
|
|
3682
|
+
(ts.isNewExpression(decl.initializer) || ts.isCallExpression(decl.initializer)) && lowerer.isStdlibGlobal(decl.initializer.expression, "Array")) {
|
|
3683
|
+
type = init.type;
|
|
3684
|
+
}
|
|
3606
3685
|
// A JS `let x = {}`: TS's empty-object-literal type admits ANY later
|
|
3607
3686
|
// non-nullish assignment (`envs = {}`, later `envs =
|
|
3608
3687
|
// Object.fromEntries(...)` — tsc accepts every such write, since
|
|
@@ -3680,7 +3759,9 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3680
3759
|
// static signature would wrap an arity-narrowing adapter that DROPS
|
|
3681
3760
|
// arguments JS would deliver; calls through the dyn binding take the
|
|
3682
3761
|
// boxed thunk's JS arity instead.
|
|
3683
|
-
if (type?.kind === "func" && init.type.kind === "dyn" &&
|
|
3762
|
+
if (type?.kind === "func" && init.type.kind === "dyn" &&
|
|
3763
|
+
(isJsSourceFile(decl.getSourceFile()) ||
|
|
3764
|
+
!decl.type && !hasJsTypeAnnotation(decl) && type.rest === true && type.restAbi === undefined)) {
|
|
3684
3765
|
type = DYN;
|
|
3685
3766
|
}
|
|
3686
3767
|
// A checker-`any` CONST whose initializer lowered to a STATIC type
|
|
@@ -3717,6 +3798,9 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3717
3798
|
if (!type)
|
|
3718
3799
|
lowerer.badType(decl.name, lowerer.typeOf(decl.name));
|
|
3719
3800
|
let settledType = type;
|
|
3801
|
+
if (!isLet && isJsSourceFile(decl.getSourceFile()) && !hasJsTypeAnnotation(decl) && decl.initializer && ts.isNewExpression(decl.initializer)) {
|
|
3802
|
+
settledType = objectFactorySignature(lowerer, decl.initializer)?.returnType ?? settledType;
|
|
3803
|
+
}
|
|
3720
3804
|
const arithmeticType = decl.initializer ? lowerer.runtimeOptionalArithmeticTypes.get(decl.initializer) : undefined;
|
|
3721
3805
|
const isStringArithmeticUnion = (t) => {
|
|
3722
3806
|
if (t.kind !== "union")
|
|
@@ -3733,16 +3817,26 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3733
3817
|
const optionalSelfWriteType = isLet
|
|
3734
3818
|
? npmStaticOptionalSelfWriteType(lowerer, decl, settledType)
|
|
3735
3819
|
: null;
|
|
3736
|
-
settledType = lowerer.runtimeOptionalBindingType(decl.name, settledType);
|
|
3820
|
+
settledType = expandsObject || preservesObjectIdentity ? DYN : lowerer.runtimeOptionalBindingType(decl.name, settledType);
|
|
3737
3821
|
if (optionalSelfWriteType !== null)
|
|
3738
3822
|
settledType = optionalSelfWriteType;
|
|
3739
3823
|
if (returnedEmptyArrayType !== null)
|
|
3740
3824
|
settledType = returnedEmptyArrayType;
|
|
3825
|
+
// Exhaustiveness witnesses (`const unreachable: never = value`) have
|
|
3826
|
+
// no useful checker layout, but their initializer still has a runtime
|
|
3827
|
+
// representation. Preserve it instead of forcing never's numeric
|
|
3828
|
+
// placeholder onto a recursive union or string. Keeping the value also
|
|
3829
|
+
// preserves behavior when an explicit assertion makes this reachable.
|
|
3830
|
+
if (!isLet && lowerer.checker.isNeverType(lowerer.typeOf(decl.name)) &&
|
|
3831
|
+
init.type.kind !== "void" && !isUnitType(init.type)) {
|
|
3832
|
+
settledType = init.type;
|
|
3833
|
+
}
|
|
3741
3834
|
// `const x: void = undefined` / `let y: undefined = undefined`: the
|
|
3742
3835
|
// unit-only union — the initializer's unit literal wraps into its arm
|
|
3743
|
-
// like any optional completion.
|
|
3744
|
-
// void
|
|
3745
|
-
|
|
3836
|
+
// like any optional completion. A generic visitor can bind the slot's
|
|
3837
|
+
// T to void; consult that binding before deciding its value layout.
|
|
3838
|
+
// coerceInto preserves a void call's effects before wrapping undefined.
|
|
3839
|
+
if (settledType.kind === "void" && isUnitOnlyTsType(lowerer.typeOf(decl.name), lowerer.typeParamResolver)) {
|
|
3746
3840
|
settledType = unitOnlyUnion(lowerer.unions);
|
|
3747
3841
|
}
|
|
3748
3842
|
if (settledType.kind === "void")
|
|
@@ -3816,15 +3910,15 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3816
3910
|
settledType = init.type;
|
|
3817
3911
|
}
|
|
3818
3912
|
// A TDZ box minted DURING this very initializer (a callback inside it
|
|
3819
|
-
// captured this
|
|
3913
|
+
// captured this binding — predeclareForwardCapture's current-statement
|
|
3820
3914
|
// case): the binding and its scope-entry varDecl already exist, so
|
|
3821
3915
|
// this declaration is the initializing `assign` into the shared box,
|
|
3822
3916
|
// not a fresh local.
|
|
3823
|
-
const preSelf = declSymbol ? lowerer.tdzPredeclared.get(declSymbol) : undefined;
|
|
3917
|
+
const preSelf = declSymbol ? lowerer.ctx.tdzPredeclared.get(declSymbol) : undefined;
|
|
3824
3918
|
if (preSelf) {
|
|
3825
|
-
lowerer.tdzPredeclared.delete(declSymbol);
|
|
3919
|
+
lowerer.ctx.tdzPredeclared.delete(declSymbol);
|
|
3826
3920
|
init = lowerer.coerceInto(decl.initializer, init, preSelf.type);
|
|
3827
|
-
return { kind: "assign", localId: preSelf.id, value: init, loc: locOf(decl) };
|
|
3921
|
+
return { kind: "assign", localId: preSelf.id, value: init, initializes: true, loc: locOf(decl) };
|
|
3828
3922
|
}
|
|
3829
3923
|
// Slot coercion: `const r: A | B = bValue;` wraps implicitly; width
|
|
3830
3924
|
// subtyping (`const p: {a: number} = wider;`) is rejected, not coerced.
|
|
@@ -3840,7 +3934,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3840
3934
|
}
|
|
3841
3935
|
return { kind: "varDecl", localId: local.id, init, loc: locOf(decl) };
|
|
3842
3936
|
}
|
|
3843
|
-
function lowerVariableInitializer(lowerer, node) {
|
|
3937
|
+
function lowerVariableInitializer(lowerer, node, expected) {
|
|
3844
3938
|
let value = node;
|
|
3845
3939
|
while (ts.isParenthesizedExpression(value) ||
|
|
3846
3940
|
ts.isAsExpression(value) ||
|
|
@@ -3848,8 +3942,18 @@ function lowerVariableInitializer(lowerer, node) {
|
|
|
3848
3942
|
ts.isSatisfiesExpression(value)) {
|
|
3849
3943
|
value = value.expression;
|
|
3850
3944
|
}
|
|
3851
|
-
|
|
3852
|
-
|
|
3945
|
+
// An explicit destination supplies the layout for fresh construction,
|
|
3946
|
+
// including either arm of a conditional. Existing values still pass
|
|
3947
|
+
// through the normal conversion and alias-preservation rules.
|
|
3948
|
+
if (!ts.isObjectLiteralExpression(value)) {
|
|
3949
|
+
// Empty Map/Set construction can use its destination, but class
|
|
3950
|
+
// instances must retain their nominal layout for generic dispatch.
|
|
3951
|
+
const empty = expected ? lowerer.emptyCollectionFor(node, expected) : null;
|
|
3952
|
+
if (empty)
|
|
3953
|
+
return lowerer.coerceInto(node, empty, expected);
|
|
3954
|
+
return ts.isArrayLiteralExpression(value) || ts.isConditionalExpression(value)
|
|
3955
|
+
? lowerer.lowerExprExpecting(node, expected) : lowerer.lowerExpr(node);
|
|
3956
|
+
}
|
|
3853
3957
|
const previous = new Map();
|
|
3854
3958
|
for (const property of value.properties) {
|
|
3855
3959
|
if (!ts.isPropertyAssignment(property) || !ts.isComputedPropertyName(property.name))
|
|
@@ -3863,7 +3967,7 @@ function lowerVariableInitializer(lowerer, node) {
|
|
|
3863
3967
|
lowerer.chainRecvByNode.set(keyNode, lowerer.ensureString(optional, keyNode));
|
|
3864
3968
|
}
|
|
3865
3969
|
try {
|
|
3866
|
-
return lowerer.
|
|
3970
|
+
return lowerer.lowerExprExpecting(node, expected);
|
|
3867
3971
|
}
|
|
3868
3972
|
finally {
|
|
3869
3973
|
for (const [keyNode, prior] of previous) {
|
|
@@ -3874,6 +3978,87 @@ function lowerVariableInitializer(lowerer, node) {
|
|
|
3874
3978
|
}
|
|
3875
3979
|
}
|
|
3876
3980
|
}
|
|
3981
|
+
/** A JS object literal's inferred fields do not close its later storage.
|
|
3982
|
+
* Keep the original native object when writes add keys or delete fields;
|
|
3983
|
+
* converting it to a fixed record would discard that behavior. */
|
|
3984
|
+
function jsObjectBindingExpands(lowerer, decl, type) {
|
|
3985
|
+
if (decl.type || !decl.initializer || !ts.isIdentifier(decl.name) || !isJsSourceFile(decl.getSourceFile()))
|
|
3986
|
+
return false;
|
|
3987
|
+
let initializer = decl.initializer;
|
|
3988
|
+
while (ts.isParenthesizedExpression(initializer))
|
|
3989
|
+
initializer = initializer.expression;
|
|
3990
|
+
if (!ts.isObjectLiteralExpression(initializer))
|
|
3991
|
+
return false;
|
|
3992
|
+
if (hasJsTypeAnnotation(decl))
|
|
3993
|
+
return false;
|
|
3994
|
+
// A generic clone retains its declared T contract. Its instantiated
|
|
3995
|
+
// record is also the factory's return/capture layout; it is not an
|
|
3996
|
+
// anonymous JavaScript object whose fields came only from inference.
|
|
3997
|
+
if (lowerer.typeParamResolver(lowerer.typeOf(decl.name)) !== null)
|
|
3998
|
+
return false;
|
|
3999
|
+
const symbol = lowerer.resolveValueSymbol(decl.name);
|
|
4000
|
+
const shape = lowerer.shapes.get(type.shapeId);
|
|
4001
|
+
if (!symbol || !shape)
|
|
4002
|
+
return false;
|
|
4003
|
+
const names = new Set(shape.fields.map((field) => field.name));
|
|
4004
|
+
let scope = decl;
|
|
4005
|
+
while (scope.parent && !ts.isFunctionLike(scope) && !ts.isSourceFile(scope))
|
|
4006
|
+
scope = scope.parent;
|
|
4007
|
+
const aliases = new Set([symbol]);
|
|
4008
|
+
const unwrap = (node) => {
|
|
4009
|
+
while (ts.isParenthesizedExpression(node))
|
|
4010
|
+
node = node.expression;
|
|
4011
|
+
return node;
|
|
4012
|
+
};
|
|
4013
|
+
let changed = true;
|
|
4014
|
+
while (changed) {
|
|
4015
|
+
changed = false;
|
|
4016
|
+
const collect = (node) => {
|
|
4017
|
+
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer && !node.type && !hasJsTypeAnnotation(node)) {
|
|
4018
|
+
const source = unwrap(node.initializer);
|
|
4019
|
+
const sourceSymbol = ts.isIdentifier(source) ? lowerer.resolveValueSymbol(source) : undefined;
|
|
4020
|
+
const alias = lowerer.resolveValueSymbol(node.name);
|
|
4021
|
+
if (sourceSymbol && aliases.has(sourceSymbol) && alias && !aliases.has(alias)) {
|
|
4022
|
+
aliases.add(alias);
|
|
4023
|
+
changed = true;
|
|
4024
|
+
}
|
|
4025
|
+
}
|
|
4026
|
+
ts.forEachChild(node, collect);
|
|
4027
|
+
};
|
|
4028
|
+
collect(scope);
|
|
4029
|
+
}
|
|
4030
|
+
let expands = false;
|
|
4031
|
+
const property = (node) => {
|
|
4032
|
+
if (!ts.isPropertyAccessExpression(node) && !ts.isElementAccessExpression(node))
|
|
4033
|
+
return undefined;
|
|
4034
|
+
const receiver = unwrap(node.expression);
|
|
4035
|
+
const receiverSymbol = ts.isIdentifier(receiver) ? lowerer.resolveValueSymbol(receiver) : undefined;
|
|
4036
|
+
if (!receiverSymbol || !aliases.has(receiverSymbol))
|
|
4037
|
+
return undefined;
|
|
4038
|
+
if (ts.isPropertyAccessExpression(node))
|
|
4039
|
+
return node.name.text;
|
|
4040
|
+
return ts.isStringLiteral(node.argumentExpression) || ts.isNumericLiteral(node.argumentExpression)
|
|
4041
|
+
? node.argumentExpression.text : null;
|
|
4042
|
+
};
|
|
4043
|
+
const visit = (node) => {
|
|
4044
|
+
if (expands)
|
|
4045
|
+
return;
|
|
4046
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && node.operatorToken.kind <= ts.SyntaxKind.LastAssignment) {
|
|
4047
|
+
const name = property(node.left);
|
|
4048
|
+
if (name === null || (name !== undefined && !names.has(name)))
|
|
4049
|
+
expands = true;
|
|
4050
|
+
}
|
|
4051
|
+
if (ts.isDeleteExpression(node) && property(node.expression) !== undefined)
|
|
4052
|
+
expands = true;
|
|
4053
|
+
ts.forEachChild(node, visit);
|
|
4054
|
+
};
|
|
4055
|
+
visit(scope);
|
|
4056
|
+
return expands;
|
|
4057
|
+
}
|
|
4058
|
+
export function hasJsTypeAnnotation(decl) {
|
|
4059
|
+
const statement = decl.parent?.parent;
|
|
4060
|
+
return !!statement && /@type\b/.test(decl.getSourceFile().text.slice(statement.pos, decl.getStart()));
|
|
4061
|
+
}
|
|
3877
4062
|
function immediatelyGuardedAbsenceProbe(lowerer, decl) {
|
|
3878
4063
|
if (decl.type || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
3879
4064
|
return false;
|
|
@@ -3898,96 +4083,71 @@ function immediatelyGuardedAbsenceProbe(lowerer, decl) {
|
|
|
3898
4083
|
operand = operand.expression;
|
|
3899
4084
|
return ts.isIdentifier(operand) && lowerer.resolveValueSymbol(operand) === lowerer.resolveValueSymbol(decl.name);
|
|
3900
4085
|
}
|
|
3901
|
-
function
|
|
4086
|
+
function falsyExitRuntimeOptionalLocals(lowerer, stmt) {
|
|
3902
4087
|
if (stmt.elseStatement)
|
|
3903
|
-
return
|
|
3904
|
-
let
|
|
3905
|
-
while (ts.
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
const local = lowerer.resolveLocal(operand);
|
|
3915
|
-
if (!local || !lowerer.runtimeOptionalLocals.has(lowerer.runtimeOptionalRootOf(local)))
|
|
3916
|
-
return null;
|
|
3917
|
-
const exits = ts.isReturnStatement(stmt.thenStatement) || ts.isThrowStatement(stmt.thenStatement) ||
|
|
3918
|
-
(ts.isBlock(stmt.thenStatement) && stmt.thenStatement.statements.length > 0 &&
|
|
3919
|
-
(ts.isReturnStatement(stmt.thenStatement.statements[stmt.thenStatement.statements.length - 1]) ||
|
|
3920
|
-
ts.isThrowStatement(stmt.thenStatement.statements[stmt.thenStatement.statements.length - 1])));
|
|
3921
|
-
return exits ? local : null;
|
|
4088
|
+
return [];
|
|
4089
|
+
let tail = stmt.thenStatement;
|
|
4090
|
+
while (ts.isBlock(tail)) {
|
|
4091
|
+
const last = tail.statements[tail.statements.length - 1];
|
|
4092
|
+
if (!last)
|
|
4093
|
+
return [];
|
|
4094
|
+
tail = last;
|
|
4095
|
+
}
|
|
4096
|
+
const exits = ts.isReturnStatement(tail) || ts.isThrowStatement(tail) ||
|
|
4097
|
+
ts.isContinueStatement(tail) || ts.isBreakStatement(tail);
|
|
4098
|
+
return exits ? runtimeOptionalGuardIds(lowerer, stmt.expression, false) : [];
|
|
3922
4099
|
}
|
|
3923
4100
|
/** JS-exact switch (see docs/ir.md): one shared lexical scope for all case
|
|
3924
4101
|
* bodies, lazy source-order test evaluation, fall-through. tsc has already
|
|
3925
4102
|
* checked case-test comparability (TS2678) — the kind check below is the
|
|
3926
4103
|
* backstop for cases tsc lets through (e.g. `unknown as` casts). */
|
|
3927
4104
|
export function lowerSwitch(lowerer, stmt) {
|
|
3928
|
-
//
|
|
3929
|
-
//
|
|
3930
|
-
// point — labeled jumps naming this switch fence at the jump).
|
|
4105
|
+
// Consume labels before a nested statement can claim them. All switch
|
|
4106
|
+
// forms keep their own break target, including union comparisons.
|
|
3931
4107
|
const labels = lowerer.takeLabels();
|
|
3932
4108
|
const disc = lowerer.lowerExpr(stmt.expression);
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
4109
|
+
return withRuntimeOptionalNarrowed(lowerer, runtimeOptionalGuardIds(lowerer, stmt.expression, null), () => {
|
|
4110
|
+
const dk = disc.type.kind;
|
|
4111
|
+
if (dk === "dyn")
|
|
4112
|
+
return lowerDynSwitch(lowerer, stmt, disc, labels);
|
|
4113
|
+
if (dk === "union")
|
|
4114
|
+
return lowerUnionSwitch(lowerer, stmt, disc, labels);
|
|
4115
|
+
if (dk !== "f64" && dk !== "string" && dk !== "bool") {
|
|
4116
|
+
lowerer.unsupported("SC1090", stmt.expression, "switch on non-primitive values");
|
|
4117
|
+
}
|
|
4118
|
+
// The whole case-body sequence is ONE lexical scope in JS: a bare `let`
|
|
4119
|
+
// in one case is visible in later cases.
|
|
4120
|
+
lowerer.scopes.push(new Map());
|
|
4121
|
+
try {
|
|
4122
|
+
const cases = [];
|
|
4123
|
+
for (const clause of stmt.caseBlock.clauses) {
|
|
4124
|
+
let test = null;
|
|
4125
|
+
if (ts.isCaseClause(clause)) {
|
|
4126
|
+
test = lowerer.lowerExpr(clause.expression);
|
|
4127
|
+
if (test.type.kind !== dk) {
|
|
4128
|
+
lowerer.unsupported("SC1090", clause.expression, "switch case tests of a different type than the discriminant");
|
|
4129
|
+
}
|
|
3952
4130
|
}
|
|
4131
|
+
cases.push({ test, body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels) });
|
|
3953
4132
|
}
|
|
3954
|
-
|
|
4133
|
+
return { kind: "switch", disc, cases, ...(labels && { labels }), loc: locOf(stmt) };
|
|
3955
4134
|
}
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
}
|
|
4135
|
+
finally {
|
|
4136
|
+
lowerer.scopes.pop();
|
|
4137
|
+
}
|
|
4138
|
+
});
|
|
3961
4139
|
}
|
|
3962
|
-
/**
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
* primitives only. The desugar is JS-exact for the shape it accepts and
|
|
3967
|
-
* fences everything it cannot reproduce:
|
|
3968
|
-
* - the discriminant evaluates exactly once; effectful values stabilize
|
|
3969
|
-
* in a hidden local that every generated equality test reuses;
|
|
3970
|
-
* - tests evaluate lazily in source order (the chain's short-circuit IS
|
|
3971
|
-
* the switch's test order — grouped empty cases `case a: case b:` OR
|
|
3972
|
-
* their tests, still in order);
|
|
3973
|
-
* - each non-final clause must EXIT (a trailing unconditional break —
|
|
3974
|
-
* dropped, it's the chain's own exit — or a return/throw/continue):
|
|
3975
|
-
* real fall-through between bodies has no if/else shape;
|
|
3976
|
-
* - any OTHER unlabeled break binding to this switch (a conditional
|
|
3977
|
-
* early break) is fenced — desugared, it would bind to an enclosing
|
|
3978
|
-
* loop instead;
|
|
3979
|
-
* - `default` may sit anywhere in source (JS tests every case first;
|
|
3980
|
-
* the chain's final else reproduces that as long as its body exits or
|
|
3981
|
-
* is last).
|
|
3982
|
-
* Case bodies share ONE lexical scope, exactly like the real switch. */
|
|
3983
|
-
function lowerUnionSwitch(lowerer, stmt, disc) {
|
|
4140
|
+
/** Compare a union discriminant through a boolean switch. The native switch
|
|
4141
|
+
* already implements lazy case tests, shared scope, fallthrough and jumps;
|
|
4142
|
+
* keeping that control-flow node avoids rebinding an early break to a loop. */
|
|
4143
|
+
function lowerUnionSwitch(lowerer, stmt, disc, labels) {
|
|
3984
4144
|
if (disc.type.kind !== "union")
|
|
3985
4145
|
throw new InternalCompilerError("lowerer bug: non-union disc");
|
|
3986
4146
|
const unionType = disc.type;
|
|
3987
4147
|
if (!lowerer.eqComparableUnion(unionType.unionId)) {
|
|
3988
4148
|
lowerer.unsupported("SC1090", stmt.expression, "switch on a union whose arms do not have static equality");
|
|
3989
4149
|
}
|
|
3990
|
-
return lowerBranchSwitch(lowerer, stmt, disc, (stableDisc, test, expression) => {
|
|
4150
|
+
return lowerBranchSwitch(lowerer, stmt, disc, labels, (stableDisc, test, expression) => {
|
|
3991
4151
|
const unitTest = test.kind === "unitLit"
|
|
3992
4152
|
? lowerer.lowerUnitComparison(stableDisc, test, false, locOf(expression))
|
|
3993
4153
|
: null;
|
|
@@ -4006,8 +4166,8 @@ function lowerUnionSwitch(lowerer, stmt, disc) {
|
|
|
4006
4166
|
/** A checked-dynamic switch whose tests have native strict-equality
|
|
4007
4167
|
* answers. Scalar tests use dynScalarEq; null/undefined use dyn kind tests.
|
|
4008
4168
|
* Other case values retain the existing unknown-switch fence. */
|
|
4009
|
-
function lowerDynSwitch(lowerer, stmt, disc) {
|
|
4010
|
-
return lowerBranchSwitch(lowerer, stmt, disc, (stableDisc, test, expression) => {
|
|
4169
|
+
function lowerDynSwitch(lowerer, stmt, disc, labels) {
|
|
4170
|
+
return lowerBranchSwitch(lowerer, stmt, disc, labels, (stableDisc, test, expression) => {
|
|
4011
4171
|
if (test.kind === "unitLit") {
|
|
4012
4172
|
return { kind: "dynTest", test: test.unit, value: stableDisc, type: BOOL, loc: locOf(expression) };
|
|
4013
4173
|
}
|
|
@@ -4018,121 +4178,47 @@ function lowerDynSwitch(lowerer, stmt, disc) {
|
|
|
4018
4178
|
return { kind: "dynScalarEq", left: stableDisc, right: test, type: BOOL, loc: locOf(expression) };
|
|
4019
4179
|
});
|
|
4020
4180
|
}
|
|
4021
|
-
function lowerBranchSwitch(lowerer, stmt, disc, compare) {
|
|
4181
|
+
function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
4022
4182
|
const loc = locOf(stmt);
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
const
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
ts.isFunctionLike(node)) {
|
|
4042
|
-
return null;
|
|
4043
|
-
}
|
|
4044
|
-
return ts.forEachChild(node, findStrayBreak) ?? null;
|
|
4045
|
-
};
|
|
4046
|
-
for (const clause of clauses) {
|
|
4047
|
-
const last = clause.statements[clause.statements.length - 1];
|
|
4048
|
-
for (const s of clause.statements) {
|
|
4049
|
-
const stray = s === last && ts.isBreakStatement(s) && !s.label ? null : findStrayBreak(s);
|
|
4050
|
-
if (stray) {
|
|
4051
|
-
lowerer.unsupported("SC1090", stray, "early 'break' inside a union-typed switch (only a trailing break exits the desugared chain — restructure with if/else)");
|
|
4052
|
-
}
|
|
4053
|
-
}
|
|
4054
|
-
}
|
|
4055
|
-
const statementExits = (last) => {
|
|
4056
|
-
if (!last)
|
|
4057
|
-
return false;
|
|
4058
|
-
if ((ts.isBreakStatement(last) && !last.label) ||
|
|
4059
|
-
ts.isReturnStatement(last) ||
|
|
4060
|
-
ts.isThrowStatement(last) ||
|
|
4061
|
-
ts.isContinueStatement(last))
|
|
4062
|
-
return true;
|
|
4063
|
-
return ts.isBlock(last) && statementExits(last.statements[last.statements.length - 1]);
|
|
4064
|
-
};
|
|
4065
|
-
const exits = (clause) => {
|
|
4066
|
-
const last = clause.statements[clause.statements.length - 1];
|
|
4067
|
-
return statementExits(last);
|
|
4068
|
-
};
|
|
4069
|
-
// The whole case-body sequence is ONE lexical scope, like the real
|
|
4070
|
-
// switch lowering.
|
|
4183
|
+
// Even a plain variable must be snapshotted: a case expression can write
|
|
4184
|
+
// it before the next comparison, without changing the switch value.
|
|
4185
|
+
const temp = lowerer.declareHiddenLocal("%switch", disc.type);
|
|
4186
|
+
const stableDisc = varRef(temp.id, disc.type, loc);
|
|
4187
|
+
// Calls/assignments in a case test may mutate a captured discriminant
|
|
4188
|
+
// binding. The checker still narrows that binding as if it were the
|
|
4189
|
+
// snapshot. Keep the original tagged value in those case bodies.
|
|
4190
|
+
const effectful = stmt.caseBlock.clauses.some((clause) => ts.isCaseClause(clause) &&
|
|
4191
|
+
!ts.isStringLiteral(clause.expression) && !ts.isNumericLiteral(clause.expression) &&
|
|
4192
|
+
!ts.isIdentifier(clause.expression) && clause.expression.kind !== ts.SyntaxKind.NullKeyword &&
|
|
4193
|
+
clause.expression.kind !== ts.SyntaxKind.TrueKeyword && clause.expression.kind !== ts.SyntaxKind.FalseKeyword);
|
|
4194
|
+
let binding = stmt.expression;
|
|
4195
|
+
while (ts.isParenthesizedExpression(binding))
|
|
4196
|
+
binding = binding.expression;
|
|
4197
|
+
const symbol = effectful && ts.isIdentifier(binding) ? lowerer.resolveValueSymbol(binding) : undefined;
|
|
4198
|
+
const alreadyUnstable = symbol != null && lowerer.unstableSwitchBindings.has(symbol);
|
|
4199
|
+
if (symbol)
|
|
4200
|
+
lowerer.unstableSwitchBindings.add(symbol);
|
|
4071
4201
|
lowerer.scopes.push(new Map());
|
|
4072
4202
|
try {
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
!isSafeToRepeat(test)) {
|
|
4088
|
-
lowerer.unsupported("SC1090", clause.expression, "effectful case tests in a union-typed switch (bind the test value to a const first)");
|
|
4089
|
-
}
|
|
4090
|
-
// A unit-literal test takes the unit-comparison lowering: a tag
|
|
4091
|
-
// test when the arm exists, the constant FALSE when the union
|
|
4092
|
-
// lacks it (`case null:` on a `number | undefined` — legal TS,
|
|
4093
|
-
// never matches; coercing the literal into the union would hit
|
|
4094
|
-
// the stranded-arm trap and throw where JS just skips the case).
|
|
4095
|
-
pendingTests.push(compare(stableDisc, test, clause.expression));
|
|
4096
|
-
}
|
|
4097
|
-
const isDefault = ts.isDefaultClause(clause);
|
|
4098
|
-
if (clause.statements.length === 0 && !isDefault && i < clauses.length - 1) {
|
|
4099
|
-
continue; // grouped with the next clause
|
|
4100
|
-
}
|
|
4101
|
-
if (!exits(clause) && i < clauses.length - 1 && (clause.statements.length > 0 || isDefault)) {
|
|
4102
|
-
// A non-final body that doesn't exit falls into the NEXT body in
|
|
4103
|
-
// JS — no if/else shape reproduces that (an EMPTY non-final
|
|
4104
|
-
// default falls through too; empty non-final cases just group).
|
|
4105
|
-
lowerer.unsupported("SC1090", clause, "fall-through between case bodies in a union-typed switch (end each case with break/return/throw/continue)");
|
|
4106
|
-
}
|
|
4107
|
-
const last = clause.statements[clause.statements.length - 1];
|
|
4108
|
-
const stmts = last && ts.isBreakStatement(last)
|
|
4109
|
-
? clause.statements.slice(0, -1)
|
|
4110
|
-
: clause.statements.slice();
|
|
4111
|
-
const body = lowerer.lowerStmts(stmts);
|
|
4112
|
-
groups.push({ tests: pendingTests, body, isDefault });
|
|
4113
|
-
pendingTests = [];
|
|
4114
|
-
}
|
|
4115
|
-
// A default clause anywhere lands in the chain's final else; JS
|
|
4116
|
-
// reaches it only after every case test fails, which the chain
|
|
4117
|
-
// reproduces because default bodies that don't exit were fenced
|
|
4118
|
-
// above (unless last in source, where falling out is falling out).
|
|
4119
|
-
const defaultBody = groups.find((g) => g.isDefault)?.body ?? null;
|
|
4120
|
-
const caseGroups = groups.filter((g) => !g.isDefault);
|
|
4121
|
-
let chain = defaultBody ?? [];
|
|
4122
|
-
for (let i = caseGroups.length - 1; i >= 0; i--) {
|
|
4123
|
-
const g = caseGroups[i];
|
|
4124
|
-
let cond = g.tests[0];
|
|
4125
|
-
if (!cond)
|
|
4126
|
-
continue; // a default-adjacent group with no tests (defensive)
|
|
4127
|
-
for (const t of g.tests.slice(1)) {
|
|
4128
|
-
cond = { kind: "logical", op: "||", left: cond, right: t, type: BOOL, loc };
|
|
4129
|
-
}
|
|
4130
|
-
chain = [{ kind: "if", cond, then: g.body, else_: chain.length > 0 ? chain : null, loc }];
|
|
4131
|
-
}
|
|
4132
|
-
return { kind: "block", body: [...prefix, ...chain], loc };
|
|
4203
|
+
const cases = stmt.caseBlock.clauses.map((clause) => ({
|
|
4204
|
+
test: ts.isCaseClause(clause)
|
|
4205
|
+
? compare(stableDisc, lowerer.lowerExpr(clause.expression), clause.expression)
|
|
4206
|
+
: null,
|
|
4207
|
+
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels),
|
|
4208
|
+
}));
|
|
4209
|
+
return {
|
|
4210
|
+
kind: "block",
|
|
4211
|
+
body: [
|
|
4212
|
+
{ kind: "varDecl", localId: temp.id, init: disc, loc },
|
|
4213
|
+
{ kind: "switch", disc: { kind: "boolLit", value: true, type: BOOL, loc }, cases, ...(labels && { labels }), loc },
|
|
4214
|
+
],
|
|
4215
|
+
loc,
|
|
4216
|
+
};
|
|
4133
4217
|
}
|
|
4134
4218
|
finally {
|
|
4135
4219
|
lowerer.scopes.pop();
|
|
4220
|
+
if (symbol && !alreadyUnstable)
|
|
4221
|
+
lowerer.unstableSwitchBindings.delete(symbol);
|
|
4136
4222
|
}
|
|
4137
4223
|
}
|
|
4138
4224
|
/** try/catch/finally:
|
|
@@ -4186,6 +4272,28 @@ export function lowerTry(lowerer, stmt) {
|
|
|
4186
4272
|
loc: locOf(stmt),
|
|
4187
4273
|
};
|
|
4188
4274
|
}
|
|
4275
|
+
function hasUseStrictDirective(statements) {
|
|
4276
|
+
for (const statement of statements) {
|
|
4277
|
+
if (!ts.isExpressionStatement(statement) || !ts.isStringLiteral(statement.expression))
|
|
4278
|
+
return false;
|
|
4279
|
+
if (statement.expression.text === "use strict")
|
|
4280
|
+
return true;
|
|
4281
|
+
}
|
|
4282
|
+
return false;
|
|
4283
|
+
}
|
|
4284
|
+
function isStrictDelete(node) {
|
|
4285
|
+
for (let parent = node.parent; parent; parent = parent.parent) {
|
|
4286
|
+
if (ts.isClassDeclaration(parent) || ts.isClassExpression(parent))
|
|
4287
|
+
return true;
|
|
4288
|
+
if (ts.isFunctionLike(parent) && parent.body && ts.isBlock(parent.body) && hasUseStrictDirective(parent.body.statements))
|
|
4289
|
+
return true;
|
|
4290
|
+
if (ts.isSourceFile(parent)) {
|
|
4291
|
+
return hasUseStrictDirective(parent.statements) ||
|
|
4292
|
+
(!isCjsJsFile(parent) && (isNodeEsmFile(parent) || ts.isExternalModule(parent)));
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
4295
|
+
return false;
|
|
4296
|
+
}
|
|
4189
4297
|
/** Statement-position `delete`: process.env keys → process.envUnset
|
|
4190
4298
|
* (unsetenv), pure `Record<string, T>` keys → recordKeyDelete (the
|
|
4191
4299
|
* overflow Map delete), declared OPTIONAL fields → the undefined-arm
|
|
@@ -4201,12 +4309,24 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4201
4309
|
lowerer.unsupported("SC1090", expr, "'delete' of non-property expressions");
|
|
4202
4310
|
}
|
|
4203
4311
|
fenceNodeModuleMutation(lowerer, target, "delete");
|
|
4312
|
+
if (ts.isPropertyAccessExpression(target) && target.name.text === "cause") {
|
|
4313
|
+
const field = lowerer.fieldTarget(target);
|
|
4314
|
+
if (field?.container === "errorCause") {
|
|
4315
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "error.deleteCause", args: [field.obj], type: VOID, loc }, loc };
|
|
4316
|
+
}
|
|
4317
|
+
}
|
|
4318
|
+
const globalKey = ts.isElementAccessExpression(target) ? globalSymbolKey(lowerer, target.expression, target.argumentExpression) : null;
|
|
4319
|
+
if (globalKey)
|
|
4320
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.globalSymbolDelete", args: [globalKey], type: VOID, loc }, loc };
|
|
4204
4321
|
const lowerKey = () => {
|
|
4205
4322
|
if (ts.isPropertyAccessExpression(target)) {
|
|
4206
4323
|
return { kind: "strLit", value: target.name.text, type: STRING, loc: locOf(target.name) };
|
|
4207
4324
|
}
|
|
4208
4325
|
const keyNode = target.argumentExpression;
|
|
4209
|
-
let key = lowerer.lowerExpr(keyNode);
|
|
4326
|
+
let key = lowerer.isProcessEnv(target.expression) ? lowerEnvironmentKey(lowerer, keyNode) : lowerer.lowerExpr(keyNode);
|
|
4327
|
+
if (key.type.kind === "dyn") {
|
|
4328
|
+
key = { kind: "libCall", fn: "dyn.toStringCoerce", args: [key], type: STRING, loc: key.loc };
|
|
4329
|
+
}
|
|
4210
4330
|
if (lowerer.runtimeOptionalWidening(key.type, STRING) !== null) {
|
|
4211
4331
|
key = lowerer.ensureString(key, keyNode);
|
|
4212
4332
|
}
|
|
@@ -4222,7 +4342,18 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4222
4342
|
loc,
|
|
4223
4343
|
};
|
|
4224
4344
|
}
|
|
4225
|
-
|
|
4345
|
+
let obj = lowerer.lowerExpr(target.expression);
|
|
4346
|
+
if (isJsSourceFile(expr.getSourceFile()) && obj.type.kind === "func" && lowerer.dynConvertible(obj.type)) {
|
|
4347
|
+
obj = lowerer.coerceToExpected(obj, DYN);
|
|
4348
|
+
}
|
|
4349
|
+
if (obj.type.kind === "dyn") {
|
|
4350
|
+
const strict = { kind: "boolLit", value: isStrictDelete(expr), type: BOOL, loc };
|
|
4351
|
+
if (ts.isElementAccessExpression(target)) {
|
|
4352
|
+
const key = lowerer.lowerExprExpecting(target.argumentExpression, DYN);
|
|
4353
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keyDeleteComputed", args: [obj, key, strict], type: VOID, loc }, loc };
|
|
4354
|
+
}
|
|
4355
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keyDelete", args: [obj, lowerKey(), strict], type: VOID, loc }, loc };
|
|
4356
|
+
}
|
|
4226
4357
|
if (obj.type.kind === "record") {
|
|
4227
4358
|
const shape = lowerer.shapes.get(obj.type.shapeId);
|
|
4228
4359
|
if (shape?.indexValue && shape.fields.length === 0 && !shape.tuple) {
|
|
@@ -4257,40 +4388,6 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4257
4388
|
}
|
|
4258
4389
|
lowerer.unsupported("SC1090", expr, `'delete' on '${lowerer.fmt(obj.type)}' receivers (process.env keys and pure Record<string, T> keys delete)`);
|
|
4259
4390
|
}
|
|
4260
|
-
/** The exact `Object.defineProperty(exports|module.exports, "__esModule",
|
|
4261
|
-
* { value: true })` interop stamp (see the no-op lowering above). */
|
|
4262
|
-
function isEsModuleStamp(expr) {
|
|
4263
|
-
if (!ts.isCallExpression(expr) || expr.questionDotToken !== undefined)
|
|
4264
|
-
return false;
|
|
4265
|
-
const callee = expr.expression;
|
|
4266
|
-
if (!ts.isPropertyAccessExpression(callee) ||
|
|
4267
|
-
!ts.isIdentifier(callee.expression) ||
|
|
4268
|
-
callee.expression.text !== "Object" ||
|
|
4269
|
-
!ts.isIdentifier(callee.name) ||
|
|
4270
|
-
callee.name.text !== "defineProperty") {
|
|
4271
|
-
return false;
|
|
4272
|
-
}
|
|
4273
|
-
if (expr.arguments.length !== 3)
|
|
4274
|
-
return false;
|
|
4275
|
-
const [recv, nameArg, desc] = expr.arguments;
|
|
4276
|
-
const isExports = (ts.isIdentifier(recv) && recv.text === "exports") ||
|
|
4277
|
-
(ts.isPropertyAccessExpression(recv) &&
|
|
4278
|
-
ts.isIdentifier(recv.expression) &&
|
|
4279
|
-
recv.expression.text === "module" &&
|
|
4280
|
-
ts.isIdentifier(recv.name) &&
|
|
4281
|
-
recv.name.text === "exports");
|
|
4282
|
-
if (!isExports)
|
|
4283
|
-
return false;
|
|
4284
|
-
if (!ts.isStringLiteral(nameArg) || nameArg.text !== "__esModule")
|
|
4285
|
-
return false;
|
|
4286
|
-
if (!ts.isObjectLiteralExpression(desc) || desc.properties.length !== 1)
|
|
4287
|
-
return false;
|
|
4288
|
-
const p = desc.properties[0];
|
|
4289
|
-
return (ts.isPropertyAssignment(p) &&
|
|
4290
|
-
ts.isIdentifier(p.name) &&
|
|
4291
|
-
p.name.text === "value" &&
|
|
4292
|
-
p.initializer.kind === ts.SyntaxKind.TrueKeyword);
|
|
4293
|
-
}
|
|
4294
4391
|
/** A top-level CommonJS export statement (see cjsExportAssignmentOf):
|
|
4295
4392
|
* `exports.f = <expr>` and each expression-valued property of
|
|
4296
4393
|
* `module.exports = { ... }` assign their pre-registered export globals
|
|
@@ -4630,7 +4727,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4630
4727
|
}
|
|
4631
4728
|
}
|
|
4632
4729
|
// `yield* inner();` — statement-position delegation desugars to the
|
|
4633
|
-
// forwarding loop (lower-generators)
|
|
4730
|
+
// forwarding loop (lower-generators), dropping the completed value.
|
|
4634
4731
|
{
|
|
4635
4732
|
const delegated = lowerYieldStarStatement(lowerer, expr);
|
|
4636
4733
|
if (delegated)
|
|
@@ -4686,7 +4783,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4686
4783
|
// site (message with the one-entry require stack), CATCHABLE — the
|
|
4687
4784
|
// optional-dependency try/require pattern. The compiled statement
|
|
4688
4785
|
// IS that throw, wherever it sits.
|
|
4689
|
-
if (isCjsJsFile(sf)) {
|
|
4786
|
+
if (isCjsJsFile(sf, lowerer.program)) {
|
|
4690
4787
|
if (!isRelativeSpecifier(spec) &&
|
|
4691
4788
|
canonicalBuiltinModule(spec) === null) {
|
|
4692
4789
|
const refusal = probeNodeRequireRefusal(sf.fileName, spec);
|
|
@@ -4706,7 +4803,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4706
4803
|
}
|
|
4707
4804
|
}
|
|
4708
4805
|
}
|
|
4709
|
-
if (isCjsJsFile(sf)) {
|
|
4806
|
+
if (isCjsJsFile(sf, lowerer.program)) {
|
|
4710
4807
|
const init = lowerer.requireInitStmt(spec, expr);
|
|
4711
4808
|
if (init)
|
|
4712
4809
|
return init;
|
|
@@ -4761,6 +4858,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4761
4858
|
};
|
|
4762
4859
|
}
|
|
4763
4860
|
if (opKind === ts.SyntaxKind.EqualsToken) {
|
|
4861
|
+
const callableWrite = lowerNativeFunctionAssignment(lowerer, expr);
|
|
4862
|
+
if (callableWrite)
|
|
4863
|
+
return { kind: "exprStmt", expr: callableWrite, loc: locOf(expr) };
|
|
4764
4864
|
// Expando function members (`foo.bar = 12`, `foo[SYM] = v` on a
|
|
4765
4865
|
// module-level function/callable const): the member's module
|
|
4766
4866
|
// global (lower-expando.ts) — claimed by symbol identity before
|
|
@@ -4878,13 +4978,20 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4878
4978
|
// SUBCLASS name (`D.x = v` creates an OWN property on D in JS —
|
|
4879
4979
|
// different storage) and through class VALUES (the same dynamic
|
|
4880
4980
|
// story) are named fences, never a silently-wrong global write.
|
|
4881
|
-
if (!expr.left.questionDotToken && ts.isIdentifier(expr.left.expression)) {
|
|
4981
|
+
if (!expr.left.questionDotToken && (ts.isIdentifier(expr.left.expression) || expr.left.expression.kind === ts.SyntaxKind.ThisKeyword)) {
|
|
4882
4982
|
// The receiver must BE the class exactly (its name, or a
|
|
4883
4983
|
// const binding holding a class expression) — a general class
|
|
4884
4984
|
// VALUE could hold a subclass, where JS creates an own
|
|
4885
4985
|
// property instead of writing this storage.
|
|
4886
4986
|
const classInfo = lowerer.exactClassOfReceiver(expr.left.expression);
|
|
4887
4987
|
if (classInfo) {
|
|
4988
|
+
const data = classStaticDataFor(lowerer, classInfo, expr.left.name.text, locOf(expr.left));
|
|
4989
|
+
if (data) {
|
|
4990
|
+
const loc = locOf(expr);
|
|
4991
|
+
const key = { kind: "strLit", value: expr.left.name.text, type: STRING, loc };
|
|
4992
|
+
const value = lowerer.lowerExprExpecting(expr.right, DYN);
|
|
4993
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keySet", args: [data, key, value], type: VOID, loc }, loc };
|
|
4994
|
+
}
|
|
4888
4995
|
const found = lowerer.findStaticOn(classInfo, expr.left.name.text);
|
|
4889
4996
|
if (found?.field !== undefined) {
|
|
4890
4997
|
if (found.declarer !== classInfo) {
|
|
@@ -4985,17 +5092,38 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4985
5092
|
if (viaStream)
|
|
4986
5093
|
return viaStream;
|
|
4987
5094
|
}
|
|
5095
|
+
const unionWrite = lowerUnionFieldWrite(lowerer, expr.left, expr.right);
|
|
5096
|
+
if (unionWrite)
|
|
5097
|
+
return unionWrite;
|
|
4988
5098
|
const target = lowerer.fieldTarget(expr.left);
|
|
4989
5099
|
if (target) {
|
|
4990
5100
|
const value = lowerer.lowerExprExpecting(expr.right, target.fieldType);
|
|
4991
5101
|
return lowerer.fieldSetStmt(target, value, locOf(expr), expr.left);
|
|
4992
5102
|
}
|
|
5103
|
+
const callback = lowerClassCallbackAssign(lowerer, expr);
|
|
5104
|
+
if (callback)
|
|
5105
|
+
return callback;
|
|
4993
5106
|
// A write to an ABSTRACT property through an abstract-typed
|
|
4994
5107
|
// receiver: the read fence's write twin (the declaration is
|
|
4995
5108
|
// erased at runtime — no shared slot exists to write).
|
|
4996
5109
|
if (abstractPropertyDeclOf(lowerer, expr.left)) {
|
|
4997
5110
|
lowerer.unsupported("SC1090", expr.left, `writing the abstract property '${expr.left.name.text}' through a '${lowerer.checker.typeToString(lowerer.typeOf(expr.left.expression))}'-typed receiver (abstract property declarations are erased at runtime, so no shared slot exists — type the receiver as the concrete class, or declare an abstract accessor pair instead)`);
|
|
4998
5111
|
}
|
|
5112
|
+
if (!expr.left.questionDotToken) {
|
|
5113
|
+
const recv = tryLowerExpression(lowerer, expr.left.expression);
|
|
5114
|
+
if (recv && isDynTypedRefType(recv.type)) {
|
|
5115
|
+
const info = lowerer.classes.get(recv.type.className);
|
|
5116
|
+
if (info && !info.def.runtime && !info.builtinError && !info.builtinEmitter && !info.builtinStream &&
|
|
5117
|
+
!isCompiledPrototypeMember(lowerer, info, expr.left.name.text)) {
|
|
5118
|
+
const loc = locOf(expr);
|
|
5119
|
+
return { kind: "exprStmt", expr: {
|
|
5120
|
+
kind: "libCall", fn: "dyn.keySet", args: [lowerer.coerceToExpected(recv, DYN),
|
|
5121
|
+
{ kind: "strLit", value: expr.left.name.text, type: STRING, loc }, lowerer.lowerExprExpecting(expr.right, DYN)],
|
|
5122
|
+
type: VOID, loc,
|
|
5123
|
+
}, loc };
|
|
5124
|
+
}
|
|
5125
|
+
}
|
|
5126
|
+
}
|
|
4999
5127
|
// Dot WRITE to an undeclared key of an index-signature shape:
|
|
5000
5128
|
// the same deliberate fence as the dotted read, with the same
|
|
5001
5129
|
// fix in the message (brackets are the index-signature form).
|
|
@@ -5038,34 +5166,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5038
5166
|
lowerer.runtimeOptionalLocals.add(runtimeOptionalRoot);
|
|
5039
5167
|
return { kind: "assign", localId: target.id, value, loc: locOf(expr) };
|
|
5040
5168
|
}
|
|
5041
|
-
if (opKind === ts.SyntaxKind.QuestionQuestionEqualsToken
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
// assign-only-when-nullish is unobservable — the value written back
|
|
5045
|
-
// on the non-nullish path is the same box. Property targets keep a
|
|
5046
|
-
// distinct fence: accessors would make the always-write observable.
|
|
5047
|
-
if (!ts.isIdentifier(expr.left)) {
|
|
5048
|
-
lowerer.unsupported("SC1090", expr.left, "'??=' on non-variable targets (write it out: if (o.f === undefined) o.f = v)");
|
|
5049
|
-
}
|
|
5050
|
-
const target = lowerer.resolveWritable(expr.left);
|
|
5051
|
-
if (!target)
|
|
5052
|
-
lowerer.rejectUnresolved(expr.left, `assignment to '${expr.left.text}' (not a writable local or module global)`);
|
|
5053
|
-
const loc = locOf(expr);
|
|
5054
|
-
if (target.type.kind !== "union") {
|
|
5055
|
-
// The checker says never nullish: JS neither evaluates e nor
|
|
5056
|
-
// assigns — the statement is a no-op (lowerNullishCoalesce's
|
|
5057
|
-
// trust-the-checker fold, statement form).
|
|
5058
|
-
return { kind: "block", body: [], loc };
|
|
5059
|
-
}
|
|
5060
|
-
const def = lowerer.unions.get(target.type.unionId);
|
|
5061
|
-
if (!def)
|
|
5062
|
-
lowerer.badType(expr.left, lowerer.typeOf(expr.left));
|
|
5063
|
-
if (!def.arms.some(isUnitType))
|
|
5064
|
-
return { kind: "block", body: [], loc };
|
|
5065
|
-
const read = { kind: "varRef", localId: target.id, type: target.type, loc: locOf(expr.left) };
|
|
5066
|
-
const right = lowerer.lowerExprExpecting(expr.right, target.type);
|
|
5067
|
-
const value = { kind: "nullish", left: read, right, type: target.type, loc };
|
|
5068
|
-
return { kind: "assign", localId: target.id, value, loc };
|
|
5169
|
+
if (opKind === ts.SyntaxKind.QuestionQuestionEqualsToken ||
|
|
5170
|
+
opKind === ts.SyntaxKind.AmpersandAmpersandEqualsToken || opKind === ts.SyntaxKind.BarBarEqualsToken) {
|
|
5171
|
+
return { kind: "exprStmt", expr: lowerShortCircuitAssignment(lowerer, expr), loc: locOf(expr) };
|
|
5069
5172
|
}
|
|
5070
5173
|
const compound = COMPOUND_ASSIGN_OPS[opKind];
|
|
5071
5174
|
if (compound !== undefined) {
|
|
@@ -5104,8 +5207,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5104
5207
|
}
|
|
5105
5208
|
if (opKind >= ts.SyntaxKind.FirstCompoundAssignment &&
|
|
5106
5209
|
opKind <= ts.SyntaxKind.LastCompoundAssignment) {
|
|
5107
|
-
|
|
5108
|
-
lowerer.unsupported("SC1090", expr, "logical assignment (&&=, ||=) — write the if out");
|
|
5210
|
+
lowerer.unsupported("SC1090", expr, "this compound assignment operator");
|
|
5109
5211
|
}
|
|
5110
5212
|
}
|
|
5111
5213
|
if ((ts.isPrefixUnaryExpression(expr) || ts.isPostfixUnaryExpression(expr)) &&
|
|
@@ -5119,6 +5221,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5119
5221
|
// increment (the member's global IS the variable); expando
|
|
5120
5222
|
// function members (`foo.count++`) are module globals too.
|
|
5121
5223
|
if (ts.isPropertyAccessExpression(expr.operand) && !expr.operand.questionDotToken) {
|
|
5224
|
+
const staticTarget = staticFieldWriteTarget(lowerer, expr.operand);
|
|
5225
|
+
if (staticTarget)
|
|
5226
|
+
return lowerIncDecToTarget(lowerer, expr, staticTarget);
|
|
5122
5227
|
const exT = expandoWritableTarget(lowerer, expr.operand);
|
|
5123
5228
|
if (exT)
|
|
5124
5229
|
return lowerIncDecToTarget(lowerer, expr, exT);
|
|
@@ -5231,44 +5336,12 @@ function lowerIncDecToTarget(lowerer, expr, target) {
|
|
|
5231
5336
|
* identifier form and the namespace-qualified spelling (`N.x += v`),
|
|
5232
5337
|
* whose target is the member's module global. */
|
|
5233
5338
|
function lowerCompoundToTarget(lowerer, expr, compound, target) {
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
const JS_COMPOUND = { "+": "add", "-": "sub", "*": "mul", "/": "div", "%": "mod", "**": "pow" };
|
|
5241
|
-
const jop = JS_COMPOUND[compound];
|
|
5242
|
-
if (jop === undefined)
|
|
5243
|
-
lowerer.unsupported("SC1043", expr);
|
|
5244
|
-
const wrapped = {
|
|
5245
|
-
kind: "jsOp", op: jop,
|
|
5246
|
-
args: [lowerer.jsvalIn(read, expr.left), lowerer.jsvalIn(rhs, expr.right)],
|
|
5247
|
-
type: JSVAL, loc,
|
|
5248
|
-
};
|
|
5249
|
-
value = lowerer.coerceInto(expr, wrapped, target.type);
|
|
5250
|
-
}
|
|
5251
|
-
else if (compound === "+" && target.type.kind === "string") {
|
|
5252
|
-
value = { kind: "strConcat", left: read, right: lowerer.ensureString(rhs, expr.right), type: STRING, loc };
|
|
5253
|
-
}
|
|
5254
|
-
else if (target.type.kind === "f64" && numericRhs.type.kind === "f64") {
|
|
5255
|
-
value = { kind: "bin", op: compound, left: read, right: numericRhs, type: F64, loc };
|
|
5256
|
-
}
|
|
5257
|
-
else if ((target.type.kind === "dyn" || rhs.type.kind === "dyn") &&
|
|
5258
|
-
(target.type.kind === "dyn" || target.type.kind === "f64") &&
|
|
5259
|
-
(rhs.type.kind === "dyn" || rhs.type.kind === "f64") &&
|
|
5260
|
-
isJsSourceFile(expr.getSourceFile())) {
|
|
5261
|
-
// JS any-origin operands: check to number and compute natively
|
|
5262
|
-
// (the binary-operator stance) — the dyn target takes the result
|
|
5263
|
-
// back through the usual dyn conversion.
|
|
5264
|
-
const checkNum = (e) => e.type.kind === "dyn" ? { kind: "dynCheck", value: e, type: F64, loc: e.loc } : e;
|
|
5265
|
-
const computed = { kind: "bin", op: compound, left: checkNum(read), right: checkNum(rhs), type: F64, loc };
|
|
5266
|
-
value = target.type.kind === "dyn" ? { kind: "dynFrom", value: computed, type: DYN, loc } : computed;
|
|
5267
|
-
}
|
|
5268
|
-
else {
|
|
5269
|
-
lowerer.unsupported("SC1043", expr);
|
|
5270
|
-
}
|
|
5271
|
-
return { kind: "assign", localId: target.id, value, loc };
|
|
5339
|
+
return {
|
|
5340
|
+
kind: "assign",
|
|
5341
|
+
localId: target.id,
|
|
5342
|
+
value: lowerCompoundValueToTarget(lowerer, expr, compound, target),
|
|
5343
|
+
loc: locOf(expr),
|
|
5344
|
+
};
|
|
5272
5345
|
}
|
|
5273
5346
|
/** One destructuring-assignment pattern the island can run: empty object/
|
|
5274
5347
|
* array patterns and flat identifier targets — shorthand `{ x }`,
|
|
@@ -5461,14 +5534,23 @@ export function lowerDestructuringAssign(lowerer, target, init, blame, loc) {
|
|
|
5461
5534
|
}
|
|
5462
5535
|
/** V8's spelling of a destructuring RHS in its TypeError message
|
|
5463
5536
|
* ("Cannot destructure 'a' as it is undefined.") — plain identifiers
|
|
5464
|
-
* spell their name (parens unwrap)
|
|
5465
|
-
*
|
|
5466
|
-
* fence at the caller. */
|
|
5537
|
+
* spell their name (parens unwrap), and calls append an ellipsis to a
|
|
5538
|
+
* supported callee spelling. Other CallPrinter forms keep a fence. */
|
|
5467
5539
|
function destrSpellingOf(rhs) {
|
|
5468
5540
|
let e = rhs;
|
|
5469
5541
|
while (ts.isParenthesizedExpression(e))
|
|
5470
5542
|
e = e.expression;
|
|
5471
|
-
|
|
5543
|
+
if (ts.isIdentifier(e))
|
|
5544
|
+
return e.text;
|
|
5545
|
+
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken) {
|
|
5546
|
+
const base = destrSpellingOf(e.expression);
|
|
5547
|
+
return base === null ? null : `${base}.${e.name.text}`;
|
|
5548
|
+
}
|
|
5549
|
+
if (ts.isCallExpression(e) && !e.questionDotToken) {
|
|
5550
|
+
const callee = destrSpellingOf(e.expression);
|
|
5551
|
+
return callee === null ? null : `${callee}(...)`;
|
|
5552
|
+
}
|
|
5553
|
+
return null;
|
|
5472
5554
|
}
|
|
5473
5555
|
/** Destructuring ASSIGNMENT (existing bindings — the declaration twin is
|
|
5474
5556
|
* lowerDestructuringDecl): the RHS evaluates ONCE into a hidden temp,
|
|
@@ -5570,7 +5652,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5570
5652
|
if (!checkedByInner) {
|
|
5571
5653
|
const spelling = rhs === null ? null : destrSpellingOf(rhs);
|
|
5572
5654
|
if (spelling === null) {
|
|
5573
|
-
lowerer.unsupported("SC1031", blame, "destructuring assignment from a checked-dynamic source
|
|
5655
|
+
lowerer.unsupported("SC1031", blame, "destructuring assignment from a checked-dynamic source whose expression spelling is unsupported (use a variable, ordinary property chain, or ordinary call)");
|
|
5574
5656
|
}
|
|
5575
5657
|
let firstProp;
|
|
5576
5658
|
const p0 = target.properties[0];
|
|
@@ -6294,10 +6376,11 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6294
6376
|
// desugars drop them — a labeled jump naming those loops fences at the
|
|
6295
6377
|
// jump site (no label point exists in their desugared shape).
|
|
6296
6378
|
const labels = lowerer.takeLabels();
|
|
6297
|
-
//
|
|
6298
|
-
// async
|
|
6299
|
-
//
|
|
6300
|
-
|
|
6379
|
+
// A synchronous array iterator is also valid in `for await`. Its values
|
|
6380
|
+
// take the async-from-sync path below; other async sources retain their
|
|
6381
|
+
// dedicated request protocols.
|
|
6382
|
+
const awaitArray = !!stmt.awaitModifier && lowerer.mapTypeOf(lowerer.typeOf(stmt.expression))?.kind === "array";
|
|
6383
|
+
if (stmt.awaitModifier && !awaitArray) {
|
|
6301
6384
|
{
|
|
6302
6385
|
const genT = lowerer.mapTypeOf(lowerer.typeOf(stmt.expression));
|
|
6303
6386
|
if (genT?.kind === "generator" && genT.async) {
|
|
@@ -6316,6 +6399,9 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6316
6399
|
return builtin;
|
|
6317
6400
|
lowerer.unsupported("SC1070", stmt, "'for await' over this value (supported: typed async generators, represented class async iterators, process.stdin, and Node/Web readable streams)");
|
|
6318
6401
|
}
|
|
6402
|
+
if (awaitArray && !lowerer.ctx.isAsync) {
|
|
6403
|
+
lowerer.unsupported("SC1090", stmt, "top-level 'for await' (await outside async functions)");
|
|
6404
|
+
}
|
|
6319
6405
|
lowerer.fenceStaticHeadersIteration(stmt.expression);
|
|
6320
6406
|
// A stored numeric value iterator declared in this function keeps its
|
|
6321
6407
|
// built-in protocol state in hidden locals (lowerVarStatement). The
|
|
@@ -6328,7 +6414,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6328
6414
|
if (ts.isIdentifier(src)) {
|
|
6329
6415
|
const sym = lowerer.resolveValueSymbol(src);
|
|
6330
6416
|
const state = sym ? lowerer.numericIterators.get(sym) : undefined;
|
|
6331
|
-
if (state
|
|
6417
|
+
if (state && state.ctx === lowerer.ctx) {
|
|
6332
6418
|
return lowerForOfStoredNumericIterator(lowerer, stmt, state, labels);
|
|
6333
6419
|
}
|
|
6334
6420
|
}
|
|
@@ -6445,16 +6531,20 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6445
6531
|
let iterable = lowerer.lowerExpr(iterSrc);
|
|
6446
6532
|
// A nested loop receiver can be an OOB-safe array read from the outer
|
|
6447
6533
|
// loop (`for (const row of grid) for (const cell of row)`). The checker
|
|
6448
|
-
// sees the inner value as an array, while its runtime slot
|
|
6449
|
-
// undefined
|
|
6534
|
+
// sees the inner value as an array, while its runtime slot retains
|
|
6535
|
+
// undefined. An Array.isArray guard can also select the array from a
|
|
6536
|
+
// node | node[] | undefined slot. Map lookups and optional fields also
|
|
6537
|
+
// retain nullable runtime slots after a guard selects a concrete
|
|
6538
|
+
// iterable. Validate the selected arm before choosing its iteration
|
|
6539
|
+
// protocol; unchecked null assertions still throw at runtime.
|
|
6450
6540
|
const checkerIterable = lowerer.mapTypeOf(lowerer.typeOf(iterSrc));
|
|
6451
|
-
if (iterable.type.kind === "union" &&
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6541
|
+
if (iterable.type.kind === "union" && checkerIterable !== null &&
|
|
6542
|
+
(checkerIterable.kind === "array" || checkerIterable.kind === "map" || checkerIterable.kind === "set" ||
|
|
6543
|
+
checkerIterable.kind === "bytes" || checkerIterable.kind === "string" || checkerIterable.kind === "searchParams" ||
|
|
6544
|
+
checkerIterable.kind === "generator" || checkerIterable.kind === "object")) {
|
|
6545
|
+
const helper = lowerer.narrowedArmHelper(iterable.type.unionId, checkerIterable, locOf(iterSrc));
|
|
6456
6546
|
if (helper)
|
|
6457
|
-
iterable = { kind: "call", callee: helper, args: [iterable], type:
|
|
6547
|
+
iterable = { kind: "call", callee: helper, args: [iterable], type: checkerIterable, loc: locOf(iterSrc) };
|
|
6458
6548
|
}
|
|
6459
6549
|
if (iterable.type.kind === "bytes") {
|
|
6460
6550
|
return lowerForOfBytes(lowerer, stmt, iterable, labels);
|
|
@@ -6572,8 +6662,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6572
6662
|
}
|
|
6573
6663
|
// A CHECKED-DYNAMIC iterable (`unknown[]`, the collapsed
|
|
6574
6664
|
// `(string | object)[]`, JSON-parsed values, wrapped engine
|
|
6575
|
-
// values):
|
|
6576
|
-
// hidden index loop binds each element as a dyn value.
|
|
6665
|
+
// values): a checked IteratorRecord binds each yielded dyn value.
|
|
6577
6666
|
if (iterable.type.kind === "dyn") {
|
|
6578
6667
|
return lowerForOfDyn(lowerer, stmt, iterable, labels);
|
|
6579
6668
|
}
|
|
@@ -6581,29 +6670,132 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6581
6670
|
lowerer.badType(stmt.expression, lowerer.typeOf(stmt.expression));
|
|
6582
6671
|
}
|
|
6583
6672
|
}
|
|
6584
|
-
const
|
|
6673
|
+
const yieldedT = arrayValueType(lowerer, iterable.type.elem);
|
|
6674
|
+
let elemValueT = yieldedT;
|
|
6675
|
+
let awaitPromiseTag = null;
|
|
6676
|
+
if (awaitArray) {
|
|
6677
|
+
let promiseElem = null;
|
|
6678
|
+
if (iterable.type.elem.kind === "promise") {
|
|
6679
|
+
promiseElem = iterable.type.elem;
|
|
6680
|
+
}
|
|
6681
|
+
else if (iterable.type.elem.kind === "union") {
|
|
6682
|
+
const arms = lowerer.unions.get(iterable.type.elem.unionId)?.arms;
|
|
6683
|
+
if (arms?.length === 2 && arms.some((arm) => arm.kind === "undefinedT")) {
|
|
6684
|
+
const arm = arms.find((candidate) => candidate.kind === "promise");
|
|
6685
|
+
if (arm?.kind === "promise")
|
|
6686
|
+
promiseElem = arm;
|
|
6687
|
+
}
|
|
6688
|
+
}
|
|
6689
|
+
const nonThenable = (type) => {
|
|
6690
|
+
if (type.kind === "union") {
|
|
6691
|
+
const arms = lowerer.unions.get(type.unionId)?.arms;
|
|
6692
|
+
return arms !== undefined && arms.every(nonThenable);
|
|
6693
|
+
}
|
|
6694
|
+
if (type.kind === "record") {
|
|
6695
|
+
const shape = lowerer.shapes.get(type.shapeId);
|
|
6696
|
+
return shape !== undefined && !shape.indexValue && !shape.fields.some((field) => field.name === "then");
|
|
6697
|
+
}
|
|
6698
|
+
return type.kind === "f64" || type.kind === "bigint" || type.kind === "string" ||
|
|
6699
|
+
type.kind === "bool" || type.kind === "symbol" || type.kind === "array" ||
|
|
6700
|
+
type.kind === "undefinedT" || type.kind === "nullT";
|
|
6701
|
+
};
|
|
6702
|
+
if (promiseElem && yieldedT.kind === "union" &&
|
|
6703
|
+
!["void", "union", "dyn", "jsval", "undefinedT", "nullT"].includes(promiseElem.inner.kind)) {
|
|
6704
|
+
awaitPromiseTag = lowerer.armTag(yieldedT.unionId, promiseElem);
|
|
6705
|
+
elemValueT = lowerer.withUndefinedArm(promiseElem.inner);
|
|
6706
|
+
}
|
|
6707
|
+
else if (!nonThenable(iterable.type.elem)) {
|
|
6708
|
+
lowerer.unsupported("SC1070", stmt.expression, "for-await over array values that may be promises or thenables");
|
|
6709
|
+
}
|
|
6710
|
+
}
|
|
6585
6711
|
// Native arrays retain their payload ABI; the loop binds the value yielded
|
|
6586
6712
|
// by Get, which is undefined for both holes and present undefined slots.
|
|
6587
6713
|
const sourceT = iterable.type;
|
|
6588
6714
|
const source = lowerer.declareHiddenLocal("%arrayIterator", sourceT);
|
|
6589
6715
|
const cursor = lowerer.declareHiddenLocal("%arrayCursor", F64);
|
|
6590
6716
|
cursor.mutable = true;
|
|
6591
|
-
const forValues = (localId, body) =>
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6717
|
+
const forValues = (localId, body) => {
|
|
6718
|
+
const loc = locOf(stmt);
|
|
6719
|
+
const needsClose = awaitArray ? lowerer.declareHiddenLocal("%arrayIteratorNeedsClose", BOOL) : null;
|
|
6720
|
+
if (needsClose)
|
|
6721
|
+
needsClose.mutable = true;
|
|
6722
|
+
const yielded = arrayValueRead(lowerer, varRef(source.id, sourceT, loc), varRef(cursor.id, F64, loc), sourceT.elem, loc);
|
|
6723
|
+
const init = awaitPromiseTag === null ? yielded : {
|
|
6724
|
+
kind: "awaitUnionExpr", value: yielded, promiseTag: awaitPromiseTag, type: elemValueT, loc,
|
|
6725
|
+
};
|
|
6726
|
+
const hops = awaitArray ? (awaitPromiseTag === null ? 2 : 1) : 0;
|
|
6727
|
+
const hop = () => ({
|
|
6728
|
+
kind: "exprStmt", expr: { kind: "libCall", fn: "async.hop", args: [], type: VOID, loc }, loc,
|
|
6729
|
+
});
|
|
6730
|
+
const nextError = awaitPromiseTag !== null ? lowerer.declareHiddenLocal("%arrayIteratorNextError", CAUGHT) : null;
|
|
6731
|
+
const awaitedValue = nextError ? lowerer.declareHiddenLocal("%arrayIteratorValue", elemValueT) : null;
|
|
6732
|
+
if (awaitedValue)
|
|
6733
|
+
awaitedValue.mutable = true;
|
|
6734
|
+
const readValue = awaitedValue
|
|
6735
|
+
? { kind: "assign", localId: awaitedValue.id, value: init, loc }
|
|
6736
|
+
: { kind: "varDecl", localId, init, loc };
|
|
6737
|
+
const nextValue = nextError ? {
|
|
6738
|
+
kind: "tryCatch",
|
|
6739
|
+
tryBody: [readValue],
|
|
6740
|
+
// Async-from-sync iteration has a continuation reaction between a
|
|
6741
|
+
// rejected element promise and the loop's rejected next result.
|
|
6742
|
+
catchBody: [hop(), { kind: "rethrow", localId: nextError.id, loc }],
|
|
6743
|
+
catchLocalId: nextError.id,
|
|
6744
|
+
finallyBody: null,
|
|
6745
|
+
loc,
|
|
6746
|
+
} : readValue;
|
|
6747
|
+
const length = () => ({
|
|
6748
|
+
kind: "arrIntrinsic", method: "length", receiver: varRef(source.id, sourceT, loc), args: [], type: F64, loc,
|
|
6749
|
+
});
|
|
6750
|
+
const loop = {
|
|
6751
|
+
kind: "for",
|
|
6752
|
+
init: { kind: "varDecl", localId: cursor.id, init: numLit(0, loc), loc },
|
|
6753
|
+
cond: awaitArray
|
|
6754
|
+
? { kind: "boolLit", value: true, type: BOOL, loc }
|
|
6755
|
+
: { kind: "bin", op: "<", left: varRef(cursor.id, F64, loc), right: length(), type: BOOL, loc },
|
|
6756
|
+
update: { kind: "assign", localId: cursor.id, value: { kind: "bin", op: "+", left: varRef(cursor.id, F64, loc), right: numLit(1, loc), type: F64, loc }, loc },
|
|
6757
|
+
body: [
|
|
6758
|
+
...(needsClose ? [{
|
|
6759
|
+
kind: "assign", localId: needsClose.id,
|
|
6760
|
+
value: { kind: "boolLit", value: false, type: BOOL, loc }, loc,
|
|
6761
|
+
}] : []),
|
|
6762
|
+
...(needsClose ? [{
|
|
6763
|
+
kind: "if",
|
|
6764
|
+
cond: { kind: "bin", op: ">=", left: varRef(cursor.id, F64, loc), right: length(), type: BOOL, loc },
|
|
6765
|
+
then: [hop(), hop(), { kind: "break", loc }],
|
|
6766
|
+
else_: null,
|
|
6767
|
+
loc,
|
|
6768
|
+
}] : []),
|
|
6769
|
+
...(awaitedValue ? [{ kind: "varDecl", localId: awaitedValue.id, init: null, loc }] : []),
|
|
6770
|
+
nextValue,
|
|
6771
|
+
...(awaitedValue ? [{ kind: "varDecl", localId, init: varRef(awaitedValue.id, elemValueT, loc), loc }] : []),
|
|
6772
|
+
...Array.from({ length: hops }, hop),
|
|
6773
|
+
// A rejected next value has no iterator close. Once a value has
|
|
6774
|
+
// arrived, an abrupt completion in the body does await close.
|
|
6775
|
+
...(needsClose ? [{
|
|
6776
|
+
kind: "assign", localId: needsClose.id,
|
|
6777
|
+
value: { kind: "boolLit", value: true, type: BOOL, loc }, loc,
|
|
6778
|
+
}] : []),
|
|
6779
|
+
...body,
|
|
6780
|
+
],
|
|
6781
|
+
...(labels && { labels }),
|
|
6782
|
+
loc,
|
|
6783
|
+
};
|
|
6784
|
+
return {
|
|
6785
|
+
kind: "block",
|
|
6786
|
+
body: [
|
|
6787
|
+
{ kind: "varDecl", localId: source.id, init: iterable, loc },
|
|
6788
|
+
...(needsClose ? [{ kind: "varDecl", localId: needsClose.id, init: { kind: "boolLit", value: false, type: BOOL, loc }, loc }] : []),
|
|
6789
|
+
needsClose ? {
|
|
6790
|
+
kind: "tryCatch",
|
|
6791
|
+
tryBody: [loop], catchBody: null, catchLocalId: null,
|
|
6792
|
+
finallyBody: [{ kind: "if", cond: varRef(needsClose.id, BOOL, loc), then: [hop()], else_: null, loc }],
|
|
6793
|
+
loc,
|
|
6794
|
+
} : loop,
|
|
6795
|
+
],
|
|
6796
|
+
loc,
|
|
6797
|
+
};
|
|
6798
|
+
};
|
|
6607
6799
|
if (!ts.isVariableDeclarationList(stmt.initializer)) {
|
|
6608
6800
|
// `for (x of xs)` over a PRE-DECLARED writable binding: JS assigns
|
|
6609
6801
|
// the existing binding once per pass — one shared binding across
|
|
@@ -6690,7 +6882,9 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6690
6882
|
return forValues(tmp.id, [write, ...body]);
|
|
6691
6883
|
}
|
|
6692
6884
|
const local = lowerer.declareLocal(decl.name, decl.name.text, elemValueT, isLet);
|
|
6693
|
-
|
|
6885
|
+
const declaredElement = lowerer.mapTypeOf(lowerer.typeOf(decl.name));
|
|
6886
|
+
if (!typeEquals(elemValueT, sourceT.elem) ||
|
|
6887
|
+
(declaredElement !== null && lowerer.runtimeOptionalWidening(elemValueT, declaredElement) !== null)) {
|
|
6694
6888
|
const root = lowerer.runtimeOptionalRootOf(local);
|
|
6695
6889
|
lowerer.runtimeOptionalLocals.add(root);
|
|
6696
6890
|
lowerer.runtimeOptionalStorageLocals.add(root);
|
|
@@ -7148,66 +7342,46 @@ function lowerForOfClassIterator(lowerer, stmt, iterable, cit, labels) {
|
|
|
7148
7342
|
lowerer.scopes.pop();
|
|
7149
7343
|
}
|
|
7150
7344
|
}
|
|
7151
|
-
/**
|
|
7152
|
-
*
|
|
7153
|
-
*
|
|
7154
|
-
* it = iterNew(v); // GetIterator (prelude; may throw)
|
|
7155
|
-
* while (true) {
|
|
7156
|
-
* r = it.next(); // callMethod
|
|
7157
|
-
* if (truthy(r.done)) break;
|
|
7158
|
-
* <bind loop var(s) from r.value> // getProp
|
|
7159
|
-
* ...body
|
|
7160
|
-
* }
|
|
7161
|
-
*
|
|
7162
|
-
* The loop variable's ELEMENT is an island handle (jsval — exactly what
|
|
7163
|
-
* the checker's package-typed element maps to); identifier heads bind
|
|
7164
|
-
* it per iteration, destructuring heads run the jsval pattern desugar,
|
|
7165
|
-
* pre-declared and var heads keep their fences (the array path's
|
|
7166
|
-
* stories don't carry over mechanically). IteratorClose on early exit
|
|
7167
|
-
* (break/return out of a partial iteration calling it.return()) is NOT
|
|
7168
|
-
* run — a divergence only a custom island iterator with a return()
|
|
7169
|
-
* method can observe. */
|
|
7170
|
-
/** For-of over a CHECKED-DYNAMIC iterable: the source packs ONCE
|
|
7171
|
-
* through the spread walk (dyn.iterPack — dyn arrays element-by-
|
|
7172
|
-
* element, strings by code point, bytes by byte; a WRAPPED engine
|
|
7173
|
-
* value drains through the ENGINE's own iterator protocol via the
|
|
7174
|
-
* iter_drain arm; every other kind throws V8's not-iterable
|
|
7175
|
-
* TypeError, the identifier spelling when the head has one), then a
|
|
7176
|
-
* hidden index loop binds each element as a dyn value. The pack is an
|
|
7177
|
-
* eager SNAPSHOT (the matchAll stance): body mutations of a dyn-array
|
|
7178
|
-
* source don't extend the iteration where JS's live array iterator
|
|
7179
|
-
* would — documented divergence; engine sources drain through their
|
|
7180
|
-
* own protocol, so generators/Maps/Sets step exactly once like Node. */
|
|
7345
|
+
/** A checked IteratorRecord stays live throughout the loop. Cache next once,
|
|
7346
|
+
* read done before value, and close only after a yielded value has arrived.
|
|
7347
|
+
* Abrupt body throws retain precedence over errors raised by return(). */
|
|
7181
7348
|
function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
7182
7349
|
const loc = locOf(stmt);
|
|
7183
|
-
const head = stmt.expression;
|
|
7184
|
-
// V8's for-of CallPrinter spellings: named sources (identifiers and
|
|
7185
|
-
// plain property chains) read "<src> is not iterable", call heads
|
|
7186
|
-
// with a nameable callee "<callee> is not a function or its return
|
|
7187
|
-
// value is not iterable"; everything else keeps the runtime kind
|
|
7188
|
-
// wording. The runtime uses the spelling VERBATIM when non-empty.
|
|
7189
7350
|
const headText = (e) => {
|
|
7190
7351
|
if (ts.isIdentifier(e))
|
|
7191
7352
|
return e.text;
|
|
7192
7353
|
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken && ts.isIdentifier(e.name)) {
|
|
7193
7354
|
const base = headText(e.expression);
|
|
7194
|
-
return base
|
|
7355
|
+
return base === null ? null : `${base}.${e.name.text}`;
|
|
7195
7356
|
}
|
|
7196
7357
|
return null;
|
|
7197
7358
|
};
|
|
7198
|
-
const
|
|
7199
|
-
const
|
|
7200
|
-
const spell =
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
const
|
|
7206
|
-
const
|
|
7207
|
-
|
|
7208
|
-
const
|
|
7209
|
-
const
|
|
7210
|
-
|
|
7359
|
+
const name = headText(stmt.expression);
|
|
7360
|
+
const callee = ts.isCallExpression(stmt.expression) ? headText(stmt.expression.expression) : null;
|
|
7361
|
+
const spell = name !== null ? `${name} is not iterable` : callee !== null ? `${callee} is not a function or its return value is not iterable` : "";
|
|
7362
|
+
const iterator = lowerer.declareHiddenLocal("%dofIterator", DYN);
|
|
7363
|
+
const next = lowerer.declareHiddenLocal("%dofNext", DYN);
|
|
7364
|
+
const step = lowerer.declareHiddenLocal("%dofStep", DYN);
|
|
7365
|
+
const value = lowerer.declareHiddenLocal("%dofValue", DYN);
|
|
7366
|
+
const returned = lowerer.declareHiddenLocal("%dofReturn", DYN);
|
|
7367
|
+
const needsClose = lowerer.declareHiddenLocal("%dofNeedsClose", BOOL);
|
|
7368
|
+
needsClose.mutable = true;
|
|
7369
|
+
const error = lowerer.declareHiddenLocal("%dofError", CAUGHT);
|
|
7370
|
+
const get = (source, key) => ({
|
|
7371
|
+
kind: "dynKeyGet", value: source, key: { kind: "strLit", value: key, type: STRING, loc }, type: DYN, loc,
|
|
7372
|
+
});
|
|
7373
|
+
const check = (value) => ({ kind: "libCall", fn: "dyn.iteratorResult", args: [value], type: DYN, loc });
|
|
7374
|
+
const call = (callee) => check({
|
|
7375
|
+
kind: "dynCall", callee, receiver: varRef(iterator.id, DYN, loc), calleeName: "iterator method", args: [], type: DYN, loc,
|
|
7376
|
+
});
|
|
7377
|
+
const setClose = (value) => ({ kind: "assign", localId: needsClose.id, value: { kind: "boolLit", value, type: BOOL, loc }, loc });
|
|
7378
|
+
const close = () => [
|
|
7379
|
+
{ kind: "varDecl", localId: returned.id, init: get(varRef(iterator.id, DYN, loc), "return"), loc },
|
|
7380
|
+
{ kind: "if", cond: { kind: "unary", op: "!", operand: { kind: "dynTest", test: "nullish", value: varRef(returned.id, DYN, loc), type: BOOL, loc }, type: BOOL, loc }, then: [
|
|
7381
|
+
{ kind: "exprStmt", expr: call(varRef(returned.id, DYN, loc)), loc },
|
|
7382
|
+
], else_: null, loc },
|
|
7383
|
+
];
|
|
7384
|
+
const elemInit = () => varRef(value.id, DYN, loc);
|
|
7211
7385
|
lowerer.scopes.push(new Map());
|
|
7212
7386
|
try {
|
|
7213
7387
|
const binds = [];
|
|
@@ -7275,40 +7449,35 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
7275
7449
|
}
|
|
7276
7450
|
}
|
|
7277
7451
|
const body = lowerer.inCtl("loop", () => lowerer.lowerScopedBlock(stmt.statement), labels);
|
|
7452
|
+
const loop = {
|
|
7453
|
+
kind: "while", cond: { kind: "boolLit", value: true, type: BOOL, loc },
|
|
7454
|
+
body: [
|
|
7455
|
+
setClose(false),
|
|
7456
|
+
{ kind: "varDecl", localId: step.id, init: call(varRef(next.id, DYN, loc)), loc },
|
|
7457
|
+
{ kind: "if", cond: { kind: "dynTest", test: "truthy", value: get(varRef(step.id, DYN, loc), "done"), type: BOOL, loc }, then: [{ kind: "break", loc }], else_: null, loc },
|
|
7458
|
+
{ kind: "varDecl", localId: value.id, init: get(varRef(step.id, DYN, loc), "value"), loc },
|
|
7459
|
+
setClose(true),
|
|
7460
|
+
...binds, ...body,
|
|
7461
|
+
],
|
|
7462
|
+
...(labels && { labels }), loc,
|
|
7463
|
+
};
|
|
7278
7464
|
return {
|
|
7279
7465
|
kind: "block",
|
|
7280
7466
|
body: [
|
|
7467
|
+
{ kind: "varDecl", localId: iterator.id, init: check({ kind: "libCall", fn: "dyn.iterator", args: [iterable, { kind: "strLit", value: spell, type: STRING, loc }], type: DYN, loc }), loc },
|
|
7468
|
+
{ kind: "varDecl", localId: next.id, init: get(varRef(iterator.id, DYN, loc), "next"), loc },
|
|
7469
|
+
{ kind: "varDecl", localId: needsClose.id, init: { kind: "boolLit", value: false, type: BOOL, loc }, loc },
|
|
7281
7470
|
{
|
|
7282
|
-
kind: "
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
loc,
|
|
7292
|
-
},
|
|
7293
|
-
{
|
|
7294
|
-
kind: "for",
|
|
7295
|
-
init: { kind: "varDecl", localId: idx.id, init: { kind: "numLit", value: 0, type: F64, loc }, loc },
|
|
7296
|
-
cond: {
|
|
7297
|
-
kind: "bin",
|
|
7298
|
-
op: "<",
|
|
7299
|
-
left: iRef(),
|
|
7300
|
-
right: { kind: "libCall", fn: "dyn.arrLen", args: [packRef()], type: F64, loc },
|
|
7301
|
-
type: BOOL,
|
|
7302
|
-
loc,
|
|
7303
|
-
},
|
|
7304
|
-
update: {
|
|
7305
|
-
kind: "assign",
|
|
7306
|
-
localId: idx.id,
|
|
7307
|
-
value: { kind: "bin", op: "+", left: iRef(), right: { kind: "numLit", value: 1, type: F64, loc }, type: F64, loc },
|
|
7308
|
-
loc,
|
|
7309
|
-
},
|
|
7310
|
-
body: [...binds, ...body],
|
|
7311
|
-
...(labels && { labels }),
|
|
7471
|
+
kind: "tryCatch", tryBody: [loop],
|
|
7472
|
+
catchBody: [
|
|
7473
|
+
{ kind: "if", cond: varRef(needsClose.id, BOOL, loc), then: [
|
|
7474
|
+
setClose(false),
|
|
7475
|
+
{ kind: "tryCatch", tryBody: close(), catchBody: [], catchLocalId: null, finallyBody: null, loc },
|
|
7476
|
+
], else_: null, loc },
|
|
7477
|
+
{ kind: "rethrow", localId: error.id, loc },
|
|
7478
|
+
],
|
|
7479
|
+
catchLocalId: error.id,
|
|
7480
|
+
finallyBody: [{ kind: "if", cond: varRef(needsClose.id, BOOL, loc), then: close(), else_: null, loc }],
|
|
7312
7481
|
loc,
|
|
7313
7482
|
},
|
|
7314
7483
|
],
|
|
@@ -7319,6 +7488,25 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
7319
7488
|
lowerer.scopes.pop();
|
|
7320
7489
|
}
|
|
7321
7490
|
}
|
|
7491
|
+
/** for-of over an ISLAND value (see lowerForOf's jsval arm): the
|
|
7492
|
+
* engine's iterator protocol desugared over jsOps —
|
|
7493
|
+
*
|
|
7494
|
+
* it = iterNew(v); // GetIterator (prelude; may throw)
|
|
7495
|
+
* while (true) {
|
|
7496
|
+
* r = it.next(); // callMethod
|
|
7497
|
+
* if (truthy(r.done)) break;
|
|
7498
|
+
* <bind loop var(s) from r.value> // getProp
|
|
7499
|
+
* ...body
|
|
7500
|
+
* }
|
|
7501
|
+
*
|
|
7502
|
+
* The loop variable's ELEMENT is an island handle (jsval — exactly what
|
|
7503
|
+
* the checker's package-typed element maps to); identifier heads bind
|
|
7504
|
+
* it per iteration, destructuring heads run the jsval pattern desugar,
|
|
7505
|
+
* pre-declared and var heads keep their fences (the array path's
|
|
7506
|
+
* stories don't carry over mechanically). IteratorClose on early exit
|
|
7507
|
+
* (break/return out of a partial iteration calling it.return()) is NOT
|
|
7508
|
+
* run — a divergence only a custom island iterator with a return()
|
|
7509
|
+
* method can observe. */
|
|
7322
7510
|
function lowerForOfIsland(lowerer, stmt, iterable, labels) {
|
|
7323
7511
|
const loc = locOf(stmt);
|
|
7324
7512
|
if (!ts.isVariableDeclarationList(stmt.initializer)) {
|
|
@@ -7538,13 +7726,25 @@ function lowerForIn(lowerer, stmt) {
|
|
|
7538
7726
|
if (stdlibGlobalNameOf(lowerer, stmt.expression) === "globalThis") {
|
|
7539
7727
|
return { kind: "block", body: [], loc };
|
|
7540
7728
|
}
|
|
7541
|
-
const
|
|
7542
|
-
|
|
7543
|
-
|
|
7729
|
+
const receiver = lowerer.lowerExpr(stmt.expression);
|
|
7730
|
+
const recvT = receiver.type;
|
|
7731
|
+
if (recvT.kind === "dyn") {
|
|
7732
|
+
const recv = lowerer.declareHiddenLocal("%indyn", DYN);
|
|
7733
|
+
const ref = { kind: "varRef", localId: recv.id, type: DYN, loc };
|
|
7734
|
+
const keys = {
|
|
7735
|
+
kind: "dynCheck", value: { kind: "libCall", fn: "dyn.forInKeys", args: [ref], type: DYN, loc },
|
|
7736
|
+
type: arrayOf(STRING), loc,
|
|
7737
|
+
};
|
|
7738
|
+
const loop = lowerForInOverKeys(lowerer, stmt, keys, labels, (key) => ({
|
|
7739
|
+
kind: "libCall", fn: "dyn.hasKey", args: [ref, key], type: BOOL, loc,
|
|
7740
|
+
}));
|
|
7741
|
+
return { kind: "block", body: [{ kind: "varDecl", localId: recv.id, init: receiver, loc }, loop], loc };
|
|
7742
|
+
}
|
|
7743
|
+
if (recvT.kind === "array")
|
|
7744
|
+
return lowerForInArray(lowerer, stmt, labels, receiver);
|
|
7544
7745
|
if (recvT?.kind === "record") {
|
|
7545
7746
|
const shape = lowerer.shapes.get(recvT.shapeId);
|
|
7546
7747
|
if (shape && !shape.tuple) {
|
|
7547
|
-
const receiver = lowerer.lowerExpr(stmt.expression);
|
|
7548
7748
|
if (receiver.type.kind !== "record")
|
|
7549
7749
|
lowerer.badType(stmt.expression, lowerer.typeOf(stmt.expression));
|
|
7550
7750
|
const rShape = lowerer.shapes.get(receiver.type.shapeId);
|
|
@@ -7673,9 +7873,8 @@ function lowerForInOverKeys(lowerer, stmt, keys, labels, guard) {
|
|
|
7673
7873
|
* live-length guard is the per-visit presence check (keys removed by
|
|
7674
7874
|
* pops are skipped, exactly Node's HasProperty re-check; indices are
|
|
7675
7875
|
* dense, so `i < length` IS presence). */
|
|
7676
|
-
function lowerForInArray(lowerer, stmt, labels) {
|
|
7876
|
+
function lowerForInArray(lowerer, stmt, labels, arrExpr) {
|
|
7677
7877
|
const loc = locOf(stmt);
|
|
7678
|
-
const arrExpr = lowerer.lowerExpr(stmt.expression);
|
|
7679
7878
|
if (arrExpr.type.kind !== "array")
|
|
7680
7879
|
lowerer.badType(stmt.expression, lowerer.typeOf(stmt.expression));
|
|
7681
7880
|
lowerer.scopes.push(new Map());
|