@scriptc/compiler 0.1.7 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +98 -39
- package/ambient/scriptc-overrides.d.ts +10 -6
- package/ambient/scriptc.d.ts +15 -0
- 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 +108 -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/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 +1 -1
- package/dist/backend/link-plan.js +16 -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 +1 -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 +2 -0
- package/dist/backend/llvm/blocks.js +9 -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 +88 -30
- 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.js +2 -7
- package/dist/backend/llvm/debug-info.js.map +1 -1
- 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 +21 -2
- package/dist/backend/llvm/dyn.js +647 -251
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +596 -1
- package/dist/backend/llvm/emitter.js +769 -425
- 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 +2 -2
- package/dist/backend/llvm/expr-bytes.js +60 -31
- 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 +10 -6
- 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 +78 -81
- 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 +62 -31
- 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 +54 -7
- 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 +220 -131
- 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 +30 -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 +44 -19
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +162 -3
- 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 +42 -131
- package/dist/backend/llvm/shapes.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 +12 -30
- package/dist/backend/native-toolchain.js +83 -233
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +77 -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 +73 -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/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 +103 -34
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +72 -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 +37 -7
- 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.js +5 -10
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +3 -4
- package/dist/executable/executable-cache.js +5 -6
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +16 -17
- 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 +1 -3
- package/dist/frontend/arguments-usage.js.map +1 -1
- 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 +74 -0
- package/dist/frontend/lowering/class-callbacks.js.map +1 -0
- package/dist/frontend/lowering/class-construction.d.ts +12 -0
- package/dist/frontend/lowering/class-construction.js +156 -0
- package/dist/frontend/lowering/class-construction.js.map +1 -0
- package/dist/frontend/lowering/class-descriptors.d.ts +10 -0
- package/dist/frontend/lowering/class-descriptors.js +114 -0
- package/dist/frontend/lowering/class-descriptors.js.map +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +51 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1158 -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 +93 -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 +67 -0
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -0
- package/dist/frontend/lowering/class-method-values.d.ts +13 -0
- package/dist/frontend/lowering/class-method-values.js +235 -0
- package/dist/frontend/lowering/class-method-values.js.map +1 -0
- package/dist/frontend/lowering/class-prototypes.d.ts +19 -0
- package/dist/frontend/lowering/class-prototypes.js +242 -0
- package/dist/frontend/lowering/class-prototypes.js.map +1 -0
- package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
- package/dist/frontend/lowering/class-runtime-statics.js +66 -0
- package/dist/frontend/lowering/class-runtime-statics.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 +208 -163
- 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 +58 -63
- 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 +14 -0
- package/dist/frontend/lowering/error-methods.js +177 -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 +51 -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 +132 -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 +509 -183
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
- package/dist/frontend/lowering/expressions/optional-chains.js +88 -24
- 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 +101 -0
- package/dist/frontend/lowering/function-context.js +109 -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 +11 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +143 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.d.ts +4 -1
- package/dist/frontend/lowering/lib-boundary.js +112 -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 +18 -0
- package/dist/frontend/lowering/lower-builtin-values.js +249 -0
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.d.ts +33 -46
- package/dist/frontend/lowering/lower-builtins.js +676 -365
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +28 -22
- package/dist/frontend/lowering/lower-calls.js +1660 -412
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +95 -57
- package/dist/frontend/lowering/lower-classes.js +1491 -404
- 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 +36 -32
- package/dist/frontend/lowering/lower-containers.js +925 -181
- 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 +3 -2
- 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 +37 -13
- package/dist/frontend/lowering/lower-exprs.js +2163 -863
- 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 +88 -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 +7 -8
- package/dist/frontend/lowering/lower-island.js +66 -33
- 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 +445 -39
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-modules.test.js +39 -0
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
- 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 +17 -17
- package/dist/frontend/lowering/lower-stmts.js +855 -514
- 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 +20 -11
- 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 +140 -190
- package/dist/frontend/lowering/lowerer.js +1193 -712
- 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 +172 -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 +10 -3
- package/dist/frontend/lowering/surfaces.js +86 -37
- 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 +12 -0
- package/dist/frontend/lowering/text-decoder-encoding.js +82 -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 +121 -38
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-prune.test.js +9 -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 +39 -20
- package/dist/frontend/program.js +393 -189
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +105 -2
- package/dist/frontend/program.test.js.map +1 -1
- 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 +25 -18
- 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 +47 -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 +34 -18
- package/dist/frontend/type-mapper.js +552 -131
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +146 -2
- package/dist/frontend/type-mapper.test.js.map +1 -1
- 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 -198
- package/dist/index.js +369 -1572
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +16 -4
- package/dist/ir/analysis.js +23 -4
- 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 +334 -176
- package/dist/ir/ir.js +710 -903
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +162 -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 +33 -14
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.d.ts +1 -0
- package/dist/ir/serialize.test.js +57 -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 +2018 -1498
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +536 -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/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 +137 -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 +94 -0
- package/dist/native/toolchain.js.map +1 -0
- package/dist/native/toolchain.test.d.ts +1 -0
- package/dist/native/toolchain.test.js +85 -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 +107 -98
- 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 -536
- package/dist/backend/c/c-emitter.js +0 -1932
- 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 -8847
- 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 -1108
- 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 -1772
- package/dist/backend/c/walkers.js.map +0 -1
- /package/dist/backend/{c/types.test.d.ts → cycle-analysis.test.d.ts} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { lowerDynObjectLiteral } from "./expressions/object-literals.js";
|
|
1
2
|
import { InternalCompilerError } from "../../errors.js";
|
|
2
3
|
/* Statement lowering: the statement dispatch (lowerStmt), variable
|
|
3
4
|
* declarations including destructuring patterns, scoped blocks, control
|
|
@@ -5,30 +6,41 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
5
6
|
* explicit resource management, and blocked-binding poisoning. */
|
|
6
7
|
import * as ts from "../ts7/adapter.js";
|
|
7
8
|
import { bindingSource } from "../binding-source.js";
|
|
8
|
-
import { arrayValueRead, arrayValueStore, arrayValueType } from "./array-values.js";
|
|
9
|
+
import { arrayValueRead, arrayValueStore, arrayValueType, unionArrayValueRead } from "./array-values.js";
|
|
9
10
|
import { lowerForAwaitGenerator, lowerForOfGenerator, lowerYieldStarStatement } from "./lower-generators.js";
|
|
10
11
|
import { lowerForAwaitBuiltin } from "./lower-async-iteration.js";
|
|
11
|
-
import { BOOL, BYTES_U8, CAUGHT, DYN, F64, JSVAL, STRING, UNDEFINED_T, VOID, arrayOf, isUnitType, shapeHasAccessorSlots, typeEquals } from "../../ir/ir.js";
|
|
12
|
+
import { BOOL, BYTES_U8, CAUGHT, DYN, F64, JSVAL, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals } from "../../ir/ir.js";
|
|
12
13
|
import { PoisonError, boundIdentifiersOf, dynFallbackType, dynUndefinedExpr, importCallHandleType, neverTaintedJsType, staticImportNamespaceType, stmtUsesIsland, uncheckedOverloadHandleCall } from "./lowerer.js";
|
|
13
|
-
import { enforceLibBoundary } from "./lib-boundary.js";
|
|
14
|
-
import { cjsExportAssignmentOf, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile, locOf, requireSpecOf } from "../program.js";
|
|
14
|
+
import { enforceLibBoundary, lowerSurplusCalls } from "./lib-boundary.js";
|
|
15
|
+
import { cjsExportAssignmentOf, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile, isNodeEsmFile, locOf, requireSpecOf } from "../program.js";
|
|
15
16
|
import { COMPOUND_ASSIGN_OPS, STR_METHODS, UNSUPPORTED_STMT, isStdlibMember, sideEffectFreeOptionValue, stdlibGlobalAliasDecl, stdlibGlobalAliasNameOf, stdlibGlobalNameOf } from "./surfaces.js";
|
|
17
|
+
import { isNativeBuiltinValueInitializer } from "./lower-builtin-values.js";
|
|
16
18
|
import { isProvenanceSourceFile } from "../provenance-registry.js";
|
|
17
19
|
import { ambientUndefVarRootOf, lowerImportEquals, nsUndefRead, nsWritableTarget, trapDeclRootOf } from "./lower-namespaces.js";
|
|
18
20
|
import { expandoWritableTarget, lowerExpandoAssignStmt } from "./lower-expando.js";
|
|
19
21
|
import { lowerForOfArrayIter, lowerForOfMap, lowerForOfSearchParams, lowerForOfSet, lowerSafeIndexRead, objectIterOverIndexShape, strCharsCall } from "./lower-containers.js";
|
|
20
22
|
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, bindingNeverReassigned, deadUnmappableBinding, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, nullishExprUnitOf, nullishGenericBindingUnitOf, recordKeysArrayCall, registerOverloadedCallableAlias } from "./lower-calls.js";
|
|
21
23
|
import { isMixinFnBinding, mixinResultBindingClassOf } from "./lower-mixins.js";
|
|
22
|
-
import {
|
|
24
|
+
import { isCompiledPrototypeMember } from "./class-prototypes.js";
|
|
25
|
+
import { classStaticDataFor } from "./class-static-data.js";
|
|
26
|
+
import { objectFactorySignature } from "./object-factory-new.js";
|
|
27
|
+
import { isClassCallback, lowerClassCallbackAssign } from "./class-callbacks.js";
|
|
28
|
+
import { classPropertiesHelper } from "./class-dynamic-dispatch.js";
|
|
29
|
+
import { genericIfaceBindingKeepsClass, staticFieldWriteTarget } from "./lower-classes.js";
|
|
23
30
|
import { lowerStreamUnderscoreAssign, streamClassAliasDecl } from "./lower-stream.js";
|
|
24
31
|
import { lowerHttpResPropertyAssignment, lowerHttpServerTimeoutAssignment, lowerServerCloseOverrideAssignment } from "./lower-server.js";
|
|
25
|
-
import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, lowerNodeModuleCall, registerBuiltinCallableAlias
|
|
32
|
+
import { isNativeFfiRequire, builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, lowerNodeModuleCall, registerBuiltinCallableAlias } from "./lower-builtins.js";
|
|
26
33
|
import { lowerEnumDeclaration } from "./lower-enums.js";
|
|
27
|
-
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerElementCompound, lowerGroupsProjection,
|
|
34
|
+
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerCompoundValueToTarget, lowerElementCompound, lowerGroupsProjection, matchResultNamedGroupsOf, runtimeOptionalGuardIds, runtimeOptionalTrueIds, symbolFieldInfo, withRuntimeOptionalNarrowed } from "./lower-exprs.js";
|
|
28
35
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
36
|
+
import { globalSymbolKey } from "./expressions/global-symbols.js";
|
|
37
|
+
import { lowerShortCircuitAssignment } from "./expressions/nullish-assignment.js";
|
|
38
|
+
import { lowerEnvironmentKey, lowerNativeFunctionAssignment } from "./lower-exprs.js";
|
|
39
|
+
import { isNativeProxyInitializer } from "./expressions/native-proxy.js";
|
|
29
40
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
41
|
+
import { lowerUnionFieldWrite } from "./expressions/union-field-write.js";
|
|
42
|
+
import { UNSUPPORTED, checkerPanicDiag, isCheckerPanic, requiresDynamicDiag } from "../../diagnostics/diagnostic.js";
|
|
43
|
+
import { isParseArgsDynTypeName, isUnitOnlyTsType, jsOpenObjectType, unitOnlyUnion } from "../type-mapper.js";
|
|
32
44
|
import { canonicalBuiltinModule } from "../builtin-modules.js";
|
|
33
45
|
import { isRelativeSpecifier } from "../workspace-registry.js";
|
|
34
46
|
import { probeNodeRequireRefusal } from "../npm.js";
|
|
@@ -56,7 +68,7 @@ function npmStaticReturnedEmptyArrayType(lowerer, decl) {
|
|
|
56
68
|
let owner = decl.parent;
|
|
57
69
|
while (owner !== undefined && !ts.isFunctionLike(owner))
|
|
58
70
|
owner = owner.parent;
|
|
59
|
-
const ownerBody = owner !== undefined &&
|
|
71
|
+
const ownerBody = owner !== undefined && ts.isFunctionLike(owner) ? owner.body : undefined;
|
|
60
72
|
if (ownerBody === undefined || !ts.isBlock(ownerBody))
|
|
61
73
|
return null;
|
|
62
74
|
let returned = false;
|
|
@@ -93,7 +105,7 @@ function npmStaticOptionalSelfWriteType(lowerer, decl, initial) {
|
|
|
93
105
|
let owner = decl.parent;
|
|
94
106
|
while (owner !== undefined && !ts.isFunctionLike(owner))
|
|
95
107
|
owner = owner.parent;
|
|
96
|
-
const ownerBody = owner !== undefined &&
|
|
108
|
+
const ownerBody = owner !== undefined && ts.isFunctionLike(owner) ? owner.body : undefined;
|
|
97
109
|
if (ownerBody === undefined || !ts.isBlock(ownerBody))
|
|
98
110
|
return null;
|
|
99
111
|
let candidate = null;
|
|
@@ -320,7 +332,7 @@ export function provenanceElidedConstDecl(lowerer, decl) {
|
|
|
320
332
|
const sf = decl.getSourceFile();
|
|
321
333
|
if (!isProvenanceSourceFile(sf.fileName))
|
|
322
334
|
return false;
|
|
323
|
-
const stmt = decl.parent
|
|
335
|
+
const stmt = decl.parent?.parent;
|
|
324
336
|
if (!ts.isVariableStatement(stmt) || !pureAnnotatedDeadConst(stmt, sf))
|
|
325
337
|
return false;
|
|
326
338
|
const diagsBefore = lowerer.diags.length;
|
|
@@ -414,13 +426,16 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
414
426
|
// fence — inside this statement's poison window, so a JS fence
|
|
415
427
|
// becomes the statement's runtimeFence exactly like every other
|
|
416
428
|
// deferred rejection.
|
|
417
|
-
if (lowered)
|
|
418
|
-
|
|
419
|
-
if (!appended) {
|
|
429
|
+
if (lowered) {
|
|
430
|
+
const body = [];
|
|
420
431
|
if (Array.isArray(lowered))
|
|
421
|
-
|
|
422
|
-
else
|
|
423
|
-
|
|
432
|
+
body.push(...lowered);
|
|
433
|
+
else
|
|
434
|
+
body.push(lowered);
|
|
435
|
+
const rewritten = lowerSurplusCalls(lowerer, body);
|
|
436
|
+
enforceLibBoundary(lowerer, rewritten);
|
|
437
|
+
if (!appended)
|
|
438
|
+
out.push(...rewritten);
|
|
424
439
|
}
|
|
425
440
|
// Island accounting (--dynamic coverage): a statement that lowered
|
|
426
441
|
// but carries island constructs compiles DYNAMICALLY — its work
|
|
@@ -509,11 +524,13 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
509
524
|
* empty-slot sentinel still works (a scalar slot has no spare state:
|
|
510
525
|
* every bit pattern is a legal value — the setTimeout-handle shape,
|
|
511
526
|
* `clearTimeout(timer)` captured above `const timer = setTimeout(...)`).
|
|
512
|
-
*
|
|
527
|
+
* Checked-dynamic values use ref boxes with their own retain/release;
|
|
528
|
+
* a NULL payload remains distinct from the allocated undefined value.
|
|
529
|
+
* caught/jsval keep their existing capture fences. Unit-only types
|
|
513
530
|
* never carry a useful forward capture. */
|
|
514
531
|
const TDZ_KINDS = new Set([
|
|
515
532
|
"func", "string", "array", "record", "object", "union", "map", "set", "regex", "bytes",
|
|
516
|
-
"f64", "bool",
|
|
533
|
+
"f64", "bool", "dyn",
|
|
517
534
|
// The runtime HANDLE kinds — heap, refcounted, pointer-backed like
|
|
518
535
|
// `object`, so the box's NULL sentinel works unchanged. The canonical
|
|
519
536
|
// shape is the const's own initializer capturing the const:
|
|
@@ -541,26 +558,25 @@ const TDZ_KINDS = new Set([
|
|
|
541
558
|
* threads captures normally. The source declaration later becomes the
|
|
542
559
|
* initializing `assign` (lowerVarDecl consumes tdzPredeclared). Reads
|
|
543
560
|
* test the box and throw Node's exact catchable ReferenceError while it
|
|
544
|
-
* is empty.
|
|
545
|
-
*
|
|
561
|
+
* is empty. Mutable bindings also guard writes; only the declaration's
|
|
562
|
+
* initializing assignment may leave the temporal dead zone. */
|
|
546
563
|
export function predeclareForwardCapture(lowerer, symbol) {
|
|
547
564
|
const decl = lowerer.checker.valueDeclarationOf(symbol);
|
|
548
565
|
if (!decl || !ts.isVariableDeclaration(decl) || decl.name === undefined || !ts.isIdentifier(decl.name))
|
|
549
566
|
return false;
|
|
550
567
|
if (!decl.initializer)
|
|
551
568
|
return false;
|
|
552
|
-
|
|
569
|
+
const flags = ts.getCombinedNodeFlags(decl);
|
|
570
|
+
if ((flags & ts.NodeFlags.BlockScoped) === 0 || (flags & ts.NodeFlags.Using) !== 0)
|
|
553
571
|
return false;
|
|
554
|
-
|
|
555
|
-
return false; // defensive: never twice
|
|
556
|
-
// MODULE-scope consts are pre-registered globals (collectGlobals):
|
|
572
|
+
// MODULE-scope bindings are pre-registered globals (collectGlobals):
|
|
557
573
|
// references resolve through globalOf after the local search fails, so
|
|
558
574
|
// a TDZ box here would SHADOW the global and never fill (the top-level
|
|
559
575
|
// `const id = setInterval(cb)` self-capture — the global slot is the
|
|
560
576
|
// binding). Function-scope declarations have no global; they predeclare.
|
|
561
577
|
if (lowerer.globalsBySymbol.has(symbol))
|
|
562
578
|
return false;
|
|
563
|
-
const varStmt = decl.parent
|
|
579
|
+
const varStmt = decl.parent?.parent;
|
|
564
580
|
if (!ts.isVariableStatement(varStmt))
|
|
565
581
|
return false; // for-initializers stay out
|
|
566
582
|
for (let i = lowerer.activeStmtLists.length - 1; i >= 0; i--) {
|
|
@@ -575,7 +591,7 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
575
591
|
// const's own initializer capturing the const (`const server =
|
|
576
592
|
// createServer(h).listen(0, go)` with `go` reading `server`) is a
|
|
577
593
|
// TDZ read until the initializing assign completes — JS exactly.
|
|
578
|
-
if (idx < entry.index || entry.ctx === lowerer.ctx)
|
|
594
|
+
if (idx < entry.index || entry.ctx === lowerer.ctx || entry.ctx.tdzPredeclared.has(symbol))
|
|
579
595
|
return false;
|
|
580
596
|
const type = lowerer.irTypeOf(decl.name);
|
|
581
597
|
if (!TDZ_KINDS.has(type.kind) || isUnitType(type))
|
|
@@ -583,11 +599,14 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
583
599
|
const name = decl.name.text;
|
|
584
600
|
const count = entry.ctx.localCounters.get(name) ?? 0;
|
|
585
601
|
entry.ctx.localCounters.set(name, count + 1);
|
|
586
|
-
const local = {
|
|
602
|
+
const local = {
|
|
603
|
+
id: `${name}.${count}`, name, type,
|
|
604
|
+
mutable: (flags & ts.NodeFlags.Const) === 0, boxed: true, tdz: true,
|
|
605
|
+
};
|
|
587
606
|
entry.ctx.locals.push(local);
|
|
588
607
|
entry.frame.set(symbol, local);
|
|
589
608
|
entry.out.push({ kind: "varDecl", localId: local.id, init: null, loc: locOf(decl) });
|
|
590
|
-
|
|
609
|
+
entry.ctx.tdzPredeclared.set(symbol, local);
|
|
591
610
|
return true;
|
|
592
611
|
}
|
|
593
612
|
return false;
|
|
@@ -599,23 +618,20 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
599
618
|
* declaration and initializing assignment are pushed before the current
|
|
600
619
|
* statement's IR, registered in the list's scope frame) and the statement
|
|
601
620
|
* loop skips the source statement when it arrives
|
|
602
|
-
* (
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
* ctx than the one currently open — that shape keeps the honest fence. */
|
|
621
|
+
* (the owner's hoistedFnDecls). Forward references from nested functions
|
|
622
|
+
* lower the declaration under the owning statement list's context, then
|
|
623
|
+
* resume the caller and thread its captures normally. */
|
|
606
624
|
export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
607
625
|
const decl = lowerer.checker.valueDeclarationOf(symbol);
|
|
608
626
|
if (!decl || !ts.isFunctionDeclaration(decl) || !decl.body || decl.typeParameters)
|
|
609
627
|
return false;
|
|
610
|
-
if (lowerer.hoistedFnDecls.has(decl))
|
|
611
|
-
return false; // defensive: never twice
|
|
612
628
|
for (let i = lowerer.activeStmtLists.length - 1; i >= 0; i--) {
|
|
613
629
|
const entry = lowerer.activeStmtLists[i];
|
|
614
630
|
const idx = entry.stmts.indexOf(decl);
|
|
615
631
|
if (idx < 0)
|
|
616
632
|
continue;
|
|
617
633
|
// Not forward — already lowered; resolution would have found it.
|
|
618
|
-
if (idx <= entry.index)
|
|
634
|
+
if (idx <= entry.index || entry.ctx.hoistedFnDecls.has(decl))
|
|
619
635
|
return false;
|
|
620
636
|
// The declaration may live in an ENCLOSING function's open list (a
|
|
621
637
|
// sibling hoisted function calling a later one — mutual recursion):
|
|
@@ -629,14 +645,14 @@ export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
|
629
645
|
const frameIdx = entry.ctx.scopes.indexOf(entry.frame);
|
|
630
646
|
if (depth < 0 || frameIdx < 0)
|
|
631
647
|
return false;
|
|
632
|
-
|
|
648
|
+
entry.ctx.hoistedFnDecls.add(decl);
|
|
633
649
|
const fnTail = lowerer.fnStack.splice(depth + 1);
|
|
634
650
|
const scopeTail = entry.ctx.scopes.splice(frameIdx + 1);
|
|
635
651
|
try {
|
|
636
652
|
entry.out.push(lowerer.lowerNestedFunctionDecl(decl));
|
|
637
653
|
}
|
|
638
654
|
catch (e) {
|
|
639
|
-
|
|
655
|
+
entry.ctx.hoistedFnDecls.delete(decl);
|
|
640
656
|
throw e;
|
|
641
657
|
}
|
|
642
658
|
finally {
|
|
@@ -651,7 +667,8 @@ export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
|
651
667
|
* was declared with `var` — no const/let/using flag anywhere on its
|
|
652
668
|
* binding chain. */
|
|
653
669
|
export function isVarDeclared(decl) {
|
|
654
|
-
|
|
670
|
+
const host = ts.isIdentifier(decl) ? hostVariableDeclarationOf(decl) : decl;
|
|
671
|
+
return host !== null && (ts.getCombinedNodeFlags(host) & ts.NodeFlags.BlockScoped) === 0;
|
|
655
672
|
}
|
|
656
673
|
/** The VariableDeclaration hosting a binding name (walking out of any
|
|
657
674
|
* enclosing binding patterns), or null when the name belongs to some
|
|
@@ -688,6 +705,11 @@ export function forOfVarTarget(lowerer, decl) {
|
|
|
688
705
|
* file rides the dyn fallback). Null when no static type can hold the
|
|
689
706
|
* binding. */
|
|
690
707
|
function varBindingType(lowerer, nameNode) {
|
|
708
|
+
if (ts.isVariableDeclaration(nameNode.parent) && isNativeProxyInitializer(lowerer, nameNode.parent.initializer))
|
|
709
|
+
return DYN;
|
|
710
|
+
if (isJsSourceFile(nameNode.getSourceFile()) && ts.isVariableDeclaration(nameNode.parent) &&
|
|
711
|
+
isNativeBuiltinValueInitializer(lowerer, nameNode.parent.initializer))
|
|
712
|
+
return DYN;
|
|
691
713
|
let type = lowerer.mapTypeOf(lowerer.typeOf(nameNode));
|
|
692
714
|
if (type?.kind === "record" && isJsSourceFile(nameNode.getSourceFile())) {
|
|
693
715
|
const shape = lowerer.shapes.get(type.shapeId);
|
|
@@ -736,13 +758,13 @@ function varBindingType(lowerer, nameNode) {
|
|
|
736
758
|
* classic capture semantics fall out: closures made in a loop share the
|
|
737
759
|
* single boxed binding, where `let` gets a fresh box per iteration. */
|
|
738
760
|
function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
739
|
-
const existing = lowerer.hoistedVars.get(symbol);
|
|
761
|
+
const existing = lowerer.ctx.hoistedVars.get(symbol);
|
|
740
762
|
if (existing)
|
|
741
763
|
return existing;
|
|
742
764
|
// The parameter merge: the symbol already binds a function-root local.
|
|
743
765
|
const bound = lowerer.bindingIn(lowerer.ctx, symbol);
|
|
744
766
|
if (bound) {
|
|
745
|
-
lowerer.hoistedVars.set(symbol, bound);
|
|
767
|
+
lowerer.ctx.hoistedVars.set(symbol, bound);
|
|
746
768
|
return bound;
|
|
747
769
|
}
|
|
748
770
|
const type = varBindingType(lowerer, nameNode);
|
|
@@ -762,7 +784,7 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
762
784
|
// engine undefined for jsval).
|
|
763
785
|
const wrapped = type.kind === "dyn" ? dynUndefinedExpr(locOf(nameNode)) : lowerer.unassignedSlotInit(type, locOf(nameNode));
|
|
764
786
|
root.out.push({ kind: "varDecl", localId: local.id, init: wrapped, loc: locOf(nameNode) });
|
|
765
|
-
lowerer.hoistedVars.set(symbol, local);
|
|
787
|
+
lowerer.ctx.hoistedVars.set(symbol, local);
|
|
766
788
|
return local;
|
|
767
789
|
}
|
|
768
790
|
/** The forward twin of hoistVarBinding, entered from resolution failure: a
|
|
@@ -779,8 +801,6 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
779
801
|
* would yield if the capture ran early, and guessing "it won't" is the
|
|
780
802
|
* silent-wrong-output sin. */
|
|
781
803
|
export function predeclareForwardVar(lowerer, symbol) {
|
|
782
|
-
if (lowerer.hoistedVars.has(symbol))
|
|
783
|
-
return false; // would have resolved
|
|
784
804
|
const decl = lowerer.checker.valueDeclarationOf(symbol);
|
|
785
805
|
if (!decl || !ts.isVariableDeclaration(decl) || !isVarDeclared(decl))
|
|
786
806
|
return false;
|
|
@@ -805,6 +825,8 @@ export function predeclareForwardVar(lowerer, symbol) {
|
|
|
805
825
|
if (!owner)
|
|
806
826
|
return false;
|
|
807
827
|
const ctx = owner.ctx;
|
|
828
|
+
if (ctx.hoistedVars.has(symbol))
|
|
829
|
+
return false; // would have resolved
|
|
808
830
|
// Only a slot that can hold `undefined` can carry the pre-
|
|
809
831
|
// initialization reads: an undefined-armed union (the interned arm),
|
|
810
832
|
// a checked-dynamic binding (the dyn undefined), or a jsval 'any'
|
|
@@ -823,7 +845,7 @@ export function predeclareForwardVar(lowerer, symbol) {
|
|
|
823
845
|
ctx.locals.push(local);
|
|
824
846
|
ctx.scopes[0].set(symbol, local);
|
|
825
847
|
root.out.push({ kind: "varDecl", localId: local.id, init: wrapped, loc: locOf(decl) });
|
|
826
|
-
|
|
848
|
+
ctx.hoistedVars.set(symbol, local);
|
|
827
849
|
return true;
|
|
828
850
|
}
|
|
829
851
|
/** Records the symbols a poisoned DECLARATION statement would have bound
|
|
@@ -868,13 +890,24 @@ export function isBlockedBinding(lowerer, symbol) {
|
|
|
868
890
|
export function lowerScopedBlock(lowerer, stmt) {
|
|
869
891
|
lowerer.scopes.push(new Map());
|
|
870
892
|
try {
|
|
871
|
-
|
|
872
|
-
return stmts;
|
|
893
|
+
return withRuntimeOptionalScope(lowerer, () => ts.isBlock(stmt) ? lowerer.lowerStmts(stmt.statements) : lowerer.lowerStmts([stmt]));
|
|
873
894
|
}
|
|
874
895
|
finally {
|
|
875
896
|
lowerer.scopes.pop();
|
|
876
897
|
}
|
|
877
898
|
}
|
|
899
|
+
function withRuntimeOptionalScope(lowerer, lower) {
|
|
900
|
+
lowerer.runtimeOptionalLocals.beginScope();
|
|
901
|
+
try {
|
|
902
|
+
return lower();
|
|
903
|
+
}
|
|
904
|
+
finally {
|
|
905
|
+
// A guard inside one branch or loop body proves presence only for
|
|
906
|
+
// its remaining statements. Keep assignments that reactivated a
|
|
907
|
+
// slot, and restore every absence possibility from the outer scope.
|
|
908
|
+
lowerer.runtimeOptionalLocals.endScope();
|
|
909
|
+
}
|
|
910
|
+
}
|
|
878
911
|
/** `lbl: stmt` — labeled statements. A label chain collapses to one name
|
|
879
912
|
* list (`a: b: while ...` — both names target the same loop, JS-exact).
|
|
880
913
|
* Loops and switches take the labels DIRECTLY (a labeled continue needs
|
|
@@ -916,6 +949,15 @@ function lowerLabeled(lowerer, stmt) {
|
|
|
916
949
|
return { kind: "block", body, labels, loc: locOf(stmt) };
|
|
917
950
|
}
|
|
918
951
|
export function lowerStmt(lowerer, stmt) {
|
|
952
|
+
if (ts.isClassDeclaration(stmt)) {
|
|
953
|
+
if (!stmt.name)
|
|
954
|
+
lowerer.unsupported("SC1090", stmt, "anonymous local class declarations");
|
|
955
|
+
const info = lowerer.lowerClassExpressionInfo(stmt);
|
|
956
|
+
const type = { kind: "classval", className: info.def.name };
|
|
957
|
+
const local = lowerer.declareLocal(stmt.name, stmt.name.text, type, true);
|
|
958
|
+
const init = lowerer.lowerClassExpression(stmt);
|
|
959
|
+
return { kind: "varDecl", localId: local.id, init, loc: locOf(stmt) };
|
|
960
|
+
}
|
|
919
961
|
if (ts.isVariableStatement(stmt)) {
|
|
920
962
|
// `declare const` — ambient: no storage, no init (collectGlobals
|
|
921
963
|
// skipped it; reads throw Node's ReferenceError at the access).
|
|
@@ -939,11 +981,11 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
939
981
|
// checker only performs for consts (aliasTypeofNarrows).
|
|
940
982
|
const then = lowerer.narrowingAliases(aliasTypeofNarrows(lowerer, stmt.expression, true), () => withRuntimeOptionalNarrowed(lowerer, runtimeOptionalTrueIds(lowerer, stmt.expression), () => lowerer.lowerScopedBlock(stmt.thenStatement)));
|
|
941
983
|
const else_ = stmt.elseStatement
|
|
942
|
-
? lowerer.narrowingAliases(aliasTypeofNarrows(lowerer, stmt.expression, false), () => lowerer.lowerScopedBlock(stmt.elseStatement))
|
|
984
|
+
? lowerer.narrowingAliases(aliasTypeofNarrows(lowerer, stmt.expression, false), () => withRuntimeOptionalNarrowed(lowerer, runtimeOptionalGuardIds(lowerer, stmt.expression, false), () => lowerer.lowerScopedBlock(stmt.elseStatement)))
|
|
943
985
|
: null;
|
|
944
|
-
const
|
|
945
|
-
|
|
946
|
-
|
|
986
|
+
for (const local of falsyExitRuntimeOptionalLocals(lowerer, stmt)) {
|
|
987
|
+
lowerer.runtimeOptionalLocals.delete(lowerer.runtimeOptionalRootOf(local));
|
|
988
|
+
}
|
|
947
989
|
return { kind: "if", cond, then, else_, loc: locOf(stmt) };
|
|
948
990
|
}
|
|
949
991
|
if (ts.isWhileStatement(stmt)) {
|
|
@@ -1093,7 +1135,7 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1093
1135
|
// Already lowered eagerly by the forward-hoisting machinery
|
|
1094
1136
|
// (predeclareForwardFnDecl) — its declaration and assignment are in
|
|
1095
1137
|
// the list's output.
|
|
1096
|
-
if (lowerer.hoistedFnDecls.has(stmt))
|
|
1138
|
+
if (lowerer.ctx.hoistedFnDecls.has(stmt))
|
|
1097
1139
|
return null;
|
|
1098
1140
|
return lowerer.lowerNestedFunctionDecl(stmt);
|
|
1099
1141
|
}
|
|
@@ -1111,7 +1153,7 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1111
1153
|
const entry = UNSUPPORTED_STMT[stmt.kind];
|
|
1112
1154
|
if (entry)
|
|
1113
1155
|
lowerer.unsupported(entry.code, stmt, entry.feature);
|
|
1114
|
-
lowerer.unsupported("SC1090", stmt, `syntax '${ts.
|
|
1156
|
+
lowerer.unsupported("SC1090", stmt, `syntax '${ts.syntaxKindName(stmt.kind)}'`);
|
|
1115
1157
|
}
|
|
1116
1158
|
/** A variable statement may carry several declarators (`let a = 1,
|
|
1117
1159
|
* b = a + 1;`): each lowers to its own varDecl IN ORDER, so later
|
|
@@ -1150,6 +1192,7 @@ export function lowerVarStatement(lowerer, stmt) {
|
|
|
1150
1192
|
// fence.
|
|
1151
1193
|
if (decl.initializer !== undefined &&
|
|
1152
1194
|
requireSpecOf(decl.initializer) !== null &&
|
|
1195
|
+
!isNativeFfiRequire(lowerer, decl.initializer) &&
|
|
1153
1196
|
isJsSourceFile(decl.getSourceFile())) {
|
|
1154
1197
|
const spec = requireSpecOf(decl.initializer);
|
|
1155
1198
|
if (lowerer.externalTypes.has(spec))
|
|
@@ -1253,7 +1296,7 @@ function lowerNumericIteratorDecl(lowerer, decl, isConst) {
|
|
|
1253
1296
|
if (sourceNode === null)
|
|
1254
1297
|
return null;
|
|
1255
1298
|
const sym = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
1256
|
-
if (!sym || lowerer.tdzPredeclared.has(sym))
|
|
1299
|
+
if (!sym || lowerer.ctx.tdzPredeclared.has(sym))
|
|
1257
1300
|
return null;
|
|
1258
1301
|
const source = lowerer.lowerExpr(sourceNode);
|
|
1259
1302
|
if (!((source.type.kind === "array" && source.type.elem.kind === "f64") ||
|
|
@@ -1291,7 +1334,7 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1291
1334
|
if (!call)
|
|
1292
1335
|
return null;
|
|
1293
1336
|
const sym = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
1294
|
-
if (!sym || lowerer.globalsBySymbol.has(sym) || lowerer.tdzPredeclared.has(sym))
|
|
1337
|
+
if (!sym || lowerer.globalsBySymbol.has(sym) || lowerer.ctx.tdzPredeclared.has(sym))
|
|
1295
1338
|
return null;
|
|
1296
1339
|
const rowsT = arrayOf(arrayOf(STRING));
|
|
1297
1340
|
const declared = lowerer.mapTypeOf(lowerer.typeOf(decl.name));
|
|
@@ -1523,6 +1566,13 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1523
1566
|
/** One pattern level: emits a declaration (or global assignment) per
|
|
1524
1567
|
* bound name, recursing through hidden temps for nested patterns. */
|
|
1525
1568
|
export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, out, dynSpell, allowDynObject = false) {
|
|
1569
|
+
if (ts.isObjectBindingPattern(pattern)) {
|
|
1570
|
+
const patternType = lowerer.typeOf(pattern);
|
|
1571
|
+
const patternSymbol = patternType.getSymbol();
|
|
1572
|
+
allowDynObject ||= patternSymbol?.name === "SegmentData" && lowerer.isStdlibSymbol(patternSymbol);
|
|
1573
|
+
allowDynObject ||= (patternType.flags & ts.TypeFlags.Object) !== 0 && lowerer.mapTypeOf(patternType)?.kind === "dyn";
|
|
1574
|
+
allowDynObject ||= (patternType.flags & ts.TypeFlags.Any) !== 0;
|
|
1575
|
+
}
|
|
1526
1576
|
const present = patternSourceValue(lowerer, srcRef(), ts.isArrayBindingPattern(pattern), out, locOf(pattern), dynSpell);
|
|
1527
1577
|
if (!typeEquals(present.type, srcType)) {
|
|
1528
1578
|
lowerer.lowerBindingPattern(pattern, () => present, present.type, isLet, out, dynSpell, allowDynObject);
|
|
@@ -1530,6 +1580,23 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1530
1580
|
}
|
|
1531
1581
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
1532
1582
|
lowerer.fenceStaticHeadersIteration(pattern);
|
|
1583
|
+
if (srcType.kind === "union" && lowerer.unions.get(srcType.unionId)?.arms.every((arm) => arm.kind === "array")) {
|
|
1584
|
+
for (let i = 0; i < pattern.elements.length; i++) {
|
|
1585
|
+
const el = pattern.elements[i];
|
|
1586
|
+
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1587
|
+
continue;
|
|
1588
|
+
if (el.dotDotDotToken)
|
|
1589
|
+
lowerer.unsupported("SC1031", el, "rest elements over a union of array layouts");
|
|
1590
|
+
const loc = locOf(el);
|
|
1591
|
+
let value = unionArrayValueRead(lowerer, srcRef(), numLit(i, loc), loc);
|
|
1592
|
+
if (!value)
|
|
1593
|
+
lowerer.unsupported("SC1031", el, "array union elements without a common native representation");
|
|
1594
|
+
if (el.initializer)
|
|
1595
|
+
value = applyBindingDefault(lowerer, el, value);
|
|
1596
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
1597
|
+
}
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1533
1600
|
// Tuple sources: each position is a field read of the tuple's record
|
|
1534
1601
|
// shape — the positional twin of object destructuring below.
|
|
1535
1602
|
const tupleShape = srcType.kind === "record" ? lowerer.shapes.get(srcType.shapeId) : undefined;
|
|
@@ -1665,13 +1732,13 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1665
1732
|
out.push({
|
|
1666
1733
|
kind: "varDecl",
|
|
1667
1734
|
localId: pack.id,
|
|
1668
|
-
init: {
|
|
1735
|
+
init: pattern.elements.some((element) => ts.isBindingElement(element) && element.dotDotDotToken) ? {
|
|
1669
1736
|
kind: "libCall",
|
|
1670
1737
|
fn: "dyn.iterPack",
|
|
1671
1738
|
args: [srcRef(), { kind: "strLit", value: dynSpell ?? "", type: STRING, loc }],
|
|
1672
1739
|
type: DYN,
|
|
1673
1740
|
loc,
|
|
1674
|
-
},
|
|
1741
|
+
} : { kind: "dynIterN", value: srcRef(), count: pattern.elements.length, ...(dynSpell ? { notIterableMessage: dynSpell } : {}), type: DYN, loc },
|
|
1675
1742
|
loc,
|
|
1676
1743
|
});
|
|
1677
1744
|
pattern.elements.forEach((el, i) => {
|
|
@@ -1679,7 +1746,9 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1679
1746
|
return; // hole: the position skips
|
|
1680
1747
|
const elLoc = locOf(el);
|
|
1681
1748
|
if (el.dotDotDotToken) {
|
|
1682
|
-
lowerer.
|
|
1749
|
+
lowerer.bindPatternTarget(el.name, { kind: "dynInvoke", recv: varRef(pack.id, DYN, elLoc),
|
|
1750
|
+
method: "slice", calleeName: "Array.prototype.slice", args: [lowerer.coerceToExpected(numLit(i, elLoc), DYN)], type: DYN, loc: elLoc }, isLet, out);
|
|
1751
|
+
return;
|
|
1683
1752
|
}
|
|
1684
1753
|
let value = {
|
|
1685
1754
|
kind: "dynKeyGet",
|
|
@@ -1693,7 +1762,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1693
1762
|
// its value converting into the checked-dynamic tree like any dyn-slot value.
|
|
1694
1763
|
const rl = lowerer.declareHiddenLocal("%delem", DYN);
|
|
1695
1764
|
out.push({ kind: "varDecl", localId: rl.id, init: value, loc: elLoc });
|
|
1696
|
-
const dflt = lowerer.
|
|
1765
|
+
const dflt = lowerer.coerceInto(el.initializer, lowerer.lowerExpr(el.initializer), DYN);
|
|
1697
1766
|
if (dflt.type.kind !== "dyn") {
|
|
1698
1767
|
lowerer.unsupported("SC1031", el.initializer, `defaults of '${lowerer.fmt(dflt.type)}' type over checked-dynamic sources (the value cannot convert into the checked-dynamic tree)`);
|
|
1699
1768
|
}
|
|
@@ -1816,14 +1885,26 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1816
1885
|
// scoped TypeScript exception: its declared result/token types are
|
|
1817
1886
|
// deliberately carried by the checked-dynamic tree, so their ordinary
|
|
1818
1887
|
// object patterns use the same exact keyed-read desugar.
|
|
1819
|
-
if (srcType.kind === "dyn"
|
|
1820
|
-
(isJsSourceFile(pattern.getSourceFile()) || allowDynObject)) {
|
|
1888
|
+
if (srcType.kind === "dyn") {
|
|
1821
1889
|
for (const el of pattern.elements) {
|
|
1822
1890
|
if (el.name === undefined)
|
|
1823
1891
|
continue;
|
|
1824
1892
|
const loc = locOf(el);
|
|
1825
1893
|
if (el.dotDotDotToken) {
|
|
1826
|
-
|
|
1894
|
+
const keys = [];
|
|
1895
|
+
for (const sibling of pattern.elements) {
|
|
1896
|
+
if (sibling === el || sibling.dotDotDotToken)
|
|
1897
|
+
continue;
|
|
1898
|
+
const key = sibling.propertyName ?? sibling.name;
|
|
1899
|
+
const name = ts.isIdentifier(key) || ts.isStringLiteralLike(key) || ts.isNumericLiteral(key) || ts.isComputedPropertyName(key)
|
|
1900
|
+
? patternKeyNameOf(lowerer, key) : null;
|
|
1901
|
+
if (name === null)
|
|
1902
|
+
lowerer.unsupported("SC1031", sibling, "rest bindings beside runtime computed keys");
|
|
1903
|
+
keys.push({ kind: "dynFrom", value: { kind: "strLit", value: name, type: STRING, loc }, type: DYN, loc });
|
|
1904
|
+
}
|
|
1905
|
+
lowerer.bindPatternTarget(el.name, { kind: "libCall", fn: "dyn.objectRest", args: [srcRef(),
|
|
1906
|
+
{ kind: "dynArrLit", elems: keys, type: DYN, loc }], type: DYN, loc }, isLet, out, allowDynObject);
|
|
1907
|
+
continue;
|
|
1827
1908
|
}
|
|
1828
1909
|
const prop = el.propertyName ?? el.name;
|
|
1829
1910
|
const propName = ts.isIdentifier(prop) || ts.isComputedPropertyName(prop) || ts.isStringLiteralLike(prop) || ts.isNumericLiteral(prop)
|
|
@@ -2058,6 +2139,17 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2058
2139
|
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
2059
2140
|
continue;
|
|
2060
2141
|
}
|
|
2142
|
+
if (!fieldType && isJsSourceFile(el.getSourceFile())) {
|
|
2143
|
+
// Inferred JavaScript shapes can omit optional own properties and
|
|
2144
|
+
// inherit values from their prototype. Read the live checked view.
|
|
2145
|
+
const loc = locOf(el);
|
|
2146
|
+
let value = { kind: "dynKeyGet", value: lowerer.coerceToExpected(srcRef(), DYN),
|
|
2147
|
+
key: { kind: "strLit", value: propName, type: STRING, loc }, type: DYN, loc };
|
|
2148
|
+
if (el.initializer)
|
|
2149
|
+
value = applyBindingDefault(lowerer, el, value);
|
|
2150
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
2151
|
+
continue;
|
|
2152
|
+
}
|
|
2061
2153
|
if (!fieldType) {
|
|
2062
2154
|
// The pattern names a field the source SHAPE does not carry —
|
|
2063
2155
|
// `for (let {x = 1} of [{}])` (signature 08): tsc types the binding
|
|
@@ -2108,7 +2200,8 @@ function patternSourceValue(lowerer, value, arrayPattern, out, loc, spelling) {
|
|
|
2108
2200
|
const unionId = value.type.unionId;
|
|
2109
2201
|
const arms = lowerer.unions.get(unionId)?.arms;
|
|
2110
2202
|
const present = arms?.filter((arm) => !isUnitType(arm));
|
|
2111
|
-
if (!arms || present?.length
|
|
2203
|
+
if (!arms || !present?.length || present.length === arms.length ||
|
|
2204
|
+
(present.length > 1 && !(arrayPattern && present.every((arm) => arm.kind === "array"))))
|
|
2112
2205
|
return value;
|
|
2113
2206
|
for (const [tag, arm] of arms.entries()) {
|
|
2114
2207
|
if (!isUnitType(arm))
|
|
@@ -2124,13 +2217,18 @@ function patternSourceValue(lowerer, value, arrayPattern, out, loc, spelling) {
|
|
|
2124
2217
|
else_: null, loc,
|
|
2125
2218
|
});
|
|
2126
2219
|
}
|
|
2127
|
-
|
|
2220
|
+
if (present.length === 1) {
|
|
2221
|
+
return { kind: "unionNarrow", unionId, tag: lowerer.armTag(unionId, present[0]), value, type: present[0], loc };
|
|
2222
|
+
}
|
|
2223
|
+
const type = { kind: "union", unionId: lowerer.unions.intern(present) };
|
|
2224
|
+
return lowerer.coerceToExpected(value, type);
|
|
2128
2225
|
}
|
|
2129
2226
|
/** The type a pattern element binds at — the checker's type of the bound
|
|
2130
2227
|
* identifier, or of the nested pattern itself (its implied type). Null
|
|
2131
|
-
* when the type has no static mapping
|
|
2228
|
+
* when the type has no static mapping or checked JS fallback. */
|
|
2132
2229
|
function patternBindingType(lowerer, name) {
|
|
2133
|
-
|
|
2230
|
+
const type = lowerer.typeOf(name);
|
|
2231
|
+
return lowerer.mapTypeOf(type) ?? (isJsSourceFile(name.getSourceFile()) ? dynFallbackType(lowerer, name, type) : null);
|
|
2134
2232
|
}
|
|
2135
2233
|
/** The STATIC property name of a destructuring key: identifiers spell
|
|
2136
2234
|
* themselves, string/numeric-literal keys and COMPUTED keys fold through
|
|
@@ -2334,7 +2432,7 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2334
2432
|
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)`);
|
|
2335
2433
|
}
|
|
2336
2434
|
const symbol = lowerer.checker.getSymbolAtLocation(el.name);
|
|
2337
|
-
if (!symbol || lowerer.tdzPredeclared.has(symbol)) {
|
|
2435
|
+
if (!symbol || lowerer.ctx.tdzPredeclared.has(symbol)) {
|
|
2338
2436
|
lowerer.unsupported("SC1031", el, `bindings with predeclared slots over the builtin global '${globalName}'`);
|
|
2339
2437
|
}
|
|
2340
2438
|
const g = lowerer.globalsBySymbol.get(symbol);
|
|
@@ -2353,7 +2451,7 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2353
2451
|
lowerer.stdlibGlobalAliases.set(symbol, b.alias);
|
|
2354
2452
|
}
|
|
2355
2453
|
if (b.g !== undefined) {
|
|
2356
|
-
out.push({ kind: "assign", localId: b.g.id, value: lowerer.coerceInto(b.name, token, b.g.type), loc });
|
|
2454
|
+
out.push({ kind: "assign", localId: b.g.id, value: lowerer.coerceInto(b.name, token, b.g.type), ...(b.g.tdz ? { initializes: true } : {}), loc });
|
|
2357
2455
|
}
|
|
2358
2456
|
else {
|
|
2359
2457
|
const local = lowerer.declareLocal(b.name, b.name.text, STRING, isLet);
|
|
@@ -2372,6 +2470,14 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2372
2470
|
* alike (the caller's bindPatternTarget recurses through the latter). */
|
|
2373
2471
|
function applyBindingDefault(lowerer, el, value) {
|
|
2374
2472
|
const name = el.name; // callers skip nameless elisions
|
|
2473
|
+
if (value.type.kind === "dyn") {
|
|
2474
|
+
const loc = value.loc;
|
|
2475
|
+
const local = lowerer.declareHiddenLocal("%bindingDefault", DYN);
|
|
2476
|
+
const ref = varRef(local.id, DYN, loc);
|
|
2477
|
+
const result = { kind: "ternary", cond: { kind: "dynTest", test: "undefined", value: ref, type: BOOL, loc },
|
|
2478
|
+
then: lowerer.lowerExprExpecting(el.initializer, DYN), else_: ref, type: DYN, loc };
|
|
2479
|
+
return { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: local.id, init: value, loc }], result, type: DYN, loc };
|
|
2480
|
+
}
|
|
2375
2481
|
if (value.type.kind !== "union")
|
|
2376
2482
|
return value; // no undefined arm: dead default
|
|
2377
2483
|
if (lowerer.armTag(value.type.unionId, UNDEFINED_T) < 0)
|
|
@@ -2401,7 +2507,12 @@ function undefArmDefault(lowerer, blame, init, value, bodyT) {
|
|
|
2401
2507
|
return { kind: "ternary", cond: isUndef, then: dflt, else_: value, type: bodyT, loc };
|
|
2402
2508
|
}
|
|
2403
2509
|
let present = null;
|
|
2404
|
-
if (bodyT.kind === "
|
|
2510
|
+
if (bodyT.kind === "dyn" && lowerer.dynConvertible(fieldType)) {
|
|
2511
|
+
// The undefined arm is handled by the ternary. A present JSON-safe
|
|
2512
|
+
// union can cross into the binding's checked-dynamic slot.
|
|
2513
|
+
present = lowerer.coerceInto(blame, value, bodyT);
|
|
2514
|
+
}
|
|
2515
|
+
else if (bodyT.kind === "union") {
|
|
2405
2516
|
const retag = lowerer.unionRetagHelper(fieldType.unionId, bodyT.unionId, loc);
|
|
2406
2517
|
if (retag)
|
|
2407
2518
|
present = { kind: "call", callee: retag, args: [value], type: bodyT, loc };
|
|
@@ -2644,6 +2755,9 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
|
|
|
2644
2755
|
* JS skips them and so does the packing. */
|
|
2645
2756
|
function classInstanceRestValue(lowerer, blame, srcRef, srcType, info, consumed, restT) {
|
|
2646
2757
|
const loc = locOf(blame);
|
|
2758
|
+
if (info.symbolFields?.size) {
|
|
2759
|
+
lowerer.unsupported("SC1031", blame, "rest bindings over class instances with symbol-keyed fields (the copied symbols have no record form)");
|
|
2760
|
+
}
|
|
2647
2761
|
for (let c = info; c; c = c.base) {
|
|
2648
2762
|
if (c.builtinError || c.builtinEmitter || c.builtinStream) {
|
|
2649
2763
|
lowerer.unsupported("SC1031", blame, "rest bindings over runtime-provided class instances (Error/EventEmitter/stream internals have no record form)");
|
|
@@ -2905,7 +3019,7 @@ function enginePatternSpec(lowerer, pattern) {
|
|
|
2905
3019
|
const d = exprText(el.initializer, boundBefore);
|
|
2906
3020
|
if (d === null)
|
|
2907
3021
|
return null;
|
|
2908
|
-
sub
|
|
3022
|
+
sub = sub + `=${d}`;
|
|
2909
3023
|
}
|
|
2910
3024
|
parts.push(el.dotDotDotToken ? `...${sub}` : sub);
|
|
2911
3025
|
}
|
|
@@ -2950,7 +3064,7 @@ function enginePatternSpec(lowerer, pattern) {
|
|
|
2950
3064
|
const d = exprText(el.initializer, boundBefore);
|
|
2951
3065
|
if (d === null)
|
|
2952
3066
|
return null;
|
|
2953
|
-
sub
|
|
3067
|
+
sub = sub + `=${d}`;
|
|
2954
3068
|
}
|
|
2955
3069
|
parts.push(`[${key}]:${sub}`);
|
|
2956
3070
|
}
|
|
@@ -3026,7 +3140,7 @@ export function lowerJsvalBindingPattern(lowerer, pattern, srcRef, isLet, out) {
|
|
|
3026
3140
|
const symbol = lowerer.checker.getSymbolAtLocation(name);
|
|
3027
3141
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
3028
3142
|
if (g) {
|
|
3029
|
-
out.push({ kind: "assign", localId: g.id, value: lowerer.coerceInto(name, value, g.type), loc: bindLoc });
|
|
3143
|
+
out.push({ kind: "assign", localId: g.id, value: lowerer.coerceInto(name, value, g.type), ...(g.tdz ? { initializes: true } : {}), loc: bindLoc });
|
|
3030
3144
|
return;
|
|
3031
3145
|
}
|
|
3032
3146
|
if (symbol && hostVariableDeclarationOf(name) !== null && isVarDeclared(name)) {
|
|
@@ -3056,7 +3170,7 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3056
3170
|
const symbol = lowerer.checker.getSymbolAtLocation(name);
|
|
3057
3171
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
3058
3172
|
if (g) {
|
|
3059
|
-
out.push({ kind: "assign", localId: g.id, value: lowerer.coerceInto(name, value, g.type), loc });
|
|
3173
|
+
out.push({ kind: "assign", localId: g.id, value: lowerer.coerceInto(name, value, g.type), ...(g.tdz ? { initializes: true } : {}), loc });
|
|
3060
3174
|
return;
|
|
3061
3175
|
}
|
|
3062
3176
|
// A `var`-declared pattern name assigns its function-scoped hoisted
|
|
@@ -3115,13 +3229,9 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3115
3229
|
out.push({ kind: "varDecl", localId: tmp.id, init: value, loc });
|
|
3116
3230
|
lowerer.lowerBindingPattern(name, () => ({ kind: "varRef", localId: tmp.id, type: value.type, loc }), value.type, isLet, out, undefined, allowDynObject);
|
|
3117
3231
|
}
|
|
3118
|
-
/** For-loop initializers
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
* function-scoped binding with no per-iteration copies to model, so
|
|
3122
|
-
* `for (var i = 0, n = xs.length; ...)` is just two hoisted-slot
|
|
3123
|
-
* assignments (wrapped in a block when several). Statement position goes
|
|
3124
|
-
* through lowerVarStatement. */
|
|
3232
|
+
/** For-loop initializers evaluate declarators from left to right. The LLVM
|
|
3233
|
+
* loop emitter keeps their scope alive and freshens every captured let
|
|
3234
|
+
* binding before the first condition and each subsequent update. */
|
|
3125
3235
|
export function lowerVarDeclList(lowerer, list) {
|
|
3126
3236
|
if ((list.flags & ts.NodeFlags.Using) !== 0) {
|
|
3127
3237
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
@@ -3144,23 +3254,19 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3144
3254
|
return out[0];
|
|
3145
3255
|
return { kind: "block", body: out, loc: locOf(list) };
|
|
3146
3256
|
}
|
|
3147
|
-
|
|
3148
|
-
|
|
3257
|
+
const out = [];
|
|
3258
|
+
for (const decl of list.declarations) {
|
|
3259
|
+
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
3260
|
+
// Destructuring produces nested initialization blocks; copying
|
|
3261
|
+
// their captured bindings still needs a distinct head-scope plan.
|
|
3262
|
+
lowerer.unsupported("SC1031", decl.name, "let/const destructuring in for-loop initializers (declare the pattern before the loop, or use var)");
|
|
3263
|
+
}
|
|
3264
|
+
const lowered = lowerer.lowerVarDecl(decl, isLet);
|
|
3265
|
+
if (!lowered)
|
|
3266
|
+
throw new InternalCompilerError("lowerer bug: for-init declarator resolved to a global");
|
|
3267
|
+
out.push(lowered);
|
|
3149
3268
|
}
|
|
3150
|
-
|
|
3151
|
-
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
3152
|
-
// `for (let [x] = init; ...)`: the desugar is a multi-statement
|
|
3153
|
-
// block, and the backend's per-iteration fresh-binding copy (what
|
|
3154
|
-
// makes closures in iteration k see iteration k's let) keys off a
|
|
3155
|
-
// single varDecl init — a captured destructured head would silently
|
|
3156
|
-
// share one binding. `var` heads above have no per-iteration story
|
|
3157
|
-
// and lower; let/const keep an honest fence.
|
|
3158
|
-
lowerer.unsupported("SC1031", decl.name, "let/const destructuring in for-loop initializers (declare the pattern before the loop, or use var)");
|
|
3159
|
-
}
|
|
3160
|
-
const lowered = lowerer.lowerVarDecl(decl, isLet);
|
|
3161
|
-
if (!lowered)
|
|
3162
|
-
throw new InternalCompilerError("lowerer bug: for-init declarator resolved to a global");
|
|
3163
|
-
return lowered;
|
|
3269
|
+
return out.length === 1 ? out[0] : { kind: "block", body: out, loc: locOf(list) };
|
|
3164
3270
|
}
|
|
3165
3271
|
/** A single static type for an initializer-less JavaScript `let` whose
|
|
3166
3272
|
* later plain writes all agree. An evolving JS local reads as `undefined`
|
|
@@ -3173,7 +3279,7 @@ function inferredEvolvingLetType(lowerer, decl) {
|
|
|
3173
3279
|
if (!ts.isIdentifier(decl.name))
|
|
3174
3280
|
return null;
|
|
3175
3281
|
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
3176
|
-
const scope = decl.parent
|
|
3282
|
+
const scope = decl.parent?.parent?.parent;
|
|
3177
3283
|
if (symbol === undefined || (!ts.isBlock(scope) && !ts.isSourceFile(scope)))
|
|
3178
3284
|
return null;
|
|
3179
3285
|
const isPlainAssignmentTarget = (node) => {
|
|
@@ -3313,8 +3419,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3313
3419
|
// and keep the plain-variable lowering.
|
|
3314
3420
|
if (!decl.initializer &&
|
|
3315
3421
|
(decl.name.text === "module" || decl.name.text === "exports") &&
|
|
3316
|
-
ts.isVariableStatement(decl.parent
|
|
3317
|
-
ts.isSourceFile(decl.parent
|
|
3422
|
+
ts.isVariableStatement(decl.parent?.parent) &&
|
|
3423
|
+
ts.isSourceFile(decl.parent?.parent?.parent) &&
|
|
3318
3424
|
!isJsSourceFile(decl.getSourceFile()) &&
|
|
3319
3425
|
!decl.getSourceFile().statements.some((s) => ts.isImportDeclaration(s) || ts.isExportDeclaration(s) || ts.isExportAssignment(s) ||
|
|
3320
3426
|
(ts.canHaveModifiers(s) && ts.getModifiers(s)?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) === true))) {
|
|
@@ -3335,7 +3441,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3335
3441
|
// plumbing: each call through the binding resolves per site
|
|
3336
3442
|
// (lowerCreateRequireCall); no storage, no code (collectGlobals
|
|
3337
3443
|
// skipped its global by the same test).
|
|
3338
|
-
if (
|
|
3444
|
+
if (createRequireBindingDecl(lowerer, decl.name, decl.initializer))
|
|
3339
3445
|
return null;
|
|
3340
3446
|
// `const fs = require("node:fs")` through that binding — a builtin
|
|
3341
3447
|
// namespace import in const clothing: alias plumbing, no storage
|
|
@@ -3366,13 +3472,6 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3366
3472
|
})());
|
|
3367
3473
|
if (stableStdlibAlias && stdlibGlobalAliasDecl(lowerer, decl.name, decl.initializer))
|
|
3368
3474
|
return null;
|
|
3369
|
-
// `const encoder = new TextEncoder()` and a statically-labelled
|
|
3370
|
-
// TextDecoder twin: the codec has no general value representation, but calls
|
|
3371
|
-
// through this stable binding resolve back to the initializer. The
|
|
3372
|
-
// supported constructors are effect-free, so the declaration itself
|
|
3373
|
-
// is compile-time alias plumbing with no storage or code.
|
|
3374
|
-
if (!isLet && textCodecBindingDecl(lowerer, decl.name, decl.initializer))
|
|
3375
|
-
return null;
|
|
3376
3475
|
// `const f = <T>(x: T) => x` — a generic function value binding: the
|
|
3377
3476
|
// initializer monomorphizes per call-site-resolved signature exactly
|
|
3378
3477
|
// like a generic function declaration (bindingGenericFnInfoOf —
|
|
@@ -3478,7 +3577,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3478
3577
|
return { kind: "assign", localId: g.id, value: wrapped, loc: locOf(decl) };
|
|
3479
3578
|
return null;
|
|
3480
3579
|
}
|
|
3481
|
-
const raw = lowerVariableInitializer(lowerer, decl.initializer)
|
|
3580
|
+
const raw = lowerVariableInitializer(lowerer, decl.initializer, g.type.kind === "dyn" && (isNativeBuiltinValueInitializer(lowerer, decl.initializer) ||
|
|
3581
|
+
ts.isArrayLiteralExpression(decl.initializer) || ts.isObjectLiteralExpression(decl.initializer)) ? DYN : undefined);
|
|
3482
3582
|
const arithmetic = raw.type.kind === "union"
|
|
3483
3583
|
? lowerer.unions.get(raw.type.unionId)?.arms
|
|
3484
3584
|
: undefined;
|
|
@@ -3488,17 +3588,17 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3488
3588
|
lowerer.runtimeOptionalArithmeticGlobals.add(g);
|
|
3489
3589
|
}
|
|
3490
3590
|
const init = lowerer.coerceInto(decl.initializer, raw, g.type);
|
|
3491
|
-
return { kind: "assign", localId: g.id, value: init, loc: locOf(decl) };
|
|
3591
|
+
return { kind: "assign", localId: g.id, value: init, ...(g.tdz ? { initializes: true } : {}), loc: locOf(decl) };
|
|
3492
3592
|
}
|
|
3493
|
-
// A forward-captured
|
|
3593
|
+
// A forward-captured binding pre-declared as a TDZ box (an earlier
|
|
3494
3594
|
// function in this scope captured it — predeclareForwardCapture): the
|
|
3495
3595
|
// binding and its scope-entry varDecl already exist; the source
|
|
3496
3596
|
// declaration is the one initializing `assign` into the shared box.
|
|
3497
|
-
const pre = declSymbol ? lowerer.tdzPredeclared.get(declSymbol) : undefined;
|
|
3597
|
+
const pre = declSymbol ? lowerer.ctx.tdzPredeclared.get(declSymbol) : undefined;
|
|
3498
3598
|
if (pre && decl.initializer) {
|
|
3499
|
-
lowerer.tdzPredeclared.delete(declSymbol);
|
|
3599
|
+
lowerer.ctx.tdzPredeclared.delete(declSymbol);
|
|
3500
3600
|
const init = lowerer.lowerExprExpecting(decl.initializer, pre.type);
|
|
3501
|
-
return { kind: "assign", localId: pre.id, value: init, loc: locOf(decl) };
|
|
3601
|
+
return { kind: "assign", localId: pre.id, value: init, initializes: true, loc: locOf(decl) };
|
|
3502
3602
|
}
|
|
3503
3603
|
// `var x = e` — an ASSIGNMENT into the function-scoped hoisted slot
|
|
3504
3604
|
// (hoistVarBinding mints it on first encounter and pushes its varDecl
|
|
@@ -3529,7 +3629,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3529
3629
|
// `var v: void;` / `let x: undefined;` — a unit-only binding rides
|
|
3530
3630
|
// the unit-only union (its undefined arm is the unassigned state,
|
|
3531
3631
|
// which is also the only state).
|
|
3532
|
-
if (type.kind === "void" && isUnitOnlyTsType(lowerer.typeOf(decl.name))) {
|
|
3632
|
+
if (type.kind === "void" && isUnitOnlyTsType(lowerer.typeOf(decl.name), lowerer.typeParamResolver)) {
|
|
3533
3633
|
type = unitOnlyUnion(lowerer.unions);
|
|
3534
3634
|
}
|
|
3535
3635
|
if (type.kind === "void")
|
|
@@ -3546,11 +3646,19 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3546
3646
|
// function (with its hint), not the unmappable declared type. If it
|
|
3547
3647
|
// poisons, still declare the local when its type is representable, so
|
|
3548
3648
|
// later references to this name don't produce cascading errors.
|
|
3649
|
+
const inferredObjectType = isJsSourceFile(decl.getSourceFile()) ? lowerer.mapTypeOf(lowerer.typeOf(decl.name)) : null;
|
|
3650
|
+
const inferredObjectArms = inferredObjectType?.kind === "union"
|
|
3651
|
+
? lowerer.unions.get(inferredObjectType.unionId)?.arms ?? [] : inferredObjectType ? [inferredObjectType] : [];
|
|
3652
|
+
const expandsObject = !decl.type && !hasJsTypeAnnotation(decl) && inferredObjectType !== null &&
|
|
3653
|
+
jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn" ||
|
|
3654
|
+
inferredObjectArms.some((arm) => arm.kind === "record" && jsObjectBindingExpands(lowerer, decl, arm));
|
|
3549
3655
|
let init;
|
|
3550
3656
|
try {
|
|
3551
|
-
init =
|
|
3657
|
+
init = expandsObject || (isJsSourceFile(decl.getSourceFile()) && !decl.type &&
|
|
3658
|
+
isNativeBuiltinValueInitializer(lowerer, decl.initializer)) ? lowerer.lowerExprExpecting(decl.initializer, DYN) : immediatelyGuardedAbsenceProbe(lowerer, decl)
|
|
3552
3659
|
? (lowerAbsenceProbe(lowerer, decl.initializer) ?? lowerer.lowerExpr(decl.initializer))
|
|
3553
|
-
: lowerVariableInitializer(lowerer, decl.initializer)
|
|
3660
|
+
: lowerVariableInitializer(lowerer, decl.initializer, decl.type && (lowerer.typeOf(decl.name).flags & ts.TypeFlags.Never) === 0
|
|
3661
|
+
? lowerer.mapTypeOf(lowerer.typeOf(decl.name)) ?? undefined : undefined);
|
|
3554
3662
|
}
|
|
3555
3663
|
catch (e) {
|
|
3556
3664
|
if (e instanceof PoisonError) {
|
|
@@ -3598,12 +3706,31 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3598
3706
|
staticImportNamespaceType(lowerer, decl.initializer) ??
|
|
3599
3707
|
(init.type.kind === "moduleNs" ? init.type : null) ??
|
|
3600
3708
|
(init.type.kind === "dyn" ? DYN : null);
|
|
3709
|
+
if (isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) && init.type.kind === "func")
|
|
3710
|
+
type = init.type;
|
|
3601
3711
|
if (lowerer.implicitParamTypes !== null &&
|
|
3602
3712
|
init.type.kind === "dyn" &&
|
|
3603
3713
|
isJsSourceFile(decl.getSourceFile()) &&
|
|
3604
3714
|
npmStaticPackageOfPath(decl.getSourceFile().fileName) !== null) {
|
|
3605
3715
|
type = DYN;
|
|
3606
3716
|
}
|
|
3717
|
+
const preservesObjectIdentity = init.type.kind === "dyn" &&
|
|
3718
|
+
(inferredObjectType?.kind === "record" || inferredObjectType?.kind === "array" ||
|
|
3719
|
+
(isJsSourceFile(decl.getSourceFile()) && inferredObjectArms.some((arm) => arm.kind === "record") &&
|
|
3720
|
+
inferredObjectArms.every((arm) => isUnitType(arm) || arm.kind === "record")) ||
|
|
3721
|
+
(isJsSourceFile(decl.getSourceFile()) && inferredObjectType !== null &&
|
|
3722
|
+
(inferredObjectType.kind === "date" || inferredObjectType.kind === "func" || inferredObjectType.kind === "object" || jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn")) ||
|
|
3723
|
+
(isJsSourceFile(decl.getSourceFile()) && inferredObjectType !== null &&
|
|
3724
|
+
(inferredObjectType.kind === "void" || isUnitType(inferredObjectType) || inferredObjectType.kind === "union" && lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType)))) &&
|
|
3725
|
+
!decl.type && !hasJsTypeAnnotation(decl);
|
|
3726
|
+
if (expandsObject || preservesObjectIdentity || (isJsSourceFile(decl.getSourceFile()) &&
|
|
3727
|
+
!decl.type && isNativeBuiltinValueInitializer(lowerer, decl.initializer))) {
|
|
3728
|
+
type = DYN;
|
|
3729
|
+
}
|
|
3730
|
+
if (isJsSourceFile(decl.getSourceFile()) && !decl.type && init.type.kind === "array" && init.type.elem.kind === "dyn" &&
|
|
3731
|
+
(ts.isNewExpression(decl.initializer) || ts.isCallExpression(decl.initializer)) && lowerer.isStdlibGlobal(decl.initializer.expression, "Array")) {
|
|
3732
|
+
type = init.type;
|
|
3733
|
+
}
|
|
3607
3734
|
// A JS `let x = {}`: TS's empty-object-literal type admits ANY later
|
|
3608
3735
|
// non-nullish assignment (`envs = {}`, later `envs =
|
|
3609
3736
|
// Object.fromEntries(...)` — tsc accepts every such write, since
|
|
@@ -3616,6 +3743,10 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3616
3743
|
if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
|
|
3617
3744
|
type = DYN;
|
|
3618
3745
|
}
|
|
3746
|
+
if (isLet && type !== null && isJsSourceFile(decl.getSourceFile()) && !decl.type && !hasJsTypeAnnotation(decl) &&
|
|
3747
|
+
(type.kind === "object" || type.kind === "symbol" || jsBindingHasOpenWrites(lowerer, decl))) {
|
|
3748
|
+
type = DYN;
|
|
3749
|
+
}
|
|
3619
3750
|
const returnedEmptyArrayType = npmStaticReturnedEmptyArrayType(lowerer, decl);
|
|
3620
3751
|
if (returnedEmptyArrayType !== null) {
|
|
3621
3752
|
type = returnedEmptyArrayType;
|
|
@@ -3681,7 +3812,9 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3681
3812
|
// static signature would wrap an arity-narrowing adapter that DROPS
|
|
3682
3813
|
// arguments JS would deliver; calls through the dyn binding take the
|
|
3683
3814
|
// boxed thunk's JS arity instead.
|
|
3684
|
-
if (type?.kind === "func" && init.type.kind === "dyn" &&
|
|
3815
|
+
if (type?.kind === "func" && init.type.kind === "dyn" &&
|
|
3816
|
+
(isJsSourceFile(decl.getSourceFile()) ||
|
|
3817
|
+
!decl.type && !hasJsTypeAnnotation(decl) && type.rest === true && type.restAbi === undefined)) {
|
|
3685
3818
|
type = DYN;
|
|
3686
3819
|
}
|
|
3687
3820
|
// A checker-`any` CONST whose initializer lowered to a STATIC type
|
|
@@ -3718,6 +3851,9 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3718
3851
|
if (!type)
|
|
3719
3852
|
lowerer.badType(decl.name, lowerer.typeOf(decl.name));
|
|
3720
3853
|
let settledType = type;
|
|
3854
|
+
if (!isLet && isJsSourceFile(decl.getSourceFile()) && !hasJsTypeAnnotation(decl) && decl.initializer && ts.isNewExpression(decl.initializer)) {
|
|
3855
|
+
settledType = init.type.kind === "dyn" ? DYN : objectFactorySignature(lowerer, decl.initializer)?.returnType ?? settledType;
|
|
3856
|
+
}
|
|
3721
3857
|
const arithmeticType = decl.initializer ? lowerer.runtimeOptionalArithmeticTypes.get(decl.initializer) : undefined;
|
|
3722
3858
|
const isStringArithmeticUnion = (t) => {
|
|
3723
3859
|
if (t.kind !== "union")
|
|
@@ -3734,16 +3870,26 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3734
3870
|
const optionalSelfWriteType = isLet
|
|
3735
3871
|
? npmStaticOptionalSelfWriteType(lowerer, decl, settledType)
|
|
3736
3872
|
: null;
|
|
3737
|
-
settledType = lowerer.runtimeOptionalBindingType(decl.name, settledType);
|
|
3873
|
+
settledType = expandsObject || preservesObjectIdentity ? DYN : lowerer.runtimeOptionalBindingType(decl.name, settledType);
|
|
3738
3874
|
if (optionalSelfWriteType !== null)
|
|
3739
3875
|
settledType = optionalSelfWriteType;
|
|
3740
3876
|
if (returnedEmptyArrayType !== null)
|
|
3741
3877
|
settledType = returnedEmptyArrayType;
|
|
3878
|
+
// Exhaustiveness witnesses (`const unreachable: never = value`) have
|
|
3879
|
+
// no useful checker layout, but their initializer still has a runtime
|
|
3880
|
+
// representation. Preserve it instead of forcing never's numeric
|
|
3881
|
+
// placeholder onto a recursive union or string. Keeping the value also
|
|
3882
|
+
// preserves behavior when an explicit assertion makes this reachable.
|
|
3883
|
+
if (!isLet && lowerer.checker.isNeverType(lowerer.typeOf(decl.name)) &&
|
|
3884
|
+
init.type.kind !== "void" && !isUnitType(init.type)) {
|
|
3885
|
+
settledType = init.type;
|
|
3886
|
+
}
|
|
3742
3887
|
// `const x: void = undefined` / `let y: undefined = undefined`: the
|
|
3743
3888
|
// unit-only union — the initializer's unit literal wraps into its arm
|
|
3744
|
-
// like any optional completion.
|
|
3745
|
-
// void
|
|
3746
|
-
|
|
3889
|
+
// like any optional completion. A generic visitor can bind the slot's
|
|
3890
|
+
// T to void; consult that binding before deciding its value layout.
|
|
3891
|
+
// coerceInto preserves a void call's effects before wrapping undefined.
|
|
3892
|
+
if (settledType.kind === "void" && isUnitOnlyTsType(lowerer.typeOf(decl.name), lowerer.typeParamResolver)) {
|
|
3747
3893
|
settledType = unitOnlyUnion(lowerer.unions);
|
|
3748
3894
|
}
|
|
3749
3895
|
if (settledType.kind === "void")
|
|
@@ -3817,15 +3963,15 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3817
3963
|
settledType = init.type;
|
|
3818
3964
|
}
|
|
3819
3965
|
// A TDZ box minted DURING this very initializer (a callback inside it
|
|
3820
|
-
// captured this
|
|
3966
|
+
// captured this binding — predeclareForwardCapture's current-statement
|
|
3821
3967
|
// case): the binding and its scope-entry varDecl already exist, so
|
|
3822
3968
|
// this declaration is the initializing `assign` into the shared box,
|
|
3823
3969
|
// not a fresh local.
|
|
3824
|
-
const preSelf = declSymbol ? lowerer.tdzPredeclared.get(declSymbol) : undefined;
|
|
3970
|
+
const preSelf = declSymbol ? lowerer.ctx.tdzPredeclared.get(declSymbol) : undefined;
|
|
3825
3971
|
if (preSelf) {
|
|
3826
|
-
lowerer.tdzPredeclared.delete(declSymbol);
|
|
3972
|
+
lowerer.ctx.tdzPredeclared.delete(declSymbol);
|
|
3827
3973
|
init = lowerer.coerceInto(decl.initializer, init, preSelf.type);
|
|
3828
|
-
return { kind: "assign", localId: preSelf.id, value: init, loc: locOf(decl) };
|
|
3974
|
+
return { kind: "assign", localId: preSelf.id, value: init, initializes: true, loc: locOf(decl) };
|
|
3829
3975
|
}
|
|
3830
3976
|
// Slot coercion: `const r: A | B = bValue;` wraps implicitly; width
|
|
3831
3977
|
// subtyping (`const p: {a: number} = wider;`) is rejected, not coerced.
|
|
@@ -3841,7 +3987,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3841
3987
|
}
|
|
3842
3988
|
return { kind: "varDecl", localId: local.id, init, loc: locOf(decl) };
|
|
3843
3989
|
}
|
|
3844
|
-
function lowerVariableInitializer(lowerer, node) {
|
|
3990
|
+
function lowerVariableInitializer(lowerer, node, expected) {
|
|
3845
3991
|
let value = node;
|
|
3846
3992
|
while (ts.isParenthesizedExpression(value) ||
|
|
3847
3993
|
ts.isAsExpression(value) ||
|
|
@@ -3849,8 +3995,20 @@ function lowerVariableInitializer(lowerer, node) {
|
|
|
3849
3995
|
ts.isSatisfiesExpression(value)) {
|
|
3850
3996
|
value = value.expression;
|
|
3851
3997
|
}
|
|
3852
|
-
|
|
3853
|
-
|
|
3998
|
+
// An explicit destination supplies the layout for fresh construction,
|
|
3999
|
+
// including either arm of a conditional. Existing values still pass
|
|
4000
|
+
// through the normal conversion and alias-preservation rules.
|
|
4001
|
+
if (!ts.isObjectLiteralExpression(value)) {
|
|
4002
|
+
// Empty Map/Set construction can use its destination, but class
|
|
4003
|
+
// instances must retain their nominal layout for generic dispatch.
|
|
4004
|
+
const empty = expected ? lowerer.emptyCollectionFor(node, expected) : null;
|
|
4005
|
+
if (empty)
|
|
4006
|
+
return lowerer.coerceInto(node, empty, expected);
|
|
4007
|
+
return ts.isArrayLiteralExpression(value) || ts.isConditionalExpression(value)
|
|
4008
|
+
? lowerer.lowerExprExpecting(node, expected) : lowerer.lowerExpr(node);
|
|
4009
|
+
}
|
|
4010
|
+
if (expected?.kind === "dyn")
|
|
4011
|
+
return lowerDynObjectLiteral(lowerer, value);
|
|
3854
4012
|
const previous = new Map();
|
|
3855
4013
|
for (const property of value.properties) {
|
|
3856
4014
|
if (!ts.isPropertyAssignment(property) || !ts.isComputedPropertyName(property.name))
|
|
@@ -3864,7 +4022,7 @@ function lowerVariableInitializer(lowerer, node) {
|
|
|
3864
4022
|
lowerer.chainRecvByNode.set(keyNode, lowerer.ensureString(optional, keyNode));
|
|
3865
4023
|
}
|
|
3866
4024
|
try {
|
|
3867
|
-
return lowerer.
|
|
4025
|
+
return lowerer.lowerExprExpecting(node, expected);
|
|
3868
4026
|
}
|
|
3869
4027
|
finally {
|
|
3870
4028
|
for (const [keyNode, prior] of previous) {
|
|
@@ -3875,6 +4033,118 @@ function lowerVariableInitializer(lowerer, node) {
|
|
|
3875
4033
|
}
|
|
3876
4034
|
}
|
|
3877
4035
|
}
|
|
4036
|
+
/** A JS object literal's inferred fields do not close its later storage.
|
|
4037
|
+
* Keep the original native object when writes add keys or delete fields;
|
|
4038
|
+
* converting it to a fixed record would discard that behavior. */
|
|
4039
|
+
function jsObjectBindingExpands(lowerer, decl, type) {
|
|
4040
|
+
if (decl.type || !decl.initializer || !ts.isIdentifier(decl.name) || !isJsSourceFile(decl.getSourceFile()))
|
|
4041
|
+
return false;
|
|
4042
|
+
let initializer = decl.initializer;
|
|
4043
|
+
while (ts.isParenthesizedExpression(initializer))
|
|
4044
|
+
initializer = initializer.expression;
|
|
4045
|
+
if (!ts.isObjectLiteralExpression(initializer) && !ts.isCallExpression(initializer))
|
|
4046
|
+
return false;
|
|
4047
|
+
if (hasJsTypeAnnotation(decl))
|
|
4048
|
+
return false;
|
|
4049
|
+
// A generic clone retains its declared T contract. Its instantiated
|
|
4050
|
+
// record is also the factory's return/capture layout; it is not an
|
|
4051
|
+
// anonymous JavaScript object whose fields came only from inference.
|
|
4052
|
+
if (lowerer.typeParamResolver(lowerer.typeOf(decl.name)) !== null)
|
|
4053
|
+
return false;
|
|
4054
|
+
const symbol = lowerer.resolveValueSymbol(decl.name);
|
|
4055
|
+
const shape = lowerer.shapes.get(type.shapeId);
|
|
4056
|
+
if (!symbol || !shape)
|
|
4057
|
+
return false;
|
|
4058
|
+
const names = new Set(shape.fields.map((field) => field.name));
|
|
4059
|
+
let scope = decl;
|
|
4060
|
+
while (scope.parent && !ts.isFunctionLike(scope) && !ts.isSourceFile(scope))
|
|
4061
|
+
scope = scope.parent;
|
|
4062
|
+
const aliases = new Set([symbol]);
|
|
4063
|
+
const unwrap = (node) => {
|
|
4064
|
+
while (ts.isParenthesizedExpression(node))
|
|
4065
|
+
node = node.expression;
|
|
4066
|
+
return node;
|
|
4067
|
+
};
|
|
4068
|
+
let changed = true;
|
|
4069
|
+
while (changed) {
|
|
4070
|
+
changed = false;
|
|
4071
|
+
const collect = (node) => {
|
|
4072
|
+
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer && !node.type && !hasJsTypeAnnotation(node)) {
|
|
4073
|
+
const source = unwrap(node.initializer);
|
|
4074
|
+
const sourceSymbol = ts.isIdentifier(source) ? lowerer.resolveValueSymbol(source) : undefined;
|
|
4075
|
+
const alias = lowerer.resolveValueSymbol(node.name);
|
|
4076
|
+
if (sourceSymbol && aliases.has(sourceSymbol) && alias && !aliases.has(alias)) {
|
|
4077
|
+
aliases.add(alias);
|
|
4078
|
+
changed = true;
|
|
4079
|
+
}
|
|
4080
|
+
}
|
|
4081
|
+
ts.forEachChild(node, collect);
|
|
4082
|
+
};
|
|
4083
|
+
collect(scope);
|
|
4084
|
+
}
|
|
4085
|
+
let expands = false;
|
|
4086
|
+
const property = (node) => {
|
|
4087
|
+
if (!ts.isPropertyAccessExpression(node) && !ts.isElementAccessExpression(node))
|
|
4088
|
+
return undefined;
|
|
4089
|
+
const receiver = unwrap(node.expression);
|
|
4090
|
+
const receiverSymbol = ts.isIdentifier(receiver) ? lowerer.resolveValueSymbol(receiver) : undefined;
|
|
4091
|
+
if (!receiverSymbol || !aliases.has(receiverSymbol))
|
|
4092
|
+
return undefined;
|
|
4093
|
+
if (ts.isPropertyAccessExpression(node))
|
|
4094
|
+
return node.name.text;
|
|
4095
|
+
return ts.isStringLiteral(node.argumentExpression) || ts.isNumericLiteral(node.argumentExpression)
|
|
4096
|
+
? node.argumentExpression.text : null;
|
|
4097
|
+
};
|
|
4098
|
+
const visit = (node) => {
|
|
4099
|
+
if (expands)
|
|
4100
|
+
return;
|
|
4101
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && node.operatorToken.kind <= ts.SyntaxKind.LastAssignment) {
|
|
4102
|
+
const name = property(node.left);
|
|
4103
|
+
if (name === null || (name !== undefined && !names.has(name)))
|
|
4104
|
+
expands = true;
|
|
4105
|
+
}
|
|
4106
|
+
if (ts.isDeleteExpression(node) && property(node.expression) !== undefined)
|
|
4107
|
+
expands = true;
|
|
4108
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && node.expression.name.text === "setPrototypeOf" &&
|
|
4109
|
+
lowerer.isStdlibGlobal(node.expression.expression, "Object")) {
|
|
4110
|
+
const target = node.arguments[0];
|
|
4111
|
+
const sym = target && ts.isIdentifier(target) ? lowerer.resolveValueSymbol(target) : undefined;
|
|
4112
|
+
if (sym && aliases.has(sym))
|
|
4113
|
+
expands = true;
|
|
4114
|
+
}
|
|
4115
|
+
ts.forEachChild(node, visit);
|
|
4116
|
+
};
|
|
4117
|
+
visit(scope);
|
|
4118
|
+
return expands;
|
|
4119
|
+
}
|
|
4120
|
+
export function hasJsTypeAnnotation(decl) {
|
|
4121
|
+
const statement = decl.parent?.parent;
|
|
4122
|
+
return !!statement && /@type\b/.test(decl.getSourceFile().text.slice(statement.pos, decl.getStart()));
|
|
4123
|
+
}
|
|
4124
|
+
/** Inferred JS scalar initializers do not constrain later writes through
|
|
4125
|
+
* an any-valued callback. Keep those bindings open, including captured writes. */
|
|
4126
|
+
export function jsBindingHasOpenWrites(lowerer, decl) {
|
|
4127
|
+
if (!isJsSourceFile(decl.getSourceFile()) || decl.type || hasJsTypeAnnotation(decl) || !ts.isIdentifier(decl.name))
|
|
4128
|
+
return false;
|
|
4129
|
+
const symbol = lowerer.resolveValueSymbol(decl.name);
|
|
4130
|
+
if (!symbol)
|
|
4131
|
+
return false;
|
|
4132
|
+
let owner = decl;
|
|
4133
|
+
while (owner.parent && !ts.isFunctionLike(owner) && !ts.isSourceFile(owner))
|
|
4134
|
+
owner = owner.parent;
|
|
4135
|
+
let open = false;
|
|
4136
|
+
ts.walkPreorder(owner, (node) => {
|
|
4137
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
4138
|
+
node.operatorToken.kind <= ts.SyntaxKind.LastAssignment && ts.isIdentifier(node.left) &&
|
|
4139
|
+
lowerer.resolveValueSymbol(node.left) === symbol &&
|
|
4140
|
+
(lowerer.typeOf(node.right).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0) {
|
|
4141
|
+
open = true;
|
|
4142
|
+
return "stop";
|
|
4143
|
+
}
|
|
4144
|
+
return undefined;
|
|
4145
|
+
});
|
|
4146
|
+
return open;
|
|
4147
|
+
}
|
|
3878
4148
|
function immediatelyGuardedAbsenceProbe(lowerer, decl) {
|
|
3879
4149
|
if (decl.type || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
3880
4150
|
return false;
|
|
@@ -3899,96 +4169,71 @@ function immediatelyGuardedAbsenceProbe(lowerer, decl) {
|
|
|
3899
4169
|
operand = operand.expression;
|
|
3900
4170
|
return ts.isIdentifier(operand) && lowerer.resolveValueSymbol(operand) === lowerer.resolveValueSymbol(decl.name);
|
|
3901
4171
|
}
|
|
3902
|
-
function
|
|
4172
|
+
function falsyExitRuntimeOptionalLocals(lowerer, stmt) {
|
|
3903
4173
|
if (stmt.elseStatement)
|
|
3904
|
-
return
|
|
3905
|
-
let
|
|
3906
|
-
while (ts.
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
const local = lowerer.resolveLocal(operand);
|
|
3916
|
-
if (!local || !lowerer.runtimeOptionalLocals.has(lowerer.runtimeOptionalRootOf(local)))
|
|
3917
|
-
return null;
|
|
3918
|
-
const exits = ts.isReturnStatement(stmt.thenStatement) || ts.isThrowStatement(stmt.thenStatement) ||
|
|
3919
|
-
(ts.isBlock(stmt.thenStatement) && stmt.thenStatement.statements.length > 0 &&
|
|
3920
|
-
(ts.isReturnStatement(stmt.thenStatement.statements[stmt.thenStatement.statements.length - 1]) ||
|
|
3921
|
-
ts.isThrowStatement(stmt.thenStatement.statements[stmt.thenStatement.statements.length - 1])));
|
|
3922
|
-
return exits ? local : null;
|
|
4174
|
+
return [];
|
|
4175
|
+
let tail = stmt.thenStatement;
|
|
4176
|
+
while (ts.isBlock(tail)) {
|
|
4177
|
+
const last = tail.statements[tail.statements.length - 1];
|
|
4178
|
+
if (!last)
|
|
4179
|
+
return [];
|
|
4180
|
+
tail = last;
|
|
4181
|
+
}
|
|
4182
|
+
const exits = ts.isReturnStatement(tail) || ts.isThrowStatement(tail) ||
|
|
4183
|
+
ts.isContinueStatement(tail) || ts.isBreakStatement(tail);
|
|
4184
|
+
return exits ? runtimeOptionalGuardIds(lowerer, stmt.expression, false) : [];
|
|
3923
4185
|
}
|
|
3924
4186
|
/** JS-exact switch (see docs/ir.md): one shared lexical scope for all case
|
|
3925
4187
|
* bodies, lazy source-order test evaluation, fall-through. tsc has already
|
|
3926
4188
|
* checked case-test comparability (TS2678) — the kind check below is the
|
|
3927
4189
|
* backstop for cases tsc lets through (e.g. `unknown as` casts). */
|
|
3928
4190
|
export function lowerSwitch(lowerer, stmt) {
|
|
3929
|
-
//
|
|
3930
|
-
//
|
|
3931
|
-
// point — labeled jumps naming this switch fence at the jump).
|
|
4191
|
+
// Consume labels before a nested statement can claim them. All switch
|
|
4192
|
+
// forms keep their own break target, including union comparisons.
|
|
3932
4193
|
const labels = lowerer.takeLabels();
|
|
3933
4194
|
const disc = lowerer.lowerExpr(stmt.expression);
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
4195
|
+
return withRuntimeOptionalNarrowed(lowerer, runtimeOptionalGuardIds(lowerer, stmt.expression, null), () => {
|
|
4196
|
+
const dk = disc.type.kind;
|
|
4197
|
+
if (dk === "dyn")
|
|
4198
|
+
return lowerDynSwitch(lowerer, stmt, disc, labels);
|
|
4199
|
+
if (dk === "union")
|
|
4200
|
+
return lowerUnionSwitch(lowerer, stmt, disc, labels);
|
|
4201
|
+
if (dk !== "f64" && dk !== "string" && dk !== "bool") {
|
|
4202
|
+
lowerer.unsupported("SC1090", stmt.expression, "switch on non-primitive values");
|
|
4203
|
+
}
|
|
4204
|
+
// The whole case-body sequence is ONE lexical scope in JS: a bare `let`
|
|
4205
|
+
// in one case is visible in later cases.
|
|
4206
|
+
lowerer.scopes.push(new Map());
|
|
4207
|
+
try {
|
|
4208
|
+
const cases = [];
|
|
4209
|
+
for (const clause of stmt.caseBlock.clauses) {
|
|
4210
|
+
let test = null;
|
|
4211
|
+
if (ts.isCaseClause(clause)) {
|
|
4212
|
+
test = lowerer.lowerExpr(clause.expression);
|
|
4213
|
+
if (test.type.kind !== dk) {
|
|
4214
|
+
lowerer.unsupported("SC1090", clause.expression, "switch case tests of a different type than the discriminant");
|
|
4215
|
+
}
|
|
3953
4216
|
}
|
|
4217
|
+
cases.push({ test, body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels) });
|
|
3954
4218
|
}
|
|
3955
|
-
|
|
4219
|
+
return { kind: "switch", disc, cases, ...(labels && { labels }), loc: locOf(stmt) };
|
|
3956
4220
|
}
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
}
|
|
4221
|
+
finally {
|
|
4222
|
+
lowerer.scopes.pop();
|
|
4223
|
+
}
|
|
4224
|
+
});
|
|
3962
4225
|
}
|
|
3963
|
-
/**
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
* primitives only. The desugar is JS-exact for the shape it accepts and
|
|
3968
|
-
* fences everything it cannot reproduce:
|
|
3969
|
-
* - the discriminant evaluates exactly once; effectful values stabilize
|
|
3970
|
-
* in a hidden local that every generated equality test reuses;
|
|
3971
|
-
* - tests evaluate lazily in source order (the chain's short-circuit IS
|
|
3972
|
-
* the switch's test order — grouped empty cases `case a: case b:` OR
|
|
3973
|
-
* their tests, still in order);
|
|
3974
|
-
* - each non-final clause must EXIT (a trailing unconditional break —
|
|
3975
|
-
* dropped, it's the chain's own exit — or a return/throw/continue):
|
|
3976
|
-
* real fall-through between bodies has no if/else shape;
|
|
3977
|
-
* - any OTHER unlabeled break binding to this switch (a conditional
|
|
3978
|
-
* early break) is fenced — desugared, it would bind to an enclosing
|
|
3979
|
-
* loop instead;
|
|
3980
|
-
* - `default` may sit anywhere in source (JS tests every case first;
|
|
3981
|
-
* the chain's final else reproduces that as long as its body exits or
|
|
3982
|
-
* is last).
|
|
3983
|
-
* Case bodies share ONE lexical scope, exactly like the real switch. */
|
|
3984
|
-
function lowerUnionSwitch(lowerer, stmt, disc) {
|
|
4226
|
+
/** Compare a union discriminant through a boolean switch. The native switch
|
|
4227
|
+
* already implements lazy case tests, shared scope, fallthrough and jumps;
|
|
4228
|
+
* keeping that control-flow node avoids rebinding an early break to a loop. */
|
|
4229
|
+
function lowerUnionSwitch(lowerer, stmt, disc, labels) {
|
|
3985
4230
|
if (disc.type.kind !== "union")
|
|
3986
4231
|
throw new InternalCompilerError("lowerer bug: non-union disc");
|
|
3987
4232
|
const unionType = disc.type;
|
|
3988
4233
|
if (!lowerer.eqComparableUnion(unionType.unionId)) {
|
|
3989
4234
|
lowerer.unsupported("SC1090", stmt.expression, "switch on a union whose arms do not have static equality");
|
|
3990
4235
|
}
|
|
3991
|
-
return lowerBranchSwitch(lowerer, stmt, disc, (stableDisc, test, expression) => {
|
|
4236
|
+
return lowerBranchSwitch(lowerer, stmt, disc, labels, (stableDisc, test, expression) => {
|
|
3992
4237
|
const unitTest = test.kind === "unitLit"
|
|
3993
4238
|
? lowerer.lowerUnitComparison(stableDisc, test, false, locOf(expression))
|
|
3994
4239
|
: null;
|
|
@@ -4007,8 +4252,8 @@ function lowerUnionSwitch(lowerer, stmt, disc) {
|
|
|
4007
4252
|
/** A checked-dynamic switch whose tests have native strict-equality
|
|
4008
4253
|
* answers. Scalar tests use dynScalarEq; null/undefined use dyn kind tests.
|
|
4009
4254
|
* Other case values retain the existing unknown-switch fence. */
|
|
4010
|
-
function lowerDynSwitch(lowerer, stmt, disc) {
|
|
4011
|
-
return lowerBranchSwitch(lowerer, stmt, disc, (stableDisc, test, expression) => {
|
|
4255
|
+
function lowerDynSwitch(lowerer, stmt, disc, labels) {
|
|
4256
|
+
return lowerBranchSwitch(lowerer, stmt, disc, labels, (stableDisc, test, expression) => {
|
|
4012
4257
|
if (test.kind === "unitLit") {
|
|
4013
4258
|
return { kind: "dynTest", test: test.unit, value: stableDisc, type: BOOL, loc: locOf(expression) };
|
|
4014
4259
|
}
|
|
@@ -4019,121 +4264,47 @@ function lowerDynSwitch(lowerer, stmt, disc) {
|
|
|
4019
4264
|
return { kind: "dynScalarEq", left: stableDisc, right: test, type: BOOL, loc: locOf(expression) };
|
|
4020
4265
|
});
|
|
4021
4266
|
}
|
|
4022
|
-
function lowerBranchSwitch(lowerer, stmt, disc, compare) {
|
|
4267
|
+
function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
4023
4268
|
const loc = locOf(stmt);
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
const
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
ts.isFunctionLike(node)) {
|
|
4043
|
-
return null;
|
|
4044
|
-
}
|
|
4045
|
-
return ts.forEachChild(node, findStrayBreak) ?? null;
|
|
4046
|
-
};
|
|
4047
|
-
for (const clause of clauses) {
|
|
4048
|
-
const last = clause.statements[clause.statements.length - 1];
|
|
4049
|
-
for (const s of clause.statements) {
|
|
4050
|
-
const stray = s === last && ts.isBreakStatement(s) && !s.label ? null : findStrayBreak(s);
|
|
4051
|
-
if (stray) {
|
|
4052
|
-
lowerer.unsupported("SC1090", stray, "early 'break' inside a union-typed switch (only a trailing break exits the desugared chain — restructure with if/else)");
|
|
4053
|
-
}
|
|
4054
|
-
}
|
|
4055
|
-
}
|
|
4056
|
-
const statementExits = (last) => {
|
|
4057
|
-
if (!last)
|
|
4058
|
-
return false;
|
|
4059
|
-
if ((ts.isBreakStatement(last) && !last.label) ||
|
|
4060
|
-
ts.isReturnStatement(last) ||
|
|
4061
|
-
ts.isThrowStatement(last) ||
|
|
4062
|
-
ts.isContinueStatement(last))
|
|
4063
|
-
return true;
|
|
4064
|
-
return ts.isBlock(last) && statementExits(last.statements[last.statements.length - 1]);
|
|
4065
|
-
};
|
|
4066
|
-
const exits = (clause) => {
|
|
4067
|
-
const last = clause.statements[clause.statements.length - 1];
|
|
4068
|
-
return statementExits(last);
|
|
4069
|
-
};
|
|
4070
|
-
// The whole case-body sequence is ONE lexical scope, like the real
|
|
4071
|
-
// switch lowering.
|
|
4269
|
+
// Even a plain variable must be snapshotted: a case expression can write
|
|
4270
|
+
// it before the next comparison, without changing the switch value.
|
|
4271
|
+
const temp = lowerer.declareHiddenLocal("%switch", disc.type);
|
|
4272
|
+
const stableDisc = varRef(temp.id, disc.type, loc);
|
|
4273
|
+
// Calls/assignments in a case test may mutate a captured discriminant
|
|
4274
|
+
// binding. The checker still narrows that binding as if it were the
|
|
4275
|
+
// snapshot. Keep the original tagged value in those case bodies.
|
|
4276
|
+
const effectful = stmt.caseBlock.clauses.some((clause) => ts.isCaseClause(clause) &&
|
|
4277
|
+
!ts.isStringLiteral(clause.expression) && !ts.isNumericLiteral(clause.expression) &&
|
|
4278
|
+
!ts.isIdentifier(clause.expression) && clause.expression.kind !== ts.SyntaxKind.NullKeyword &&
|
|
4279
|
+
clause.expression.kind !== ts.SyntaxKind.TrueKeyword && clause.expression.kind !== ts.SyntaxKind.FalseKeyword);
|
|
4280
|
+
let binding = stmt.expression;
|
|
4281
|
+
while (ts.isParenthesizedExpression(binding))
|
|
4282
|
+
binding = binding.expression;
|
|
4283
|
+
const symbol = effectful && ts.isIdentifier(binding) ? lowerer.resolveValueSymbol(binding) : undefined;
|
|
4284
|
+
const alreadyUnstable = symbol != null && lowerer.unstableSwitchBindings.has(symbol);
|
|
4285
|
+
if (symbol)
|
|
4286
|
+
lowerer.unstableSwitchBindings.add(symbol);
|
|
4072
4287
|
lowerer.scopes.push(new Map());
|
|
4073
4288
|
try {
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
!isSafeToRepeat(test)) {
|
|
4089
|
-
lowerer.unsupported("SC1090", clause.expression, "effectful case tests in a union-typed switch (bind the test value to a const first)");
|
|
4090
|
-
}
|
|
4091
|
-
// A unit-literal test takes the unit-comparison lowering: a tag
|
|
4092
|
-
// test when the arm exists, the constant FALSE when the union
|
|
4093
|
-
// lacks it (`case null:` on a `number | undefined` — legal TS,
|
|
4094
|
-
// never matches; coercing the literal into the union would hit
|
|
4095
|
-
// the stranded-arm trap and throw where JS just skips the case).
|
|
4096
|
-
pendingTests.push(compare(stableDisc, test, clause.expression));
|
|
4097
|
-
}
|
|
4098
|
-
const isDefault = ts.isDefaultClause(clause);
|
|
4099
|
-
if (clause.statements.length === 0 && !isDefault && i < clauses.length - 1) {
|
|
4100
|
-
continue; // grouped with the next clause
|
|
4101
|
-
}
|
|
4102
|
-
if (!exits(clause) && i < clauses.length - 1 && (clause.statements.length > 0 || isDefault)) {
|
|
4103
|
-
// A non-final body that doesn't exit falls into the NEXT body in
|
|
4104
|
-
// JS — no if/else shape reproduces that (an EMPTY non-final
|
|
4105
|
-
// default falls through too; empty non-final cases just group).
|
|
4106
|
-
lowerer.unsupported("SC1090", clause, "fall-through between case bodies in a union-typed switch (end each case with break/return/throw/continue)");
|
|
4107
|
-
}
|
|
4108
|
-
const last = clause.statements[clause.statements.length - 1];
|
|
4109
|
-
const stmts = last && ts.isBreakStatement(last)
|
|
4110
|
-
? clause.statements.slice(0, -1)
|
|
4111
|
-
: clause.statements.slice();
|
|
4112
|
-
const body = lowerer.lowerStmts(stmts);
|
|
4113
|
-
groups.push({ tests: pendingTests, body, isDefault });
|
|
4114
|
-
pendingTests = [];
|
|
4115
|
-
}
|
|
4116
|
-
// A default clause anywhere lands in the chain's final else; JS
|
|
4117
|
-
// reaches it only after every case test fails, which the chain
|
|
4118
|
-
// reproduces because default bodies that don't exit were fenced
|
|
4119
|
-
// above (unless last in source, where falling out is falling out).
|
|
4120
|
-
const defaultBody = groups.find((g) => g.isDefault)?.body ?? null;
|
|
4121
|
-
const caseGroups = groups.filter((g) => !g.isDefault);
|
|
4122
|
-
let chain = defaultBody ?? [];
|
|
4123
|
-
for (let i = caseGroups.length - 1; i >= 0; i--) {
|
|
4124
|
-
const g = caseGroups[i];
|
|
4125
|
-
let cond = g.tests[0];
|
|
4126
|
-
if (!cond)
|
|
4127
|
-
continue; // a default-adjacent group with no tests (defensive)
|
|
4128
|
-
for (const t of g.tests.slice(1)) {
|
|
4129
|
-
cond = { kind: "logical", op: "||", left: cond, right: t, type: BOOL, loc };
|
|
4130
|
-
}
|
|
4131
|
-
chain = [{ kind: "if", cond, then: g.body, else_: chain.length > 0 ? chain : null, loc }];
|
|
4132
|
-
}
|
|
4133
|
-
return { kind: "block", body: [...prefix, ...chain], loc };
|
|
4289
|
+
const cases = stmt.caseBlock.clauses.map((clause) => ({
|
|
4290
|
+
test: ts.isCaseClause(clause)
|
|
4291
|
+
? compare(stableDisc, lowerer.lowerExpr(clause.expression), clause.expression)
|
|
4292
|
+
: null,
|
|
4293
|
+
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels),
|
|
4294
|
+
}));
|
|
4295
|
+
return {
|
|
4296
|
+
kind: "block",
|
|
4297
|
+
body: [
|
|
4298
|
+
{ kind: "varDecl", localId: temp.id, init: disc, loc },
|
|
4299
|
+
{ kind: "switch", disc: { kind: "boolLit", value: true, type: BOOL, loc }, cases, ...(labels && { labels }), loc },
|
|
4300
|
+
],
|
|
4301
|
+
loc,
|
|
4302
|
+
};
|
|
4134
4303
|
}
|
|
4135
4304
|
finally {
|
|
4136
4305
|
lowerer.scopes.pop();
|
|
4306
|
+
if (symbol && !alreadyUnstable)
|
|
4307
|
+
lowerer.unstableSwitchBindings.delete(symbol);
|
|
4137
4308
|
}
|
|
4138
4309
|
}
|
|
4139
4310
|
/** try/catch/finally:
|
|
@@ -4143,9 +4314,10 @@ function lowerBranchSwitch(lowerer, stmt, disc, compare) {
|
|
|
4143
4314
|
* narrowing tests (`e instanceof C` over hierarchy classes, `typeof e
|
|
4144
4315
|
* === "string"/"number"/"boolean"`), reads under a proven narrow
|
|
4145
4316
|
* (caughtRead bridges them with caughtNarrow, trust-the-checker like
|
|
4146
|
-
* unionNarrow), and rethrow (`throw e`).
|
|
4147
|
-
*
|
|
4148
|
-
* are SC1062.
|
|
4317
|
+
* unionNarrow), and rethrow (`throw e`). Unsupported raw uses and
|
|
4318
|
+
* assignments are fenced (SC1063 and friends); destructuring patterns
|
|
4319
|
+
* are SC1062. Captures retain the snapshot beyond the catch scope.
|
|
4320
|
+
* The `: any` / `: unknown` annotations tsc admits both
|
|
4149
4321
|
* lower the same way (tsc narrows either through the tests).
|
|
4150
4322
|
* - `finally` runs on normal completion, exception paths, and every
|
|
4151
4323
|
* abrupt completion that crosses it. Return values are snapshotted
|
|
@@ -4187,6 +4359,28 @@ export function lowerTry(lowerer, stmt) {
|
|
|
4187
4359
|
loc: locOf(stmt),
|
|
4188
4360
|
};
|
|
4189
4361
|
}
|
|
4362
|
+
function hasUseStrictDirective(statements) {
|
|
4363
|
+
for (const statement of statements) {
|
|
4364
|
+
if (!ts.isExpressionStatement(statement) || !ts.isStringLiteral(statement.expression))
|
|
4365
|
+
return false;
|
|
4366
|
+
if (statement.expression.text === "use strict")
|
|
4367
|
+
return true;
|
|
4368
|
+
}
|
|
4369
|
+
return false;
|
|
4370
|
+
}
|
|
4371
|
+
function isStrictDelete(node) {
|
|
4372
|
+
for (let parent = node.parent; parent; parent = parent.parent) {
|
|
4373
|
+
if (ts.isClassDeclaration(parent) || ts.isClassExpression(parent))
|
|
4374
|
+
return true;
|
|
4375
|
+
if (ts.isFunctionLike(parent) && parent.body && ts.isBlock(parent.body) && hasUseStrictDirective(parent.body.statements))
|
|
4376
|
+
return true;
|
|
4377
|
+
if (ts.isSourceFile(parent)) {
|
|
4378
|
+
return hasUseStrictDirective(parent.statements) ||
|
|
4379
|
+
(!isCjsJsFile(parent) && (isNodeEsmFile(parent) || ts.isExternalModule(parent)));
|
|
4380
|
+
}
|
|
4381
|
+
}
|
|
4382
|
+
return false;
|
|
4383
|
+
}
|
|
4190
4384
|
/** Statement-position `delete`: process.env keys → process.envUnset
|
|
4191
4385
|
* (unsetenv), pure `Record<string, T>` keys → recordKeyDelete (the
|
|
4192
4386
|
* overflow Map delete), declared OPTIONAL fields → the undefined-arm
|
|
@@ -4202,12 +4396,24 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4202
4396
|
lowerer.unsupported("SC1090", expr, "'delete' of non-property expressions");
|
|
4203
4397
|
}
|
|
4204
4398
|
fenceNodeModuleMutation(lowerer, target, "delete");
|
|
4399
|
+
if (ts.isPropertyAccessExpression(target) && target.name.text === "cause") {
|
|
4400
|
+
const field = lowerer.fieldTarget(target);
|
|
4401
|
+
if (field?.container === "errorCause") {
|
|
4402
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "error.deleteCause", args: [field.obj], type: VOID, loc }, loc };
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
const globalKey = ts.isElementAccessExpression(target) ? globalSymbolKey(lowerer, target.expression, target.argumentExpression) : null;
|
|
4406
|
+
if (globalKey)
|
|
4407
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.globalSymbolDelete", args: [globalKey], type: VOID, loc }, loc };
|
|
4205
4408
|
const lowerKey = () => {
|
|
4206
4409
|
if (ts.isPropertyAccessExpression(target)) {
|
|
4207
4410
|
return { kind: "strLit", value: target.name.text, type: STRING, loc: locOf(target.name) };
|
|
4208
4411
|
}
|
|
4209
4412
|
const keyNode = target.argumentExpression;
|
|
4210
|
-
let key = lowerer.lowerExpr(keyNode);
|
|
4413
|
+
let key = lowerer.isProcessEnv(target.expression) ? lowerEnvironmentKey(lowerer, keyNode) : lowerer.lowerExpr(keyNode);
|
|
4414
|
+
if (key.type.kind === "dyn") {
|
|
4415
|
+
key = { kind: "libCall", fn: "dyn.toStringCoerce", args: [key], type: STRING, loc: key.loc };
|
|
4416
|
+
}
|
|
4211
4417
|
if (lowerer.runtimeOptionalWidening(key.type, STRING) !== null) {
|
|
4212
4418
|
key = lowerer.ensureString(key, keyNode);
|
|
4213
4419
|
}
|
|
@@ -4223,7 +4429,28 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4223
4429
|
loc,
|
|
4224
4430
|
};
|
|
4225
4431
|
}
|
|
4226
|
-
|
|
4432
|
+
let obj = lowerer.lowerExpr(target.expression);
|
|
4433
|
+
if (isJsSourceFile(expr.getSourceFile()) && obj.type.kind === "object") {
|
|
4434
|
+
const info = lowerer.classes.get(obj.type.className);
|
|
4435
|
+
const keyType = ts.isElementAccessExpression(target) ? lowerer.typeOf(target.argumentExpression) : null;
|
|
4436
|
+
const name = ts.isPropertyAccessExpression(target) ? target.name.text
|
|
4437
|
+
: keyType?.isStringLiteralType() ? keyType.value : null;
|
|
4438
|
+
if (info && name !== null && isClassCallback(lowerer, info, name)) {
|
|
4439
|
+
obj = { kind: "call", callee: classPropertiesHelper(lowerer, loc).name,
|
|
4440
|
+
args: [lowerer.coerceToExpected(obj, DYN)], type: DYN, loc };
|
|
4441
|
+
}
|
|
4442
|
+
}
|
|
4443
|
+
if (isJsSourceFile(expr.getSourceFile()) && obj.type.kind === "func" && lowerer.dynConvertible(obj.type)) {
|
|
4444
|
+
obj = lowerer.coerceToExpected(obj, DYN);
|
|
4445
|
+
}
|
|
4446
|
+
if (obj.type.kind === "dyn") {
|
|
4447
|
+
const strict = { kind: "boolLit", value: isStrictDelete(expr), type: BOOL, loc };
|
|
4448
|
+
if (ts.isElementAccessExpression(target)) {
|
|
4449
|
+
const key = lowerer.lowerExprExpecting(target.argumentExpression, DYN);
|
|
4450
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keyDeleteComputed", args: [obj, key, strict], type: VOID, loc }, loc };
|
|
4451
|
+
}
|
|
4452
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keyDelete", args: [obj, lowerKey(), strict], type: VOID, loc }, loc };
|
|
4453
|
+
}
|
|
4227
4454
|
if (obj.type.kind === "record") {
|
|
4228
4455
|
const shape = lowerer.shapes.get(obj.type.shapeId);
|
|
4229
4456
|
if (shape?.indexValue && shape.fields.length === 0 && !shape.tuple) {
|
|
@@ -4520,7 +4747,7 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
|
|
|
4520
4747
|
const exportSym = lowerer.checker.getSymbolAtLocation(expr.left);
|
|
4521
4748
|
if (exportSym && !lowerer.classBySymbol.has(exportSym))
|
|
4522
4749
|
lowerer.classBySymbol.set(exportSym, info);
|
|
4523
|
-
return { kind: "
|
|
4750
|
+
return { kind: "exprStmt", expr: lowerer.lowerClassExpression(rhs), loc };
|
|
4524
4751
|
}
|
|
4525
4752
|
const g = lowerer.globalsByDeclNode.get(expr);
|
|
4526
4753
|
if (!g)
|
|
@@ -4597,7 +4824,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4597
4824
|
}
|
|
4598
4825
|
}
|
|
4599
4826
|
// `yield* inner();` — statement-position delegation desugars to the
|
|
4600
|
-
// forwarding loop (lower-generators)
|
|
4827
|
+
// forwarding loop (lower-generators), dropping the completed value.
|
|
4601
4828
|
{
|
|
4602
4829
|
const delegated = lowerYieldStarStatement(lowerer, expr);
|
|
4603
4830
|
if (delegated)
|
|
@@ -4653,7 +4880,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4653
4880
|
// site (message with the one-entry require stack), CATCHABLE — the
|
|
4654
4881
|
// optional-dependency try/require pattern. The compiled statement
|
|
4655
4882
|
// IS that throw, wherever it sits.
|
|
4656
|
-
if (isCjsJsFile(sf)) {
|
|
4883
|
+
if (isCjsJsFile(sf, lowerer.program)) {
|
|
4657
4884
|
if (!isRelativeSpecifier(spec) &&
|
|
4658
4885
|
canonicalBuiltinModule(spec) === null) {
|
|
4659
4886
|
const refusal = probeNodeRequireRefusal(sf.fileName, spec);
|
|
@@ -4673,7 +4900,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4673
4900
|
}
|
|
4674
4901
|
}
|
|
4675
4902
|
}
|
|
4676
|
-
if (isCjsJsFile(sf)) {
|
|
4903
|
+
if (isCjsJsFile(sf, lowerer.program)) {
|
|
4677
4904
|
const init = lowerer.requireInitStmt(spec, expr);
|
|
4678
4905
|
if (init)
|
|
4679
4906
|
return init;
|
|
@@ -4728,6 +4955,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4728
4955
|
};
|
|
4729
4956
|
}
|
|
4730
4957
|
if (opKind === ts.SyntaxKind.EqualsToken) {
|
|
4958
|
+
const callableWrite = lowerNativeFunctionAssignment(lowerer, expr);
|
|
4959
|
+
if (callableWrite)
|
|
4960
|
+
return { kind: "exprStmt", expr: callableWrite, loc: locOf(expr) };
|
|
4731
4961
|
// Expando function members (`foo.bar = 12`, `foo[SYM] = v` on a
|
|
4732
4962
|
// module-level function/callable const): the member's module
|
|
4733
4963
|
// global (lower-expando.ts) — claimed by symbol identity before
|
|
@@ -4845,13 +5075,20 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4845
5075
|
// SUBCLASS name (`D.x = v` creates an OWN property on D in JS —
|
|
4846
5076
|
// different storage) and through class VALUES (the same dynamic
|
|
4847
5077
|
// story) are named fences, never a silently-wrong global write.
|
|
4848
|
-
if (!expr.left.questionDotToken && ts.isIdentifier(expr.left.expression)) {
|
|
5078
|
+
if (!expr.left.questionDotToken && (ts.isIdentifier(expr.left.expression) || expr.left.expression.kind === ts.SyntaxKind.ThisKeyword)) {
|
|
4849
5079
|
// The receiver must BE the class exactly (its name, or a
|
|
4850
5080
|
// const binding holding a class expression) — a general class
|
|
4851
5081
|
// VALUE could hold a subclass, where JS creates an own
|
|
4852
5082
|
// property instead of writing this storage.
|
|
4853
5083
|
const classInfo = lowerer.exactClassOfReceiver(expr.left.expression);
|
|
4854
5084
|
if (classInfo) {
|
|
5085
|
+
const data = classStaticDataFor(lowerer, classInfo, expr.left.name.text, locOf(expr.left));
|
|
5086
|
+
if (data) {
|
|
5087
|
+
const loc = locOf(expr);
|
|
5088
|
+
const key = { kind: "strLit", value: expr.left.name.text, type: STRING, loc };
|
|
5089
|
+
const value = lowerer.lowerExprExpecting(expr.right, DYN);
|
|
5090
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keySet", args: [data, key, value], type: VOID, loc }, loc };
|
|
5091
|
+
}
|
|
4855
5092
|
const found = lowerer.findStaticOn(classInfo, expr.left.name.text);
|
|
4856
5093
|
if (found?.field !== undefined) {
|
|
4857
5094
|
if (found.declarer !== classInfo) {
|
|
@@ -4952,17 +5189,50 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
4952
5189
|
if (viaStream)
|
|
4953
5190
|
return viaStream;
|
|
4954
5191
|
}
|
|
5192
|
+
if (expr.left.name.text === "lastIndex" && lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression))?.kind === "regex") {
|
|
5193
|
+
const loc = locOf(expr);
|
|
5194
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "regex.resetLastIndex",
|
|
5195
|
+
args: [lowerer.lowerExpr(expr.left.expression), lowerer.lowerExprExpecting(expr.right, F64)], type: VOID, loc }, loc };
|
|
5196
|
+
}
|
|
5197
|
+
const unionWrite = lowerUnionFieldWrite(lowerer, expr.left, expr.right);
|
|
5198
|
+
if (unionWrite)
|
|
5199
|
+
return unionWrite;
|
|
4955
5200
|
const target = lowerer.fieldTarget(expr.left);
|
|
4956
5201
|
if (target) {
|
|
4957
5202
|
const value = lowerer.lowerExprExpecting(expr.right, target.fieldType);
|
|
4958
5203
|
return lowerer.fieldSetStmt(target, value, locOf(expr), expr.left);
|
|
4959
5204
|
}
|
|
5205
|
+
const callback = lowerClassCallbackAssign(lowerer, expr);
|
|
5206
|
+
if (callback)
|
|
5207
|
+
return callback;
|
|
4960
5208
|
// A write to an ABSTRACT property through an abstract-typed
|
|
4961
5209
|
// receiver: the read fence's write twin (the declaration is
|
|
4962
5210
|
// erased at runtime — no shared slot exists to write).
|
|
4963
5211
|
if (abstractPropertyDeclOf(lowerer, expr.left)) {
|
|
4964
5212
|
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)`);
|
|
4965
5213
|
}
|
|
5214
|
+
if (!expr.left.questionDotToken) {
|
|
5215
|
+
const recv = tryLowerExpression(lowerer, expr.left.expression);
|
|
5216
|
+
if (recv?.type.kind === "object" && recv.type.className === "%Error") {
|
|
5217
|
+
const loc = locOf(expr);
|
|
5218
|
+
return { kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.keySet", args: [
|
|
5219
|
+
lowerer.coerceToExpected(recv, DYN), { kind: "strLit", value: expr.left.name.text, type: STRING, loc },
|
|
5220
|
+
lowerer.lowerExprExpecting(expr.right, DYN),
|
|
5221
|
+
], type: VOID, loc }, loc };
|
|
5222
|
+
}
|
|
5223
|
+
if (recv && isDynTypedRefType(recv.type)) {
|
|
5224
|
+
const info = lowerer.classes.get(recv.type.className);
|
|
5225
|
+
if (info && !info.def.runtime && !info.builtinError && !info.builtinEmitter && !info.builtinStream &&
|
|
5226
|
+
!isCompiledPrototypeMember(lowerer, info, expr.left.name.text)) {
|
|
5227
|
+
const loc = locOf(expr);
|
|
5228
|
+
return { kind: "exprStmt", expr: {
|
|
5229
|
+
kind: "libCall", fn: "dyn.keySet", args: [lowerer.coerceToExpected(recv, DYN),
|
|
5230
|
+
{ kind: "strLit", value: expr.left.name.text, type: STRING, loc }, lowerer.lowerExprExpecting(expr.right, DYN)],
|
|
5231
|
+
type: VOID, loc,
|
|
5232
|
+
}, loc };
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
5235
|
+
}
|
|
4966
5236
|
// Dot WRITE to an undeclared key of an index-signature shape:
|
|
4967
5237
|
// the same deliberate fence as the dotted read, with the same
|
|
4968
5238
|
// fix in the message (brackets are the index-signature form).
|
|
@@ -5005,34 +5275,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5005
5275
|
lowerer.runtimeOptionalLocals.add(runtimeOptionalRoot);
|
|
5006
5276
|
return { kind: "assign", localId: target.id, value, loc: locOf(expr) };
|
|
5007
5277
|
}
|
|
5008
|
-
if (opKind === ts.SyntaxKind.QuestionQuestionEqualsToken
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
// assign-only-when-nullish is unobservable — the value written back
|
|
5012
|
-
// on the non-nullish path is the same box. Property targets keep a
|
|
5013
|
-
// distinct fence: accessors would make the always-write observable.
|
|
5014
|
-
if (!ts.isIdentifier(expr.left)) {
|
|
5015
|
-
lowerer.unsupported("SC1090", expr.left, "'??=' on non-variable targets (write it out: if (o.f === undefined) o.f = v)");
|
|
5016
|
-
}
|
|
5017
|
-
const target = lowerer.resolveWritable(expr.left);
|
|
5018
|
-
if (!target)
|
|
5019
|
-
lowerer.rejectUnresolved(expr.left, `assignment to '${expr.left.text}' (not a writable local or module global)`);
|
|
5020
|
-
const loc = locOf(expr);
|
|
5021
|
-
if (target.type.kind !== "union") {
|
|
5022
|
-
// The checker says never nullish: JS neither evaluates e nor
|
|
5023
|
-
// assigns — the statement is a no-op (lowerNullishCoalesce's
|
|
5024
|
-
// trust-the-checker fold, statement form).
|
|
5025
|
-
return { kind: "block", body: [], loc };
|
|
5026
|
-
}
|
|
5027
|
-
const def = lowerer.unions.get(target.type.unionId);
|
|
5028
|
-
if (!def)
|
|
5029
|
-
lowerer.badType(expr.left, lowerer.typeOf(expr.left));
|
|
5030
|
-
if (!def.arms.some(isUnitType))
|
|
5031
|
-
return { kind: "block", body: [], loc };
|
|
5032
|
-
const read = { kind: "varRef", localId: target.id, type: target.type, loc: locOf(expr.left) };
|
|
5033
|
-
const right = lowerer.lowerExprExpecting(expr.right, target.type);
|
|
5034
|
-
const value = { kind: "nullish", left: read, right, type: target.type, loc };
|
|
5035
|
-
return { kind: "assign", localId: target.id, value, loc };
|
|
5278
|
+
if (opKind === ts.SyntaxKind.QuestionQuestionEqualsToken ||
|
|
5279
|
+
opKind === ts.SyntaxKind.AmpersandAmpersandEqualsToken || opKind === ts.SyntaxKind.BarBarEqualsToken) {
|
|
5280
|
+
return { kind: "exprStmt", expr: lowerShortCircuitAssignment(lowerer, expr), loc: locOf(expr) };
|
|
5036
5281
|
}
|
|
5037
5282
|
const compound = COMPOUND_ASSIGN_OPS[opKind];
|
|
5038
5283
|
if (compound !== undefined) {
|
|
@@ -5071,8 +5316,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5071
5316
|
}
|
|
5072
5317
|
if (opKind >= ts.SyntaxKind.FirstCompoundAssignment &&
|
|
5073
5318
|
opKind <= ts.SyntaxKind.LastCompoundAssignment) {
|
|
5074
|
-
|
|
5075
|
-
lowerer.unsupported("SC1090", expr, "logical assignment (&&=, ||=) — write the if out");
|
|
5319
|
+
lowerer.unsupported("SC1090", expr, "this compound assignment operator");
|
|
5076
5320
|
}
|
|
5077
5321
|
}
|
|
5078
5322
|
if ((ts.isPrefixUnaryExpression(expr) || ts.isPostfixUnaryExpression(expr)) &&
|
|
@@ -5086,6 +5330,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5086
5330
|
// increment (the member's global IS the variable); expando
|
|
5087
5331
|
// function members (`foo.count++`) are module globals too.
|
|
5088
5332
|
if (ts.isPropertyAccessExpression(expr.operand) && !expr.operand.questionDotToken) {
|
|
5333
|
+
const staticTarget = staticFieldWriteTarget(lowerer, expr.operand);
|
|
5334
|
+
if (staticTarget)
|
|
5335
|
+
return lowerIncDecToTarget(lowerer, expr, staticTarget);
|
|
5089
5336
|
const exT = expandoWritableTarget(lowerer, expr.operand);
|
|
5090
5337
|
if (exT)
|
|
5091
5338
|
return lowerIncDecToTarget(lowerer, expr, exT);
|
|
@@ -5198,44 +5445,12 @@ function lowerIncDecToTarget(lowerer, expr, target) {
|
|
|
5198
5445
|
* identifier form and the namespace-qualified spelling (`N.x += v`),
|
|
5199
5446
|
* whose target is the member's module global. */
|
|
5200
5447
|
function lowerCompoundToTarget(lowerer, expr, compound, target) {
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
const JS_COMPOUND = { "+": "add", "-": "sub", "*": "mul", "/": "div", "%": "mod", "**": "pow" };
|
|
5208
|
-
const jop = JS_COMPOUND[compound];
|
|
5209
|
-
if (jop === undefined)
|
|
5210
|
-
lowerer.unsupported("SC1043", expr);
|
|
5211
|
-
const wrapped = {
|
|
5212
|
-
kind: "jsOp", op: jop,
|
|
5213
|
-
args: [lowerer.jsvalIn(read, expr.left), lowerer.jsvalIn(rhs, expr.right)],
|
|
5214
|
-
type: JSVAL, loc,
|
|
5215
|
-
};
|
|
5216
|
-
value = lowerer.coerceInto(expr, wrapped, target.type);
|
|
5217
|
-
}
|
|
5218
|
-
else if (compound === "+" && target.type.kind === "string") {
|
|
5219
|
-
value = { kind: "strConcat", left: read, right: lowerer.ensureString(rhs, expr.right), type: STRING, loc };
|
|
5220
|
-
}
|
|
5221
|
-
else if (target.type.kind === "f64" && numericRhs.type.kind === "f64") {
|
|
5222
|
-
value = { kind: "bin", op: compound, left: read, right: numericRhs, type: F64, loc };
|
|
5223
|
-
}
|
|
5224
|
-
else if ((target.type.kind === "dyn" || rhs.type.kind === "dyn") &&
|
|
5225
|
-
(target.type.kind === "dyn" || target.type.kind === "f64") &&
|
|
5226
|
-
(rhs.type.kind === "dyn" || rhs.type.kind === "f64") &&
|
|
5227
|
-
isJsSourceFile(expr.getSourceFile())) {
|
|
5228
|
-
// JS any-origin operands: check to number and compute natively
|
|
5229
|
-
// (the binary-operator stance) — the dyn target takes the result
|
|
5230
|
-
// back through the usual dyn conversion.
|
|
5231
|
-
const checkNum = (e) => e.type.kind === "dyn" ? { kind: "dynCheck", value: e, type: F64, loc: e.loc } : e;
|
|
5232
|
-
const computed = { kind: "bin", op: compound, left: checkNum(read), right: checkNum(rhs), type: F64, loc };
|
|
5233
|
-
value = target.type.kind === "dyn" ? { kind: "dynFrom", value: computed, type: DYN, loc } : computed;
|
|
5234
|
-
}
|
|
5235
|
-
else {
|
|
5236
|
-
lowerer.unsupported("SC1043", expr);
|
|
5237
|
-
}
|
|
5238
|
-
return { kind: "assign", localId: target.id, value, loc };
|
|
5448
|
+
return {
|
|
5449
|
+
kind: "assign",
|
|
5450
|
+
localId: target.id,
|
|
5451
|
+
value: lowerCompoundValueToTarget(lowerer, expr, compound, target),
|
|
5452
|
+
loc: locOf(expr),
|
|
5453
|
+
};
|
|
5239
5454
|
}
|
|
5240
5455
|
/** One destructuring-assignment pattern the island can run: empty object/
|
|
5241
5456
|
* array patterns and flat identifier targets — shorthand `{ x }`,
|
|
@@ -5428,14 +5643,23 @@ export function lowerDestructuringAssign(lowerer, target, init, blame, loc) {
|
|
|
5428
5643
|
}
|
|
5429
5644
|
/** V8's spelling of a destructuring RHS in its TypeError message
|
|
5430
5645
|
* ("Cannot destructure 'a' as it is undefined.") — plain identifiers
|
|
5431
|
-
* spell their name (parens unwrap)
|
|
5432
|
-
*
|
|
5433
|
-
* fence at the caller. */
|
|
5646
|
+
* spell their name (parens unwrap), and calls append an ellipsis to a
|
|
5647
|
+
* supported callee spelling. Other CallPrinter forms keep a fence. */
|
|
5434
5648
|
function destrSpellingOf(rhs) {
|
|
5435
5649
|
let e = rhs;
|
|
5436
5650
|
while (ts.isParenthesizedExpression(e))
|
|
5437
5651
|
e = e.expression;
|
|
5438
|
-
|
|
5652
|
+
if (ts.isIdentifier(e))
|
|
5653
|
+
return e.text;
|
|
5654
|
+
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken) {
|
|
5655
|
+
const base = destrSpellingOf(e.expression);
|
|
5656
|
+
return base === null ? null : `${base}.${e.name.text}`;
|
|
5657
|
+
}
|
|
5658
|
+
if (ts.isCallExpression(e) && !e.questionDotToken) {
|
|
5659
|
+
const callee = destrSpellingOf(e.expression);
|
|
5660
|
+
return callee === null ? null : `${callee}(...)`;
|
|
5661
|
+
}
|
|
5662
|
+
return null;
|
|
5439
5663
|
}
|
|
5440
5664
|
/** Destructuring ASSIGNMENT (existing bindings — the declaration twin is
|
|
5441
5665
|
* lowerDestructuringDecl): the RHS evaluates ONCE into a hidden temp,
|
|
@@ -5537,7 +5761,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5537
5761
|
if (!checkedByInner) {
|
|
5538
5762
|
const spelling = rhs === null ? null : destrSpellingOf(rhs);
|
|
5539
5763
|
if (spelling === null) {
|
|
5540
|
-
lowerer.unsupported("SC1031", blame, "destructuring assignment from a checked-dynamic source
|
|
5764
|
+
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)");
|
|
5541
5765
|
}
|
|
5542
5766
|
let firstProp;
|
|
5543
5767
|
const p0 = target.properties[0];
|
|
@@ -6261,10 +6485,11 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6261
6485
|
// desugars drop them — a labeled jump naming those loops fences at the
|
|
6262
6486
|
// jump site (no label point exists in their desugared shape).
|
|
6263
6487
|
const labels = lowerer.takeLabels();
|
|
6264
|
-
//
|
|
6265
|
-
// async
|
|
6266
|
-
//
|
|
6267
|
-
|
|
6488
|
+
// A synchronous array iterator is also valid in `for await`. Its values
|
|
6489
|
+
// take the async-from-sync path below; other async sources retain their
|
|
6490
|
+
// dedicated request protocols.
|
|
6491
|
+
const awaitArray = !!stmt.awaitModifier && lowerer.mapTypeOf(lowerer.typeOf(stmt.expression))?.kind === "array";
|
|
6492
|
+
if (stmt.awaitModifier && !awaitArray) {
|
|
6268
6493
|
{
|
|
6269
6494
|
const genT = lowerer.mapTypeOf(lowerer.typeOf(stmt.expression));
|
|
6270
6495
|
if (genT?.kind === "generator" && genT.async) {
|
|
@@ -6283,6 +6508,9 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6283
6508
|
return builtin;
|
|
6284
6509
|
lowerer.unsupported("SC1070", stmt, "'for await' over this value (supported: typed async generators, represented class async iterators, process.stdin, and Node/Web readable streams)");
|
|
6285
6510
|
}
|
|
6511
|
+
if (awaitArray && !lowerer.ctx.isAsync) {
|
|
6512
|
+
lowerer.unsupported("SC1090", stmt, "top-level 'for await' (await outside async functions)");
|
|
6513
|
+
}
|
|
6286
6514
|
lowerer.fenceStaticHeadersIteration(stmt.expression);
|
|
6287
6515
|
// A stored numeric value iterator declared in this function keeps its
|
|
6288
6516
|
// built-in protocol state in hidden locals (lowerVarStatement). The
|
|
@@ -6295,7 +6523,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6295
6523
|
if (ts.isIdentifier(src)) {
|
|
6296
6524
|
const sym = lowerer.resolveValueSymbol(src);
|
|
6297
6525
|
const state = sym ? lowerer.numericIterators.get(sym) : undefined;
|
|
6298
|
-
if (state
|
|
6526
|
+
if (state && state.ctx === lowerer.ctx) {
|
|
6299
6527
|
return lowerForOfStoredNumericIterator(lowerer, stmt, state, labels);
|
|
6300
6528
|
}
|
|
6301
6529
|
}
|
|
@@ -6412,16 +6640,20 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6412
6640
|
let iterable = lowerer.lowerExpr(iterSrc);
|
|
6413
6641
|
// A nested loop receiver can be an OOB-safe array read from the outer
|
|
6414
6642
|
// loop (`for (const row of grid) for (const cell of row)`). The checker
|
|
6415
|
-
// sees the inner value as an array, while its runtime slot
|
|
6416
|
-
// undefined
|
|
6643
|
+
// sees the inner value as an array, while its runtime slot retains
|
|
6644
|
+
// undefined. An Array.isArray guard can also select the array from a
|
|
6645
|
+
// node | node[] | undefined slot. Map lookups and optional fields also
|
|
6646
|
+
// retain nullable runtime slots after a guard selects a concrete
|
|
6647
|
+
// iterable. Validate the selected arm before choosing its iteration
|
|
6648
|
+
// protocol; unchecked null assertions still throw at runtime.
|
|
6417
6649
|
const checkerIterable = lowerer.mapTypeOf(lowerer.typeOf(iterSrc));
|
|
6418
|
-
if (iterable.type.kind === "union" &&
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6650
|
+
if (iterable.type.kind === "union" && checkerIterable !== null &&
|
|
6651
|
+
(checkerIterable.kind === "array" || checkerIterable.kind === "map" || checkerIterable.kind === "set" ||
|
|
6652
|
+
checkerIterable.kind === "bytes" || checkerIterable.kind === "string" || checkerIterable.kind === "searchParams" ||
|
|
6653
|
+
checkerIterable.kind === "generator" || checkerIterable.kind === "object")) {
|
|
6654
|
+
const helper = lowerer.narrowedArmHelper(iterable.type.unionId, checkerIterable, locOf(iterSrc));
|
|
6423
6655
|
if (helper)
|
|
6424
|
-
iterable = { kind: "call", callee: helper, args: [iterable], type:
|
|
6656
|
+
iterable = { kind: "call", callee: helper, args: [iterable], type: checkerIterable, loc: locOf(iterSrc) };
|
|
6425
6657
|
}
|
|
6426
6658
|
if (iterable.type.kind === "bytes") {
|
|
6427
6659
|
return lowerForOfBytes(lowerer, stmt, iterable, labels);
|
|
@@ -6539,8 +6771,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6539
6771
|
}
|
|
6540
6772
|
// A CHECKED-DYNAMIC iterable (`unknown[]`, the collapsed
|
|
6541
6773
|
// `(string | object)[]`, JSON-parsed values, wrapped engine
|
|
6542
|
-
// values):
|
|
6543
|
-
// hidden index loop binds each element as a dyn value.
|
|
6774
|
+
// values): a checked IteratorRecord binds each yielded dyn value.
|
|
6544
6775
|
if (iterable.type.kind === "dyn") {
|
|
6545
6776
|
return lowerForOfDyn(lowerer, stmt, iterable, labels);
|
|
6546
6777
|
}
|
|
@@ -6548,29 +6779,132 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6548
6779
|
lowerer.badType(stmt.expression, lowerer.typeOf(stmt.expression));
|
|
6549
6780
|
}
|
|
6550
6781
|
}
|
|
6551
|
-
const
|
|
6782
|
+
const yieldedT = arrayValueType(lowerer, iterable.type.elem);
|
|
6783
|
+
let elemValueT = yieldedT;
|
|
6784
|
+
let awaitPromiseTag = null;
|
|
6785
|
+
if (awaitArray) {
|
|
6786
|
+
let promiseElem = null;
|
|
6787
|
+
if (iterable.type.elem.kind === "promise") {
|
|
6788
|
+
promiseElem = iterable.type.elem;
|
|
6789
|
+
}
|
|
6790
|
+
else if (iterable.type.elem.kind === "union") {
|
|
6791
|
+
const arms = lowerer.unions.get(iterable.type.elem.unionId)?.arms;
|
|
6792
|
+
if (arms?.length === 2 && arms.some((arm) => arm.kind === "undefinedT")) {
|
|
6793
|
+
const arm = arms.find((candidate) => candidate.kind === "promise");
|
|
6794
|
+
if (arm?.kind === "promise")
|
|
6795
|
+
promiseElem = arm;
|
|
6796
|
+
}
|
|
6797
|
+
}
|
|
6798
|
+
const nonThenable = (type) => {
|
|
6799
|
+
if (type.kind === "union") {
|
|
6800
|
+
const arms = lowerer.unions.get(type.unionId)?.arms;
|
|
6801
|
+
return arms !== undefined && arms.every(nonThenable);
|
|
6802
|
+
}
|
|
6803
|
+
if (type.kind === "record") {
|
|
6804
|
+
const shape = lowerer.shapes.get(type.shapeId);
|
|
6805
|
+
return shape !== undefined && !shape.indexValue && !shape.fields.some((field) => field.name === "then");
|
|
6806
|
+
}
|
|
6807
|
+
return type.kind === "f64" || type.kind === "bigint" || type.kind === "string" ||
|
|
6808
|
+
type.kind === "bool" || type.kind === "symbol" || type.kind === "array" ||
|
|
6809
|
+
type.kind === "undefinedT" || type.kind === "nullT";
|
|
6810
|
+
};
|
|
6811
|
+
if (promiseElem && yieldedT.kind === "union" &&
|
|
6812
|
+
!["void", "union", "dyn", "jsval", "undefinedT", "nullT"].includes(promiseElem.inner.kind)) {
|
|
6813
|
+
awaitPromiseTag = lowerer.armTag(yieldedT.unionId, promiseElem);
|
|
6814
|
+
elemValueT = lowerer.withUndefinedArm(promiseElem.inner);
|
|
6815
|
+
}
|
|
6816
|
+
else if (!nonThenable(iterable.type.elem)) {
|
|
6817
|
+
lowerer.unsupported("SC1070", stmt.expression, "for-await over array values that may be promises or thenables");
|
|
6818
|
+
}
|
|
6819
|
+
}
|
|
6552
6820
|
// Native arrays retain their payload ABI; the loop binds the value yielded
|
|
6553
6821
|
// by Get, which is undefined for both holes and present undefined slots.
|
|
6554
6822
|
const sourceT = iterable.type;
|
|
6555
6823
|
const source = lowerer.declareHiddenLocal("%arrayIterator", sourceT);
|
|
6556
6824
|
const cursor = lowerer.declareHiddenLocal("%arrayCursor", F64);
|
|
6557
6825
|
cursor.mutable = true;
|
|
6558
|
-
const forValues = (localId, body) =>
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6826
|
+
const forValues = (localId, body) => {
|
|
6827
|
+
const loc = locOf(stmt);
|
|
6828
|
+
const needsClose = awaitArray ? lowerer.declareHiddenLocal("%arrayIteratorNeedsClose", BOOL) : null;
|
|
6829
|
+
if (needsClose)
|
|
6830
|
+
needsClose.mutable = true;
|
|
6831
|
+
const yielded = arrayValueRead(lowerer, varRef(source.id, sourceT, loc), varRef(cursor.id, F64, loc), sourceT.elem, loc);
|
|
6832
|
+
const init = awaitPromiseTag === null ? yielded : {
|
|
6833
|
+
kind: "awaitUnionExpr", value: yielded, promiseTag: awaitPromiseTag, type: elemValueT, loc,
|
|
6834
|
+
};
|
|
6835
|
+
const hops = awaitArray ? (awaitPromiseTag === null ? 2 : 1) : 0;
|
|
6836
|
+
const hop = () => ({
|
|
6837
|
+
kind: "exprStmt", expr: { kind: "libCall", fn: "async.hop", args: [], type: VOID, loc }, loc,
|
|
6838
|
+
});
|
|
6839
|
+
const nextError = awaitPromiseTag !== null ? lowerer.declareHiddenLocal("%arrayIteratorNextError", CAUGHT) : null;
|
|
6840
|
+
const awaitedValue = nextError ? lowerer.declareHiddenLocal("%arrayIteratorValue", elemValueT) : null;
|
|
6841
|
+
if (awaitedValue)
|
|
6842
|
+
awaitedValue.mutable = true;
|
|
6843
|
+
const readValue = awaitedValue
|
|
6844
|
+
? { kind: "assign", localId: awaitedValue.id, value: init, loc }
|
|
6845
|
+
: { kind: "varDecl", localId, init, loc };
|
|
6846
|
+
const nextValue = nextError ? {
|
|
6847
|
+
kind: "tryCatch",
|
|
6848
|
+
tryBody: [readValue],
|
|
6849
|
+
// Async-from-sync iteration has a continuation reaction between a
|
|
6850
|
+
// rejected element promise and the loop's rejected next result.
|
|
6851
|
+
catchBody: [hop(), { kind: "rethrow", localId: nextError.id, loc }],
|
|
6852
|
+
catchLocalId: nextError.id,
|
|
6853
|
+
finallyBody: null,
|
|
6854
|
+
loc,
|
|
6855
|
+
} : readValue;
|
|
6856
|
+
const length = () => ({
|
|
6857
|
+
kind: "arrIntrinsic", method: "length", receiver: varRef(source.id, sourceT, loc), args: [], type: F64, loc,
|
|
6858
|
+
});
|
|
6859
|
+
const loop = {
|
|
6860
|
+
kind: "for",
|
|
6861
|
+
init: { kind: "varDecl", localId: cursor.id, init: numLit(0, loc), loc },
|
|
6862
|
+
cond: awaitArray
|
|
6863
|
+
? { kind: "boolLit", value: true, type: BOOL, loc }
|
|
6864
|
+
: { kind: "bin", op: "<", left: varRef(cursor.id, F64, loc), right: length(), type: BOOL, loc },
|
|
6865
|
+
update: { kind: "assign", localId: cursor.id, value: { kind: "bin", op: "+", left: varRef(cursor.id, F64, loc), right: numLit(1, loc), type: F64, loc }, loc },
|
|
6866
|
+
body: [
|
|
6867
|
+
...(needsClose ? [{
|
|
6868
|
+
kind: "assign", localId: needsClose.id,
|
|
6869
|
+
value: { kind: "boolLit", value: false, type: BOOL, loc }, loc,
|
|
6870
|
+
}] : []),
|
|
6871
|
+
...(needsClose ? [{
|
|
6872
|
+
kind: "if",
|
|
6873
|
+
cond: { kind: "bin", op: ">=", left: varRef(cursor.id, F64, loc), right: length(), type: BOOL, loc },
|
|
6874
|
+
then: [hop(), hop(), { kind: "break", loc }],
|
|
6875
|
+
else_: null,
|
|
6876
|
+
loc,
|
|
6877
|
+
}] : []),
|
|
6878
|
+
...(awaitedValue ? [{ kind: "varDecl", localId: awaitedValue.id, init: null, loc }] : []),
|
|
6879
|
+
nextValue,
|
|
6880
|
+
...(awaitedValue ? [{ kind: "varDecl", localId, init: varRef(awaitedValue.id, elemValueT, loc), loc }] : []),
|
|
6881
|
+
...Array.from({ length: hops }, hop),
|
|
6882
|
+
// A rejected next value has no iterator close. Once a value has
|
|
6883
|
+
// arrived, an abrupt completion in the body does await close.
|
|
6884
|
+
...(needsClose ? [{
|
|
6885
|
+
kind: "assign", localId: needsClose.id,
|
|
6886
|
+
value: { kind: "boolLit", value: true, type: BOOL, loc }, loc,
|
|
6887
|
+
}] : []),
|
|
6888
|
+
...body,
|
|
6889
|
+
],
|
|
6890
|
+
...(labels && { labels }),
|
|
6891
|
+
loc,
|
|
6892
|
+
};
|
|
6893
|
+
return {
|
|
6894
|
+
kind: "block",
|
|
6895
|
+
body: [
|
|
6896
|
+
{ kind: "varDecl", localId: source.id, init: iterable, loc },
|
|
6897
|
+
...(needsClose ? [{ kind: "varDecl", localId: needsClose.id, init: { kind: "boolLit", value: false, type: BOOL, loc }, loc }] : []),
|
|
6898
|
+
needsClose ? {
|
|
6899
|
+
kind: "tryCatch",
|
|
6900
|
+
tryBody: [loop], catchBody: null, catchLocalId: null,
|
|
6901
|
+
finallyBody: [{ kind: "if", cond: varRef(needsClose.id, BOOL, loc), then: [hop()], else_: null, loc }],
|
|
6902
|
+
loc,
|
|
6903
|
+
} : loop,
|
|
6904
|
+
],
|
|
6905
|
+
loc,
|
|
6906
|
+
};
|
|
6907
|
+
};
|
|
6574
6908
|
if (!ts.isVariableDeclarationList(stmt.initializer)) {
|
|
6575
6909
|
// `for (x of xs)` over a PRE-DECLARED writable binding: JS assigns
|
|
6576
6910
|
// the existing binding once per pass — one shared binding across
|
|
@@ -6657,7 +6991,9 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6657
6991
|
return forValues(tmp.id, [write, ...body]);
|
|
6658
6992
|
}
|
|
6659
6993
|
const local = lowerer.declareLocal(decl.name, decl.name.text, elemValueT, isLet);
|
|
6660
|
-
|
|
6994
|
+
const declaredElement = lowerer.mapTypeOf(lowerer.typeOf(decl.name));
|
|
6995
|
+
if (!typeEquals(elemValueT, sourceT.elem) ||
|
|
6996
|
+
(declaredElement !== null && lowerer.runtimeOptionalWidening(elemValueT, declaredElement) !== null)) {
|
|
6661
6997
|
const root = lowerer.runtimeOptionalRootOf(local);
|
|
6662
6998
|
lowerer.runtimeOptionalLocals.add(root);
|
|
6663
6999
|
lowerer.runtimeOptionalStorageLocals.add(root);
|
|
@@ -7115,66 +7451,46 @@ function lowerForOfClassIterator(lowerer, stmt, iterable, cit, labels) {
|
|
|
7115
7451
|
lowerer.scopes.pop();
|
|
7116
7452
|
}
|
|
7117
7453
|
}
|
|
7118
|
-
/**
|
|
7119
|
-
*
|
|
7120
|
-
*
|
|
7121
|
-
* it = iterNew(v); // GetIterator (prelude; may throw)
|
|
7122
|
-
* while (true) {
|
|
7123
|
-
* r = it.next(); // callMethod
|
|
7124
|
-
* if (truthy(r.done)) break;
|
|
7125
|
-
* <bind loop var(s) from r.value> // getProp
|
|
7126
|
-
* ...body
|
|
7127
|
-
* }
|
|
7128
|
-
*
|
|
7129
|
-
* The loop variable's ELEMENT is an island handle (jsval — exactly what
|
|
7130
|
-
* the checker's package-typed element maps to); identifier heads bind
|
|
7131
|
-
* it per iteration, destructuring heads run the jsval pattern desugar,
|
|
7132
|
-
* pre-declared and var heads keep their fences (the array path's
|
|
7133
|
-
* stories don't carry over mechanically). IteratorClose on early exit
|
|
7134
|
-
* (break/return out of a partial iteration calling it.return()) is NOT
|
|
7135
|
-
* run — a divergence only a custom island iterator with a return()
|
|
7136
|
-
* method can observe. */
|
|
7137
|
-
/** For-of over a CHECKED-DYNAMIC iterable: the source packs ONCE
|
|
7138
|
-
* through the spread walk (dyn.iterPack — dyn arrays element-by-
|
|
7139
|
-
* element, strings by code point, bytes by byte; a WRAPPED engine
|
|
7140
|
-
* value drains through the ENGINE's own iterator protocol via the
|
|
7141
|
-
* iter_drain arm; every other kind throws V8's not-iterable
|
|
7142
|
-
* TypeError, the identifier spelling when the head has one), then a
|
|
7143
|
-
* hidden index loop binds each element as a dyn value. The pack is an
|
|
7144
|
-
* eager SNAPSHOT (the matchAll stance): body mutations of a dyn-array
|
|
7145
|
-
* source don't extend the iteration where JS's live array iterator
|
|
7146
|
-
* would — documented divergence; engine sources drain through their
|
|
7147
|
-
* own protocol, so generators/Maps/Sets step exactly once like Node. */
|
|
7454
|
+
/** A checked IteratorRecord stays live throughout the loop. Cache next once,
|
|
7455
|
+
* read done before value, and close only after a yielded value has arrived.
|
|
7456
|
+
* Abrupt body throws retain precedence over errors raised by return(). */
|
|
7148
7457
|
function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
7149
7458
|
const loc = locOf(stmt);
|
|
7150
|
-
const head = stmt.expression;
|
|
7151
|
-
// V8's for-of CallPrinter spellings: named sources (identifiers and
|
|
7152
|
-
// plain property chains) read "<src> is not iterable", call heads
|
|
7153
|
-
// with a nameable callee "<callee> is not a function or its return
|
|
7154
|
-
// value is not iterable"; everything else keeps the runtime kind
|
|
7155
|
-
// wording. The runtime uses the spelling VERBATIM when non-empty.
|
|
7156
7459
|
const headText = (e) => {
|
|
7157
7460
|
if (ts.isIdentifier(e))
|
|
7158
7461
|
return e.text;
|
|
7159
7462
|
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken && ts.isIdentifier(e.name)) {
|
|
7160
7463
|
const base = headText(e.expression);
|
|
7161
|
-
return base
|
|
7464
|
+
return base === null ? null : `${base}.${e.name.text}`;
|
|
7162
7465
|
}
|
|
7163
7466
|
return null;
|
|
7164
7467
|
};
|
|
7165
|
-
const
|
|
7166
|
-
const
|
|
7167
|
-
const spell =
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
const
|
|
7173
|
-
const
|
|
7174
|
-
|
|
7175
|
-
const
|
|
7176
|
-
const
|
|
7177
|
-
|
|
7468
|
+
const name = headText(stmt.expression);
|
|
7469
|
+
const callee = ts.isCallExpression(stmt.expression) ? headText(stmt.expression.expression) : null;
|
|
7470
|
+
const spell = name !== null ? `${name} is not iterable` : callee !== null ? `${callee} is not a function or its return value is not iterable` : "";
|
|
7471
|
+
const iterator = lowerer.declareHiddenLocal("%dofIterator", DYN);
|
|
7472
|
+
const next = lowerer.declareHiddenLocal("%dofNext", DYN);
|
|
7473
|
+
const step = lowerer.declareHiddenLocal("%dofStep", DYN);
|
|
7474
|
+
const value = lowerer.declareHiddenLocal("%dofValue", DYN);
|
|
7475
|
+
const returned = lowerer.declareHiddenLocal("%dofReturn", DYN);
|
|
7476
|
+
const needsClose = lowerer.declareHiddenLocal("%dofNeedsClose", BOOL);
|
|
7477
|
+
needsClose.mutable = true;
|
|
7478
|
+
const error = lowerer.declareHiddenLocal("%dofError", CAUGHT);
|
|
7479
|
+
const get = (source, key) => ({
|
|
7480
|
+
kind: "dynKeyGet", value: source, key: { kind: "strLit", value: key, type: STRING, loc }, type: DYN, loc,
|
|
7481
|
+
});
|
|
7482
|
+
const check = (value) => ({ kind: "libCall", fn: "dyn.iteratorResult", args: [value], type: DYN, loc });
|
|
7483
|
+
const call = (callee) => check({
|
|
7484
|
+
kind: "dynCall", callee, receiver: varRef(iterator.id, DYN, loc), calleeName: "iterator method", args: [], type: DYN, loc,
|
|
7485
|
+
});
|
|
7486
|
+
const setClose = (value) => ({ kind: "assign", localId: needsClose.id, value: { kind: "boolLit", value, type: BOOL, loc }, loc });
|
|
7487
|
+
const close = () => [
|
|
7488
|
+
{ kind: "varDecl", localId: returned.id, init: get(varRef(iterator.id, DYN, loc), "return"), loc },
|
|
7489
|
+
{ kind: "if", cond: { kind: "unary", op: "!", operand: { kind: "dynTest", test: "nullish", value: varRef(returned.id, DYN, loc), type: BOOL, loc }, type: BOOL, loc }, then: [
|
|
7490
|
+
{ kind: "exprStmt", expr: call(varRef(returned.id, DYN, loc)), loc },
|
|
7491
|
+
], else_: null, loc },
|
|
7492
|
+
];
|
|
7493
|
+
const elemInit = () => varRef(value.id, DYN, loc);
|
|
7178
7494
|
lowerer.scopes.push(new Map());
|
|
7179
7495
|
try {
|
|
7180
7496
|
const binds = [];
|
|
@@ -7242,40 +7558,35 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
7242
7558
|
}
|
|
7243
7559
|
}
|
|
7244
7560
|
const body = lowerer.inCtl("loop", () => lowerer.lowerScopedBlock(stmt.statement), labels);
|
|
7561
|
+
const loop = {
|
|
7562
|
+
kind: "while", cond: { kind: "boolLit", value: true, type: BOOL, loc },
|
|
7563
|
+
body: [
|
|
7564
|
+
setClose(false),
|
|
7565
|
+
{ kind: "varDecl", localId: step.id, init: call(varRef(next.id, DYN, loc)), loc },
|
|
7566
|
+
{ 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 },
|
|
7567
|
+
{ kind: "varDecl", localId: value.id, init: get(varRef(step.id, DYN, loc), "value"), loc },
|
|
7568
|
+
setClose(true),
|
|
7569
|
+
...binds, ...body,
|
|
7570
|
+
],
|
|
7571
|
+
...(labels && { labels }), loc,
|
|
7572
|
+
};
|
|
7245
7573
|
return {
|
|
7246
7574
|
kind: "block",
|
|
7247
7575
|
body: [
|
|
7576
|
+
{ 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 },
|
|
7577
|
+
{ kind: "varDecl", localId: next.id, init: get(varRef(iterator.id, DYN, loc), "next"), loc },
|
|
7578
|
+
{ kind: "varDecl", localId: needsClose.id, init: { kind: "boolLit", value: false, type: BOOL, loc }, loc },
|
|
7248
7579
|
{
|
|
7249
|
-
kind: "
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
loc,
|
|
7259
|
-
},
|
|
7260
|
-
{
|
|
7261
|
-
kind: "for",
|
|
7262
|
-
init: { kind: "varDecl", localId: idx.id, init: { kind: "numLit", value: 0, type: F64, loc }, loc },
|
|
7263
|
-
cond: {
|
|
7264
|
-
kind: "bin",
|
|
7265
|
-
op: "<",
|
|
7266
|
-
left: iRef(),
|
|
7267
|
-
right: { kind: "libCall", fn: "dyn.arrLen", args: [packRef()], type: F64, loc },
|
|
7268
|
-
type: BOOL,
|
|
7269
|
-
loc,
|
|
7270
|
-
},
|
|
7271
|
-
update: {
|
|
7272
|
-
kind: "assign",
|
|
7273
|
-
localId: idx.id,
|
|
7274
|
-
value: { kind: "bin", op: "+", left: iRef(), right: { kind: "numLit", value: 1, type: F64, loc }, type: F64, loc },
|
|
7275
|
-
loc,
|
|
7276
|
-
},
|
|
7277
|
-
body: [...binds, ...body],
|
|
7278
|
-
...(labels && { labels }),
|
|
7580
|
+
kind: "tryCatch", tryBody: [loop],
|
|
7581
|
+
catchBody: [
|
|
7582
|
+
{ kind: "if", cond: varRef(needsClose.id, BOOL, loc), then: [
|
|
7583
|
+
setClose(false),
|
|
7584
|
+
{ kind: "tryCatch", tryBody: close(), catchBody: [], catchLocalId: null, finallyBody: null, loc },
|
|
7585
|
+
], else_: null, loc },
|
|
7586
|
+
{ kind: "rethrow", localId: error.id, loc },
|
|
7587
|
+
],
|
|
7588
|
+
catchLocalId: error.id,
|
|
7589
|
+
finallyBody: [{ kind: "if", cond: varRef(needsClose.id, BOOL, loc), then: close(), else_: null, loc }],
|
|
7279
7590
|
loc,
|
|
7280
7591
|
},
|
|
7281
7592
|
],
|
|
@@ -7286,6 +7597,25 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
7286
7597
|
lowerer.scopes.pop();
|
|
7287
7598
|
}
|
|
7288
7599
|
}
|
|
7600
|
+
/** for-of over an ISLAND value (see lowerForOf's jsval arm): the
|
|
7601
|
+
* engine's iterator protocol desugared over jsOps —
|
|
7602
|
+
*
|
|
7603
|
+
* it = iterNew(v); // GetIterator (prelude; may throw)
|
|
7604
|
+
* while (true) {
|
|
7605
|
+
* r = it.next(); // callMethod
|
|
7606
|
+
* if (truthy(r.done)) break;
|
|
7607
|
+
* <bind loop var(s) from r.value> // getProp
|
|
7608
|
+
* ...body
|
|
7609
|
+
* }
|
|
7610
|
+
*
|
|
7611
|
+
* The loop variable's ELEMENT is an island handle (jsval — exactly what
|
|
7612
|
+
* the checker's package-typed element maps to); identifier heads bind
|
|
7613
|
+
* it per iteration, destructuring heads run the jsval pattern desugar,
|
|
7614
|
+
* pre-declared and var heads keep their fences (the array path's
|
|
7615
|
+
* stories don't carry over mechanically). IteratorClose on early exit
|
|
7616
|
+
* (break/return out of a partial iteration calling it.return()) is NOT
|
|
7617
|
+
* run — a divergence only a custom island iterator with a return()
|
|
7618
|
+
* method can observe. */
|
|
7289
7619
|
function lowerForOfIsland(lowerer, stmt, iterable, labels) {
|
|
7290
7620
|
const loc = locOf(stmt);
|
|
7291
7621
|
if (!ts.isVariableDeclarationList(stmt.initializer)) {
|
|
@@ -7505,13 +7835,25 @@ function lowerForIn(lowerer, stmt) {
|
|
|
7505
7835
|
if (stdlibGlobalNameOf(lowerer, stmt.expression) === "globalThis") {
|
|
7506
7836
|
return { kind: "block", body: [], loc };
|
|
7507
7837
|
}
|
|
7508
|
-
const
|
|
7509
|
-
|
|
7510
|
-
|
|
7838
|
+
const receiver = lowerer.lowerExpr(stmt.expression);
|
|
7839
|
+
const recvT = receiver.type;
|
|
7840
|
+
if (recvT.kind === "dyn") {
|
|
7841
|
+
const recv = lowerer.declareHiddenLocal("%indyn", DYN);
|
|
7842
|
+
const ref = { kind: "varRef", localId: recv.id, type: DYN, loc };
|
|
7843
|
+
const keys = {
|
|
7844
|
+
kind: "dynCheck", value: { kind: "libCall", fn: "dyn.forInKeys", args: [ref], type: DYN, loc },
|
|
7845
|
+
type: arrayOf(STRING), loc,
|
|
7846
|
+
};
|
|
7847
|
+
const loop = lowerForInOverKeys(lowerer, stmt, keys, labels, (key) => ({
|
|
7848
|
+
kind: "libCall", fn: "dyn.hasKey", args: [ref, key], type: BOOL, loc,
|
|
7849
|
+
}));
|
|
7850
|
+
return { kind: "block", body: [{ kind: "varDecl", localId: recv.id, init: receiver, loc }, loop], loc };
|
|
7851
|
+
}
|
|
7852
|
+
if (recvT.kind === "array")
|
|
7853
|
+
return lowerForInArray(lowerer, stmt, labels, receiver);
|
|
7511
7854
|
if (recvT?.kind === "record") {
|
|
7512
7855
|
const shape = lowerer.shapes.get(recvT.shapeId);
|
|
7513
7856
|
if (shape && !shape.tuple) {
|
|
7514
|
-
const receiver = lowerer.lowerExpr(stmt.expression);
|
|
7515
7857
|
if (receiver.type.kind !== "record")
|
|
7516
7858
|
lowerer.badType(stmt.expression, lowerer.typeOf(stmt.expression));
|
|
7517
7859
|
const rShape = lowerer.shapes.get(receiver.type.shapeId);
|
|
@@ -7640,9 +7982,8 @@ function lowerForInOverKeys(lowerer, stmt, keys, labels, guard) {
|
|
|
7640
7982
|
* live-length guard is the per-visit presence check (keys removed by
|
|
7641
7983
|
* pops are skipped, exactly Node's HasProperty re-check; indices are
|
|
7642
7984
|
* dense, so `i < length` IS presence). */
|
|
7643
|
-
function lowerForInArray(lowerer, stmt, labels) {
|
|
7985
|
+
function lowerForInArray(lowerer, stmt, labels, arrExpr) {
|
|
7644
7986
|
const loc = locOf(stmt);
|
|
7645
|
-
const arrExpr = lowerer.lowerExpr(stmt.expression);
|
|
7646
7987
|
if (arrExpr.type.kind !== "array")
|
|
7647
7988
|
lowerer.badType(stmt.expression, lowerer.typeOf(stmt.expression));
|
|
7648
7989
|
lowerer.scopes.push(new Map());
|