@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 { objectEnumerationReceiver } from "./object-enumeration-receiver.js";
|
|
1
2
|
import { InternalCompilerError } from "../../errors.js";
|
|
2
3
|
/* Container-surface call lowering: array methods (including the HOF family
|
|
3
4
|
* map/filter/forEach with their synthesized helper functions), Map/Set
|
|
@@ -7,16 +8,31 @@ import * as ts from "../ts7/adapter.js";
|
|
|
7
8
|
import { BOOL, CAUGHT, DYN, F64, JSVAL, STRING, UNDEFINED_T, VOID, arrayOf, funcOf, isRefCounted, isSupportedArrayElem, isSupportedIndexValue, isUnitType, typeEquals } from "../../ir/ir.js";
|
|
8
9
|
import { ARRAY_METHODS, MAP_METHODS, SET_COMBINE_METHODS, SET_METHODS } from "./surfaces.js";
|
|
9
10
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
10
|
-
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
11
11
|
import { forOfVarTarget, lowerDestructuringAssign } from "./lower-stmts.js";
|
|
12
12
|
import { isJsSourceFile, locOf } from "../program.js";
|
|
13
13
|
import { islandPrimitiveExit, lowerDynDispatchMethodCall } from "./lower-calls.js";
|
|
14
14
|
import { buildArraySortFn } from "./lower-array-sort.js";
|
|
15
15
|
import { arrayIndexPresent, arrayValueRead, arrayValueStore, arrayValueType, currentArrayIndexPresent } from "./array-values.js";
|
|
16
16
|
import { typeKey } from "../type-mapper.js";
|
|
17
|
+
import { dynUndefinedExpr, newFnCtx, nodeThrowExpr } from "./lowerer.js";
|
|
17
18
|
import { boolLit, countedFor, numLit, strLit, varRef } from "../../ir/build.js";
|
|
18
19
|
import { defaultAfterUndefined, lowerPositionArgument, lowerStaticallyUndefinedArgument, positionNumber } from "./optional-arguments.js";
|
|
19
20
|
import { lowerArrayCopyWithin, lowerArrayFill } from "./array-indexed-mutation.js";
|
|
21
|
+
/** Object() and new Object() preserve known object inputs. Primitive
|
|
22
|
+
* boxing and unproven checked-dynamic values retain their refusal. */
|
|
23
|
+
export function lowerObjectConstructor(lowerer, args, loc) {
|
|
24
|
+
if (args.length === 0) {
|
|
25
|
+
return { kind: "recordLit", fields: [], type: { kind: "record", shapeId: lowerer.shapes.intern([]) }, loc };
|
|
26
|
+
}
|
|
27
|
+
if (args.length !== 1 || ts.isSpreadElement(args[0]))
|
|
28
|
+
return null;
|
|
29
|
+
const value = lowerer.lowerExpr(args[0]);
|
|
30
|
+
if (value.kind === "dynObjLit" || value.kind === "dynArrLit")
|
|
31
|
+
return value;
|
|
32
|
+
if (["record", "array", "object", "regex", "date", "bytes", "map", "set", "func", "classval"].includes(value.type.kind))
|
|
33
|
+
return value;
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
20
36
|
function primitivePositionType(lowerer, type) {
|
|
21
37
|
if (type.kind === "union") {
|
|
22
38
|
return lowerer.unions.get(type.unionId)?.arms.every((arm) => primitivePositionType(lowerer, arm)) ?? false;
|
|
@@ -79,7 +95,13 @@ function lowerArraySpreadItems(lowerer, nodes, elem, arrType, loc) {
|
|
|
79
95
|
];
|
|
80
96
|
for (const node of nodes) {
|
|
81
97
|
if (ts.isSpreadElement(node)) {
|
|
82
|
-
|
|
98
|
+
let source = lowerer.lowerExpr(node.expression);
|
|
99
|
+
if (source.type.kind === "set" && typeEquals(source.type.elem, elem)) {
|
|
100
|
+
source = { kind: "setIntrinsic", method: "toArray", receiver: source, args: [], type: arrType, loc };
|
|
101
|
+
}
|
|
102
|
+
if (source.type.kind === "record" && lowerer.shapes.get(source.type.shapeId)?.tuple) {
|
|
103
|
+
source = lowerer.widthCoerce(source, arrType) ?? source;
|
|
104
|
+
}
|
|
83
105
|
if (!typeEquals(source.type, arrType)) {
|
|
84
106
|
lowerer.noLowering(`Array insertion spread from '${lowerer.fmt(source.type)}'`, node);
|
|
85
107
|
}
|
|
@@ -137,9 +159,6 @@ function lowerArrayJoinSeparator(lowerer, node, loc) {
|
|
|
137
159
|
* directly from its IR return type. Fence element kinds ScrArr cannot hold
|
|
138
160
|
* before constructing that array type. */
|
|
139
161
|
function fenceProducedArrayElem(lowerer, node, producer, elem) {
|
|
140
|
-
if (elem.kind === "dyn") {
|
|
141
|
-
lowerer.unsupported("SC1090", node, `${producer} with a callback returning 'unknown'-typed values (the result array has no static element type — annotate the callback's return)`);
|
|
142
|
-
}
|
|
143
162
|
if (!isSupportedArrayElem(elem)) {
|
|
144
163
|
lowerer.unsupported("SC1090", node, `${producer} with a callback returning '${lowerer.fmt(elem)}' values (arrays of this element kind have no representation — store the values individually)`);
|
|
145
164
|
}
|
|
@@ -205,6 +224,21 @@ export function lowerArrayMethodCall(lowerer, call, access) {
|
|
|
205
224
|
// static arrIntrinsic over a jsval (the validator ICE).
|
|
206
225
|
{
|
|
207
226
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
227
|
+
if (receiver.type.kind === "union") {
|
|
228
|
+
const arms = lowerer.unions.get(receiver.type.unionId)?.arms;
|
|
229
|
+
const present = arms?.find((arm) => arm.kind === "array");
|
|
230
|
+
if (present?.kind === "array" && arms?.every((arm) => typeEquals(arm, present) || isUnitType(arm))) {
|
|
231
|
+
// A predicate can narrow the element type without changing the
|
|
232
|
+
// original array layout. Extract that stored array before choosing
|
|
233
|
+
// a helper, then adapt callback arguments at their actual ABI.
|
|
234
|
+
const array = lowerer.runtimeOptionalPropertyReceiver(access.expression, receiver, present, name) ??
|
|
235
|
+
lowerer.coerceInto(access.expression, receiver, present);
|
|
236
|
+
return lowerer.withExpressionOverride(access.expression, array, () => lowerArrayMethodCall(lowerer, call, access));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (receiver.type.kind === "record" && lowerer.shapes.get(receiver.type.shapeId)?.tuple) {
|
|
240
|
+
return lowerTupleReadMethodCall(lowerer, call, access, receiver);
|
|
241
|
+
}
|
|
208
242
|
if (receiver.type.kind === "jsval") {
|
|
209
243
|
const loweredArgs = call.arguments.map((a) => lowerer.lowerExpr(a));
|
|
210
244
|
if (name === "filter" && loweredArgs[0]?.type.kind === "func" && loweredArgs[0].type.ret.kind === "void") {
|
|
@@ -228,16 +262,11 @@ export function lowerArrayMethodCall(lowerer, call, access) {
|
|
|
228
262
|
return dispatched;
|
|
229
263
|
lowerer.noLowering(`.${name} on an array value held in a checked-dynamic binding`, call, "assign it to an array-typed binding first (the validated extraction), then call the method");
|
|
230
264
|
}
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
|
|
236
|
-
// the truth — ride the explicit-`any[]` handle-element lowering
|
|
237
|
-
// (pushes marshal in, HOF callbacks bind the handle, results exit
|
|
238
|
-
// per the checker type), never a typed intrinsic over a jsval-
|
|
239
|
-
// element array (the validator ICE).
|
|
240
|
-
if (receiver.type.kind === "array" && receiver.type.elem.kind === "jsval" && !typeEquals(receiverIr, receiver.type)) {
|
|
265
|
+
// Flow predicates and evolving-any analysis can refine the checker
|
|
266
|
+
// element type without changing the array's storage. Helpers and
|
|
267
|
+
// callback array arguments must retain the original layout and
|
|
268
|
+
// identity; element conversions happen at the callback boundary.
|
|
269
|
+
if (receiver.type.kind === "array" && !typeEquals(receiverIr, receiver.type)) {
|
|
241
270
|
receiverIr = receiver.type;
|
|
242
271
|
elem = receiver.type.elem;
|
|
243
272
|
}
|
|
@@ -445,6 +474,17 @@ export function lowerArrayMethodCall(lowerer, call, access) {
|
|
|
445
474
|
loc,
|
|
446
475
|
};
|
|
447
476
|
}
|
|
477
|
+
if (call.arguments.some(ts.isSpreadElement)) {
|
|
478
|
+
// Finish argument evaluation before mutating the receiver. Each
|
|
479
|
+
// spread snapshots its elements immediately, so a later argument
|
|
480
|
+
// can mutate that source without changing already-collected values.
|
|
481
|
+
const items = lowerArraySpreadItems(lowerer, call.arguments, elem, receiverIr, loc);
|
|
482
|
+
return {
|
|
483
|
+
kind: "arrIntrinsic",
|
|
484
|
+
method: name === "push" ? "pushSpread" : "unshiftSpread",
|
|
485
|
+
receiver, args: [items], type: F64, loc,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
448
488
|
const valueProbes = call.arguments.map((arg) => tryLowerExpression(lowerer, arg));
|
|
449
489
|
if (valueProbes.some((probe) => probe !== null && lowerer.runtimeOptionalWidening(probe.type, elem) !== null)) {
|
|
450
490
|
const items = lowerArrayValueItems(lowerer, call.arguments.map((arg) => lowerer.lowerExpr(arg)), elem, receiverIr, loc);
|
|
@@ -471,12 +511,11 @@ export function lowerArrayMethodCall(lowerer, call, access) {
|
|
|
471
511
|
};
|
|
472
512
|
}
|
|
473
513
|
if (name === "pop") {
|
|
474
|
-
//
|
|
475
|
-
//
|
|
476
|
-
//
|
|
477
|
-
// wrapper would lose the element identity contract.
|
|
514
|
+
// Widen a union payload through the normal array-read machinery
|
|
515
|
+
// before removing it. Reinterpreting the stored union's tag as the
|
|
516
|
+
// result union would confuse arms when undefined changes their order.
|
|
478
517
|
if (elem.kind === "union" && lowerer.armTag(elem.unionId, UNDEFINED_T) < 0) {
|
|
479
|
-
lowerer.
|
|
518
|
+
return lowerUnionArrayRemoval(lowerer, access.expression, elem, false, loc);
|
|
480
519
|
}
|
|
481
520
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
482
521
|
return {
|
|
@@ -518,7 +557,12 @@ export function lowerArrayMethodCall(lowerer, call, access) {
|
|
|
518
557
|
// IsArray says spread; no honest static answer exists.
|
|
519
558
|
lowerer.unsupported("SC1090", argNode, "concat of a bare inner array onto an array-of-arrays (JS would SPREAD it one level — wrap it: a.concat([inner]))");
|
|
520
559
|
}
|
|
521
|
-
|
|
560
|
+
// Declaration-backed JS methods can return checked values even
|
|
561
|
+
// when their public signature names a concrete array. Validate
|
|
562
|
+
// that boundary before spreading the represented elements.
|
|
563
|
+
let arg = lowerer.lowerExpr(argNode);
|
|
564
|
+
if (arg.type.kind === "dyn")
|
|
565
|
+
arg = lowerer.coerceInto(argNode, arg, argArrayType);
|
|
522
566
|
if (arg.type.kind !== "array")
|
|
523
567
|
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
524
568
|
shape.push("a");
|
|
@@ -580,19 +624,20 @@ export function lowerArrayMethodCall(lowerer, call, access) {
|
|
|
580
624
|
return { kind: "arrIntrinsic", method: "spliceInsert", receiver, args: [...args, items], type: receiverIr, loc };
|
|
581
625
|
}
|
|
582
626
|
if (name === "shift") {
|
|
583
|
-
//
|
|
584
|
-
// element with the tail sliding down — the result is the interned
|
|
585
|
-
// `elem | undefined` union, the env-read convention. Union-element
|
|
586
|
-
// arrays are fenced: their shift result would collapse arms
|
|
587
|
-
// (`(string | undefined)[]`'s shift is `string | undefined` too, and
|
|
588
|
-
// the box can't say which world the undefined came from).
|
|
627
|
+
// Like pop, a union without undefined needs an explicit tag widening.
|
|
589
628
|
if (elem.kind === "union" && lowerer.armTag(elem.unionId, UNDEFINED_T) < 0) {
|
|
590
|
-
lowerer.
|
|
629
|
+
return lowerUnionArrayRemoval(lowerer, access.expression, elem, true, loc);
|
|
591
630
|
}
|
|
592
631
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
593
632
|
return { kind: "arrIntrinsic", method: "shift", receiver, args: [], type: arrayValueType(lowerer, elem), loc };
|
|
594
633
|
}
|
|
595
634
|
if (name === "join") {
|
|
635
|
+
if (elem.kind === "dyn") {
|
|
636
|
+
const receiver = lowerer.coerceToExpected(lowerer.lowerExpr(access.expression), DYN);
|
|
637
|
+
const args = call.arguments.length ? [lowerer.lowerExprExpecting(call.arguments[0], DYN)] : [];
|
|
638
|
+
return lowerer.coerceToExpected({ kind: "dynInvoke", recv: receiver, method: "join",
|
|
639
|
+
calleeName: access.getText(), args, type: DYN, loc }, STRING);
|
|
640
|
+
}
|
|
596
641
|
// The ambient declares join on every Array<T> (a per-element-type
|
|
597
642
|
// interface split isn't expressible there), so string-convertible
|
|
598
643
|
// elements are enforced here: nested arrays would need JS's recursive
|
|
@@ -627,6 +672,38 @@ export function lowerArrayMethodCall(lowerer, call, access) {
|
|
|
627
672
|
// reduce / reduceRight
|
|
628
673
|
return lowerArrayReduceCall(lowerer, call, access, name, elem);
|
|
629
674
|
}
|
|
675
|
+
/** Read before splice so removal cannot destroy the result's owned payload.
|
|
676
|
+
* The source is evaluated once and empty/sparse arrays yield undefined using
|
|
677
|
+
* the same slot-state checks as an indexed read. */
|
|
678
|
+
function lowerUnionArrayRemoval(lowerer, source, elem, first, loc) {
|
|
679
|
+
const receiver = lowerer.lowerExpr(source);
|
|
680
|
+
const arr = lowerer.declareHiddenLocal("%removeArray", receiver.type);
|
|
681
|
+
const arrRef = varRef(arr.id, arr.type, loc);
|
|
682
|
+
const index = lowerer.declareHiddenLocal("%removeIndex", F64);
|
|
683
|
+
const indexRef = varRef(index.id, F64, loc);
|
|
684
|
+
const value = arrayValueRead(lowerer, arrRef, indexRef, elem, loc);
|
|
685
|
+
const result = lowerer.declareHiddenLocal("%removedValue", value.type);
|
|
686
|
+
return {
|
|
687
|
+
kind: "seqExpr",
|
|
688
|
+
stmts: [
|
|
689
|
+
{ kind: "varDecl", localId: arr.id, init: receiver, loc },
|
|
690
|
+
{
|
|
691
|
+
kind: "varDecl", localId: index.id,
|
|
692
|
+
init: first ? numLit(0, loc) : {
|
|
693
|
+
kind: "bin", op: "-",
|
|
694
|
+
left: { kind: "arrIntrinsic", method: "length", receiver: arrRef, args: [], type: F64, loc },
|
|
695
|
+
right: numLit(1, loc), type: F64, loc,
|
|
696
|
+
}, loc,
|
|
697
|
+
},
|
|
698
|
+
{ kind: "varDecl", localId: result.id, init: value, loc },
|
|
699
|
+
{
|
|
700
|
+
kind: "exprStmt",
|
|
701
|
+
expr: { kind: "arrIntrinsic", method: "splice", receiver: arrRef, args: [indexRef, numLit(1, loc)], type: arr.type, loc }, loc,
|
|
702
|
+
},
|
|
703
|
+
],
|
|
704
|
+
result: varRef(result.id, result.type, loc), type: result.type, loc,
|
|
705
|
+
};
|
|
706
|
+
}
|
|
630
707
|
function literalFlatDepth(value) {
|
|
631
708
|
if (value.kind === "numLit")
|
|
632
709
|
return value.value;
|
|
@@ -709,10 +786,9 @@ function lowerArrayFlatCall(lowerer, call, access, receiverType) {
|
|
|
709
786
|
function lowerArraySearchCall(lowerer, call, access, method, elem) {
|
|
710
787
|
const loc = locOf(call);
|
|
711
788
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
712
|
-
const argNode = call.arguments[0] ?? call;
|
|
713
789
|
if (call.arguments.some(ts.isSpreadElement))
|
|
714
790
|
lowerer.noLowering(`.${method} with spread arguments`, call);
|
|
715
|
-
|
|
791
|
+
const needle = call.arguments[0]
|
|
716
792
|
? lowerer.lowerExpr(call.arguments[0])
|
|
717
793
|
: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc };
|
|
718
794
|
const fromIndex = call.arguments[1]
|
|
@@ -720,6 +796,11 @@ function lowerArraySearchCall(lowerer, call, access, method, elem) {
|
|
|
720
796
|
: method === "lastIndexOf"
|
|
721
797
|
? { kind: "bin", op: "/", left: numLit(1, loc), right: numLit(0, loc), type: F64, loc }
|
|
722
798
|
: numLit(0, loc);
|
|
799
|
+
return lowerArraySearchValues(lowerer, call, method, elem, receiver, needle, fromIndex);
|
|
800
|
+
}
|
|
801
|
+
function lowerArraySearchValues(lowerer, call, method, elem, receiver, needle, fromIndex) {
|
|
802
|
+
const loc = locOf(call);
|
|
803
|
+
const argNode = call.arguments[0] ?? call;
|
|
723
804
|
// A derived CLASS VALUE against a base-classval element widens (the same
|
|
724
805
|
// pointer — identity search is exact); the coercion path owns the ABI gate.
|
|
725
806
|
if (needle.type.kind === "classval" && elem.kind === "classval" && !typeEquals(needle.type, elem)) {
|
|
@@ -765,14 +846,15 @@ function lowerArraySearchCall(lowerer, call, access, method, elem) {
|
|
|
765
846
|
: [needle.type];
|
|
766
847
|
const scalarNeedle = needleArms.every((arm) => arm.kind === "f64" || arm.kind === "string" || arm.kind === "bool" ||
|
|
767
848
|
arm.kind === "bigint" || arm.kind === "symbol" || isUnitType(arm));
|
|
768
|
-
const
|
|
849
|
+
const valueDef = lowerer.unions.get(valueT.unionId);
|
|
850
|
+
const valueArms = valueDef.arms;
|
|
769
851
|
if (scalarNeedle && !valueArms.some((arm) => arm.kind === "func" || arm.kind === "set")) {
|
|
770
852
|
const arms = [...valueArms];
|
|
771
853
|
for (const arm of needleArms)
|
|
772
854
|
if (!arms.some((existing) => typeEquals(existing, arm)))
|
|
773
855
|
arms.push(arm);
|
|
774
856
|
if (arms.length !== valueArms.length)
|
|
775
|
-
valueT = { kind: "union", unionId: lowerer.unions.
|
|
857
|
+
valueT = { kind: "union", unionId: lowerer.unions.transform(valueDef, arms) };
|
|
776
858
|
}
|
|
777
859
|
const directNeedle = method === "lastIndexOf" && elem.kind !== "union" && typeEquals(needle.type, elem);
|
|
778
860
|
const searchNeedle = directNeedle ? needle : lowerer.coerceInto(argNode, needle, valueT);
|
|
@@ -791,6 +873,12 @@ function lowerArraySearchCall(lowerer, call, access, method, elem) {
|
|
|
791
873
|
* includes, where NaN equals NaN while +0 and -0 remain equal. */
|
|
792
874
|
function arraySearchEquality(lowerer, left, right, sameValueZero, loc) {
|
|
793
875
|
if (left.type.kind !== "union" || right.type.kind !== "union" || left.type.unionId !== right.type.unionId) {
|
|
876
|
+
if (left.type.kind === "string" && right.type.kind === "string") {
|
|
877
|
+
return { kind: "strEq", negated: false, left, right, type: BOOL, loc };
|
|
878
|
+
}
|
|
879
|
+
if (left.type.kind === "bigint" && right.type.kind === "bigint") {
|
|
880
|
+
return { kind: "bin", op: "===", left: { kind: "libCall", fn: "bigint.cmp", args: [left, right], type: F64, loc }, right: numLit(0, loc), type: BOOL, loc };
|
|
881
|
+
}
|
|
794
882
|
return { kind: "bin", op: "===", left, right, type: BOOL, loc };
|
|
795
883
|
}
|
|
796
884
|
const unionId = left.type.unionId;
|
|
@@ -1004,7 +1092,7 @@ function arraySearchHelper(lowerer, method, elem, valueT, needleT, directNeedle,
|
|
|
1004
1092
|
* loop passes exactly what it declares (JS passes everything; a callback
|
|
1005
1093
|
* only sees the parameters it names). Returns the lowered callback and
|
|
1006
1094
|
* its declared arity. */
|
|
1007
|
-
function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
|
|
1095
|
+
function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false, expectedReturn) {
|
|
1008
1096
|
const full = [...lead, F64, arrT];
|
|
1009
1097
|
// A DYN-receiver HOF's callback (`parsed.flatMap((value) => ...)`):
|
|
1010
1098
|
// the contextual signature types the unannotated param `any` (the
|
|
@@ -1039,15 +1127,16 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
|
|
|
1039
1127
|
lowerer.jsvalParamOverrides.add(p);
|
|
1040
1128
|
});
|
|
1041
1129
|
}
|
|
1042
|
-
//
|
|
1043
|
-
//
|
|
1044
|
-
//
|
|
1045
|
-
//
|
|
1046
|
-
//
|
|
1130
|
+
// An untyped or flow-refined array can contextually type an inline
|
|
1131
|
+
// callback differently from the stored element and array layout. Bind
|
|
1132
|
+
// unannotated parameters to the helper's ABI when a boundary adapter
|
|
1133
|
+
// cannot carry it. Include the optional-read prepass's parameter type
|
|
1134
|
+
// in this comparison. The override is temporary because one callback
|
|
1135
|
+
// AST can lower under several generic instances.
|
|
1047
1136
|
const contextual = [];
|
|
1048
1137
|
const previousImplicit = lowerer.implicitParamTypes;
|
|
1049
1138
|
let contextualTs = null;
|
|
1050
|
-
if (
|
|
1139
|
+
if (ts.isArrowFunction(argNode) || ts.isFunctionExpression(argNode)) {
|
|
1051
1140
|
argNode.parameters.forEach((param, i) => {
|
|
1052
1141
|
const expected = full[i];
|
|
1053
1142
|
if (expected === undefined || expected.kind === "dyn" || expected.kind === "jsval" ||
|
|
@@ -1055,7 +1144,10 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
|
|
|
1055
1144
|
return;
|
|
1056
1145
|
}
|
|
1057
1146
|
const checkerType = lowerer.checker.getTypeAtLocation(param.name);
|
|
1058
|
-
|
|
1147
|
+
const untyped = (checkerType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0;
|
|
1148
|
+
const raw = untyped ? null : lowerer.mapTypeOf(checkerType);
|
|
1149
|
+
const mapped = raw ? lowerer.runtimeOptionalBindingType(param.name, raw) : null;
|
|
1150
|
+
if (untyped ? !bindUntyped : mapped === null || lowerer.coercibleValue(expected, mapped))
|
|
1059
1151
|
return;
|
|
1060
1152
|
const symbol = lowerer.checker.getSymbolAtLocation(param.name);
|
|
1061
1153
|
if (!symbol)
|
|
@@ -1076,6 +1168,10 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
|
|
|
1076
1168
|
}
|
|
1077
1169
|
if (contextualTs !== null)
|
|
1078
1170
|
lowerer.implicitParamTypes = contextualTs;
|
|
1171
|
+
const previousReturn = lowerer.contextualFunctionReturns.get(argNode);
|
|
1172
|
+
if (expectedReturn && (ts.isArrowFunction(argNode) || ts.isFunctionExpression(argNode))) {
|
|
1173
|
+
lowerer.contextualFunctionReturns.set(argNode, expectedReturn);
|
|
1174
|
+
}
|
|
1079
1175
|
let fnArg;
|
|
1080
1176
|
try {
|
|
1081
1177
|
fnArg = lowerer.lowerExpr(argNode);
|
|
@@ -1090,6 +1186,27 @@ function hofCallbackArg(lowerer, argNode, lead, arrT, bindUntyped = false) {
|
|
|
1090
1186
|
lowerer.runtimeOptionalBindingTypes.set(symbol, previous);
|
|
1091
1187
|
}
|
|
1092
1188
|
lowerer.implicitParamTypes = previousImplicit;
|
|
1189
|
+
if (previousReturn === undefined)
|
|
1190
|
+
lowerer.contextualFunctionReturns.delete(argNode);
|
|
1191
|
+
else
|
|
1192
|
+
lowerer.contextualFunctionReturns.set(argNode, previousReturn);
|
|
1193
|
+
}
|
|
1194
|
+
// A callback can accept a wider parameter type than the array supplies
|
|
1195
|
+
// (a reusable predicate over a union is common). Its closure still has
|
|
1196
|
+
// that wider ABI: adapt each actual argument before invoking it, just
|
|
1197
|
+
// as assignment to a narrower function slot does. Require a conversion
|
|
1198
|
+
// plan so this path never manufactures a stranded callback.
|
|
1199
|
+
if (fnArg.type.kind === "dyn") {
|
|
1200
|
+
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(argNode));
|
|
1201
|
+
const ret = expectedReturn ?? (signatures[0] ? lowerer.mapTypeOf(lowerer.checker.getReturnTypeOfSignature(signatures[0])) : null);
|
|
1202
|
+
if (ret && ret.kind !== "void")
|
|
1203
|
+
fnArg = lowerer.coerceToExpected(fnArg, funcOf(full, ret));
|
|
1204
|
+
}
|
|
1205
|
+
if (fnArg.type.kind === "func" && fnArg.type.params.length <= full.length &&
|
|
1206
|
+
fnArg.type.params.every((param, i) => lowerer.coercibleValue(full[i], param))) {
|
|
1207
|
+
const callbackType = funcOf(full.slice(0, fnArg.type.params.length), fnArg.type.ret);
|
|
1208
|
+
if (!typeEquals(fnArg.type, callbackType))
|
|
1209
|
+
fnArg = lowerer.coerceToExpected(fnArg, callbackType);
|
|
1093
1210
|
}
|
|
1094
1211
|
// Array storage widens indexed reads with undefined so holes remain
|
|
1095
1212
|
// observable. The HOF helper guards every callback behind arrayHas,
|
|
@@ -1193,12 +1310,10 @@ function filterResultElem(lowerer, call, argNode, elem, valueT, booleanFilter) {
|
|
|
1193
1310
|
const checkerReceiver = access
|
|
1194
1311
|
? lowerer.mapTypeOf(lowerer.typeOf(access.expression))
|
|
1195
1312
|
: null;
|
|
1196
|
-
//
|
|
1197
|
-
//
|
|
1198
|
-
//
|
|
1199
|
-
|
|
1200
|
-
if (elem.kind === "jsval" && valueT.kind === "jsval" &&
|
|
1201
|
-
result?.kind === "array" && checkerReceiver?.kind === "array" &&
|
|
1313
|
+
// Equal checker elements mean the filter introduces no new refinement.
|
|
1314
|
+
// Preserve the stored element layout even if an earlier predicate or
|
|
1315
|
+
// evolving-any analysis changed the receiver's flow type.
|
|
1316
|
+
if (result?.kind === "array" && checkerReceiver?.kind === "array" &&
|
|
1202
1317
|
typeEquals(result.elem, checkerReceiver.elem)) {
|
|
1203
1318
|
return elem;
|
|
1204
1319
|
}
|
|
@@ -1451,29 +1566,22 @@ function arrayUnionHofHelper(lowerer, method, receiverT, arrays, callbackT, arit
|
|
|
1451
1566
|
});
|
|
1452
1567
|
return name;
|
|
1453
1568
|
}
|
|
1454
|
-
/**
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
* each read wrapped into its arm (exactly the checker's callback
|
|
1461
|
-
* parameter type). Null when this isn't a tuple slice/map — writers and
|
|
1462
|
-
* the rest of the surface keep their fences. */
|
|
1463
|
-
export function lowerTupleReadMethodCall(lowerer, call, access) {
|
|
1569
|
+
/** Tuple methods keep the original receiver alive through argument evaluation.
|
|
1570
|
+
* Callback methods read each position only when it is visited, so writes to
|
|
1571
|
+
* later positions through a captured alias are visible. A tuple cannot be
|
|
1572
|
+
* passed as the callback's array parameter without changing its identity;
|
|
1573
|
+
* that parameter retains an explicit representation boundary. */
|
|
1574
|
+
export function lowerTupleReadMethodCall(lowerer, call, access, tupleReceiver) {
|
|
1464
1575
|
if (lowerer.chainBlocked(access, call))
|
|
1465
1576
|
return null;
|
|
1466
|
-
const
|
|
1467
|
-
|
|
1577
|
+
const method = access.name.text;
|
|
1578
|
+
const search = method === "includes" || method === "indexOf" || method === "lastIndexOf";
|
|
1579
|
+
if (method !== "slice" && method !== "map" && method !== "flatMap" && method !== "join" && !search)
|
|
1468
1580
|
return null;
|
|
1469
1581
|
if (!lowerer.isStdlibMember(access))
|
|
1470
1582
|
return null;
|
|
1471
|
-
let receiverIr = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
1472
|
-
let receiver = null;
|
|
1473
|
-
// A readonly tuple union under Array.isArray is checker-typed as an
|
|
1474
|
-
// unmappable intersection with any[], while maybeNarrow still extracts
|
|
1475
|
-
// its one tuple arm. Dispatch the supported tuple read methods from
|
|
1476
|
-
// that lowered representation, like tuple indexing and `.length`.
|
|
1583
|
+
let receiverIr = tupleReceiver?.type ?? lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
1584
|
+
let receiver = tupleReceiver ?? null;
|
|
1477
1585
|
const checkerArray = lowerer.checkerArrayValue(access.expression);
|
|
1478
1586
|
if (checkerArray?.type.kind === "record") {
|
|
1479
1587
|
receiverIr = checkerArray.type;
|
|
@@ -1485,75 +1593,188 @@ export function lowerTupleReadMethodCall(lowerer, call, access) {
|
|
|
1485
1593
|
if (!shape?.tuple)
|
|
1486
1594
|
return null;
|
|
1487
1595
|
receiver ??= lowerer.lowerExpr(access.expression);
|
|
1596
|
+
if (method === "join") {
|
|
1597
|
+
// Object.entries can retain its dynamic array representation behind a
|
|
1598
|
+
// checker tuple. Native tuples box as live references, so separator
|
|
1599
|
+
// evaluation can still mutate their elements before join reads them.
|
|
1600
|
+
// An unchecked outer array read must validate its optional payload
|
|
1601
|
+
// before passing the tuple to the runtime.
|
|
1602
|
+
if (receiver.type.kind === "union") {
|
|
1603
|
+
receiver = lowerer.coerceInto(access.expression, receiver, receiverIr);
|
|
1604
|
+
}
|
|
1605
|
+
const converted = lowerer.coerceInto(access.expression, receiver, DYN);
|
|
1606
|
+
const boxed = converted.kind === "dynFrom" && converted.value.type.kind === "record"
|
|
1607
|
+
? { ...converted, liveRef: true } : converted;
|
|
1608
|
+
const joined = lowerDynDispatchMethodCall(lowerer, call, access, boxed, true);
|
|
1609
|
+
return joined ? lowerer.coerceInto(call, joined, STRING) : null;
|
|
1610
|
+
}
|
|
1488
1611
|
if (receiver.type.kind !== "record")
|
|
1489
1612
|
return null;
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1613
|
+
const fields = [...shape.fields].sort((a, b) => Number(a.name) - Number(b.name));
|
|
1614
|
+
const arms = [];
|
|
1615
|
+
for (const field of fields) {
|
|
1616
|
+
const types = field.type.kind === "union" ? lowerer.unions.get(field.type.unionId).arms : [field.type];
|
|
1617
|
+
for (const type of types)
|
|
1618
|
+
if (!arms.some(arm => typeEquals(arm, type)))
|
|
1619
|
+
arms.push(type);
|
|
1620
|
+
}
|
|
1621
|
+
if (arms.length === 0)
|
|
1622
|
+
return null;
|
|
1623
|
+
const elem = arms.length === 1 ? arms[0] : { kind: "union", unionId: lowerer.unions.intern(arms) };
|
|
1493
1624
|
const loc = locOf(call);
|
|
1494
|
-
const
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1625
|
+
const tuple = varRef("a.0", receiver.type, loc);
|
|
1626
|
+
const read = (field) => lowerer.coerceInto(access.expression, {
|
|
1627
|
+
kind: "recordGet", obj: tuple, shapeId: receiverIr.shapeId, field: field.name, type: field.type, loc,
|
|
1628
|
+
}, elem);
|
|
1629
|
+
if (search) {
|
|
1630
|
+
if (call.arguments.length > 2 || call.arguments.some(ts.isSpreadElement)) {
|
|
1631
|
+
return lowerer.noLowering(`tuple .${method} with spread or extra arguments`, call);
|
|
1632
|
+
}
|
|
1633
|
+
const arg = call.arguments[0];
|
|
1634
|
+
const undefinedArg = arg ? lowerStaticallyUndefinedArgument(lowerer, arg) : null;
|
|
1635
|
+
let needle = arg ? undefinedArg ?? lowerer.lowerExpr(arg) : null;
|
|
1636
|
+
if (!needle || isUnitType(needle.type) || needle.type.kind === "void") {
|
|
1637
|
+
const optional = arrayValueType(lowerer, elem);
|
|
1638
|
+
const wrapped = needle?.type.kind === "nullT"
|
|
1639
|
+
? lowerer.coerceInto(arg ?? call, needle, optional) : lowerer.wrappedUndefined(optional, loc);
|
|
1640
|
+
if (!wrapped)
|
|
1641
|
+
return lowerer.noLowering(`tuple .${method} missing search value`, call);
|
|
1642
|
+
needle = needle ? defaultAfterUndefined(needle, wrapped) : wrapped;
|
|
1506
1643
|
}
|
|
1644
|
+
const from = call.arguments[1]
|
|
1645
|
+
? lowerPositionArgument(lowerer, call.arguments[1], numLit(0, loc))
|
|
1646
|
+
: numLit(method === "lastIndexOf" ? Infinity : 0, loc);
|
|
1647
|
+
const key = `tuple.${method}:${typeKey(receiver.type)}:${typeKey(needle.type)}:${typeKey(from.type)}:${call.arguments.length}`;
|
|
1648
|
+
let helper = lowerer.arrHofHelpers.get(key);
|
|
1649
|
+
const resultType = method === "includes" ? BOOL : F64;
|
|
1650
|
+
if (!helper) {
|
|
1651
|
+
helper = `%tuple.${method}.${lowerer.arrHofHelpers.size}`;
|
|
1652
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
1653
|
+
const params = [
|
|
1654
|
+
{ localId: "a.0", name: "a", type: receiver.type },
|
|
1655
|
+
{ localId: "needle.0", name: "needle", type: needle.type },
|
|
1656
|
+
{ localId: "from.0", name: "from", type: from.type },
|
|
1657
|
+
];
|
|
1658
|
+
const result = lowerArraySearchValues(lowerer, call, method, elem, { kind: "arrayLit", elems: fields.map(read), type: arrayOf(elem), loc }, varRef("needle.0", needle.type, loc), varRef("position.0", F64, loc));
|
|
1659
|
+
lowerer.liftedFns.push({
|
|
1660
|
+
name: helper, params, returnType: resultType,
|
|
1661
|
+
locals: [
|
|
1662
|
+
...params.map(param => ({ id: param.localId, name: param.name, type: param.type, mutable: false })),
|
|
1663
|
+
{ id: "position.0", name: "position", type: F64, mutable: false },
|
|
1664
|
+
],
|
|
1665
|
+
body: [
|
|
1666
|
+
{ kind: "varDecl", localId: "position.0", init: positionNumber(lowerer, varRef("from.0", from.type, loc), numLit(0, loc), call.arguments[1] ?? call, "tuple search position"), loc },
|
|
1667
|
+
{ kind: "return", value: result, loc },
|
|
1668
|
+
], loc,
|
|
1669
|
+
});
|
|
1670
|
+
}
|
|
1671
|
+
return { kind: "call", callee: helper, args: [receiver, needle, from], type: resultType, loc };
|
|
1507
1672
|
}
|
|
1508
|
-
if (
|
|
1509
|
-
|
|
1510
|
-
const snapshotElem = elemT;
|
|
1511
|
-
const snapshot = {
|
|
1512
|
-
kind: "arrayLit",
|
|
1513
|
-
elems: byIndex.map((f) => {
|
|
1514
|
-
const read = {
|
|
1515
|
-
kind: "recordGet",
|
|
1516
|
-
obj: receiver,
|
|
1517
|
-
shapeId: receiverIr.shapeId,
|
|
1518
|
-
field: f.name,
|
|
1519
|
-
type: f.type,
|
|
1520
|
-
loc,
|
|
1521
|
-
};
|
|
1522
|
-
return typeEquals(f.type, snapshotElem) ? read : lowerer.coerceInto(access.expression, read, snapshotElem);
|
|
1523
|
-
}),
|
|
1524
|
-
type: arrayOf(snapshotElem),
|
|
1525
|
-
loc,
|
|
1526
|
-
};
|
|
1527
|
-
if (name === "slice") {
|
|
1528
|
-
if (call.arguments.length > 2) {
|
|
1673
|
+
if (method === "slice") {
|
|
1674
|
+
if (call.arguments.length > 2 || call.arguments.some(ts.isSpreadElement)) {
|
|
1529
1675
|
lowerer.noLowering(`.slice with ${call.arguments.length} arguments`, call);
|
|
1530
1676
|
}
|
|
1531
|
-
const args = call.arguments.map(
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1677
|
+
const args = call.arguments.map(arg => lowerer.lowerExpr(arg));
|
|
1678
|
+
args.forEach((arg, i) => { if (arg.type.kind !== "f64")
|
|
1679
|
+
lowerer.badType(call.arguments[i], lowerer.typeOf(call.arguments[i])); });
|
|
1680
|
+
const resultType = arrayOf(elem);
|
|
1681
|
+
const key = `tuple.slice:${typeKey(receiver.type)}:${args.length}`;
|
|
1682
|
+
let helper = lowerer.arrHofHelpers.get(key);
|
|
1683
|
+
if (!helper) {
|
|
1684
|
+
helper = `%tuple.slice.${lowerer.arrHofHelpers.size}`;
|
|
1685
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
1686
|
+
const params = [receiver, ...args].map((arg, i) => ({ localId: i === 0 ? "a.0" : `arg.${i}`, name: `arg${i}`, type: arg.type }));
|
|
1687
|
+
lowerer.liftedFns.push({
|
|
1688
|
+
name: helper, params, returnType: resultType,
|
|
1689
|
+
locals: params.map(param => ({ id: param.localId, name: param.name, type: param.type, mutable: false })),
|
|
1690
|
+
body: [{ kind: "return", value: {
|
|
1691
|
+
kind: "arrIntrinsic", method: "slice",
|
|
1692
|
+
receiver: { kind: "arrayLit", elems: fields.map(read), type: resultType, loc },
|
|
1693
|
+
args: args.map((arg, i) => varRef(`arg.${i + 1}`, arg.type, loc)), type: resultType, loc,
|
|
1694
|
+
}, loc }], loc,
|
|
1695
|
+
});
|
|
1535
1696
|
}
|
|
1536
|
-
return { kind: "
|
|
1697
|
+
return { kind: "call", callee: helper, args: [receiver, ...args], type: resultType, loc };
|
|
1537
1698
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
lowerer.noLowering(`.map with ${call.arguments.length} arguments`, call, "the thisArg parameter has no lowering — use an arrow function");
|
|
1699
|
+
if (call.arguments.length !== 1 || call.arguments.some(ts.isSpreadElement)) {
|
|
1700
|
+
lowerer.noLowering(`.${method} with ${call.arguments.length} arguments`, call, "the thisArg parameter has no lowering — use an arrow function");
|
|
1541
1701
|
}
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1544
|
-
const
|
|
1545
|
-
if (
|
|
1702
|
+
const callback = call.arguments[0];
|
|
1703
|
+
// Check before the array HOF adapter can create a tuple-to-array copy.
|
|
1704
|
+
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(callback));
|
|
1705
|
+
if (signatures.some(signature => signature.getParameters().length > 2)) {
|
|
1706
|
+
lowerer.noLowering(`tuple .${method} callback array parameter`, callback, "capture the original tuple explicitly to preserve its identity");
|
|
1707
|
+
}
|
|
1708
|
+
const { fnArg, arity } = hofCallbackArg(lowerer, callback, [elem], receiver.type);
|
|
1709
|
+
const ret = fnArg.type.ret;
|
|
1710
|
+
if (ret.kind === "void" || ret.kind === "func")
|
|
1546
1711
|
lowerer.badType(call, lowerer.typeOf(call));
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1712
|
+
if (method === "flatMap" && (ret.kind === "dyn" || ret.kind === "jsval" || (ret.kind === "record" && lowerer.shapes.get(ret.shapeId)?.tuple))) {
|
|
1713
|
+
return { kind: "dynInvoke", recv: { kind: "dynFrom", value: receiver, type: DYN, loc }, method: "flatMap", calleeName: access.getText(), args: [{ kind: "dynFrom", value: fnArg, type: DYN, loc }], type: DYN, loc };
|
|
1714
|
+
}
|
|
1715
|
+
if (method === "flatMap" && ret.kind === "union" && lowerer.unions.get(ret.unionId).arms.some(arm => arm.kind === "array")) {
|
|
1716
|
+
lowerer.noLowering("tuple .flatMap callback mixing array and scalar results", callback, "return an array from every path");
|
|
1717
|
+
}
|
|
1718
|
+
const flatten = method === "flatMap" && ret.kind === "array";
|
|
1719
|
+
const outElem = flatten ? ret.elem : callbackArrayElem(lowerer, call, ret);
|
|
1720
|
+
fenceProducedArrayElem(lowerer, call, `'.${method}()'`, outElem);
|
|
1721
|
+
const outType = arrayOf(outElem);
|
|
1722
|
+
const key = `tuple.${method}:${typeKey(receiver.type)}:${typeKey(fnArg.type)}:${typeKey(outElem)}`;
|
|
1723
|
+
let helper = lowerer.arrHofHelpers.get(key);
|
|
1724
|
+
if (!helper) {
|
|
1725
|
+
helper = `%tuple.${method}.${lowerer.arrHofHelpers.size}`;
|
|
1726
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
1727
|
+
const out = varRef("out.0", outType, loc);
|
|
1728
|
+
const result = varRef("r.0", ret, loc);
|
|
1729
|
+
const outputLength = { kind: "arrIntrinsic", method: "length", receiver: out, args: [], type: F64, loc };
|
|
1730
|
+
const body = [{ kind: "varDecl", localId: "out.0", init: { kind: "arrayLit", elems: [], type: outType, loc }, loc }];
|
|
1731
|
+
for (const field of fields) {
|
|
1732
|
+
const invocation = {
|
|
1733
|
+
kind: "callValue", callee: varRef("f.0", fnArg.type, loc),
|
|
1734
|
+
args: [read(field), numLit(Number(field.name), loc)].slice(0, arity), type: ret, loc,
|
|
1735
|
+
};
|
|
1736
|
+
body.push(field === fields[0]
|
|
1737
|
+
? { kind: "varDecl", localId: "r.0", init: invocation, loc }
|
|
1738
|
+
: { kind: "assign", localId: "r.0", value: invocation, loc });
|
|
1739
|
+
if (flatten) {
|
|
1740
|
+
const index = varRef("i.0", F64, loc);
|
|
1741
|
+
body.push(countedFor(loc, { kind: "arrIntrinsic", method: "length", receiver: result, args: [], type: F64, loc }, () => [{
|
|
1742
|
+
kind: "if", cond: arrayIndexPresent(result, index, loc), then: [
|
|
1743
|
+
{ kind: "varDecl", localId: "inner.0", init: arrayValueRead(lowerer, result, index, outElem, loc), loc },
|
|
1744
|
+
arrayValueStore(lowerer, out, outputLength, varRef("inner.0", arrayValueType(lowerer, outElem), loc), outElem, loc),
|
|
1745
|
+
], else_: null, loc,
|
|
1746
|
+
}]));
|
|
1747
|
+
}
|
|
1748
|
+
else {
|
|
1749
|
+
body.push(arrayValueStore(lowerer, out, outputLength, result, outElem, loc));
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
body.push({ kind: "return", value: out, loc });
|
|
1753
|
+
lowerer.liftedFns.push({
|
|
1754
|
+
name: helper,
|
|
1755
|
+
params: [{ localId: "a.0", name: "a", type: receiver.type }, { localId: "f.0", name: "f", type: fnArg.type }],
|
|
1756
|
+
returnType: outType,
|
|
1757
|
+
locals: [
|
|
1758
|
+
{ id: "a.0", name: "a", type: receiver.type, mutable: false },
|
|
1759
|
+
{ id: "f.0", name: "f", type: fnArg.type, mutable: false },
|
|
1760
|
+
{ id: "out.0", name: "out", type: outType, mutable: false },
|
|
1761
|
+
{ id: "r.0", name: "r", type: ret, mutable: true },
|
|
1762
|
+
...(flatten ? [
|
|
1763
|
+
{ id: "i.0", name: "i", type: F64, mutable: true },
|
|
1764
|
+
{ id: "inner.0", name: "inner", type: arrayValueType(lowerer, outElem), mutable: false },
|
|
1765
|
+
] : []),
|
|
1766
|
+
], body, loc,
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
return { kind: "call", callee: helper, args: [receiver, fnArg], type: outType, loc };
|
|
1551
1770
|
}
|
|
1552
1771
|
/** An ordinary indexed read: values retain their element type, while
|
|
1553
1772
|
* holes, missing properties, and present undefined yield undefined. */
|
|
1554
1773
|
export function lowerSafeIndexRead(lowerer, arr, index, loc) {
|
|
1774
|
+
if (arr.type.kind !== "array")
|
|
1775
|
+
throw new InternalCompilerError("indexed read requires an array");
|
|
1555
1776
|
const elem = arr.type.elem;
|
|
1556
|
-
if (elem.kind === "void"
|
|
1777
|
+
if (elem.kind === "void")
|
|
1557
1778
|
return null;
|
|
1558
1779
|
const resultT = arrayValueType(lowerer, elem);
|
|
1559
1780
|
const key = `idxOr:${typeKey(elem)}`;
|
|
@@ -1780,8 +2001,7 @@ function buildArrayHofFn(lowerer, name, method, elem, fnRet, arity, loc, outElem
|
|
|
1780
2001
|
* undefined unit arm (for REF elements that arm is the unit instance, the
|
|
1781
2002
|
* standard union machinery). The Last pair is the SAME loop walked
|
|
1782
2003
|
* backwards (`i = n - 1; i >= 0; i--`), exactly the es2023 spec's
|
|
1783
|
-
* descending index walk.
|
|
1784
|
-
* (JS's ToBoolean of arbitrary predicate results has no lowering). */
|
|
2004
|
+
* descending index walk. Predicate results use JavaScript ToBoolean. */
|
|
1785
2005
|
function lowerArrayFindLikeCall(lowerer, call, access, method, elem, bindUntyped = false) {
|
|
1786
2006
|
const loc = locOf(call);
|
|
1787
2007
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
@@ -1796,7 +2016,7 @@ function lowerArrayFindLikeCall(lowerer, call, access, method, elem, bindUntyped
|
|
|
1796
2016
|
// `packages.some((p) => p.scripts[name])` idiom, whose callback
|
|
1797
2017
|
// returns the index read's `string | undefined`).
|
|
1798
2018
|
const fnRet = fnArg.type.ret;
|
|
1799
|
-
const truthyRet = fnRet.kind === "bool" || fnRet.kind === "f64" || fnRet.kind === "string" ||
|
|
2019
|
+
const truthyRet = fnRet.kind === "bool" || fnRet.kind === "f64" || fnRet.kind === "string" || fnRet.kind === "dyn" ||
|
|
1800
2020
|
(fnRet.kind === "union" &&
|
|
1801
2021
|
(lowerer.unions.get(fnRet.unionId)?.arms ?? []).every((a) => a.kind !== "dyn" && a.kind !== "caught" && a.kind !== "jsval"));
|
|
1802
2022
|
if (!truthyRet)
|
|
@@ -1814,26 +2034,48 @@ function lowerArrayFindLikeCall(lowerer, call, access, method, elem, bindUntyped
|
|
|
1814
2034
|
loc,
|
|
1815
2035
|
};
|
|
1816
2036
|
}
|
|
1817
|
-
// find
|
|
1818
|
-
//
|
|
1819
|
-
//
|
|
1820
|
-
//
|
|
1821
|
-
//
|
|
1822
|
-
const
|
|
2037
|
+
// find visits holes as undefined and can infer a predicate that selects
|
|
2038
|
+
// a subset of the element union. A result matching the receiver's flow
|
|
2039
|
+
// element inherits that earlier refinement. Otherwise only an inline,
|
|
2040
|
+
// inferred predicate proves a new narrowing; explicit assertions keep
|
|
2041
|
+
// the same refusal boundary as filter.
|
|
2042
|
+
const valueT = arrayValueType(lowerer, elem);
|
|
2043
|
+
const checkerReceiver = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
2044
|
+
const checkerResult = lowerer.irTypeOf(call);
|
|
2045
|
+
const unchangedElement = checkerReceiver?.kind === "array" &&
|
|
2046
|
+
typeEquals(checkerResult, arrayValueType(lowerer, checkerReceiver.elem));
|
|
2047
|
+
const resultT = bindUntyped ? valueT : checkerResult;
|
|
1823
2048
|
if (resultT.kind !== "union")
|
|
1824
2049
|
lowerer.badType(call, lowerer.typeOf(call)); // defensive: T | undefined always maps to a union
|
|
1825
2050
|
const undefTag = lowerer.armTag(resultT.unionId, UNDEFINED_T);
|
|
1826
2051
|
if (undefTag < 0)
|
|
1827
2052
|
lowerer.badType(call, lowerer.typeOf(call));
|
|
1828
|
-
|
|
2053
|
+
let retag = null;
|
|
2054
|
+
if (!lowerer.coercibleValue(valueT, resultT)) {
|
|
2055
|
+
const inline = ts.isArrowFunction(argNode) || ts.isFunctionExpression(argNode);
|
|
2056
|
+
if (!unchangedElement && (!inline || argNode.type !== undefined)) {
|
|
2057
|
+
lowerer.unsupported("SC1090", argNode, `narrowing '.${method}' requires an inline callback with an inferred predicate (annotate the return ': boolean' to keep the receiver's element type)`);
|
|
2058
|
+
}
|
|
2059
|
+
const signature = inline ? lowerer.checker.getSignatureFromDeclaration(argNode) : undefined;
|
|
2060
|
+
const predicate = signature ? lowerer.checker.getTypePredicateOfSignature(signature) : undefined;
|
|
2061
|
+
if ((!unchangedElement && (!predicate || predicate.parameterIndex !== 0)) || valueT.kind !== "union") {
|
|
2062
|
+
lowerer.unsupported("SC1090", call, `'.${method}' result narrowing without a predicate over its element`);
|
|
2063
|
+
}
|
|
2064
|
+
retag = lowerer.narrowedRetagHelper(call, valueT.unionId, resultT.unionId, loc);
|
|
2065
|
+
if (retag === null)
|
|
2066
|
+
lowerer.unsupported("SC1090", call, `'.${method}' narrowing to an incompatible result layout`);
|
|
2067
|
+
}
|
|
2068
|
+
const helper = findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc, retag);
|
|
1829
2069
|
return { kind: "call", callee: helper, args: [receiver, fnArg], type: resultT, loc };
|
|
1830
2070
|
}
|
|
1831
2071
|
/** ToBoolean of a predicate result inside a synthesized HOF helper — the
|
|
1832
|
-
* ensureBool subset the find-like path admits (bool through;
|
|
1833
|
-
* truthy-answerable unions via toBool). */
|
|
2072
|
+
* ensureBool subset the find-like path admits (bool through; checked
|
|
2073
|
+
* values via dynTest; f64/string/truthy-answerable unions via toBool). */
|
|
1834
2074
|
function predToBool(e) {
|
|
1835
2075
|
if (e.type.kind === "bool")
|
|
1836
2076
|
return e;
|
|
2077
|
+
if (e.type.kind === "dyn")
|
|
2078
|
+
return { kind: "dynTest", test: "truthy", value: e, type: BOOL, loc: e.loc };
|
|
1837
2079
|
return { kind: "toBool", operand: e, type: BOOL, loc: e.loc };
|
|
1838
2080
|
}
|
|
1839
2081
|
/** The find loop, from existing IR nodes:
|
|
@@ -1842,7 +2084,7 @@ function predToBool(e) {
|
|
|
1842
2084
|
* for (i = 0; i < n; i++) { v = a[i]; if (f(v)) return <v as result arm>; }
|
|
1843
2085
|
* return <undefined arm>;
|
|
1844
2086
|
*/
|
|
1845
|
-
function findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc) {
|
|
2087
|
+
function findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc, retag) {
|
|
1846
2088
|
const method = last ? "findLast" : "find";
|
|
1847
2089
|
const key = `${method}:${typeKey(elem)}:${typeKey(resultT)}:${typeKey(fnRet)}:${arity}`;
|
|
1848
2090
|
const existing = lowerer.arrHofHelpers.get(key);
|
|
@@ -1854,7 +2096,8 @@ function findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc) {
|
|
|
1854
2096
|
const fnT = funcOf([arrayValueType(lowerer, elem), F64, arrT].slice(0, arity), fnRet);
|
|
1855
2097
|
const valueT = arrayValueType(lowerer, elem);
|
|
1856
2098
|
const v = varRef("v.0", valueT, loc);
|
|
1857
|
-
const found = lowerer.coerceToExpected(v, resultT)
|
|
2099
|
+
const found = retag === null ? lowerer.coerceToExpected(v, resultT) :
|
|
2100
|
+
{ kind: "call", callee: retag, args: [v], type: resultT, loc };
|
|
1858
2101
|
const miss = {
|
|
1859
2102
|
kind: "unionWrap",
|
|
1860
2103
|
unionId: resultT.unionId,
|
|
@@ -2034,6 +2277,9 @@ function lowerArrayFlatMapCall(lowerer, call, access, elem) {
|
|
|
2034
2277
|
lowerer.unsupported("SC1090", call, "this call form"); // tsc-guarded
|
|
2035
2278
|
const { fnArg, arity } = hofCallbackArg(lowerer, argNode, [arrayValueType(lowerer, elem)], arrT);
|
|
2036
2279
|
const fnRet = fnArg.type.ret;
|
|
2280
|
+
if (fnRet.kind === "dyn" || fnRet.kind === "jsval" || (fnRet.kind === "record" && lowerer.shapes.get(fnRet.shapeId)?.tuple)) {
|
|
2281
|
+
return { kind: "dynInvoke", recv: { kind: "dynFrom", value: receiver, liveRef: true, type: DYN, loc }, method: "flatMap", calleeName: access.getText(), args: [{ kind: "dynFrom", value: fnArg, type: DYN, loc }], type: DYN, loc };
|
|
2282
|
+
}
|
|
2037
2283
|
if (fnRet.kind === "union") {
|
|
2038
2284
|
const def = lowerer.unions.get(fnRet.unionId);
|
|
2039
2285
|
if (def?.arms.some((a) => a.kind === "array")) {
|
|
@@ -2170,7 +2416,7 @@ function lowerArrayReduceCall(lowerer, call, access, method, elem) {
|
|
|
2170
2416
|
(hasInit ? lowerer.irTypeOf(call) : arrayValueType(lowerer, elem));
|
|
2171
2417
|
if (accT.kind === "void" || accT.kind === "func")
|
|
2172
2418
|
lowerer.badType(call, lowerer.typeOf(call));
|
|
2173
|
-
const { fnArg, arity } = hofCallbackArg(lowerer, argNode, [accT, arrayValueType(lowerer, elem)], arrT);
|
|
2419
|
+
const { fnArg, arity } = hofCallbackArg(lowerer, argNode, [accT, arrayValueType(lowerer, elem)], arrT, false, accT);
|
|
2174
2420
|
const helper = reduceHelper(lowerer, method, elem, accT, fnArg.type.ret, arity, hasInit, loc);
|
|
2175
2421
|
const args = [receiver, fnArg];
|
|
2176
2422
|
if (hasInit)
|
|
@@ -2311,7 +2557,18 @@ function lowerArraySortCall(lowerer, call, access, elem, arrT) {
|
|
|
2311
2557
|
}
|
|
2312
2558
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
2313
2559
|
const argNode = call.arguments[0];
|
|
2314
|
-
|
|
2560
|
+
let fnArg = lowerer.lowerExpr(argNode);
|
|
2561
|
+
// Reusable JS comparators often accept checked values. Adapt the array's
|
|
2562
|
+
// element ABI just as other array callbacks do before sorting.
|
|
2563
|
+
if (fnArg.type.kind === "func" && fnArg.type.params.length <= 2 &&
|
|
2564
|
+
fnArg.type.params.every((param) => lowerer.coercibleValue(elem, param))) {
|
|
2565
|
+
// Arithmetic on inferred JS values retains a checked result because
|
|
2566
|
+
// it can produce BigInt. The sort callback still requires a number.
|
|
2567
|
+
const result = fnArg.type.ret.kind === "dyn" && isJsSourceFile(argNode.getSourceFile()) ? F64 : fnArg.type.ret;
|
|
2568
|
+
const expected = funcOf(fnArg.type.params.map(() => elem), result);
|
|
2569
|
+
if (!typeEquals(fnArg.type, expected))
|
|
2570
|
+
fnArg = lowerer.coerceToExpected(fnArg, expected);
|
|
2571
|
+
}
|
|
2315
2572
|
// The comparator receives exactly (a, b); declaring a prefix is
|
|
2316
2573
|
// ordinary TS. Its result must be number (the spec coerces arbitrary
|
|
2317
2574
|
// results — no lowering for that).
|
|
@@ -2556,10 +2813,25 @@ export function lowerArrayConstructor(lowerer, expr, args) {
|
|
|
2556
2813
|
if (contextual)
|
|
2557
2814
|
result = lowerer.mapTypeOf(contextual);
|
|
2558
2815
|
}
|
|
2816
|
+
if (isJsSourceFile(expr.getSourceFile()) && (result === null || result.kind === "dyn"))
|
|
2817
|
+
result = arrayOf(DYN);
|
|
2559
2818
|
if (result?.kind !== "array" || !isSupportedArrayElem(result.elem)) {
|
|
2560
2819
|
lowerer.badType(expr, lowerer.typeOf(expr));
|
|
2561
2820
|
}
|
|
2562
2821
|
const argType = args.length === 1 ? lowerer.mapTypeOf(lowerer.typeOf(args[0])) : null;
|
|
2822
|
+
if (args.length === 1 && result.elem.kind === "dyn" && (argType === null || argType.kind === "dyn")) {
|
|
2823
|
+
const input = lowerer.declareHiddenLocal("%arrayCtorValue", DYN);
|
|
2824
|
+
const value = varRef(input.id, DYN, loc);
|
|
2825
|
+
const local = lowerer.declareHiddenLocal("%arrayCtor", result);
|
|
2826
|
+
const array = varRef(local.id, result, loc);
|
|
2827
|
+
return { kind: "seqExpr", stmts: [
|
|
2828
|
+
{ kind: "varDecl", localId: input.id, init: lowerer.lowerExprExpecting(args[0], DYN), loc },
|
|
2829
|
+
{ kind: "varDecl", localId: local.id, init: { kind: "arrayLit", elems: [], type: result, loc }, loc },
|
|
2830
|
+
{ kind: "if", cond: { kind: "dynTest", test: "number", value, type: BOOL, loc },
|
|
2831
|
+
then: [{ kind: "arraySetLength", arr: array, length: { kind: "dynCheck", value, type: F64, loc }, loc }],
|
|
2832
|
+
else_: [arrayValueStore(lowerer, array, numLit(0, loc), value, DYN, loc)], loc },
|
|
2833
|
+
], result: array, type: result, loc };
|
|
2834
|
+
}
|
|
2563
2835
|
if (argType?.kind === "dyn" || argType?.kind === "jsval") {
|
|
2564
2836
|
lowerer.noLowering("Array constructor with a dynamically typed sole argument", args[0]);
|
|
2565
2837
|
}
|
|
@@ -2622,6 +2894,84 @@ export function lowerArrayOfCall(lowerer, call, access) {
|
|
|
2622
2894
|
loc: locOf(call),
|
|
2623
2895
|
};
|
|
2624
2896
|
}
|
|
2897
|
+
/** Mapper-less checked Array.from: acquire once, then step through emitted
|
|
2898
|
+
* property and call dispatch so native class iterators retain their methods. */
|
|
2899
|
+
export function lowerCheckedArrayFrom(lowerer, source, loc, mapper, receiver, numeric = false) {
|
|
2900
|
+
const iterator = lowerer.declareHiddenLocal("%fromIterator", DYN);
|
|
2901
|
+
const next = lowerer.declareHiddenLocal("%fromNext", DYN);
|
|
2902
|
+
const step = lowerer.declareHiddenLocal("%fromStep", DYN);
|
|
2903
|
+
const out = lowerer.declareHiddenLocal("%fromArray", DYN);
|
|
2904
|
+
const done = lowerer.declareHiddenLocal("%fromDone", BOOL);
|
|
2905
|
+
done.mutable = true;
|
|
2906
|
+
const index = mapper ? lowerer.declareHiddenLocal("%fromIndex", F64) : null;
|
|
2907
|
+
if (index)
|
|
2908
|
+
index.mutable = true;
|
|
2909
|
+
const get = (value, key) => ({ kind: "dynKeyGet", value, key: strLit(key, loc), type: DYN, loc });
|
|
2910
|
+
const item = get(varRef(step.id, DYN, loc), "value");
|
|
2911
|
+
const mapped = mapper && index ? { kind: "ternary", cond: { kind: "dynTest", test: "undefined", value: mapper, type: BOOL, loc },
|
|
2912
|
+
then: item, else_: { kind: "dynCall", callee: mapper, ...(receiver ? { receiver } : {}), calleeName: "Array.from mapper", args: [item, lowerer.coerceToExpected(varRef(index.id, F64, loc), DYN)], type: DYN, loc }, type: DYN, loc } : item;
|
|
2913
|
+
const element = numeric ? lowerer.coerceToExpected({ kind: "libCall", fn: "dyn.toNumberCoerce", args: [mapped], type: F64, loc }, DYN) : mapped;
|
|
2914
|
+
let append = { kind: "exprStmt", expr: { kind: "dynInvoke", recv: varRef(out.id, DYN, loc), method: "push", calleeName: "Array.from", args: [element], type: DYN, loc }, loc };
|
|
2915
|
+
if (mapper) {
|
|
2916
|
+
const error = lowerer.declareHiddenLocal("%fromError", CAUGHT);
|
|
2917
|
+
const close = lowerer.declareHiddenLocal("%fromReturn", DYN);
|
|
2918
|
+
append = { kind: "tryCatch", tryBody: [append], catchLocalId: error.id, finallyBody: null, loc, catchBody: [
|
|
2919
|
+
{ kind: "tryCatch", catchLocalId: null, catchBody: [], finallyBody: null, loc, tryBody: [
|
|
2920
|
+
{ kind: "varDecl", localId: close.id, init: get(varRef(iterator.id, DYN, loc), "return"), loc },
|
|
2921
|
+
{ kind: "if", cond: { kind: "dynTest", test: "function", value: varRef(close.id, DYN, loc), type: BOOL, loc }, then: [
|
|
2922
|
+
{ kind: "exprStmt", expr: { kind: "dynCall", callee: varRef(close.id, DYN, loc), receiver: varRef(iterator.id, DYN, loc), calleeName: "iterator.return", args: [], type: DYN, loc }, loc },
|
|
2923
|
+
], else_: null, loc },
|
|
2924
|
+
] },
|
|
2925
|
+
{ kind: "rethrow", localId: error.id, loc },
|
|
2926
|
+
] };
|
|
2927
|
+
}
|
|
2928
|
+
const stmts = [
|
|
2929
|
+
...(mapper ? [{ kind: "if", cond: { kind: "dynTest", test: "undefined", value: mapper, type: BOOL, loc }, then: [], else_: [
|
|
2930
|
+
{ kind: "if", cond: { kind: "dynTest", test: "function", value: mapper, type: BOOL, loc }, then: [], else_: [
|
|
2931
|
+
{ kind: "exprStmt", expr: nodeThrowExpr(1, "", "Array.from mapper is not a function", DYN, loc), loc },
|
|
2932
|
+
], loc },
|
|
2933
|
+
], loc }] : []),
|
|
2934
|
+
{ kind: "varDecl", localId: iterator.id, init: { kind: "libCall", fn: "dyn.iteratorResult", args: [{ kind: "libCall", fn: "dyn.arrayFromIterator", args: [source], type: DYN, loc }], type: DYN, loc }, loc },
|
|
2935
|
+
{ kind: "varDecl", localId: next.id, init: get(varRef(iterator.id, DYN, loc), "next"), loc },
|
|
2936
|
+
{ kind: "varDecl", localId: out.id, init: { kind: "dynArrLit", elems: [], type: DYN, loc }, loc },
|
|
2937
|
+
{ kind: "varDecl", localId: done.id, init: boolLit(false, loc), loc },
|
|
2938
|
+
...(index ? [{ kind: "varDecl", localId: index.id, init: numLit(0, loc), loc }] : []),
|
|
2939
|
+
{ kind: "while", cond: { kind: "unary", op: "!", operand: varRef(done.id, BOOL, loc), type: BOOL, loc }, body: [
|
|
2940
|
+
{ kind: "varDecl", localId: step.id, init: { kind: "libCall", fn: "dyn.iteratorResult", args: [{
|
|
2941
|
+
kind: "dynCall", callee: varRef(next.id, DYN, loc), receiver: varRef(iterator.id, DYN, loc), calleeName: "iterator.next", args: [], type: DYN, loc,
|
|
2942
|
+
}], type: DYN, loc }, loc },
|
|
2943
|
+
{ kind: "assign", localId: done.id, value: { kind: "dynTest", test: "truthy", value: get(varRef(step.id, DYN, loc), "done"), type: BOOL, loc }, loc },
|
|
2944
|
+
{ kind: "if", cond: { kind: "unary", op: "!", operand: varRef(done.id, BOOL, loc), type: BOOL, loc }, then: [
|
|
2945
|
+
append,
|
|
2946
|
+
...(index ? [{ kind: "assign", localId: index.id, value: { kind: "bin", op: "+", left: varRef(index.id, F64, loc), right: numLit(1, loc), type: F64, loc }, loc }] : []),
|
|
2947
|
+
], else_: null, loc },
|
|
2948
|
+
], loc },
|
|
2949
|
+
];
|
|
2950
|
+
return { kind: "seqExpr", stmts, result: varRef(out.id, DYN, loc), type: DYN, loc };
|
|
2951
|
+
}
|
|
2952
|
+
export function lowerArrayFromValue(lowerer, loc) {
|
|
2953
|
+
const name = "%builtin.Array.from";
|
|
2954
|
+
if (!lowerer.liftedFns.some((fn) => fn.name === name)) {
|
|
2955
|
+
const context = newFnCtx(false, null, null, DYN);
|
|
2956
|
+
lowerer.fnStack.push(context);
|
|
2957
|
+
try {
|
|
2958
|
+
const params = ["source", "options"].map((name) => {
|
|
2959
|
+
const local = lowerer.declareHiddenLocal(name, DYN);
|
|
2960
|
+
return { localId: local.id, name, type: DYN };
|
|
2961
|
+
});
|
|
2962
|
+
const [source, options] = params.map((p) => varRef(p.localId, DYN, loc));
|
|
2963
|
+
const argument = (index) => ({ kind: "dynKeyGet", value: options, key: strLit(index, loc), type: DYN, loc });
|
|
2964
|
+
const value = lowerCheckedArrayFrom(lowerer, source, loc, argument("0"), argument("1"));
|
|
2965
|
+
const constructorCheck = { kind: "if", cond: { kind: "dynTest", test: "function", value: { kind: "libCall", fn: "dyn.this", args: [], type: DYN, loc }, type: BOOL, loc },
|
|
2966
|
+
then: [{ kind: "runtimeFence", code: "SC2020", message: "Array.from with a custom constructor receiver is not supported", loc }], else_: null, loc };
|
|
2967
|
+
lowerer.liftedFns.push({ name, params, returnType: DYN, locals: context.locals, body: [constructorCheck, ...value.stmts, { kind: "return", value: value.result, loc }], loc });
|
|
2968
|
+
}
|
|
2969
|
+
finally {
|
|
2970
|
+
lowerer.fnStack.pop();
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
return { kind: "dynFrom", value: { kind: "closure", fnName: name, captures: [], type: { kind: "func", params: [DYN], ret: DYN, rest: true }, loc }, fnName: "from", type: DYN, loc };
|
|
2974
|
+
}
|
|
2625
2975
|
/** `Array.from({ length: n }, mapfn)` — the counted-generation idiom — on
|
|
2626
2976
|
* THE stdlib Array global. The source must be an OBJECT LITERAL whose
|
|
2627
2977
|
* single property is `length` (the shape the idiom always spells; the
|
|
@@ -2645,6 +2995,28 @@ export function lowerArrayFromCall(lowerer, call, access) {
|
|
|
2645
2995
|
return null;
|
|
2646
2996
|
const loc = locOf(call);
|
|
2647
2997
|
const args = call.arguments;
|
|
2998
|
+
if (isJsSourceFile(call.getSourceFile()) && args.length >= 1 && args.length <= 3 && !args.some(ts.isSpreadElement)) {
|
|
2999
|
+
const name = "%builtin.Array.fromDirect";
|
|
3000
|
+
if (!lowerer.liftedFns.some((fn) => fn.name === name)) {
|
|
3001
|
+
const context = newFnCtx(false, null, null, DYN);
|
|
3002
|
+
lowerer.fnStack.push(context);
|
|
3003
|
+
try {
|
|
3004
|
+
const params = ["source", "mapper", "receiver"].map((name) => {
|
|
3005
|
+
const local = lowerer.declareHiddenLocal(name, DYN);
|
|
3006
|
+
return { localId: local.id, name, type: DYN };
|
|
3007
|
+
});
|
|
3008
|
+
const refs = params.map((param) => varRef(param.localId, DYN, loc));
|
|
3009
|
+
const value = lowerCheckedArrayFrom(lowerer, refs[0], loc, refs[1], refs[2]);
|
|
3010
|
+
lowerer.liftedFns.push({ name, params, returnType: DYN, locals: context.locals,
|
|
3011
|
+
body: [...value.stmts, { kind: "return", value: value.result, loc }], loc });
|
|
3012
|
+
}
|
|
3013
|
+
finally {
|
|
3014
|
+
lowerer.fnStack.pop();
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
return { kind: "call", callee: name, args: [0, 1, 2].map((i) => args[i]
|
|
3018
|
+
? lowerer.lowerExprExpecting(args[i], DYN) : dynUndefinedExpr(loc)), type: DYN, loc };
|
|
3019
|
+
}
|
|
2648
3020
|
// MAPPER-LESS `Array.from({ length: n })` (usually with an explicit
|
|
2649
3021
|
// type argument — the pMap results-array idiom): a length-n array of
|
|
2650
3022
|
// ABSENT slots, filled by index before any read. Union elements with
|
|
@@ -2719,6 +3091,9 @@ export function lowerArrayFromCall(lowerer, call, access) {
|
|
|
2719
3091
|
}
|
|
2720
3092
|
return { kind: "call", callee: helper, args: [src, fnArg], type: arrayOf(outElem), loc };
|
|
2721
3093
|
}
|
|
3094
|
+
if (src.type.kind === "bytes" && args.length === 1) {
|
|
3095
|
+
return { kind: "bytesIntrinsic", method: "toArray", receiver: src, args: [], type: arrayOf(F64), loc };
|
|
3096
|
+
}
|
|
2722
3097
|
if (src.type.kind === "set" && args.length === 1) {
|
|
2723
3098
|
return { kind: "setIntrinsic", method: "toArray", receiver: src, args: [], type: arrayOf(src.type.elem), loc };
|
|
2724
3099
|
}
|
|
@@ -2726,6 +3101,9 @@ export function lowerArrayFromCall(lowerer, call, access) {
|
|
|
2726
3101
|
// `[...s]` and both Array.from(s) forms.
|
|
2727
3102
|
if (src.type.kind === "string" && args.length === 1)
|
|
2728
3103
|
return strCharsCall(lowerer, src, loc);
|
|
3104
|
+
if (src.type.kind === "dyn" && args.length === 1) {
|
|
3105
|
+
return lowerCheckedArrayFrom(lowerer, src, loc);
|
|
3106
|
+
}
|
|
2729
3107
|
lowerer.noLowering("Array.from with this argument shape", call, "Array.from(array), Array.from(array, mapper), Array.from(aString), Array.from(aString, mapper), and Array.from({ length: n }, mapper) are the lowered forms");
|
|
2730
3108
|
}
|
|
2731
3109
|
const n = args.length === 2 && ts.isObjectLiteralExpression(args[0]) && args[0].properties.length === 1
|
|
@@ -2949,13 +3327,12 @@ export function lowerMapMethodCall(lowerer, call, access) {
|
|
|
2949
3327
|
}
|
|
2950
3328
|
if (receiverIr?.kind !== "map")
|
|
2951
3329
|
return null;
|
|
2952
|
-
|
|
3330
|
+
// Collection views can refine has() while retaining its native ABI.
|
|
3331
|
+
if (!probedUntyped && !lowerer.isStdlibMember(access) && name !== "has")
|
|
2953
3332
|
return null;
|
|
2954
3333
|
const loc = locOf(call);
|
|
2955
|
-
const
|
|
2956
|
-
|
|
2957
|
-
// set is a void statement, so a chained receiver has no value — fence
|
|
2958
|
-
// it instead of emitting a void receiver.
|
|
3334
|
+
const value = lowerer.lowerExpr(access.expression);
|
|
3335
|
+
const receiver = lowerer.runtimeOptionalPropertyReceiver(access.expression, value, receiverIr, name) ?? value;
|
|
2959
3336
|
if (receiver.type.kind !== "map") {
|
|
2960
3337
|
lowerer.noLowering("chained Map method calls", access.expression, "the lowered set() produces no value — call each set(k, v) as its own statement");
|
|
2961
3338
|
}
|
|
@@ -2964,23 +3341,30 @@ export function lowerMapMethodCall(lowerer, call, access) {
|
|
|
2964
3341
|
lowerer.noLowering(`.forEach with ${call.arguments.length} arguments`, call, "the thisArg parameter has no lowering — use an arrow function");
|
|
2965
3342
|
}
|
|
2966
3343
|
if (name === "get") {
|
|
2967
|
-
const k = lowerer.
|
|
3344
|
+
const k = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.key);
|
|
2968
3345
|
// The checker types the call `V | undefined`, which interns the
|
|
2969
3346
|
// result union. `undefined` sorts LAST among all possible arm
|
|
2970
3347
|
// typeKeys, so when V is itself a union its arms keep their tags in
|
|
2971
3348
|
// the result union — the backend leans on that (docs/ir.md).
|
|
2972
|
-
const type = lowerer.irTypeOf(call);
|
|
2973
|
-
if (type.kind !== "union")
|
|
3349
|
+
const type = receiverIr.value.kind === "dyn" ? DYN : lowerer.irTypeOf(call);
|
|
3350
|
+
if (type.kind !== "union" && type.kind !== "dyn")
|
|
2974
3351
|
lowerer.badType(call, lowerer.typeOf(call));
|
|
2975
3352
|
return { kind: "mapIntrinsic", method: "get", receiver, args: [k], type, loc };
|
|
2976
3353
|
}
|
|
2977
3354
|
if (name === "set") {
|
|
2978
|
-
const k = lowerer.
|
|
2979
|
-
const v =
|
|
2980
|
-
|
|
3355
|
+
const k = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.key);
|
|
3356
|
+
const v = receiverIr.value.kind === "dyn"
|
|
3357
|
+
? lowerer.lowerCollectionKey(call.arguments[1], receiverIr.value)
|
|
3358
|
+
: lowerer.lowerExprExpecting(call.arguments[1], receiverIr.value);
|
|
3359
|
+
const slot = lowerer.declareHiddenLocal("%mapSetReceiver", receiver.type);
|
|
3360
|
+
const ref = varRef(slot.id, receiver.type, loc);
|
|
3361
|
+
return { kind: "seqExpr", stmts: [
|
|
3362
|
+
{ kind: "varDecl", localId: slot.id, init: receiver, loc },
|
|
3363
|
+
{ kind: "exprStmt", expr: { kind: "mapIntrinsic", method: "set", receiver: ref, args: [k, v], type: VOID, loc }, loc },
|
|
3364
|
+
], result: ref, type: receiver.type, loc };
|
|
2981
3365
|
}
|
|
2982
3366
|
if (name === "has" || name === "delete") {
|
|
2983
|
-
const k = lowerer.
|
|
3367
|
+
const k = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.key);
|
|
2984
3368
|
return { kind: "mapIntrinsic", method: name, receiver, args: [k], type: BOOL, loc };
|
|
2985
3369
|
}
|
|
2986
3370
|
if (name === "clear") {
|
|
@@ -3100,6 +3484,65 @@ function buildMapIterDrainFn(name, mapT, method, elemT, tupleT, loc) {
|
|
|
3100
3484
|
loc,
|
|
3101
3485
|
};
|
|
3102
3486
|
}
|
|
3487
|
+
/** An immediate Map spread observes the same entry order as entries().
|
|
3488
|
+
* Each pair is new; its key and value retain their original identities. */
|
|
3489
|
+
export function mapEntriesArray(lowerer, receiver) {
|
|
3490
|
+
const mapT = receiver.type;
|
|
3491
|
+
if (mapT.kind !== "map")
|
|
3492
|
+
throw new InternalCompilerError("Map entries require a map");
|
|
3493
|
+
const tupleT = {
|
|
3494
|
+
kind: "record", shapeId: lowerer.shapes.intern([
|
|
3495
|
+
{ name: "0", type: mapT.key }, { name: "1", type: mapT.value },
|
|
3496
|
+
], true),
|
|
3497
|
+
};
|
|
3498
|
+
const key = `entries:${typeKey(mapT.key)}:${typeKey(mapT.value)}`;
|
|
3499
|
+
let helper = lowerer.mapHofHelpers.get(key);
|
|
3500
|
+
if (!helper) {
|
|
3501
|
+
helper = `%map.entries.${lowerer.mapHofHelpers.size}`;
|
|
3502
|
+
lowerer.mapHofHelpers.set(key, helper);
|
|
3503
|
+
lowerer.liftedFns.push(buildMapIterDrainFn(helper, mapT, "entries", tupleT, tupleT, receiver.loc));
|
|
3504
|
+
}
|
|
3505
|
+
return { kind: "call", callee: helper, args: [receiver], type: arrayOf(tupleT), loc: receiver.loc };
|
|
3506
|
+
}
|
|
3507
|
+
/** Snapshot a collection for immediate iteration. Array reads and callback
|
|
3508
|
+
* parameters may retain an undefined arm even when the checker spells a
|
|
3509
|
+
* bare collection. Observe that arm before touching native storage. */
|
|
3510
|
+
export function lowerCollectionSpread(lowerer, source, node) {
|
|
3511
|
+
if (source.type.kind === "map")
|
|
3512
|
+
return mapEntriesArray(lowerer, source);
|
|
3513
|
+
if (source.type.kind === "set")
|
|
3514
|
+
return {
|
|
3515
|
+
kind: "setIntrinsic", method: "toArray", receiver: source, args: [], type: arrayOf(source.type.elem), loc: source.loc,
|
|
3516
|
+
};
|
|
3517
|
+
if (source.type.kind !== "union")
|
|
3518
|
+
return null;
|
|
3519
|
+
const arms = lowerer.unions.get(source.type.unionId)?.arms;
|
|
3520
|
+
const tag = arms?.findIndex((arm) => arm.kind === "map" || arm.kind === "set") ?? -1;
|
|
3521
|
+
const collection = arms?.[tag];
|
|
3522
|
+
if ((collection?.kind !== "map" && collection?.kind !== "set") ||
|
|
3523
|
+
!arms?.every((arm, index) => index === tag || isUnitType(arm)))
|
|
3524
|
+
return null;
|
|
3525
|
+
const loc = locOf(node);
|
|
3526
|
+
const slot = lowerer.declareHiddenLocal("%collectionSpread", source.type);
|
|
3527
|
+
const value = varRef(slot.id, source.type, loc);
|
|
3528
|
+
const narrowed = {
|
|
3529
|
+
kind: "unionNarrow", unionId: source.type.unionId, tag, value, type: collection, loc,
|
|
3530
|
+
};
|
|
3531
|
+
const entries = collection.kind === "map"
|
|
3532
|
+
? mapEntriesArray(lowerer, narrowed)
|
|
3533
|
+
: { kind: "setIntrinsic", method: "toArray", receiver: narrowed, args: [], type: arrayOf(collection.elem), loc };
|
|
3534
|
+
return {
|
|
3535
|
+
kind: "seqExpr", stmts: [{ kind: "varDecl", localId: slot.id, init: source, loc }],
|
|
3536
|
+
result: {
|
|
3537
|
+
kind: "ternary",
|
|
3538
|
+
cond: { kind: "unionIsTag", unionId: source.type.unionId, tag, value, negated: false, type: BOOL, loc },
|
|
3539
|
+
then: entries,
|
|
3540
|
+
else_: nodeThrowExpr(1, "", `${node.getText()} is not iterable`, entries.type, loc),
|
|
3541
|
+
type: entries.type, loc,
|
|
3542
|
+
},
|
|
3543
|
+
type: entries.type, loc,
|
|
3544
|
+
};
|
|
3545
|
+
}
|
|
3103
3546
|
/** `m.forEach(fn)` desugars to a direct call of a synthetic module
|
|
3104
3547
|
* function — one per key/value type + callback arity, interned — whose
|
|
3105
3548
|
* body is an index loop over the map's ITERATION PRIMITIVES: read
|
|
@@ -3274,21 +3717,28 @@ export function lowerSetMethodCall(lowerer, call, access) {
|
|
|
3274
3717
|
if (!SET_METHODS.has(name) && !SET_COMBINE_METHODS.has(name))
|
|
3275
3718
|
return null;
|
|
3276
3719
|
let receiverIr = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
3720
|
+
let probedUntyped = false;
|
|
3277
3721
|
// The identity-Set idiom (JS): the CHECKER type is an unmappable
|
|
3278
3722
|
// Set<union-of-signatures>, but the VALUE lowered as a real Set of
|
|
3279
3723
|
// identity tokens (the new-Set probe) — the lowered receiver's type
|
|
3280
3724
|
// is the honest dispatch key.
|
|
3281
3725
|
if (receiverIr?.kind !== "set" && isJsSourceFile(access.getSourceFile())) {
|
|
3282
3726
|
const probed = tryLowerExpression(lowerer, access.expression);
|
|
3283
|
-
if (probed?.type.kind === "set")
|
|
3727
|
+
if (probed?.type.kind === "set") {
|
|
3284
3728
|
receiverIr = probed.type;
|
|
3729
|
+
probedUntyped = true;
|
|
3730
|
+
}
|
|
3285
3731
|
}
|
|
3286
3732
|
if (receiverIr?.kind !== "set")
|
|
3287
3733
|
return null;
|
|
3288
|
-
|
|
3734
|
+
// A collection interface may refine has() into a type predicate.
|
|
3735
|
+
// Type mapping checked that view's native ABI; the value check below
|
|
3736
|
+
// still rejects structural mocks and assertions over other objects.
|
|
3737
|
+
if (!probedUntyped && !lowerer.isStdlibMember(access) && name !== "has")
|
|
3289
3738
|
return null;
|
|
3290
3739
|
const loc = locOf(call);
|
|
3291
|
-
const
|
|
3740
|
+
const value = lowerer.lowerExpr(access.expression);
|
|
3741
|
+
const receiver = lowerer.runtimeOptionalPropertyReceiver(access.expression, value, receiverIr, name) ?? value;
|
|
3292
3742
|
// The lib's `add` returns the Set (chaining typechecks); the lowered
|
|
3293
3743
|
// add is a void statement — fence chained receivers like Map's set.
|
|
3294
3744
|
if (receiver.type.kind !== "set") {
|
|
@@ -3301,11 +3751,11 @@ export function lowerSetMethodCall(lowerer, call, access) {
|
|
|
3301
3751
|
return lowerSetCombineCall(lowerer, call, name, receiver, receiverIr);
|
|
3302
3752
|
}
|
|
3303
3753
|
if (name === "add") {
|
|
3304
|
-
const v = lowerer.
|
|
3754
|
+
const v = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.elem);
|
|
3305
3755
|
return { kind: "setIntrinsic", method: "add", receiver, args: [v], type: VOID, loc };
|
|
3306
3756
|
}
|
|
3307
3757
|
if (name === "has" || name === "delete") {
|
|
3308
|
-
const v = lowerer.
|
|
3758
|
+
const v = lowerer.lowerCollectionKey(call.arguments[0], receiverIr.elem);
|
|
3309
3759
|
return { kind: "setIntrinsic", method: name, receiver, args: [v], type: BOOL, loc };
|
|
3310
3760
|
}
|
|
3311
3761
|
if (name === "clear") {
|
|
@@ -3771,7 +4221,11 @@ export function lowerIteratorHelperCall(lowerer, call, access) {
|
|
|
3771
4221
|
if (terminal !== "forEach" && (checkerT === null || !typeEquals(checkerT, resultT))) {
|
|
3772
4222
|
lowerer.noLowering(`.${terminal} at this result type`, call, "the chain's element and result types must be representable — annotate the callbacks' types");
|
|
3773
4223
|
}
|
|
3774
|
-
const stageKeys = stageIrs.map((s) =>
|
|
4224
|
+
const stageKeys = stageIrs.map((s) => {
|
|
4225
|
+
if (!s)
|
|
4226
|
+
throw new InternalCompilerError("missing iterator stage");
|
|
4227
|
+
return "budget" in s ? s.kind : `${s.kind}:${typeKey(s.fn.type)}`;
|
|
4228
|
+
});
|
|
3775
4229
|
const key = `iter:${srcProj}:${typeKey(items.type)}:${stageKeys.join(",")}:${terminal}:${termArgs.map((a) => typeKey(a.type)).join(",")}`;
|
|
3776
4230
|
let helper = lowerer.arrHofHelpers.get(key);
|
|
3777
4231
|
if (!helper) {
|
|
@@ -3779,7 +4233,11 @@ export function lowerIteratorHelperCall(lowerer, call, access) {
|
|
|
3779
4233
|
lowerer.arrHofHelpers.set(key, helper);
|
|
3780
4234
|
lowerer.liftedFns.push(buildIterChainFn(lowerer, helper, items.type, srcProj, stageIrs, terminal, termArgs.map((a) => a.type), resultT, loc));
|
|
3781
4235
|
}
|
|
3782
|
-
const budgetOrFn = stageIrs.map((s) =>
|
|
4236
|
+
const budgetOrFn = stageIrs.map((s) => {
|
|
4237
|
+
if (!s)
|
|
4238
|
+
throw new InternalCompilerError("missing iterator stage");
|
|
4239
|
+
return "budget" in s ? s.budget : s.fn;
|
|
4240
|
+
});
|
|
3783
4241
|
return { kind: "call", callee: helper, args: [items, ...budgetOrFn, ...termArgs], type: resultT, loc };
|
|
3784
4242
|
}
|
|
3785
4243
|
const ITER_STAGES = new Set(["map", "filter", "take", "drop", "flatMap"]);
|
|
@@ -4457,6 +4915,8 @@ export function lowerForOfSearchParams(lowerer, stmt, iterable, proj) {
|
|
|
4457
4915
|
export function lowerForOfArrayIter(lowerer, stmt, iterable, proj) {
|
|
4458
4916
|
const loc = locOf(stmt);
|
|
4459
4917
|
const arrT = iterable.type;
|
|
4918
|
+
if (arrT.kind !== "array" && arrT.kind !== "bytes")
|
|
4919
|
+
throw new InternalCompilerError("array iterator requires indexed storage");
|
|
4460
4920
|
const elemT = arrT.kind === "array" ? arrayValueType(lowerer, arrT.elem) : F64;
|
|
4461
4921
|
const yieldsPair = proj === "entries";
|
|
4462
4922
|
if (!ts.isVariableDeclarationList(stmt.initializer)) {
|
|
@@ -4715,22 +5175,12 @@ function lowerForOfMapOrSet(lowerer, stmt, iterable, contT, proj) {
|
|
|
4715
5175
|
}
|
|
4716
5176
|
}
|
|
4717
5177
|
else {
|
|
4718
|
-
//
|
|
4719
|
-
//
|
|
4720
|
-
//
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
const shape = elemT?.kind === "record" ? lowerer.shapes.get(elemT.shapeId) : null;
|
|
4725
|
-
if (elemT?.kind !== "record" || !shape?.tuple || shape.fields.length !== 2 ||
|
|
4726
|
-
!typeEquals(shape.fields.find((f) => f.name === "0").type, keyT) ||
|
|
4727
|
-
!typeEquals(shape.fields.find((f) => f.name === "1").type, secondT)) {
|
|
4728
|
-
lowerer.badType(decl.name, lowerer.checker.getTypeAtLocation(decl.name)); // defensive: the lib declares [K, V]
|
|
4729
|
-
}
|
|
4730
|
-
}
|
|
4731
|
-
else if (!elemT || !typeEquals(elemT, singleT)) {
|
|
4732
|
-
lowerer.badType(decl.name, lowerer.checker.getTypeAtLocation(decl.name)); // defensive: the lib declares T
|
|
4733
|
-
}
|
|
5178
|
+
// Derive the yielded layout from the represented container. JS
|
|
5179
|
+
// inference can leave the pattern at any even when the Map's
|
|
5180
|
+
// native key/value types are known after specialization.
|
|
5181
|
+
const elemT = yieldsPair
|
|
5182
|
+
? { kind: "record", shapeId: lowerer.shapes.intern([{ name: "0", type: keyT }, { name: "1", type: secondT }], true) }
|
|
5183
|
+
: singleT;
|
|
4734
5184
|
const elemInit = yieldsPair
|
|
4735
5185
|
? {
|
|
4736
5186
|
kind: "recordLit",
|
|
@@ -4835,7 +5285,11 @@ function exitBeforeReturns(stmts, make) {
|
|
|
4835
5285
|
case "block":
|
|
4836
5286
|
return [{ ...s, body: walk(s.body) }];
|
|
4837
5287
|
case "switch":
|
|
4838
|
-
return [{ ...s, cases: s.cases.map((c) =>
|
|
5288
|
+
return [{ ...s, cases: s.cases.map((c) => {
|
|
5289
|
+
if (!c)
|
|
5290
|
+
throw new InternalCompilerError("missing switch clause");
|
|
5291
|
+
return { ...c, body: walk(c.body) };
|
|
5292
|
+
}) }];
|
|
4839
5293
|
case "tryCatch":
|
|
4840
5294
|
return [
|
|
4841
5295
|
{
|
|
@@ -4851,18 +5305,291 @@ function exitBeforeReturns(stmts, make) {
|
|
|
4851
5305
|
});
|
|
4852
5306
|
return walk(stmts);
|
|
4853
5307
|
}
|
|
4854
|
-
/**
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
5308
|
+
/** Consume a Set seed immediately, including optional inherited sets used
|
|
5309
|
+
* by compiler tables. Nullish seeds construct empty sets; a lazy fallback
|
|
5310
|
+
* consumes its evaluated branch even when it reassigns the source binding. */
|
|
5311
|
+
export function lowerSetSeedNew(lowerer, node, setT) {
|
|
5312
|
+
if (ts.isSpreadElement(node))
|
|
5313
|
+
return null;
|
|
5314
|
+
while (ts.isParenthesizedExpression(node))
|
|
5315
|
+
node = node.expression;
|
|
5316
|
+
const loc = locOf(node);
|
|
5317
|
+
const undefinedSeed = lowerStaticallyUndefinedArgument(lowerer, node);
|
|
5318
|
+
if (undefinedSeed)
|
|
5319
|
+
return defaultAfterUndefined(undefinedSeed, { kind: "setNew", type: setT, loc });
|
|
5320
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
5321
|
+
const undefinedLeft = lowerStaticallyUndefinedArgument(lowerer, node.left);
|
|
5322
|
+
const fallback = node.right;
|
|
5323
|
+
if (undefinedLeft) {
|
|
5324
|
+
const selected = lowerSetSeedNew(lowerer, fallback, setT);
|
|
5325
|
+
return selected ? defaultAfterUndefined(undefinedLeft, selected) : null;
|
|
5326
|
+
}
|
|
5327
|
+
const source = lowerer.lowerExpr(node.left);
|
|
5328
|
+
if (isUnitType(source.type)) {
|
|
5329
|
+
const selected = lowerSetSeedNew(lowerer, fallback, setT);
|
|
5330
|
+
return selected ? defaultAfterUndefined(source, selected) : null;
|
|
5331
|
+
}
|
|
5332
|
+
return setFromSeedValue(lowerer, source, setT, () => lowerSetSeedNew(lowerer, fallback, setT));
|
|
5333
|
+
}
|
|
5334
|
+
if (ts.isConditionalExpression(node)) {
|
|
5335
|
+
const yes = lowerSetSeedNew(lowerer, node.whenTrue, setT);
|
|
5336
|
+
const no = lowerSetSeedNew(lowerer, node.whenFalse, setT);
|
|
5337
|
+
return yes && no ? { kind: "ternary", cond: lowerer.lowerCondition(node.condition), then: yes, else_: no, type: setT, loc } : null;
|
|
5338
|
+
}
|
|
5339
|
+
// Constructor contextual types include Iterable<T>, which has no value
|
|
5340
|
+
// representation. Build a literal at the actual Set element ABI instead.
|
|
5341
|
+
if (ts.isArrayLiteralExpression(node) && !node.elements.some(ts.isSpreadElement)) {
|
|
5342
|
+
const elems = node.elements.map((element) => lowerer.lowerCollectionKey(element, setT.elem));
|
|
5343
|
+
return { kind: "setNew", seed: { kind: "arrayLit", elems, type: arrayOf(setT.elem), loc }, type: setT, loc };
|
|
5344
|
+
}
|
|
5345
|
+
const declared = lowerer.mapTypeOf(lowerer.typeOf(node));
|
|
5346
|
+
const scalar = setT.elem.kind === "f64" || setT.elem.kind === "string";
|
|
5347
|
+
let source = !scalar && (declared?.kind === "array" || declared?.kind === "record")
|
|
5348
|
+
? lowerer.lowerCollectionKey(node, declared)
|
|
5349
|
+
: lowerer.lowerExpr(node);
|
|
5350
|
+
if (declared?.kind === "string" && setT.elem.kind === "string" &&
|
|
5351
|
+
(source.type.kind === "dyn" || source.type.kind === "jsval")) {
|
|
5352
|
+
source = lowerer.coerceInto(node, source, STRING);
|
|
5353
|
+
}
|
|
5354
|
+
if (source.type.kind === "dyn" && setT.elem.kind === "dyn") {
|
|
5355
|
+
return { kind: "dynCheck", value: { kind: "libCall", fn: "dyn.nativeSetNew", args: [source], type: DYN, loc }, type: setT, loc };
|
|
5356
|
+
}
|
|
5357
|
+
if (declared?.kind === "array" && typeEquals(declared.elem, setT.elem)) {
|
|
5358
|
+
// Preserve the existing checked scalar-iterable bridge. Reference
|
|
5359
|
+
// elements must retain identity and cannot enter via a copying exit.
|
|
5360
|
+
if (source.type.kind === "jsval" && lowerer.boundaryExitSafe(arrayOf(setT.elem))) {
|
|
5361
|
+
source = { kind: "jsExit", value: source, type: arrayOf(setT.elem), loc };
|
|
5362
|
+
}
|
|
5363
|
+
if (source.type.kind === "dyn" && scalar) {
|
|
5364
|
+
source = lowerer.coerceInto(node, {
|
|
5365
|
+
kind: "libCall", fn: "dyn.iterPack", args: [source, strLit(node.getText(), loc)], type: DYN, loc,
|
|
5366
|
+
}, arrayOf(setT.elem));
|
|
5367
|
+
}
|
|
5368
|
+
}
|
|
5369
|
+
return setFromSeedValue(lowerer, source, setT, () => ({ kind: "setNew", type: setT, loc }));
|
|
5370
|
+
}
|
|
5371
|
+
function setFromSeedValue(lowerer, source, setT, missing) {
|
|
5372
|
+
const loc = source.loc;
|
|
5373
|
+
if (isUnitType(source.type)) {
|
|
5374
|
+
const empty = missing();
|
|
5375
|
+
return empty ? defaultAfterUndefined(source, empty) : null;
|
|
5376
|
+
}
|
|
5377
|
+
if (source.type.kind === "union") {
|
|
5378
|
+
const unionId = source.type.unionId;
|
|
5379
|
+
const arms = lowerer.unions.get(unionId)?.arms;
|
|
5380
|
+
if (!arms)
|
|
5381
|
+
return null;
|
|
5382
|
+
const slot = lowerer.declareHiddenLocal("%setSeed", source.type);
|
|
5383
|
+
const ref = varRef(slot.id, source.type, loc);
|
|
5384
|
+
let result = null;
|
|
5385
|
+
for (let tag = arms.length - 1; tag >= 0; tag--) {
|
|
5386
|
+
const arm = arms[tag];
|
|
5387
|
+
const branch = isUnitType(arm) ? missing() : setFromSeedValue(lowerer, {
|
|
5388
|
+
kind: "unionNarrow", unionId, tag, value: ref, type: arm, loc,
|
|
5389
|
+
}, setT, missing);
|
|
5390
|
+
if (!branch)
|
|
5391
|
+
return null;
|
|
5392
|
+
result = result === null ? branch : {
|
|
5393
|
+
kind: "ternary", cond: { kind: "unionIsTag", unionId, tag, value: ref, negated: false, type: BOOL, loc },
|
|
5394
|
+
then: branch, else_: result, type: setT, loc,
|
|
5395
|
+
};
|
|
5396
|
+
}
|
|
5397
|
+
return result ? {
|
|
5398
|
+
kind: "seqExpr", stmts: [{ kind: "varDecl", localId: slot.id, init: source, loc }], result, type: setT, loc,
|
|
5399
|
+
} : null;
|
|
5400
|
+
}
|
|
5401
|
+
let seed;
|
|
5402
|
+
if (source.type.kind === "set" && typeEquals(source.type, setT)) {
|
|
5403
|
+
seed = { kind: "setIntrinsic", method: "toArray", receiver: source, args: [], type: arrayOf(setT.elem), loc };
|
|
5404
|
+
}
|
|
5405
|
+
else if (source.type.kind === "string" && setT.elem.kind === "string") {
|
|
5406
|
+
seed = strCharsCall(lowerer, source, loc);
|
|
5407
|
+
}
|
|
5408
|
+
else if (source.type.kind === "array" && typeEquals(source.type.elem, setT.elem)) {
|
|
5409
|
+
seed = source;
|
|
5410
|
+
}
|
|
5411
|
+
else if (source.type.kind === "record") {
|
|
5412
|
+
const shape = lowerer.shapes.get(source.type.shapeId);
|
|
5413
|
+
if (!shape?.tuple || !shape.fields.every((field) => typeEquals(field.type, setT.elem)))
|
|
5414
|
+
return null;
|
|
5415
|
+
const arrayT = { kind: "array", elem: setT.elem };
|
|
5416
|
+
const helper = lowerer.tupleArrayWidthHelper(source.type.shapeId, arrayT, loc);
|
|
5417
|
+
if (!helper)
|
|
5418
|
+
return null;
|
|
5419
|
+
seed = { kind: "call", callee: helper, args: [source], type: arrayT, loc };
|
|
5420
|
+
}
|
|
5421
|
+
else
|
|
5422
|
+
return null;
|
|
5423
|
+
return { kind: "setNew", seed, type: setT, loc };
|
|
5424
|
+
}
|
|
5425
|
+
/** Consume supported Map seeds: matching Maps and tuple arrays, plus
|
|
5426
|
+
* nullish values that construct an empty Map. Conditional/nullish seeds
|
|
5427
|
+
* select one lazy branch without representing a first-class iterable.
|
|
5428
|
+
* Copy loops preserve entry order and stored reference identities. */
|
|
5429
|
+
export function lowerMapSeedNew(lowerer, argNode, mapT) {
|
|
4863
5430
|
if (ts.isSpreadElement(argNode))
|
|
4864
5431
|
return null;
|
|
5432
|
+
const empty = lowerer.emptyCollectionFor(argNode, mapT);
|
|
5433
|
+
if (empty)
|
|
5434
|
+
return empty;
|
|
5435
|
+
while (ts.isParenthesizedExpression(argNode))
|
|
5436
|
+
argNode = argNode.expression;
|
|
5437
|
+
// A constructor consumes either iterable branch immediately. It does
|
|
5438
|
+
// not need a first-class Map|array representation for `cached ?? []`.
|
|
5439
|
+
// Snapshot the left before the lazy fallback can mutate its binding.
|
|
5440
|
+
if (ts.isBinaryExpression(argNode) && argNode.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
5441
|
+
const source = lowerer.lowerExpr(argNode.left);
|
|
5442
|
+
if (isUnitType(source.type)) {
|
|
5443
|
+
const fallback = lowerMapSeedNew(lowerer, argNode.right, mapT);
|
|
5444
|
+
return fallback ? defaultAfterUndefined(source, fallback) : null;
|
|
5445
|
+
}
|
|
5446
|
+
if (source.type.kind !== "union")
|
|
5447
|
+
return mapFromSeedValue(lowerer, source, mapT);
|
|
5448
|
+
const arms = lowerer.unions.get(source.type.unionId)?.arms;
|
|
5449
|
+
if (!arms)
|
|
5450
|
+
return null;
|
|
5451
|
+
const loc = locOf(argNode);
|
|
5452
|
+
const saved = lowerer.declareHiddenLocal("%mapSeed", source.type);
|
|
5453
|
+
const ref = varRef(saved.id, source.type, loc);
|
|
5454
|
+
let result = null;
|
|
5455
|
+
for (let tag = arms.length - 1; tag >= 0; tag--) {
|
|
5456
|
+
const arm = arms[tag];
|
|
5457
|
+
const branch = isUnitType(arm)
|
|
5458
|
+
? lowerMapSeedNew(lowerer, argNode.right, mapT)
|
|
5459
|
+
: mapFromSeedValue(lowerer, { kind: "unionNarrow", unionId: source.type.unionId, tag, value: ref, type: arm, loc }, mapT);
|
|
5460
|
+
if (!branch)
|
|
5461
|
+
return null;
|
|
5462
|
+
result = result === null ? branch : {
|
|
5463
|
+
kind: "ternary",
|
|
5464
|
+
cond: { kind: "unionIsTag", unionId: source.type.unionId, tag, value: ref, negated: false, type: BOOL, loc },
|
|
5465
|
+
then: branch, else_: result, type: mapT, loc,
|
|
5466
|
+
};
|
|
5467
|
+
}
|
|
5468
|
+
return result ? { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: saved.id, init: source, loc }], result, type: mapT, loc } : null;
|
|
5469
|
+
}
|
|
5470
|
+
if (ts.isConditionalExpression(argNode)) {
|
|
5471
|
+
const yes = lowerMapSeedNew(lowerer, argNode.whenTrue, mapT);
|
|
5472
|
+
const no = lowerMapSeedNew(lowerer, argNode.whenFalse, mapT);
|
|
5473
|
+
return yes && no ? { kind: "ternary", cond: lowerer.lowerCondition(argNode.condition), then: yes, else_: no, type: mapT, loc: locOf(argNode) } : null;
|
|
5474
|
+
}
|
|
5475
|
+
if (ts.isArrayLiteralExpression(argNode)) {
|
|
5476
|
+
if (isJsSourceFile(argNode.getSourceFile()) && argNode.elements.some((entry) => !ts.isArrayLiteralExpression(entry))) {
|
|
5477
|
+
return mapFromSeedValue(lowerer, lowerer.lowerExprExpecting(argNode, DYN), mapT);
|
|
5478
|
+
}
|
|
5479
|
+
const tuple = { kind: "record", shapeId: lowerer.shapes.intern([
|
|
5480
|
+
{ name: "0", type: mapT.key }, { name: "1", type: mapT.value },
|
|
5481
|
+
], true) };
|
|
5482
|
+
return mapFromSeedValue(lowerer, lowerer.lowerArrayLiteral(argNode, { kind: "array", elem: tuple }), mapT);
|
|
5483
|
+
}
|
|
4865
5484
|
const seed = lowerer.lowerExpr(argNode);
|
|
5485
|
+
return mapFromSeedValue(lowerer, seed, mapT);
|
|
5486
|
+
}
|
|
5487
|
+
function mapFromSeedValue(lowerer, seed, mapT) {
|
|
5488
|
+
const loc = seed.loc;
|
|
5489
|
+
if (isUnitType(seed.type)) {
|
|
5490
|
+
return defaultAfterUndefined(seed, { kind: "mapNew", type: mapT, loc });
|
|
5491
|
+
}
|
|
5492
|
+
if (seed.type.kind === "union") {
|
|
5493
|
+
const arms = lowerer.unions.get(seed.type.unionId)?.arms;
|
|
5494
|
+
if (!arms)
|
|
5495
|
+
return null;
|
|
5496
|
+
const saved = lowerer.declareHiddenLocal("%mapSeed", seed.type);
|
|
5497
|
+
const ref = varRef(saved.id, seed.type, loc);
|
|
5498
|
+
let result = null;
|
|
5499
|
+
for (let tag = arms.length - 1; tag >= 0; tag--) {
|
|
5500
|
+
const arm = arms[tag];
|
|
5501
|
+
const branch = isUnitType(arm) ? { kind: "mapNew", type: mapT, loc }
|
|
5502
|
+
: mapFromSeedValue(lowerer, { kind: "unionNarrow", unionId: seed.type.unionId, tag, value: ref, type: arm, loc }, mapT);
|
|
5503
|
+
if (!branch)
|
|
5504
|
+
return null;
|
|
5505
|
+
result = result === null ? branch : {
|
|
5506
|
+
kind: "ternary",
|
|
5507
|
+
cond: { kind: "unionIsTag", unionId: seed.type.unionId, tag, value: ref, negated: false, type: BOOL, loc },
|
|
5508
|
+
then: branch, else_: result, type: mapT, loc,
|
|
5509
|
+
};
|
|
5510
|
+
}
|
|
5511
|
+
return result ? { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: saved.id, init: seed, loc }], result, type: mapT, loc } : null;
|
|
5512
|
+
}
|
|
5513
|
+
if (seed.type.kind === "map") {
|
|
5514
|
+
if (!typeEquals(seed.type, mapT))
|
|
5515
|
+
return null;
|
|
5516
|
+
const key = `copy:${typeKey(mapT)}`;
|
|
5517
|
+
let name = lowerer.mapHofHelpers.get(key);
|
|
5518
|
+
if (!name) {
|
|
5519
|
+
name = `%map.copy.${lowerer.mapHofHelpers.size}`;
|
|
5520
|
+
lowerer.mapHofHelpers.set(key, name);
|
|
5521
|
+
const source = varRef("source.0", mapT, loc);
|
|
5522
|
+
const target = varRef("target.0", mapT, loc);
|
|
5523
|
+
const index = varRef("i.0", F64, loc);
|
|
5524
|
+
const read = (method, type) => ({
|
|
5525
|
+
kind: "mapIntrinsic", method, receiver: source, args: method === "iterCount" ? [] : [index], type, loc,
|
|
5526
|
+
});
|
|
5527
|
+
lowerer.liftedFns.push({
|
|
5528
|
+
name, params: [{ localId: "source.0", name: "source", type: mapT }], returnType: mapT,
|
|
5529
|
+
locals: [
|
|
5530
|
+
{ id: "source.0", name: "source", type: mapT, mutable: false },
|
|
5531
|
+
{ id: "target.0", name: "target", type: mapT, mutable: false },
|
|
5532
|
+
{ id: "i.0", name: "i", type: F64, mutable: true },
|
|
5533
|
+
],
|
|
5534
|
+
body: [
|
|
5535
|
+
{ kind: "varDecl", localId: "target.0", init: { kind: "mapNew", type: mapT, loc }, loc },
|
|
5536
|
+
countedFor(loc, read("iterCount", F64), () => [{
|
|
5537
|
+
kind: "if", cond: read("iterLive", BOOL), then: [{ kind: "exprStmt", expr: {
|
|
5538
|
+
kind: "mapIntrinsic", method: "set", receiver: target,
|
|
5539
|
+
args: [read("iterKey", mapT.key), read("iterValue", mapT.value)], type: VOID, loc,
|
|
5540
|
+
}, loc }], else_: null, loc,
|
|
5541
|
+
}]),
|
|
5542
|
+
{ kind: "return", value: target, loc },
|
|
5543
|
+
], loc,
|
|
5544
|
+
});
|
|
5545
|
+
}
|
|
5546
|
+
return { kind: "call", callee: name, args: [seed], type: mapT, loc };
|
|
5547
|
+
}
|
|
5548
|
+
if (seed.type.kind === "dyn" || seed.type.kind === "array" &&
|
|
5549
|
+
(seed.type.elem.kind === "dyn" || seed.type.elem.kind === "array")) {
|
|
5550
|
+
const key = `checked-seed:${typeKey(mapT)}`;
|
|
5551
|
+
let name = lowerer.mapHofHelpers.get(key);
|
|
5552
|
+
if (!name) {
|
|
5553
|
+
name = `%map.checkedSeed.${lowerer.mapHofHelpers.size}`;
|
|
5554
|
+
lowerer.mapHofHelpers.set(key, name);
|
|
5555
|
+
const source = varRef("source.0", DYN, loc);
|
|
5556
|
+
const entries = varRef("entries.0", DYN, loc);
|
|
5557
|
+
const entry = varRef("entry.0", DYN, loc);
|
|
5558
|
+
const target = varRef("target.0", mapT, loc);
|
|
5559
|
+
const keyValue = varRef("key.0", DYN, loc);
|
|
5560
|
+
const itemValue = varRef("value.0", DYN, loc);
|
|
5561
|
+
const checked = (value, type) => type.kind === "dyn" ? value
|
|
5562
|
+
: { kind: "dynCheck", value, type, loc };
|
|
5563
|
+
lowerer.liftedFns.push({
|
|
5564
|
+
name, params: [{ localId: "source.0", name: "source", type: DYN }], returnType: mapT,
|
|
5565
|
+
locals: [
|
|
5566
|
+
{ id: "source.0", name: "source", type: DYN, mutable: false },
|
|
5567
|
+
{ id: "entries.0", name: "entries", type: DYN, mutable: false },
|
|
5568
|
+
{ id: "entry.0", name: "entry", type: DYN, mutable: false },
|
|
5569
|
+
{ id: "key.0", name: "key", type: DYN, mutable: false },
|
|
5570
|
+
{ id: "value.0", name: "value", type: DYN, mutable: false },
|
|
5571
|
+
{ id: "target.0", name: "target", type: mapT, mutable: false },
|
|
5572
|
+
{ id: "i.0", name: "i", type: F64, mutable: true },
|
|
5573
|
+
],
|
|
5574
|
+
body: [
|
|
5575
|
+
{ kind: "varDecl", localId: "target.0", init: { kind: "mapNew", type: mapT, loc }, loc },
|
|
5576
|
+
{ kind: "varDecl", localId: "entries.0", init: { kind: "libCall", fn: "dyn.mapSeedEntries", args: [source], type: DYN, loc }, loc },
|
|
5577
|
+
countedFor(loc, { kind: "libCall", fn: "dyn.arrLen", args: [entries], type: F64, loc }, () => [
|
|
5578
|
+
{ kind: "varDecl", localId: "entry.0", init: { kind: "libCall", fn: "dyn.mapSeedEntry", args: [
|
|
5579
|
+
{ kind: "libCall", fn: "dyn.arrAt", args: [entries, varRef("i.0", F64, loc)], type: DYN, loc },
|
|
5580
|
+
], type: DYN, loc }, loc },
|
|
5581
|
+
{ kind: "varDecl", localId: "key.0", init: { kind: "dynKeyGet", value: entry, key: strLit("0", loc), type: DYN, loc }, loc },
|
|
5582
|
+
{ kind: "varDecl", localId: "value.0", init: { kind: "dynKeyGet", value: entry, key: strLit("1", loc), type: DYN, loc }, loc },
|
|
5583
|
+
{ kind: "exprStmt", expr: { kind: "mapIntrinsic", method: "set", receiver: target,
|
|
5584
|
+
args: [checked(keyValue, mapT.key), checked(itemValue, mapT.value)], type: VOID, loc }, loc },
|
|
5585
|
+
]),
|
|
5586
|
+
{ kind: "return", value: target, loc },
|
|
5587
|
+
], loc,
|
|
5588
|
+
});
|
|
5589
|
+
}
|
|
5590
|
+
const source = seed.type.kind === "dyn" ? seed : { kind: "dynFrom", value: seed, type: DYN, loc };
|
|
5591
|
+
return { kind: "call", callee: name, args: [source], type: mapT, loc };
|
|
5592
|
+
}
|
|
4866
5593
|
if (seed.type.kind !== "array" || seed.type.elem.kind !== "record")
|
|
4867
5594
|
return null;
|
|
4868
5595
|
const elem = seed.type.elem;
|
|
@@ -4873,7 +5600,6 @@ export function lowerMapSeedArrayNew(lowerer, argNode, mapT) {
|
|
|
4873
5600
|
const vT = shape.fields.find((f) => f.name === "1").type;
|
|
4874
5601
|
if (!typeEquals(kT, mapT.key) || !typeEquals(vT, mapT.value))
|
|
4875
5602
|
return null;
|
|
4876
|
-
const loc = locOf(argNode);
|
|
4877
5603
|
const key = `seed:${typeKey(mapT.key)}:${typeKey(mapT.value)}:${elem.shapeId}`;
|
|
4878
5604
|
let helper = lowerer.mapHofHelpers.get(key);
|
|
4879
5605
|
if (!helper) {
|
|
@@ -4946,7 +5672,7 @@ export function lowerObjectIterOverIndexShape(lowerer, call, member, argIr, shap
|
|
|
4946
5672
|
const resultT = lowerer.irTypeOf(call);
|
|
4947
5673
|
if (resultT.kind !== "array")
|
|
4948
5674
|
lowerer.badType(call, lowerer.typeOf(call)); // defensive
|
|
4949
|
-
return objectIterOverIndexShape(lowerer, call, member, argIr, shape, lowerer.lowerExpr(call.arguments[0]), resultT, locOf(call));
|
|
5675
|
+
return objectIterOverIndexShape(lowerer, call, member, argIr, shape, objectEnumerationReceiver(lowerer, lowerer.lowerExpr(call.arguments[0]), argIr, locOf(call)), resultT, locOf(call));
|
|
4950
5676
|
}
|
|
4951
5677
|
/** The construction core, receiver/result pre-resolved — `node` anchors
|
|
4952
5678
|
* the fences. for-in reuses the "keys" arm directly (it iterates exactly
|
|
@@ -5146,6 +5872,21 @@ export function objectIterOverIndexShape(lowerer, node, member, argIr, shape, re
|
|
|
5146
5872
|
* (lowerRecordOvfCaptureHelper). Null when the argument or result shape
|
|
5147
5873
|
* is outside this (Maps, richer iterables → the SC2020 fence). */
|
|
5148
5874
|
export function lowerObjectFromEntriesCall(lowerer, call, callee) {
|
|
5875
|
+
const typed = lowerTypedObjectFromEntriesCall(lowerer, call, callee);
|
|
5876
|
+
if (typed)
|
|
5877
|
+
return typed;
|
|
5878
|
+
if (!ts.isPropertyAccessExpression(callee) || call.questionDotToken || callee.questionDotToken ||
|
|
5879
|
+
!lowerer.isStdlibGlobal(callee.expression, "Object") || callee.name.text !== "fromEntries" ||
|
|
5880
|
+
call.arguments.length !== 1 || ts.isSpreadElement(call.arguments[0]))
|
|
5881
|
+
return null;
|
|
5882
|
+
if (lowerer.dynamic)
|
|
5883
|
+
return null;
|
|
5884
|
+
return {
|
|
5885
|
+
kind: "libCall", fn: "dyn.fromEntries", type: DYN, loc: locOf(call),
|
|
5886
|
+
args: [lowerer.lowerExprExpecting(call.arguments[0], DYN)],
|
|
5887
|
+
};
|
|
5888
|
+
}
|
|
5889
|
+
function lowerTypedObjectFromEntriesCall(lowerer, call, callee) {
|
|
5149
5890
|
if (!ts.isPropertyAccessExpression(callee))
|
|
5150
5891
|
return null;
|
|
5151
5892
|
if (call.questionDotToken || callee.questionDotToken)
|
|
@@ -5202,7 +5943,10 @@ export function lowerObjectFromEntriesCall(lowerer, call, callee) {
|
|
|
5202
5943
|
if (!convertible) {
|
|
5203
5944
|
lowerer.unsupported("SC1090", call, `Object.fromEntries over '${lowerer.fmt(argIr)}' (the tuple's '${lowerer.fmt(valT)}' value cannot flow into the '${lowerer.fmt(iv)}' signature slot)`);
|
|
5204
5945
|
}
|
|
5205
|
-
|
|
5946
|
+
// Enumeration/filtering may keep the array in checked-dynamic storage.
|
|
5947
|
+
// Validate its tuple layout before calling a helper with a native-array
|
|
5948
|
+
// ABI; opaque tuple values themselves retain their original references.
|
|
5949
|
+
const receiver = lowerer.lowerExprExpecting(argNode, argIr);
|
|
5206
5950
|
const key = `obj.fromEntries:${argIr.elem.shapeId}:${resultT.shapeId}`;
|
|
5207
5951
|
let helper = lowerer.arrHofHelpers.get(key);
|
|
5208
5952
|
if (!helper) {
|