@scriptc/compiler 0.2.3 → 0.2.5
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 +915 -215
- package/ambient/scriptc-overrides.d.ts +5 -1
- package/ambient/scriptc.d.ts +22 -2
- package/dist/backend/build-cache.d.ts +4 -0
- package/dist/backend/build-cache.js +16 -2
- package/dist/backend/build-cache.js.map +1 -1
- package/dist/backend/cycle-analysis.js +17 -5
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +50 -11
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/debug-symbols.js.map +1 -1
- package/dist/backend/executable-features.js +2 -1
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/external-c.d.ts +13 -6
- package/dist/backend/external-c.js +15 -3
- package/dist/backend/external-c.js.map +1 -1
- package/dist/backend/ffi-callbacks.js +6 -9
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/library-identity-markers.js.map +1 -1
- package/dist/backend/library-pack.d.ts +1 -1
- package/dist/backend/library-pack.js +81 -24
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/link-plan-core.js +9 -2
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan.d.ts +1 -1
- package/dist/backend/link-plan.js +4 -5
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/linker.d.ts +1 -1
- package/dist/backend/linker.js +42 -23
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/literals.js +5 -4
- package/dist/backend/literals.js.map +1 -1
- package/dist/backend/literals.test.js +30 -5
- package/dist/backend/literals.test.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +5 -2
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/borrowed-inputs.d.ts +15 -0
- package/dist/backend/llvm/borrowed-inputs.js +28 -0
- package/dist/backend/llvm/borrowed-inputs.js.map +1 -0
- package/dist/backend/llvm/borrowed-receivers.js +43 -19
- package/dist/backend/llvm/borrowed-receivers.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.d.ts +10 -0
- package/dist/backend/llvm/byte-numbers.js +240 -0
- package/dist/backend/llvm/byte-numbers.js.map +1 -0
- package/dist/backend/llvm/bytes-bounds.d.ts +9 -0
- package/dist/backend/llvm/bytes-bounds.js +240 -0
- package/dist/backend/llvm/bytes-bounds.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.d.ts +10 -0
- package/dist/backend/llvm/call-lifetimes.js +83 -20
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +203 -18
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.d.ts +13 -0
- package/dist/backend/llvm/checked-value-lifetimes.js +45 -0
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -0
- package/dist/backend/llvm/classes.js +16 -12
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.js +4 -1
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +6 -0
- package/dist/backend/llvm/counted-loops.js +35 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -0
- package/dist/backend/llvm/debug-info.js +33 -13
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/debug-info.test.js +28 -6
- package/dist/backend/llvm/debug-info.test.js.map +1 -1
- package/dist/backend/llvm/dyn.js +68 -22
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +34 -12
- package/dist/backend/llvm/emitter.js +357 -124
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +237 -46
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +28 -8
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +4 -4
- package/dist/backend/llvm/expr-bytes.js +78 -36
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +10 -4
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +40 -21
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +4 -1
- package/dist/backend/llvm/expr-containers.js +157 -76
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +11 -0
- package/dist/backend/llvm/expr-control.js +27 -8
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +3 -1
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +50 -33
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.js +26 -6
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +139 -37
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +43 -1
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +16 -9
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +44 -26
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +51 -14
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.js +34 -14
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/integer-values.d.ts +10 -0
- package/dist/backend/llvm/integer-values.js +52 -0
- package/dist/backend/llvm/integer-values.js.map +1 -0
- package/dist/backend/llvm/integer-views.d.ts +7 -0
- package/dist/backend/llvm/integer-views.js +83 -0
- package/dist/backend/llvm/integer-views.js.map +1 -0
- package/dist/backend/llvm/integer-views.test.d.ts +1 -0
- package/dist/backend/llvm/integer-views.test.js +69 -0
- package/dist/backend/llvm/integer-views.test.js.map +1 -0
- package/dist/backend/llvm/lib-abi.js +13 -4
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +7 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +35 -10
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +36 -15
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +38 -23
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +60 -15
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +12 -5
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +97 -31
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +57 -14
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +107 -31
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +33 -14
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +21 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +69 -20
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +3 -4
- package/dist/backend/llvm/local-array-reads.js +100 -121
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +379 -71
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.d.ts +25 -0
- package/dist/backend/llvm/local-union-storage.js +109 -0
- package/dist/backend/llvm/local-union-storage.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.test.d.ts +1 -0
- package/dist/backend/llvm/local-union-storage.test.js +210 -0
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.d.ts +6 -2
- package/dist/backend/llvm/map-read-lifetimes.js +46 -16
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +93 -17
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/reference-effects.d.ts +23 -0
- package/dist/backend/llvm/reference-effects.js +179 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -0
- package/dist/backend/llvm/reference-effects.test.d.ts +1 -0
- package/dist/backend/llvm/reference-effects.test.js +157 -0
- package/dist/backend/llvm/reference-effects.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +7 -4
- package/dist/backend/llvm/shapes.js +82 -22
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +3 -1
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split.js +4 -4
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/split.test.js +14 -6
- package/dist/backend/llvm/split.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.js +14 -5
- package/dist/backend/llvm/stack-unions.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +172 -32
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-construction.d.ts +10 -0
- package/dist/backend/llvm/string-construction.js +38 -0
- package/dist/backend/llvm/string-construction.js.map +1 -0
- package/dist/backend/llvm/string-construction.test.d.ts +1 -0
- package/dist/backend/llvm/string-construction.test.js +90 -0
- package/dist/backend/llvm/string-construction.test.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.d.ts +2 -2
- package/dist/backend/llvm/string-lifetimes.js +19 -11
- package/dist/backend/llvm/string-lifetimes.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +127 -32
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.d.ts +9 -0
- package/dist/backend/llvm/switch-dispatch.js +114 -0
- package/dist/backend/llvm/switch-dispatch.js.map +1 -0
- package/dist/backend/llvm/switch-dispatch.test.d.ts +1 -0
- package/dist/backend/llvm/switch-dispatch.test.js +83 -0
- package/dist/backend/llvm/switch-dispatch.test.js.map +1 -0
- package/dist/backend/llvm/unsupported.js.map +1 -1
- package/dist/backend/llvm/walkers.js +6 -3
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/mangle.js +9 -3
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.js +18 -8
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +118 -22
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native/artifact-stamps.d.ts +39 -0
- package/dist/backend/native/artifact-stamps.js +371 -0
- package/dist/backend/native/artifact-stamps.js.map +1 -0
- package/dist/backend/native/cache-warm.d.ts +24 -0
- package/dist/backend/native/cache-warm.js +80 -0
- package/dist/backend/native/cache-warm.js.map +1 -0
- package/dist/backend/native/compiler-fingerprint.d.ts +19 -0
- package/dist/backend/native/compiler-fingerprint.js +357 -0
- package/dist/backend/native/compiler-fingerprint.js.map +1 -0
- package/dist/backend/native/contracts.d.ts +314 -0
- package/dist/backend/native/contracts.js +2 -0
- package/dist/backend/native/contracts.js.map +1 -0
- package/dist/backend/native/dependency-files.d.ts +5 -0
- package/dist/backend/native/dependency-files.js +83 -0
- package/dist/backend/native/dependency-files.js.map +1 -0
- package/dist/backend/native/driver.d.ts +50 -0
- package/dist/backend/native/driver.js +294 -0
- package/dist/backend/native/driver.js.map +1 -0
- package/dist/backend/native/executable.d.ts +18 -0
- package/dist/backend/native/executable.js +1267 -0
- package/dist/backend/native/executable.js.map +1 -0
- package/dist/backend/native/library.d.ts +2 -0
- package/dist/backend/native/library.js +614 -0
- package/dist/backend/native/library.js.map +1 -0
- package/dist/backend/native/linker-fingerprint.d.ts +8 -0
- package/dist/backend/native/linker-fingerprint.js +174 -0
- package/dist/backend/native/linker-fingerprint.js.map +1 -0
- package/dist/backend/native/object-merge.d.ts +2 -0
- package/dist/backend/native/object-merge.js +154 -0
- package/dist/backend/native/object-merge.js.map +1 -0
- package/dist/backend/native/process.d.ts +17 -0
- package/dist/backend/native/process.js +42 -0
- package/dist/backend/native/process.js.map +1 -0
- package/dist/backend/native/program-shards.d.ts +21 -0
- package/dist/backend/native/program-shards.js +99 -0
- package/dist/backend/native/program-shards.js.map +1 -0
- package/dist/backend/native/runtime-inputs.d.ts +12 -0
- package/dist/backend/native/runtime-inputs.js +163 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -0
- package/dist/backend/native/runtime-inputs.test.d.ts +1 -0
- package/dist/backend/native/runtime-inputs.test.js +64 -0
- package/dist/backend/native/runtime-inputs.test.js.map +1 -0
- package/dist/backend/native/runtime-objects.d.ts +16 -0
- package/dist/backend/native/runtime-objects.js +122 -0
- package/dist/backend/native/runtime-objects.js.map +1 -0
- package/dist/backend/native/session.d.ts +12 -0
- package/dist/backend/native/session.js +31 -0
- package/dist/backend/native/session.js.map +1 -0
- package/dist/backend/native/tool-identity.d.ts +37 -0
- package/dist/backend/native/tool-identity.js +310 -0
- package/dist/backend/native/tool-identity.js.map +1 -0
- package/dist/backend/native/trace-paths.d.ts +12 -0
- package/dist/backend/native/trace-paths.js +73 -0
- package/dist/backend/native/trace-paths.js.map +1 -0
- package/dist/backend/native/vendor.d.ts +1 -0
- package/dist/backend/native/vendor.js +12 -0
- package/dist/backend/native/vendor.js.map +1 -0
- package/dist/backend/native-codegen-core.js +2 -1
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +1 -1
- package/dist/backend/native-codegen.js +24 -13
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +12 -9
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.js +9 -5
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-link-info.js +14 -5
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-link-info.test.js +58 -13
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +17 -450
- package/dist/backend/native-toolchain.js +17 -3971
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +103 -72
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/native-tools.js +27 -8
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/object-localize.js +17 -14
- package/dist/backend/object-localize.js.map +1 -1
- package/dist/backend/object-localize.test.js +59 -12
- package/dist/backend/object-localize.test.js.map +1 -1
- package/dist/backend/runtime-pack-core.js +96 -49
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +5 -3
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +87 -15
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.d.ts +1 -1
- package/dist/backend/runtime-pack.js +11 -12
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +40 -24
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/source-locations.js.map +1 -1
- package/dist/backend/source-locations.test.js +7 -2
- package/dist/backend/source-locations.test.js.map +1 -1
- package/dist/backend/target-diagnostics.js +44 -14
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +93 -20
- package/dist/backend/target-diagnostics.test.js.map +1 -1
- package/dist/backend/targets.js +230 -86
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +32 -18
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/backend/toolchain-environment.js +5 -1
- package/dist/backend/toolchain-environment.js.map +1 -1
- package/dist/backend/vendor-archives.d.ts +2 -2
- package/dist/backend/vendor-archives.js +84 -35
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.js +13 -1
- package/dist/backend/vendor-inputs.js.map +1 -1
- package/dist/backend/warm-cache.d.ts +1 -1
- package/dist/backend/warm-cache.js +33 -9
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/cli/command.js +39 -9
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/output-options.js +14 -4
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/paths.js.map +1 -1
- package/dist/cli/wasi-runner.js.map +1 -1
- package/dist/compat/fetch-profile.js +36 -35
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/coverage/report.js +16 -17
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +112 -26
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +55 -16
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +1 -1
- package/dist/executable/executable-cache.js +78 -48
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +75 -26
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -2
- package/dist/executable/prepare.js.map +1 -1
- package/dist/ffi/ffi-manifest.js +78 -20
- package/dist/ffi/ffi-manifest.js.map +1 -1
- package/dist/ffi/ffi-manifest.test.js +96 -16
- package/dist/ffi/ffi-manifest.test.js.map +1 -1
- package/dist/format-integer.js.map +1 -1
- package/dist/frontend/analysis.js +12 -2
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/arguments-usage.js.map +1 -1
- package/dist/frontend/binding-source.js +9 -3
- package/dist/frontend/binding-source.js.map +1 -1
- package/dist/frontend/builtin-modules.js +46 -2
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-resolve.js +40 -17
- package/dist/frontend/cjs-resolve.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +31 -10
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/comptime-node.test.js +10 -11
- package/dist/frontend/comptime-node.test.js.map +1 -1
- package/dist/frontend/dts-paths.js +7 -3
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/fork-target.js +17 -12
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/function-completion.js +11 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +53 -6
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +18 -2
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +32 -12
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.test.js +11 -15
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
- package/dist/frontend/input-tracker.js +11 -11
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +4 -1
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lib-contract.js +38 -9
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/literal-values.js.map +1 -1
- package/dist/frontend/literal-values.test.js +28 -8
- package/dist/frontend/literal-values.test.js.map +1 -1
- package/dist/frontend/lowering/abstract-equality.js +53 -10
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-indexed-mutation.d.ts +1 -1
- package/dist/frontend/lowering/array-indexed-mutation.js +108 -106
- package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
- package/dist/frontend/lowering/array-values.js +37 -14
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/binding-analysis.d.ts +50 -0
- package/dist/frontend/lowering/binding-analysis.js +376 -0
- package/dist/frontend/lowering/binding-analysis.js.map +1 -0
- package/dist/frontend/lowering/builtin-calls.d.ts +9 -0
- package/dist/frontend/lowering/builtin-calls.js +60 -0
- package/dist/frontend/lowering/builtin-calls.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.d.ts +43 -0
- package/dist/frontend/lowering/builtins/arguments.js +247 -0
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -0
- package/dist/frontend/lowering/builtins/async-context.d.ts +52 -0
- package/dist/frontend/lowering/builtins/async-context.js +436 -0
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -0
- package/dist/frontend/lowering/builtins/atomics.d.ts +15 -0
- package/dist/frontend/lowering/builtins/atomics.js +46 -0
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.d.ts +13 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +87 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -0
- package/dist/frontend/lowering/builtins/child-process-async.d.ts +18 -0
- package/dist/frontend/lowering/builtins/child-process-async.js +245 -0
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -0
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +21 -0
- package/dist/frontend/lowering/builtins/child-process-methods.js +362 -0
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -0
- package/dist/frontend/lowering/builtins/child-process-sync.d.ts +4 -0
- package/dist/frontend/lowering/builtins/child-process-sync.js +639 -0
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -0
- package/dist/frontend/lowering/builtins/child-process.d.ts +55 -0
- package/dist/frontend/lowering/builtins/child-process.js +669 -0
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +7 -0
- package/dist/frontend/lowering/builtins/compression.js +115 -0
- package/dist/frontend/lowering/builtins/compression.js.map +1 -0
- package/dist/frontend/lowering/builtins/console.d.ts +10 -0
- package/dist/frontend/lowering/builtins/console.js +38 -0
- package/dist/frontend/lowering/builtins/console.js.map +1 -0
- package/dist/frontend/lowering/builtins/constants.d.ts +24 -0
- package/dist/frontend/lowering/builtins/constants.js +141 -0
- package/dist/frontend/lowering/builtins/constants.js.map +1 -0
- package/dist/frontend/lowering/builtins/crypto.d.ts +22 -0
- package/dist/frontend/lowering/builtins/crypto.js +517 -0
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -0
- package/dist/frontend/lowering/builtins/dates.js +101 -0
- package/dist/frontend/lowering/builtins/dates.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.d.ts +34 -0
- package/dist/frontend/lowering/builtins/environment.js +95 -0
- package/dist/frontend/lowering/builtins/environment.js.map +1 -0
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -0
- package/dist/frontend/lowering/builtins/errors.js +83 -0
- package/dist/frontend/lowering/builtins/errors.js.map +1 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +32 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +678 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -0
- package/dist/frontend/lowering/builtins/filesystem.d.ts +108 -0
- package/dist/frontend/lowering/builtins/filesystem.js +1061 -0
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -0
- package/dist/frontend/lowering/builtins/ipc.d.ts +8 -0
- package/dist/frontend/lowering/builtins/ipc.js +76 -0
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -0
- package/dist/frontend/lowering/builtins/json.d.ts +12 -0
- package/dist/frontend/lowering/builtins/json.js +387 -0
- package/dist/frontend/lowering/builtins/json.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +85 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +346 -0
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-calls.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-calls.js +303 -0
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +38 -0
- package/dist/frontend/lowering/builtins/module-resolution.js +344 -0
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.d.ts +15 -0
- package/dist/frontend/lowering/builtins/numbers.js +124 -0
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -0
- package/dist/frontend/lowering/builtins/operating-system.d.ts +13 -0
- package/dist/frontend/lowering/builtins/operating-system.js +148 -0
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -0
- package/dist/frontend/lowering/builtins/performance.d.ts +13 -0
- package/dist/frontend/lowering/builtins/performance.js +100 -0
- package/dist/frontend/lowering/builtins/performance.js.map +1 -0
- package/dist/frontend/lowering/builtins/process.d.ts +50 -0
- package/dist/frontend/lowering/builtins/process.js +1138 -0
- package/dist/frontend/lowering/builtins/process.js.map +1 -0
- package/dist/frontend/lowering/builtins/promises.d.ts +14 -0
- package/dist/frontend/lowering/builtins/promises.js +356 -0
- package/dist/frontend/lowering/builtins/promises.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.d.ts +11 -0
- package/dist/frontend/lowering/builtins/properties.js +186 -0
- package/dist/frontend/lowering/builtins/properties.js.map +1 -0
- package/dist/frontend/lowering/builtins/querystring.d.ts +19 -0
- package/dist/frontend/lowering/builtins/querystring.js +150 -0
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -0
- package/dist/frontend/lowering/builtins/readline.d.ts +13 -0
- package/dist/frontend/lowering/builtins/readline.js +138 -0
- package/dist/frontend/lowering/builtins/readline.js.map +1 -0
- package/dist/frontend/lowering/builtins/receiver-types.d.ts +5 -0
- package/dist/frontend/lowering/builtins/receiver-types.js +15 -0
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -0
- package/dist/frontend/lowering/builtins/reflection.d.ts +13 -0
- package/dist/frontend/lowering/builtins/reflection.js +95 -0
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.d.ts +14 -0
- package/dist/frontend/lowering/builtins/strings.js +121 -0
- package/dist/frontend/lowering/builtins/strings.js.map +1 -0
- package/dist/frontend/lowering/builtins/text-codecs.d.ts +29 -0
- package/dist/frontend/lowering/builtins/text-codecs.js +590 -0
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -0
- package/dist/frontend/lowering/builtins/timers.d.ts +22 -0
- package/dist/frontend/lowering/builtins/timers.js +180 -0
- package/dist/frontend/lowering/builtins/timers.js.map +1 -0
- package/dist/frontend/lowering/builtins/url.d.ts +37 -0
- package/dist/frontend/lowering/builtins/url.js +596 -0
- package/dist/frontend/lowering/builtins/url.js.map +1 -0
- package/dist/frontend/lowering/builtins/util-types.d.ts +7 -0
- package/dist/frontend/lowering/builtins/util-types.js +31 -0
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -0
- package/dist/frontend/lowering/call-arguments.d.ts +72 -0
- package/dist/frontend/lowering/call-arguments.js +618 -0
- package/dist/frontend/lowering/call-arguments.js.map +1 -0
- package/dist/frontend/lowering/call-signatures.d.ts +115 -0
- package/dist/frontend/lowering/call-signatures.js +719 -0
- package/dist/frontend/lowering/call-signatures.js.map +1 -0
- package/dist/frontend/lowering/callback-arg.js.map +1 -1
- package/dist/frontend/lowering/checked-iterable-spread.js +53 -10
- package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.js +41 -9
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +1 -1
- package/dist/frontend/lowering/class-callbacks.js +130 -27
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +1 -1
- package/dist/frontend/lowering/class-construction.js +247 -50
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.js +109 -29
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +6 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.js +2471 -465
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +284 -44
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +17 -5
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +199 -51
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.js +345 -86
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +80 -17
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +76 -16
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/coercions/builders.d.ts +13 -0
- package/dist/frontend/lowering/coercions/builders.js +77 -0
- package/dist/frontend/lowering/coercions/builders.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +58 -0
- package/dist/frontend/lowering/coercions/function-adapters.js +430 -0
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -0
- package/dist/frontend/lowering/coercions/island.d.ts +37 -0
- package/dist/frontend/lowering/coercions/island.js +350 -0
- package/dist/frontend/lowering/coercions/island.js.map +1 -0
- package/dist/frontend/lowering/coercions/state.d.ts +14 -0
- package/dist/frontend/lowering/coercions/state.js +16 -0
- package/dist/frontend/lowering/coercions/state.js.map +1 -0
- package/dist/frontend/lowering/coercions/structural-plans.d.ts +40 -0
- package/dist/frontend/lowering/coercions/structural-plans.js +447 -0
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -0
- package/dist/frontend/lowering/coercions/structural.d.ts +63 -0
- package/dist/frontend/lowering/coercions/structural.js +616 -0
- package/dist/frontend/lowering/coercions/structural.js.map +1 -0
- package/dist/frontend/lowering/coercions/unions.d.ts +65 -0
- package/dist/frontend/lowering/coercions/unions.js +318 -0
- package/dist/frontend/lowering/coercions/unions.js.map +1 -0
- package/dist/frontend/lowering/collection-ingestion.js +359 -67
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +92 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +1646 -0
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -0
- package/dist/frontend/lowering/containers/array-construction.d.ts +42 -0
- package/dist/frontend/lowering/containers/array-construction.js +1044 -0
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -0
- package/dist/frontend/lowering/containers/array-iteration.d.ts +16 -0
- package/dist/frontend/lowering/containers/array-iteration.js +95 -0
- package/dist/frontend/lowering/containers/array-iteration.js.map +1 -0
- package/dist/frontend/lowering/containers/array-methods.d.ts +27 -0
- package/dist/frontend/lowering/containers/array-methods.js +1854 -0
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.d.ts +17 -17
- package/dist/frontend/lowering/containers/bytes.js +419 -105
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +26 -0
- package/dist/frontend/lowering/containers/callback-arguments.js +179 -0
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -0
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +19 -0
- package/dist/frontend/lowering/containers/collection-grouping.js +297 -0
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -0
- package/dist/frontend/lowering/containers/collection-methods.d.ts +57 -0
- package/dist/frontend/lowering/containers/collection-methods.js +1314 -0
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -0
- package/dist/frontend/lowering/containers/dynamic-receivers.d.ts +18 -0
- package/dist/frontend/lowering/containers/dynamic-receivers.js +114 -0
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -0
- package/dist/frontend/lowering/containers/for-of.d.ts +60 -0
- package/dist/frontend/lowering/containers/for-of.js +643 -0
- package/dist/frontend/lowering/containers/for-of.js.map +1 -0
- package/dist/frontend/lowering/containers/indexed-objects.d.ts +132 -0
- package/dist/frontend/lowering/containers/indexed-objects.js +1743 -0
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -0
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +20 -0
- package/dist/frontend/lowering/containers/iterator-helpers.js +809 -0
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +585 -157
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +213 -63
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/crypto-tables.js +263 -64
- package/dist/frontend/lowering/crypto-tables.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +172 -68
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.test.js +41 -8
- package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -1
- package/dist/frontend/lowering/error-methods.js +339 -65
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/expressions/evaluation-safety.js +3 -2
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/global-symbols.js +2 -1
- package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -1
- package/dist/frontend/lowering/expressions/native-proxy.js +11 -5
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +67 -13
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +589 -162
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +68 -17
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-field-write.js +45 -18
- package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -1
- package/dist/frontend/lowering/function-context.js +5 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.d.ts +67 -0
- package/dist/frontend/lowering/function-returns.js +392 -0
- package/dist/frontend/lowering/function-returns.js.map +1 -0
- package/dist/frontend/lowering/generator-delegation.d.ts +1 -1
- package/dist/frontend/lowering/generator-delegation.js +171 -39
- package/dist/frontend/lowering/generator-delegation.js.map +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +176 -36
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +274 -0
- package/dist/frontend/lowering/generic-functions.js +1727 -0
- package/dist/frontend/lowering/generic-functions.js.map +1 -0
- package/dist/frontend/lowering/import-meta.d.ts +1 -1
- package/dist/frontend/lowering/import-meta.js +37 -14
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/indexed-comparison.js +6 -2
- package/dist/frontend/lowering/indexed-comparison.js.map +1 -1
- package/dist/frontend/lowering/iterator-consumption.d.ts +9 -0
- package/dist/frontend/lowering/iterator-consumption.js +91 -0
- package/dist/frontend/lowering/iterator-consumption.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.js +40 -17
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.test.js +49 -11
- package/dist/frontend/lowering/lib-boundary.test.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.d.ts +0 -19
- package/dist/frontend/lowering/lower-array-sort.js +331 -566
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +248 -43
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js +71 -16
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.js +420 -71
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +39 -558
- package/dist/frontend/lowering/lower-calls.js +2593 -5667
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +243 -242
- package/dist/frontend/lowering/lower-classes.js +1704 -727
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +35 -35
- package/dist/frontend/lowering/lower-comptime.js +39 -37
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +59 -31
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +5 -2
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +322 -85
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +19 -7
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +194 -194
- package/dist/frontend/lowering/lower-exprs.js +3455 -1153
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.d.ts +23 -0
- package/dist/frontend/lowering/lower-functions.js +449 -0
- package/dist/frontend/lowering/lower-functions.js.map +1 -0
- package/dist/frontend/lowering/lower-generators.js +121 -32
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +15 -4
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +479 -89
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +79 -79
- package/dist/frontend/lowering/lower-island.js +365 -273
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-island.test.js +7 -2
- package/dist/frontend/lowering/lower-island.test.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +17 -8
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +94 -94
- package/dist/frontend/lowering/lower-modules.js +612 -321
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.js +91 -20
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +25 -8
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.js +115 -34
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +1210 -290
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +148 -148
- package/dist/frontend/lowering/lower-stmts.js +2312 -984
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.test.js +13 -5
- package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +362 -90
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-system-errors.js +30 -8
- package/dist/frontend/lowering/lower-system-errors.js.map +1 -1
- package/dist/frontend/lowering/lower-test.js +40 -13
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.d.ts +31 -0
- package/dist/frontend/lowering/lower-timers.js +336 -0
- package/dist/frontend/lowering/lower-timers.js.map +1 -0
- package/dist/frontend/lowering/lower-url.d.ts +1 -1
- package/dist/frontend/lowering/lower-url.js +46 -13
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +21 -351
- package/dist/frontend/lowering/lowerer.js +1031 -2704
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +85 -17
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js +43 -8
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.d.ts +21 -1
- package/dist/frontend/lowering/native-ffi.js +487 -18
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-enumeration-receiver.js +55 -10
- package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.d.ts +1 -1
- package/dist/frontend/lowering/object-factory-new.js +36 -11
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.js +49 -20
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.js +66 -14
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-locals.js +3 -1
- package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.js +4 -1
- package/dist/frontend/lowering/sanitize-class-types.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +86 -18
- package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -1
- package/dist/frontend/lowering/static-this.js +13 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/string-index.js +32 -10
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +42 -42
- package/dist/frontend/lowering/surfaces.js +1094 -249
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.js +40 -15
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.js +236 -24
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.test.js +84 -12
- package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -1
- package/dist/frontend/lowering/union-narrow.js +59 -16
- package/dist/frontend/lowering/union-narrow.js.map +1 -1
- package/dist/frontend/lowering/union-narrow.test.js +24 -7
- package/dist/frontend/lowering/union-narrow.test.js.map +1 -1
- package/dist/frontend/lowering/union-retag.js +155 -40
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +131 -33
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/unregistered-class-types.js.map +1 -1
- package/dist/frontend/lowering/unregistered-class-types.test.js +34 -8
- package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +21 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/module-syntax.test.js +37 -13
- package/dist/frontend/module-syntax.test.js.map +1 -1
- package/dist/frontend/npm-fetch-analysis.js +13 -4
- package/dist/frontend/npm-fetch-analysis.js.map +1 -1
- package/dist/frontend/npm-fetch-analysis.test.js +33 -10
- package/dist/frontend/npm-fetch-analysis.test.js.map +1 -1
- package/dist/frontend/npm-fetch-node.js.map +1 -1
- package/dist/frontend/npm-fetch-syntax.js +4 -9
- package/dist/frontend/npm-fetch-syntax.js.map +1 -1
- package/dist/frontend/npm-node.js +3 -1
- package/dist/frontend/npm-node.js.map +1 -1
- package/dist/frontend/npm-static-bundled-cjs.js +88 -29
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-cjs.test.js +29 -10
- package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -1
- package/dist/frontend/npm-static-declaration-syntax.js +148 -56
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-declarations.d.ts +1 -1
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +33 -7
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +26 -12
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-prune.test.js +17 -3
- package/dist/frontend/npm-static-prune.test.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.js +2 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.js +64 -21
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +9 -4
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.test.js +30 -6
- package/dist/frontend/npm-static-subtyping.test.js.map +1 -1
- package/dist/frontend/npm-static.js +15 -4
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.js +122 -36
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +30 -10
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.js.map +1 -1
- package/dist/frontend/pipeline.js +25 -8
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +21 -7
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-node.js +5 -3
- package/dist/frontend/program-node.js.map +1 -1
- package/dist/frontend/program.d.ts +2 -2
- package/dist/frontend/program.js +234 -101
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +27 -27
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/provenance-core.js +8 -4
- package/dist/frontend/provenance-core.js.map +1 -1
- package/dist/frontend/provenance-registry.js +1 -4
- package/dist/frontend/provenance-registry.js.map +1 -1
- package/dist/frontend/resolve.js +32 -20
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +1 -1
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/runtime-resolve.js +13 -4
- package/dist/frontend/runtime-resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.test.js +25 -9
- package/dist/frontend/runtime-resolve.test.js.map +1 -1
- package/dist/frontend/services-node.js +6 -2
- package/dist/frontend/services-node.js.map +1 -1
- package/dist/frontend/services-node.test.js +18 -6
- package/dist/frontend/services-node.test.js.map +1 -1
- package/dist/frontend/services.js +8 -4
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +6 -2
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/ts7/api.js +12 -4
- package/dist/frontend/ts7/api.js.map +1 -1
- package/dist/frontend/ts7/ast-bytes.js +10 -3
- package/dist/frontend/ts7/ast-bytes.js.map +1 -1
- package/dist/frontend/ts7/ast-bytes.test.js +23 -4
- package/dist/frontend/ts7/ast-bytes.test.js.map +1 -1
- package/dist/frontend/ts7/ast-guards.test.js +14 -5
- package/dist/frontend/ts7/ast-guards.test.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +6 -1
- package/dist/frontend/ts7/ast-node.js +484 -164
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +109 -36
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-text.js +13 -3
- package/dist/frontend/ts7/ast-text.js.map +1 -1
- package/dist/frontend/ts7/ast-text.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.d.ts +1 -1
- package/dist/frontend/ts7/ast-wire.js +55 -20
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.test.js +53 -8
- package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
- package/dist/frontend/ts7/ast.js +47 -28
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/census-check.js +1 -1
- package/dist/frontend/ts7/census-check.js.map +1 -1
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.js +5 -3
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +54 -17
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/enums.test.js +9 -4
- package/dist/frontend/ts7/enums.test.js.map +1 -1
- package/dist/frontend/ts7/native-api.js.map +1 -1
- package/dist/frontend/ts7/native-host.js.map +1 -1
- package/dist/frontend/ts7/native-process.js +9 -3
- package/dist/frontend/ts7/native-process.js.map +1 -1
- package/dist/frontend/ts7/program-adapter.js +1 -1
- package/dist/frontend/ts7/program-adapter.js.map +1 -1
- package/dist/frontend/ts7/program-host.js +7 -4
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/program-host.test.js +43 -11
- package/dist/frontend/ts7/program-host.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.js +3 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/rpc-client.js +15 -5
- package/dist/frontend/ts7/rpc-client.js.map +1 -1
- package/dist/frontend/ts7/rpc-client.test.js +26 -8
- package/dist/frontend/ts7/rpc-client.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-filesystem.js.map +1 -1
- package/dist/frontend/ts7/rpc-filesystem.test.js +43 -10
- package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-process.js +16 -6
- package/dist/frontend/ts7/rpc-process.js.map +1 -1
- package/dist/frontend/ts7/rpc-process.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-wire.d.ts +1 -0
- package/dist/frontend/ts7/rpc-wire.js +41 -14
- package/dist/frontend/ts7/rpc-wire.js.map +1 -1
- package/dist/frontend/ts7/rpc-wire.test.js +36 -6
- package/dist/frontend/ts7/rpc-wire.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.js +209 -68
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +29 -14
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.js +7 -1
- package/dist/frontend/ts7/semantic-json.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.test.js +17 -3
- package/dist/frontend/ts7/semantic-json.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.js +147 -51
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +72 -19
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +2 -2
- package/dist/frontend/ts7/session-cache.js +10 -3
- package/dist/frontend/ts7/session-cache.js.map +1 -1
- package/dist/frontend/ts7/session-cache.test.js +13 -4
- package/dist/frontend/ts7/session-cache.test.js.map +1 -1
- package/dist/frontend/ts7/session-path.js +25 -10
- package/dist/frontend/ts7/session-path.js.map +1 -1
- package/dist/frontend/ts7/session-path.test.js +47 -4
- package/dist/frontend/ts7/session-path.test.js.map +1 -1
- package/dist/frontend/ts7/session-timing.js +22 -3
- package/dist/frontend/ts7/session-timing.js.map +1 -1
- package/dist/frontend/ts7/session-timing.test.js +12 -3
- package/dist/frontend/ts7/session-timing.test.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +1 -0
- package/dist/frontend/ts7/session.js +109 -35
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +69 -15
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.js +17 -6
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +32 -9
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/tsc-codes.js +56 -11
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/tsc-codes.test.d.ts +1 -0
- package/dist/frontend/tsc-codes.test.js +16 -0
- package/dist/frontend/tsc-codes.test.js.map +1 -0
- package/dist/frontend/type-mapper.js +547 -206
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +108 -33
- package/dist/frontend/type-mapper.test.js.map +1 -1
- package/dist/frontend/union-discriminants.js +8 -2
- package/dist/frontend/union-discriminants.js.map +1 -1
- package/dist/frontend/union-discriminants.test.js +77 -20
- package/dist/frontend/union-discriminants.test.js.map +1 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.js +150 -81
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +97 -38
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +91 -15
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/api.d.ts +4 -0
- package/dist/ir/api.js +6 -0
- package/dist/ir/api.js.map +1 -0
- package/dist/ir/build.d.ts +7 -0
- package/dist/ir/build.js +27 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.d.ts +9 -0
- package/dist/ir/builtin-effects.js +631 -0
- package/dist/ir/builtin-effects.js.map +1 -0
- package/dist/ir/builtin-signatures.d.ts +15 -0
- package/dist/ir/builtin-signatures.js +3396 -0
- package/dist/ir/builtin-signatures.js.map +1 -0
- package/dist/ir/byte-numbers.d.ts +20 -0
- package/dist/ir/byte-numbers.js +116 -0
- package/dist/ir/byte-numbers.js.map +1 -0
- package/dist/ir/byte-numbers.test.d.ts +1 -0
- package/dist/ir/byte-numbers.test.js +55 -0
- package/dist/ir/byte-numbers.test.js.map +1 -0
- package/dist/ir/constant-tables.js +13 -5
- package/dist/ir/constant-tables.js.map +1 -1
- package/dist/ir/constant-tables.test.js +47 -7
- package/dist/ir/constant-tables.test.js.map +1 -1
- package/dist/ir/control-flow.js +2 -1
- package/dist/ir/control-flow.js.map +1 -1
- package/dist/ir/control-flow.test.js +35 -11
- package/dist/ir/control-flow.test.js.map +1 -1
- package/dist/ir/initializer-bindings.d.ts +9 -0
- package/dist/ir/initializer-bindings.js +115 -0
- package/dist/ir/initializer-bindings.js.map +1 -0
- package/dist/ir/initializer-bindings.test.d.ts +1 -0
- package/dist/ir/initializer-bindings.test.js +118 -0
- package/dist/ir/initializer-bindings.test.js.map +1 -0
- package/dist/ir/integer-loop-facts.d.ts +12 -0
- package/dist/ir/integer-loop-facts.js +137 -0
- package/dist/ir/integer-loop-facts.js.map +1 -0
- package/dist/ir/integer-loops.d.ts +19 -0
- package/dist/ir/integer-loops.js +172 -11
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +122 -9
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +8 -6
- package/dist/ir/integer-ranges.js +416 -90
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +239 -10
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.d.ts +20 -0
- package/dist/ir/intrinsic-signatures.js +57 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -0
- package/dist/ir/ir.d.ts +14 -2155
- package/dist/ir/ir.js +169 -1394
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +98 -77
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +221 -0
- package/dist/ir/runtime-features.js +551 -0
- package/dist/ir/runtime-features.js.map +1 -0
- package/dist/ir/runtime-features.test.d.ts +1 -0
- package/dist/ir/runtime-features.test.js +98 -0
- package/dist/ir/runtime-features.test.js.map +1 -0
- package/dist/ir/scalar-records.js +130 -40
- package/dist/ir/scalar-records.js.map +1 -1
- package/dist/ir/scalar-records.test.js +146 -27
- package/dist/ir/scalar-records.test.js.map +1 -1
- package/dist/ir/serialize.js +4 -2
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +44 -9
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/traverse.js +156 -43
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +99 -24
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/validate.d.ts +1 -31
- package/dist/ir/validate.js +826 -1915
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +627 -111
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/cache-primitives.js +9 -10
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/cache-reset.test.js +2 -1
- package/dist/library/cache-reset.test.js.map +1 -1
- package/dist/library/compiler-self-identity.js +11 -5
- package/dist/library/compiler-self-identity.js.map +1 -1
- package/dist/library/compiler-self-identity.test.js +10 -3
- package/dist/library/compiler-self-identity.test.js.map +1 -1
- package/dist/library/fence-eval.js +24 -7
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/fence-eval.test.js +31 -7
- package/dist/library/fence-eval.test.js.map +1 -1
- package/dist/library/int-infer.js +199 -59
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +133 -57
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/ir-policy.d.ts +27 -0
- package/dist/library/ir-policy.js +232 -0
- package/dist/library/ir-policy.js.map +1 -0
- package/dist/library/library-cache.js +40 -17
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +24 -13
- package/dist/library/library-cache.test.js.map +1 -1
- package/dist/library/library-profile.js +68 -13
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +48 -20
- package/dist/library/prepare.js.map +1 -1
- package/dist/library/semantic-source.js +16 -14
- package/dist/library/semantic-source.js.map +1 -1
- package/dist/library/semantic-source.test.js +9 -14
- package/dist/library/semantic-source.test.js.map +1 -1
- package/dist/library/sidecar-validate.js +53 -12
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.js +85 -24
- package/dist/library/sidecar.js.map +1 -1
- package/dist/library/trap-teaching.js +11 -2
- package/dist/library/trap-teaching.js.map +1 -1
- package/dist/native/cache.js +10 -4
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cli.js +34 -9
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +167 -43
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +129 -32
- package/dist/native/compiler.test.js.map +1 -1
- package/dist/native/comptime.js +23 -7
- package/dist/native/comptime.js.map +1 -1
- package/dist/native/comptime.test.js +26 -6
- package/dist/native/comptime.test.js.map +1 -1
- package/dist/native/executable-cache.js +77 -27
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/executable-cache.test.js +41 -6
- package/dist/native/executable-cache.test.js.map +1 -1
- package/dist/native/file-identity.js +9 -2
- package/dist/native/file-identity.js.map +1 -1
- package/dist/native/file-identity.test.js.map +1 -1
- package/dist/native/library.js +50 -12
- package/dist/native/library.js.map +1 -1
- package/dist/native/prepare.js +119 -34
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +22 -6
- package/dist/native/prepare.test.js.map +1 -1
- package/dist/native/runtime-typescript.js +24 -11
- package/dist/native/runtime-typescript.js.map +1 -1
- package/dist/native/runtime-typescript.test.js.map +1 -1
- package/dist/native/sanitizer.js +71 -18
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/sanitizer.test.js +77 -20
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/task.js.map +1 -1
- package/dist/native/task.test.js +7 -2
- package/dist/native/task.test.js.map +1 -1
- package/dist/native/toolchain.js +74 -29
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +95 -18
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -1
- package/dist/startup-cache.js +1 -1
- package/dist/startup-cache.js.map +1 -1
- package/dist/timing.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +0 -601
- package/dist/frontend/lowering/lower-builtins.js +0 -8984
- package/dist/frontend/lowering/lower-builtins.js.map +0 -1
- package/dist/frontend/lowering/lower-containers.d.ts +0 -382
- package/dist/frontend/lowering/lower-containers.js +0 -7366
- package/dist/frontend/lowering/lower-containers.js.map +0 -1
|
@@ -0,0 +1,1646 @@
|
|
|
1
|
+
import { boolLit, countedFor, numLit, varRef } from "../../../ir/build.js";
|
|
2
|
+
import { InternalCompilerError } from "../../../errors.js";
|
|
3
|
+
import * as ts from "../../ts7/adapter.js";
|
|
4
|
+
import { BOOL, DYN, F64, STRING, UNDEFINED_T, VOID, arrayOf, funcOf, isUnitType, typeEquals, } from "../../../ir/ir.js";
|
|
5
|
+
import { isJsSourceFile, locOf } from "../../program.js";
|
|
6
|
+
import { buildArraySortFn } from "../lower-array-sort.js";
|
|
7
|
+
import { arrayIndexPresent, arrayValueRead, arrayValueStore, arrayValueType, currentArrayIndexPresent, } from "../array-values.js";
|
|
8
|
+
import { typeKey } from "../../type-mapper.js";
|
|
9
|
+
import { lowerArrayCallback, requireProducedArrayElement, callbackArrayElement, } from "./callback-arguments.js";
|
|
10
|
+
import { reverseArrayLoop, arrayLengthDeclaration, arrayCallbackParams, arrayCallbackLocals, callArrayCallback, } from "./array-iteration.js";
|
|
11
|
+
import { dynamicReceiverThrows } from "./dynamic-receivers.js";
|
|
12
|
+
/** `a.map(fn)` / `a.filter(fn)` / `a.forEach(fn)` desugar to a direct
|
|
13
|
+
* call of a synthetic module function — one per method + element/result
|
|
14
|
+
* type + callback-arity combination, interned — whose body is a plain
|
|
15
|
+
* loop over EXISTING IR nodes (varDecl/for/arrayGet/callValue/push/
|
|
16
|
+
* return). No new IR kinds, no backend or runtime involvement. JS
|
|
17
|
+
* semantics: the length is read ONCE up front (Array.prototype.map/
|
|
18
|
+
* filter/forEach cache it — elements appended by the callback are not
|
|
19
|
+
* visited), elements are read fresh each iteration, callbacks run
|
|
20
|
+
* left-to-right and receive whatever prefix of (element, index, array)
|
|
21
|
+
* they declare. */
|
|
22
|
+
export function lowerArrayHofCall(lowerer, call, access, method, elem) {
|
|
23
|
+
const loc = locOf(call);
|
|
24
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
25
|
+
const argNode = call.arguments[0];
|
|
26
|
+
if (!argNode)
|
|
27
|
+
lowerer.unsupported("SC1090", call, "this call form"); // tsc-guarded
|
|
28
|
+
const booleanFilter = method === "filter" &&
|
|
29
|
+
ts.isIdentifier(argNode) &&
|
|
30
|
+
argNode.text === "Boolean" &&
|
|
31
|
+
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(argNode) ?? undefined);
|
|
32
|
+
const valueT = arrayValueType(lowerer, elem);
|
|
33
|
+
if (booleanFilter) {
|
|
34
|
+
if (valueT.kind === "union")
|
|
35
|
+
lowerer.requireTruthyUnion(valueT.unionId, argNode);
|
|
36
|
+
if (valueT.kind === "dyn" ||
|
|
37
|
+
valueT.kind === "jsval" ||
|
|
38
|
+
valueT.kind === "void" ||
|
|
39
|
+
isUnitType(valueT)) {
|
|
40
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const callback = booleanFilter
|
|
44
|
+
? { fnArg: truthyFilterCallback(lowerer, valueT, loc), arity: 1 }
|
|
45
|
+
: lowerArrayCallback(lowerer, argNode, [valueT], arrayOf(elem));
|
|
46
|
+
const { fnArg, arity } = callback;
|
|
47
|
+
const fnRet = fnArg.type.ret;
|
|
48
|
+
if (method === "map" && (fnRet.kind === "void" || fnRet.kind === "func")) {
|
|
49
|
+
// The result array U[] is unrepresentable here (no void elements;
|
|
50
|
+
// the map helper's closure-returning form has no fixture-backed
|
|
51
|
+
// story yet).
|
|
52
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
53
|
+
}
|
|
54
|
+
if (method === "map")
|
|
55
|
+
requireProducedArrayElement(lowerer, call, "'.map()'", fnRet);
|
|
56
|
+
// JS applies ToBoolean to whatever the predicate answers, so a non-bool
|
|
57
|
+
// result is not an error — the filter loop wraps the call in the same
|
|
58
|
+
// toBool an `if` statement would apply. The island/dyn shapes, whose
|
|
59
|
+
// truthiness needs the engine, and void, whose real answer the ABI has
|
|
60
|
+
// already discarded, keep the fence. No separate
|
|
61
|
+
// requireTruthyUnion call belongs here: its check (no dyn/caught arm)
|
|
62
|
+
// IS filterPredicateOk's union branch, so it could never speak.
|
|
63
|
+
if (method === "filter" && !filterPredicateOk(lowerer, fnRet)) {
|
|
64
|
+
if (fnRet.kind === "void") {
|
|
65
|
+
lowerer.unsupported("SC1090", argNode, "'.filter()' with a void-returning predicate (the callback return value is erased before its truthiness can be tested)");
|
|
66
|
+
}
|
|
67
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
68
|
+
}
|
|
69
|
+
const outElem = method === "filter"
|
|
70
|
+
? filterResultElem(lowerer, call, argNode, elem, valueT, booleanFilter)
|
|
71
|
+
: callbackArrayElement(lowerer, call, fnRet);
|
|
72
|
+
const helper = arrayHofHelper(lowerer, method, elem, fnRet, arity, loc, outElem);
|
|
73
|
+
const resultType = method === "map" || method === "filter" ? arrayOf(outElem) : VOID;
|
|
74
|
+
return { kind: "call", callee: helper, args: [receiver, fnArg], type: resultType, loc };
|
|
75
|
+
}
|
|
76
|
+
/** The checker-selected element of a filter result, with the same trust
|
|
77
|
+
* boundary as the historical narrowing filter: an inferred inline type
|
|
78
|
+
* predicate may prove one source arm; a written predicate annotation may
|
|
79
|
+
* not. Boolean is safe when every discarded arm is a nullish unit. */
|
|
80
|
+
function filterResultElem(lowerer, call, argNode, elem, valueT, booleanFilter) {
|
|
81
|
+
const callT = lowerer.typeOf(call);
|
|
82
|
+
const result = lowerer.mapTypeOf(callT);
|
|
83
|
+
let outElem = result?.kind === "array" ? result.elem : elem;
|
|
84
|
+
const access = ts.isPropertyAccessExpression(call.expression) ? call.expression : null;
|
|
85
|
+
const checkerReceiver = access ? lowerer.mapTypeOf(lowerer.typeOf(access.expression)) : null;
|
|
86
|
+
// Equal checker elements mean the filter introduces no new refinement.
|
|
87
|
+
// Preserve the stored element layout even if an earlier predicate or
|
|
88
|
+
// evolving-any analysis changed the receiver's flow type.
|
|
89
|
+
if (result?.kind === "array" &&
|
|
90
|
+
checkerReceiver?.kind === "array" &&
|
|
91
|
+
typeEquals(result.elem, checkerReceiver.elem)) {
|
|
92
|
+
return elem;
|
|
93
|
+
}
|
|
94
|
+
if (!typeEquals(outElem, elem)) {
|
|
95
|
+
const contextual = lowerer.mapTypeOf(lowerer.checker.getContextualType(call) ?? callT);
|
|
96
|
+
if (contextual?.kind === "array" && typeEquals(contextual.elem, elem))
|
|
97
|
+
outElem = elem;
|
|
98
|
+
}
|
|
99
|
+
if (typeEquals(outElem, elem))
|
|
100
|
+
return elem;
|
|
101
|
+
const annotateEscape = "keep the receiver's element type instead — annotate the callback's return ': boolean' " +
|
|
102
|
+
"(the checker then skips the predicate) or annotate the result with the receiver's own " +
|
|
103
|
+
"element type — and narrow the elements after";
|
|
104
|
+
if (!booleanFilter) {
|
|
105
|
+
if (!ts.isArrowFunction(argNode) && !ts.isFunctionExpression(argNode)) {
|
|
106
|
+
lowerer.unsupported("SC1090", argNode, `narrowing '.filter' through a callback VALUE (only an inline callback whose predicate ` +
|
|
107
|
+
`the checker inferred can re-tag — ${annotateEscape})`);
|
|
108
|
+
}
|
|
109
|
+
if (argNode.type) {
|
|
110
|
+
lowerer.unsupported("SC1090", argNode, `narrowing '.filter' with a hand-written type predicate (a written 'x is T' is an ` +
|
|
111
|
+
`unchecked assertion nothing validates at runtime — ${annotateEscape})`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (valueT.kind !== "union" || lowerer.armTag(valueT.unionId, outElem) < 0) {
|
|
115
|
+
const multiArm = outElem.kind === "union";
|
|
116
|
+
lowerer.unsupported("SC1090", call, `'.filter' narrowing '${lowerer.fmt(elem)}' elements to ` +
|
|
117
|
+
`${multiArm ? `the multi-arm '${lowerer.fmt(outElem)}'` : `'${lowerer.fmt(outElem)}'`} ` +
|
|
118
|
+
`(${multiArm ? "only a SINGLE arm re-tags" : "only a single runtime arm re-tags"} — ${annotateEscape})`);
|
|
119
|
+
}
|
|
120
|
+
if (booleanFilter) {
|
|
121
|
+
const arms = lowerer.unions.get(valueT.unionId)?.arms ?? [];
|
|
122
|
+
if (arms.some((arm) => !typeEquals(arm, outElem) && !isUnitType(arm))) {
|
|
123
|
+
lowerer.unsupported("SC1090", call, `'.filter(Boolean)' narrowing '${lowerer.fmt(elem)}' to '${lowerer.fmt(outElem)}' ` +
|
|
124
|
+
"when another truthy arm could survive");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return outElem;
|
|
128
|
+
}
|
|
129
|
+
/** A native closure for the ambient Boolean callback. Reifying the
|
|
130
|
+
* JavaScript constructor itself is unnecessary; Array#filter only observes
|
|
131
|
+
* its one-argument ToBoolean result. */
|
|
132
|
+
function truthyFilterCallback(lowerer, valueT, loc) {
|
|
133
|
+
const fnT = { kind: "func", params: [valueT], ret: BOOL };
|
|
134
|
+
const key = `filterBoolean:${typeKey(valueT)}`;
|
|
135
|
+
let name = lowerer.arrHofHelpers.get(key);
|
|
136
|
+
if (!name) {
|
|
137
|
+
name = `%arr.filterBoolean.${lowerer.arrHofHelpers.size}`;
|
|
138
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
139
|
+
const value = varRef("v.0", valueT, loc);
|
|
140
|
+
lowerer.liftedFns.push({
|
|
141
|
+
name,
|
|
142
|
+
params: [{ localId: "v.0", name: "v", type: valueT }],
|
|
143
|
+
returnType: BOOL,
|
|
144
|
+
locals: [{ id: "v.0", name: "v", type: valueT, mutable: false }],
|
|
145
|
+
body: [{ kind: "return", value: { kind: "toBool", operand: value, type: BOOL, loc }, loc }],
|
|
146
|
+
loc,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
return { kind: "closure", fnName: name, captures: [], type: fnT, loc };
|
|
150
|
+
}
|
|
151
|
+
/** The predicate result kinds `.filter()` accepts. JS applies ToBoolean to
|
|
152
|
+
* whatever the callback answers, so a bool is not required: the scalars and
|
|
153
|
+
* the reference kinds have constant or by-value answers, checked-dynamic
|
|
154
|
+
* values ask their runtime kind, and a union is fine when every arm does.
|
|
155
|
+
* void/jsval/caught stay out — see below. */
|
|
156
|
+
function filterPredicateOk(lowerer, ret) {
|
|
157
|
+
if (ret.kind === "bool")
|
|
158
|
+
return true;
|
|
159
|
+
// VOID is a TYPE erasure, not a runtime value: TS lets a value-returning
|
|
160
|
+
// function sit in a void-returning slot (`const p: (n: number) => void =
|
|
161
|
+
// (n) => n`), so the predicate's real answer can be truthy while the
|
|
162
|
+
// compiled ABI has already discarded it. Treating void as constantly
|
|
163
|
+
// falsy would silently answer [] where Node answers [1]. Fenced until
|
|
164
|
+
// the returned value can be preserved through the void ABI.
|
|
165
|
+
// A checked-dynamic value retains its runtime kind, so scr_dyn_truthy can
|
|
166
|
+
// apply JavaScript ToBoolean exactly. Island and caught values stay out.
|
|
167
|
+
if (ret.kind === "void")
|
|
168
|
+
return false;
|
|
169
|
+
if (ret.kind === "dyn")
|
|
170
|
+
return true;
|
|
171
|
+
if (ret.kind === "jsval" || ret.kind === "caught")
|
|
172
|
+
return false;
|
|
173
|
+
if (ret.kind === "union") {
|
|
174
|
+
const def = lowerer.unions.get(ret.unionId);
|
|
175
|
+
return def !== undefined && def.arms.every((a) => a.kind !== "dyn" && a.kind !== "caught");
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
/** The filter loop's condition: the predicate's result put through JS
|
|
180
|
+
* ToBoolean. A bool answer is already the condition; everything else takes
|
|
181
|
+
* the same `toBool` wrapper an `if` statement would apply (a union answer
|
|
182
|
+
* routes through its interned per-arm truthy helper). */
|
|
183
|
+
function filterCond(call, fnRet, loc) {
|
|
184
|
+
if (fnRet.kind === "bool")
|
|
185
|
+
return call;
|
|
186
|
+
// No constant-false arm here: void is fenced at the call site, and a
|
|
187
|
+
// bare undefinedT/nullT return cannot arise (mapType sends `undefined`/
|
|
188
|
+
// `void` returns to void and a standalone `null` return to the unit-ONLY
|
|
189
|
+
// UNION, which routes through toBool below; ir/validate.ts rejects a
|
|
190
|
+
// bare unit return type outright). filterPredicateOk already rejected
|
|
191
|
+
// unsafe union arms (dyn/caught) at the call site, where a real node
|
|
192
|
+
// exists for the diagnostic. A bare dyn value is handled directly by
|
|
193
|
+
// the runtime's kind-aware ToBoolean.
|
|
194
|
+
return { kind: "toBool", operand: call, type: BOOL, loc };
|
|
195
|
+
}
|
|
196
|
+
/** Interned synthetic loop function for one (method, elem, fnRet, arity)
|
|
197
|
+
* combo. Named `%arr.<method>.<n>` ('%' keeps it out of the user
|
|
198
|
+
* namespace); rides `liftedFns` into the module like a lifted lambda (it
|
|
199
|
+
* is a plain function — no captures). */
|
|
200
|
+
function arrayHofHelper(lowerer, method, elem, fnRet, arity, loc, outElem = fnRet) {
|
|
201
|
+
const key = `${method}:${typeKey(elem)}:${typeKey(fnRet)}:${arity}:${typeKey(outElem)}`;
|
|
202
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
203
|
+
if (existing)
|
|
204
|
+
return existing;
|
|
205
|
+
const name = `%arr.${method}.${lowerer.arrHofHelpers.size}`;
|
|
206
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
207
|
+
lowerer.liftedFns.push(buildArrayHofFn(lowerer, name, method, elem, fnRet, arity, loc, outElem));
|
|
208
|
+
return name;
|
|
209
|
+
}
|
|
210
|
+
/** The TS 5.2+ callable-union array rule: a `T[] | U[]` receiver exposes
|
|
211
|
+
* common HOFs with a callback over `T | U`. The runtime value remains the
|
|
212
|
+
* original concrete array arm — never a copied `(T | U)[]` — and an
|
|
213
|
+
* arm-specific function adapter wraps the element and receiver arguments
|
|
214
|
+
* into the union-wide callback ABI. That preserves sparse-array reads,
|
|
215
|
+
* callback mutation, and the callback's third-argument identity. */
|
|
216
|
+
export function lowerArrayUnionHofCall(lowerer, call, access, receiverT) {
|
|
217
|
+
const method = access.name.text;
|
|
218
|
+
if (method !== "map" && method !== "forEach")
|
|
219
|
+
return null;
|
|
220
|
+
if (!lowerer.isStdlibMember(access))
|
|
221
|
+
return null;
|
|
222
|
+
const def = lowerer.unions.get(receiverT.unionId);
|
|
223
|
+
if (!def || def.arms.length < 2 || !def.arms.every((arm) => arm.kind === "array"))
|
|
224
|
+
return null;
|
|
225
|
+
if (call.arguments.length !== 1 || !call.arguments[0])
|
|
226
|
+
return null;
|
|
227
|
+
const arrays = def.arms;
|
|
228
|
+
const valueArms = [];
|
|
229
|
+
const addValueArm = (type) => {
|
|
230
|
+
if (type.kind === "dyn" ||
|
|
231
|
+
type.kind === "jsval" ||
|
|
232
|
+
type.kind === "caught" ||
|
|
233
|
+
type.kind === "void")
|
|
234
|
+
return false;
|
|
235
|
+
if (type.kind === "union") {
|
|
236
|
+
const inner = lowerer.unions.get(type.unionId);
|
|
237
|
+
if (!inner)
|
|
238
|
+
return false;
|
|
239
|
+
for (const arm of inner.arms) {
|
|
240
|
+
if (!valueArms.some((candidate) => typeEquals(candidate, arm)))
|
|
241
|
+
valueArms.push(arm);
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
if (!valueArms.some((candidate) => typeEquals(candidate, type)))
|
|
246
|
+
valueArms.push(type);
|
|
247
|
+
return true;
|
|
248
|
+
};
|
|
249
|
+
for (const array of arrays) {
|
|
250
|
+
if (!addValueArm(array.elem))
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
const valueT = valueArms.length === 1
|
|
254
|
+
? valueArms[0]
|
|
255
|
+
: { kind: "union", unionId: lowerer.unions.intern(valueArms) };
|
|
256
|
+
const argNode = call.arguments[0];
|
|
257
|
+
const { fnArg, arity } = lowerArrayCallback(lowerer, argNode, [valueT], receiverT);
|
|
258
|
+
const fnRet = fnArg.type.ret;
|
|
259
|
+
if (method === "map" && (fnRet.kind === "void" || fnRet.kind === "func")) {
|
|
260
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
261
|
+
}
|
|
262
|
+
if (method === "map")
|
|
263
|
+
requireProducedArrayElement(lowerer, call, "'.map()'", fnRet);
|
|
264
|
+
const outElem = method === "map" ? callbackArrayElement(lowerer, call, fnRet) : VOID;
|
|
265
|
+
const resultT = method === "map" ? arrayOf(outElem) : VOID;
|
|
266
|
+
for (const array of arrays) {
|
|
267
|
+
const armFnT = funcOf([arrayValueType(lowerer, array.elem), F64, array].slice(0, arity), fnRet);
|
|
268
|
+
if (!lowerer.cleanFuncAdaptable(fnArg.type, armFnT))
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
const helper = arrayUnionHofHelper(lowerer, method, receiverT, arrays, fnArg.type, arity, fnRet, outElem, locOf(call));
|
|
272
|
+
return {
|
|
273
|
+
kind: "call",
|
|
274
|
+
callee: helper,
|
|
275
|
+
args: [
|
|
276
|
+
lowerer.coerceInto(access.expression, lowerer.lowerExpr(access.expression), receiverT),
|
|
277
|
+
fnArg,
|
|
278
|
+
],
|
|
279
|
+
type: resultT,
|
|
280
|
+
loc: locOf(call),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function arrayUnionHofHelper(lowerer, method, receiverT, arrays, callbackT, arity, fnRet, outElem, loc) {
|
|
284
|
+
const resultT = method === "map" ? arrayOf(outElem) : VOID;
|
|
285
|
+
const key = `union:${method}:${receiverT.unionId}:${typeKey(callbackT)}:${typeKey(resultT)}`;
|
|
286
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
287
|
+
if (existing)
|
|
288
|
+
return existing;
|
|
289
|
+
const name = `%arr.union.${lowerer.arrHofHelpers.size}`;
|
|
290
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
291
|
+
const receiver = varRef("a.0", receiverT, loc);
|
|
292
|
+
const callback = varRef("f.0", callbackT, loc);
|
|
293
|
+
const branch = (array) => {
|
|
294
|
+
const tag = lowerer.armTag(receiverT.unionId, array);
|
|
295
|
+
const concrete = {
|
|
296
|
+
kind: "unionNarrow",
|
|
297
|
+
unionId: receiverT.unionId,
|
|
298
|
+
tag,
|
|
299
|
+
value: receiver,
|
|
300
|
+
type: array,
|
|
301
|
+
loc,
|
|
302
|
+
};
|
|
303
|
+
const armFnT = funcOf([arrayValueType(lowerer, array.elem), F64, array].slice(0, arity), fnRet);
|
|
304
|
+
const adapted = lowerer.coerceToExpected(callback, armFnT);
|
|
305
|
+
if (!typeEquals(adapted.type, armFnT)) {
|
|
306
|
+
throw new InternalCompilerError("lowerer bug: union-array callback stopped adapting");
|
|
307
|
+
}
|
|
308
|
+
const callee = arrayHofHelper(lowerer, method, array.elem, fnRet, arity, loc, outElem);
|
|
309
|
+
const invoke = { kind: "call", callee, args: [concrete, adapted], type: resultT, loc };
|
|
310
|
+
return resultT.kind === "void"
|
|
311
|
+
? [
|
|
312
|
+
{ kind: "exprStmt", expr: invoke, loc },
|
|
313
|
+
{ kind: "return", value: null, loc },
|
|
314
|
+
]
|
|
315
|
+
: [{ kind: "return", value: invoke, loc }];
|
|
316
|
+
};
|
|
317
|
+
let body = branch(arrays[arrays.length - 1]);
|
|
318
|
+
for (let i = arrays.length - 2; i >= 0; i--) {
|
|
319
|
+
const array = arrays[i];
|
|
320
|
+
body = [
|
|
321
|
+
{
|
|
322
|
+
kind: "if",
|
|
323
|
+
cond: {
|
|
324
|
+
kind: "unionIsTag",
|
|
325
|
+
unionId: receiverT.unionId,
|
|
326
|
+
tag: lowerer.armTag(receiverT.unionId, array),
|
|
327
|
+
negated: false,
|
|
328
|
+
value: receiver,
|
|
329
|
+
type: BOOL,
|
|
330
|
+
loc,
|
|
331
|
+
},
|
|
332
|
+
then: branch(array),
|
|
333
|
+
else_: body,
|
|
334
|
+
loc,
|
|
335
|
+
},
|
|
336
|
+
];
|
|
337
|
+
}
|
|
338
|
+
lowerer.liftedFns.push({
|
|
339
|
+
name,
|
|
340
|
+
params: [
|
|
341
|
+
{ localId: "a.0", name: "a", type: receiverT },
|
|
342
|
+
{ localId: "f.0", name: "f", type: callbackT },
|
|
343
|
+
],
|
|
344
|
+
returnType: resultT,
|
|
345
|
+
locals: [
|
|
346
|
+
{ id: "a.0", name: "a", type: receiverT, mutable: false },
|
|
347
|
+
{ id: "f.0", name: "f", type: callbackT, mutable: false },
|
|
348
|
+
],
|
|
349
|
+
body,
|
|
350
|
+
loc,
|
|
351
|
+
});
|
|
352
|
+
return name;
|
|
353
|
+
}
|
|
354
|
+
/** The loop body of one synthetic array HOF, from existing IR nodes:
|
|
355
|
+
*
|
|
356
|
+
* map: out = []; n = a.length; for (i = 0; i < n; i++) out.push(f(a[i])); return out;
|
|
357
|
+
* filter: out = []; n = a.length; for (...) { v = a[i]; if (f(v)) out.push(v); } return out;
|
|
358
|
+
* forEach: n = a.length; for (...) f(a[i]);
|
|
359
|
+
*
|
|
360
|
+
* `filter` reads the element once into `v` so the callback and the push
|
|
361
|
+
* see the same value even if the callback mutates `a[i]` (JS-exact).
|
|
362
|
+
* `arity` is the callback's declared parameter count (1–3): the loop
|
|
363
|
+
* passes the index and the receiver itself after the element when the
|
|
364
|
+
* callback names them, exactly the arguments JS supplies. */
|
|
365
|
+
function buildArrayHofFn(lowerer, name, method, elem, fnRet, arity, loc, outElem) {
|
|
366
|
+
const arrT = arrayOf(elem);
|
|
367
|
+
const valueT = arrayValueType(lowerer, elem);
|
|
368
|
+
const fnT = funcOf([arrayValueType(lowerer, elem), F64, arrT].slice(0, arity), fnRet);
|
|
369
|
+
const locals = arrayCallbackLocals(arrT, fnT);
|
|
370
|
+
const params = arrayCallbackParams(arrT, fnT);
|
|
371
|
+
const callF = (arg) => callArrayCallback(arrT, fnT, fnRet, arity, arg, loc);
|
|
372
|
+
const getElem = arrayValueRead(lowerer, varRef("a.0", arrT, loc), varRef("i.0", F64, loc), elem, loc);
|
|
373
|
+
const hasElem = {
|
|
374
|
+
kind: "arrayHas",
|
|
375
|
+
arr: varRef("a.0", arrT, loc),
|
|
376
|
+
index: varRef("i.0", F64, loc),
|
|
377
|
+
type: BOOL,
|
|
378
|
+
loc,
|
|
379
|
+
};
|
|
380
|
+
const readLen = arrayLengthDeclaration(arrT, loc);
|
|
381
|
+
const forLoop = (body) => countedFor(loc, varRef("n.0", F64, loc), () => body);
|
|
382
|
+
let returnType;
|
|
383
|
+
let body;
|
|
384
|
+
if (method === "map" || method === "flatMap") {
|
|
385
|
+
const outT = arrayOf(outElem);
|
|
386
|
+
locals.push({ id: "out.0", name: "out", type: outT, mutable: false }, { id: "mapped.0", name: "mapped", type: fnRet, mutable: false });
|
|
387
|
+
returnType = outT;
|
|
388
|
+
body = [
|
|
389
|
+
{
|
|
390
|
+
kind: "varDecl",
|
|
391
|
+
localId: "out.0",
|
|
392
|
+
init: { kind: "arrayLit", elems: [], type: outT, loc },
|
|
393
|
+
loc,
|
|
394
|
+
},
|
|
395
|
+
readLen,
|
|
396
|
+
...(method === "map"
|
|
397
|
+
? [
|
|
398
|
+
{
|
|
399
|
+
kind: "arraySetLength",
|
|
400
|
+
arr: varRef("out.0", outT, loc),
|
|
401
|
+
length: varRef("n.0", F64, loc),
|
|
402
|
+
loc,
|
|
403
|
+
},
|
|
404
|
+
]
|
|
405
|
+
: []),
|
|
406
|
+
forLoop([
|
|
407
|
+
{
|
|
408
|
+
kind: "if",
|
|
409
|
+
cond: hasElem,
|
|
410
|
+
then: [
|
|
411
|
+
{ kind: "varDecl", localId: "mapped.0", init: callF(getElem), loc },
|
|
412
|
+
arrayValueStore(lowerer, varRef("out.0", outT, loc), method === "map"
|
|
413
|
+
? varRef("i.0", F64, loc)
|
|
414
|
+
: {
|
|
415
|
+
kind: "arrIntrinsic",
|
|
416
|
+
method: "length",
|
|
417
|
+
receiver: varRef("out.0", outT, loc),
|
|
418
|
+
args: [],
|
|
419
|
+
type: F64,
|
|
420
|
+
loc,
|
|
421
|
+
}, varRef("mapped.0", fnRet, loc), outElem, loc),
|
|
422
|
+
],
|
|
423
|
+
else_: null,
|
|
424
|
+
loc,
|
|
425
|
+
},
|
|
426
|
+
]),
|
|
427
|
+
{ kind: "return", value: varRef("out.0", outT, loc), loc },
|
|
428
|
+
];
|
|
429
|
+
}
|
|
430
|
+
else if (method === "filter") {
|
|
431
|
+
const outT = arrayOf(outElem);
|
|
432
|
+
locals.push({ id: "out.0", name: "out", type: outT, mutable: false }, { id: "v.0", name: "v", type: valueT, mutable: false });
|
|
433
|
+
returnType = outT;
|
|
434
|
+
const retained = typeEquals(outElem, elem)
|
|
435
|
+
? varRef("v.0", valueT, loc)
|
|
436
|
+
: valueT.kind === "union"
|
|
437
|
+
? {
|
|
438
|
+
kind: "unionNarrow",
|
|
439
|
+
unionId: valueT.unionId,
|
|
440
|
+
tag: lowerer.armTag(valueT.unionId, outElem),
|
|
441
|
+
value: varRef("v.0", valueT, loc),
|
|
442
|
+
type: outElem,
|
|
443
|
+
loc,
|
|
444
|
+
}
|
|
445
|
+
: varRef("v.0", valueT, loc);
|
|
446
|
+
body = [
|
|
447
|
+
{
|
|
448
|
+
kind: "varDecl",
|
|
449
|
+
localId: "out.0",
|
|
450
|
+
init: { kind: "arrayLit", elems: [], type: outT, loc },
|
|
451
|
+
loc,
|
|
452
|
+
},
|
|
453
|
+
readLen,
|
|
454
|
+
forLoop([
|
|
455
|
+
{
|
|
456
|
+
kind: "if",
|
|
457
|
+
cond: hasElem,
|
|
458
|
+
then: [
|
|
459
|
+
{ kind: "varDecl", localId: "v.0", init: getElem, loc },
|
|
460
|
+
{
|
|
461
|
+
kind: "if",
|
|
462
|
+
// ToBoolean over the predicate's answer — inert when it already
|
|
463
|
+
// returned bool, the per-union helper when it returned a union.
|
|
464
|
+
cond: filterCond(callF(varRef("v.0", valueT, loc)), fnRet, loc),
|
|
465
|
+
then: [
|
|
466
|
+
arrayValueStore(lowerer, varRef("out.0", outT, loc), {
|
|
467
|
+
kind: "arrIntrinsic",
|
|
468
|
+
method: "length",
|
|
469
|
+
receiver: varRef("out.0", outT, loc),
|
|
470
|
+
args: [],
|
|
471
|
+
type: F64,
|
|
472
|
+
loc,
|
|
473
|
+
}, retained, outElem, loc),
|
|
474
|
+
],
|
|
475
|
+
else_: null,
|
|
476
|
+
loc,
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
else_: null,
|
|
480
|
+
loc,
|
|
481
|
+
},
|
|
482
|
+
]),
|
|
483
|
+
{ kind: "return", value: varRef("out.0", outT, loc), loc },
|
|
484
|
+
];
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
returnType = VOID;
|
|
488
|
+
body = [
|
|
489
|
+
readLen,
|
|
490
|
+
forLoop([
|
|
491
|
+
{
|
|
492
|
+
kind: "if",
|
|
493
|
+
cond: hasElem,
|
|
494
|
+
then: [{ kind: "exprStmt", expr: callF(getElem), loc }],
|
|
495
|
+
else_: null,
|
|
496
|
+
loc,
|
|
497
|
+
},
|
|
498
|
+
]),
|
|
499
|
+
];
|
|
500
|
+
}
|
|
501
|
+
return { name, params, returnType, locals, body, loc };
|
|
502
|
+
}
|
|
503
|
+
/** `a.find(f)` / `a.findIndex(f)` / `a.findLast(f)` / `a.findLastIndex(f)`
|
|
504
|
+
* / `a.some(f)` / `a.every(f)` — the early-return HOFs, same
|
|
505
|
+
* desugar-to-loop machinery. some/every return bool from a short-circuit
|
|
506
|
+
* loop; findIndex/findLastIndex return the first matching index or -1
|
|
507
|
+
* (plain f64 — no union). find/findLast return `T | undefined` — the
|
|
508
|
+
* checker's own result union —
|
|
509
|
+
* with the found element wrapped into its arm and the miss producing the
|
|
510
|
+
* undefined unit arm (for REF elements that arm is the unit instance, the
|
|
511
|
+
* standard union machinery). The Last pair is the SAME loop walked
|
|
512
|
+
* backwards (`i = n - 1; i >= 0; i--`), exactly the es2023 spec's
|
|
513
|
+
* descending index walk. Predicate results use JavaScript ToBoolean. */
|
|
514
|
+
export function lowerArrayFindLikeCall(lowerer, call, access, method, elem, bindUntyped = false) {
|
|
515
|
+
const loc = locOf(call);
|
|
516
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
517
|
+
const arrT = arrayOf(elem);
|
|
518
|
+
const argNode = call.arguments[0];
|
|
519
|
+
if (!argNode)
|
|
520
|
+
lowerer.unsupported("SC1090", call, "this call form"); // tsc-guarded
|
|
521
|
+
const { fnArg, arity } = lowerArrayCallback(lowerer, argNode, [arrayValueType(lowerer, elem)], arrT, bindUntyped);
|
|
522
|
+
// JS takes the ToBoolean of the predicate's result — allowed wherever
|
|
523
|
+
// that ToBoolean has a static answer (bool passes through; f64/string
|
|
524
|
+
// by value; a truthy-answerable union by its arm — the
|
|
525
|
+
// `packages.some((p) => p.scripts[name])` idiom, whose callback
|
|
526
|
+
// returns the index read's `string | undefined`).
|
|
527
|
+
const fnRet = fnArg.type.ret;
|
|
528
|
+
const truthyRet = fnRet.kind === "bool" ||
|
|
529
|
+
fnRet.kind === "f64" ||
|
|
530
|
+
fnRet.kind === "string" ||
|
|
531
|
+
fnRet.kind === "dyn" ||
|
|
532
|
+
(fnRet.kind === "union" &&
|
|
533
|
+
(lowerer.unions.get(fnRet.unionId)?.arms ?? []).every((a) => a.kind !== "dyn" && a.kind !== "caught" && a.kind !== "jsval"));
|
|
534
|
+
if (!truthyRet)
|
|
535
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
536
|
+
const last = method === "findLast" || method === "findLastIndex";
|
|
537
|
+
if (method === "some" ||
|
|
538
|
+
method === "every" ||
|
|
539
|
+
method === "findIndex" ||
|
|
540
|
+
method === "findLastIndex") {
|
|
541
|
+
const helper = method === "findIndex" || method === "findLastIndex"
|
|
542
|
+
? findIndexHelper(lowerer, elem, fnRet, arity, last, loc)
|
|
543
|
+
: someEveryHelper(lowerer, method, elem, fnRet, arity, loc);
|
|
544
|
+
return {
|
|
545
|
+
kind: "call",
|
|
546
|
+
callee: helper,
|
|
547
|
+
args: [receiver, fnArg],
|
|
548
|
+
type: method === "findIndex" || method === "findLastIndex" ? F64 : BOOL,
|
|
549
|
+
loc,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
// find visits holes as undefined and can infer a predicate that selects
|
|
553
|
+
// a subset of the element union. A result matching the receiver's flow
|
|
554
|
+
// element inherits that earlier refinement. Otherwise only an inline,
|
|
555
|
+
// inferred predicate proves a new narrowing; explicit assertions keep
|
|
556
|
+
// the same refusal boundary as filter.
|
|
557
|
+
const valueT = arrayValueType(lowerer, elem);
|
|
558
|
+
const checkerReceiver = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
559
|
+
const checkerResult = lowerer.irTypeOf(call);
|
|
560
|
+
const unchangedElement = checkerReceiver?.kind === "array" &&
|
|
561
|
+
typeEquals(checkerResult, arrayValueType(lowerer, checkerReceiver.elem));
|
|
562
|
+
const resultT = bindUntyped ? valueT : checkerResult;
|
|
563
|
+
if (resultT.kind !== "union")
|
|
564
|
+
lowerer.badType(call, lowerer.typeOf(call)); // defensive: T | undefined always maps to a union
|
|
565
|
+
const undefTag = lowerer.armTag(resultT.unionId, UNDEFINED_T);
|
|
566
|
+
if (undefTag < 0)
|
|
567
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
568
|
+
let retag = null;
|
|
569
|
+
if (!lowerer.coercibleValue(valueT, resultT)) {
|
|
570
|
+
const inline = ts.isArrowFunction(argNode) || ts.isFunctionExpression(argNode);
|
|
571
|
+
if (!unchangedElement && (!inline || argNode.type !== undefined)) {
|
|
572
|
+
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)`);
|
|
573
|
+
}
|
|
574
|
+
const signature = inline ? lowerer.checker.getSignatureFromDeclaration(argNode) : undefined;
|
|
575
|
+
const predicate = signature
|
|
576
|
+
? lowerer.checker.getTypePredicateOfSignature(signature)
|
|
577
|
+
: undefined;
|
|
578
|
+
if ((!unchangedElement && (!predicate || predicate.parameterIndex !== 0)) ||
|
|
579
|
+
valueT.kind !== "union") {
|
|
580
|
+
lowerer.unsupported("SC1090", call, `'.${method}' result narrowing without a predicate over its element`);
|
|
581
|
+
}
|
|
582
|
+
retag = lowerer.narrowedRetagHelper(call, valueT.unionId, resultT.unionId, loc);
|
|
583
|
+
if (retag === null)
|
|
584
|
+
lowerer.unsupported("SC1090", call, `'.${method}' narrowing to an incompatible result layout`);
|
|
585
|
+
}
|
|
586
|
+
const helper = findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc, retag);
|
|
587
|
+
return { kind: "call", callee: helper, args: [receiver, fnArg], type: resultT, loc };
|
|
588
|
+
}
|
|
589
|
+
/** ToBoolean of a predicate result inside a synthesized HOF helper — the
|
|
590
|
+
* ensureBool subset the find-like path admits (bool through; checked
|
|
591
|
+
* values via dynTest; f64/string/truthy-answerable unions via toBool). */
|
|
592
|
+
function predicateToBoolean(e) {
|
|
593
|
+
if (e.type.kind === "bool")
|
|
594
|
+
return e;
|
|
595
|
+
if (e.type.kind === "dyn")
|
|
596
|
+
return { kind: "dynTest", test: "truthy", value: e, type: BOOL, loc: e.loc };
|
|
597
|
+
return { kind: "toBool", operand: e, type: BOOL, loc: e.loc };
|
|
598
|
+
}
|
|
599
|
+
/** The find loop, from existing IR nodes:
|
|
600
|
+
*
|
|
601
|
+
* n = a.length;
|
|
602
|
+
* for (i = 0; i < n; i++) { v = a[i]; if (f(v)) return <v as result arm>; }
|
|
603
|
+
* return <undefined arm>;
|
|
604
|
+
*/
|
|
605
|
+
function findHelper(lowerer, elem, resultT, undefTag, fnRet, arity, last, loc, retag) {
|
|
606
|
+
const method = last ? "findLast" : "find";
|
|
607
|
+
const key = `${method}:${typeKey(elem)}:${typeKey(resultT)}:${typeKey(fnRet)}:${arity}`;
|
|
608
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
609
|
+
if (existing)
|
|
610
|
+
return existing;
|
|
611
|
+
const name = `%arr.${method}.${lowerer.arrHofHelpers.size}`;
|
|
612
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
613
|
+
const arrT = arrayOf(elem);
|
|
614
|
+
const fnT = funcOf([arrayValueType(lowerer, elem), F64, arrT].slice(0, arity), fnRet);
|
|
615
|
+
const valueT = arrayValueType(lowerer, elem);
|
|
616
|
+
const v = varRef("v.0", valueT, loc);
|
|
617
|
+
const found = retag === null
|
|
618
|
+
? lowerer.coerceToExpected(v, resultT)
|
|
619
|
+
: { kind: "call", callee: retag, args: [v], type: resultT, loc };
|
|
620
|
+
const miss = {
|
|
621
|
+
kind: "unionWrap",
|
|
622
|
+
unionId: resultT.unionId,
|
|
623
|
+
tag: undefTag,
|
|
624
|
+
value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc },
|
|
625
|
+
type: resultT,
|
|
626
|
+
loc,
|
|
627
|
+
};
|
|
628
|
+
const visitBody = [
|
|
629
|
+
{
|
|
630
|
+
kind: "varDecl",
|
|
631
|
+
localId: "v.0",
|
|
632
|
+
init: arrayValueRead(lowerer, varRef("a.0", arrT, loc), varRef("i.0", F64, loc), elem, loc),
|
|
633
|
+
loc,
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
kind: "if",
|
|
637
|
+
cond: predicateToBoolean(callArrayCallback(arrT, fnT, fnRet, arity, v, loc)),
|
|
638
|
+
then: [{ kind: "return", value: found, loc }],
|
|
639
|
+
else_: null,
|
|
640
|
+
loc,
|
|
641
|
+
},
|
|
642
|
+
];
|
|
643
|
+
const visit = visitBody;
|
|
644
|
+
const loop = last
|
|
645
|
+
? reverseArrayLoop(loc, visit)
|
|
646
|
+
: countedFor(loc, varRef("n.0", F64, loc), () => visit);
|
|
647
|
+
const body = [
|
|
648
|
+
arrayLengthDeclaration(arrT, loc),
|
|
649
|
+
loop,
|
|
650
|
+
{ kind: "return", value: miss, loc },
|
|
651
|
+
];
|
|
652
|
+
lowerer.liftedFns.push({
|
|
653
|
+
name,
|
|
654
|
+
params: arrayCallbackParams(arrT, fnT),
|
|
655
|
+
returnType: resultT,
|
|
656
|
+
locals: [
|
|
657
|
+
...arrayCallbackLocals(arrT, fnT),
|
|
658
|
+
{ id: "v.0", name: "v", type: valueT, mutable: false },
|
|
659
|
+
],
|
|
660
|
+
body,
|
|
661
|
+
loc,
|
|
662
|
+
});
|
|
663
|
+
return name;
|
|
664
|
+
}
|
|
665
|
+
/** The findIndex/findLastIndex loop — find's index-returning sibling, no
|
|
666
|
+
* union; findLastIndex is the identical loop walked backwards:
|
|
667
|
+
*
|
|
668
|
+
* n = a.length; for (...) if (f(a[i], i, a)) return i; return -1;
|
|
669
|
+
*/
|
|
670
|
+
function findIndexHelper(lowerer, elem, fnRet, arity, last, loc) {
|
|
671
|
+
const method = last ? "findLastIndex" : "findIndex";
|
|
672
|
+
const key = `${method}:${typeKey(elem)}:${typeKey(fnRet)}:${arity}`;
|
|
673
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
674
|
+
if (existing)
|
|
675
|
+
return existing;
|
|
676
|
+
const name = `%arr.${method}.${lowerer.arrHofHelpers.size}`;
|
|
677
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
678
|
+
const arrT = arrayOf(elem);
|
|
679
|
+
const fnT = funcOf([arrayValueType(lowerer, elem), F64, arrT].slice(0, arity), fnRet);
|
|
680
|
+
const visit = [
|
|
681
|
+
{
|
|
682
|
+
kind: "if",
|
|
683
|
+
cond: predicateToBoolean(callArrayCallback(arrT, fnT, fnRet, arity, arrayValueRead(lowerer, varRef("a.0", arrT, loc), varRef("i.0", F64, loc), elem, loc), loc)),
|
|
684
|
+
then: [{ kind: "return", value: varRef("i.0", F64, loc), loc }],
|
|
685
|
+
else_: null,
|
|
686
|
+
loc,
|
|
687
|
+
},
|
|
688
|
+
];
|
|
689
|
+
const loop = last
|
|
690
|
+
? reverseArrayLoop(loc, visit)
|
|
691
|
+
: countedFor(loc, varRef("n.0", F64, loc), () => visit);
|
|
692
|
+
const body = [
|
|
693
|
+
arrayLengthDeclaration(arrT, loc),
|
|
694
|
+
loop,
|
|
695
|
+
{ kind: "return", value: { kind: "numLit", value: -1, type: F64, loc }, loc },
|
|
696
|
+
];
|
|
697
|
+
lowerer.liftedFns.push({
|
|
698
|
+
name,
|
|
699
|
+
params: arrayCallbackParams(arrT, fnT),
|
|
700
|
+
returnType: F64,
|
|
701
|
+
locals: [...arrayCallbackLocals(arrT, fnT)],
|
|
702
|
+
body,
|
|
703
|
+
loc,
|
|
704
|
+
});
|
|
705
|
+
return name;
|
|
706
|
+
}
|
|
707
|
+
/** The some/every loops — short-circuit early returns, JS-exact:
|
|
708
|
+
*
|
|
709
|
+
* some: n = a.length; for (...) if (f(a[i])) return true; return false;
|
|
710
|
+
* every: n = a.length; for (...) if (!f(a[i])) return false; return true;
|
|
711
|
+
*/
|
|
712
|
+
function someEveryHelper(lowerer, method, elem, fnRet, arity, loc) {
|
|
713
|
+
const key = `${method}:${typeKey(elem)}:${typeKey(fnRet)}:${arity}`;
|
|
714
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
715
|
+
if (existing)
|
|
716
|
+
return existing;
|
|
717
|
+
const name = `%arr.${method}.${lowerer.arrHofHelpers.size}`;
|
|
718
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
719
|
+
const arrT = arrayOf(elem);
|
|
720
|
+
const fnT = funcOf([arrayValueType(lowerer, elem), F64, arrT].slice(0, arity), fnRet);
|
|
721
|
+
const callF = predicateToBoolean(callArrayCallback(arrT, fnT, fnRet, arity, arrayValueRead(lowerer, varRef("a.0", arrT, loc), varRef("i.0", F64, loc), elem, loc), loc));
|
|
722
|
+
const body = [
|
|
723
|
+
arrayLengthDeclaration(arrT, loc),
|
|
724
|
+
countedFor(loc, varRef("n.0", F64, loc), () => [
|
|
725
|
+
{
|
|
726
|
+
kind: "if",
|
|
727
|
+
cond: currentArrayIndexPresent(arrT, loc),
|
|
728
|
+
then: [
|
|
729
|
+
{
|
|
730
|
+
kind: "if",
|
|
731
|
+
cond: method === "some"
|
|
732
|
+
? callF
|
|
733
|
+
: { kind: "unary", op: "!", operand: callF, type: BOOL, loc },
|
|
734
|
+
then: [{ kind: "return", value: boolLit(method === "some", loc), loc }],
|
|
735
|
+
else_: null,
|
|
736
|
+
loc,
|
|
737
|
+
},
|
|
738
|
+
],
|
|
739
|
+
else_: null,
|
|
740
|
+
loc,
|
|
741
|
+
},
|
|
742
|
+
]),
|
|
743
|
+
{ kind: "return", value: boolLit(method !== "some", loc), loc },
|
|
744
|
+
];
|
|
745
|
+
lowerer.liftedFns.push({
|
|
746
|
+
name,
|
|
747
|
+
params: arrayCallbackParams(arrT, fnT),
|
|
748
|
+
returnType: BOOL,
|
|
749
|
+
locals: [...arrayCallbackLocals(arrT, fnT)],
|
|
750
|
+
body,
|
|
751
|
+
loc,
|
|
752
|
+
});
|
|
753
|
+
return name;
|
|
754
|
+
}
|
|
755
|
+
/** `a.flatMap(f)` — map plus a one-level flatten. A callback returning
|
|
756
|
+
* `U[]` appends the returned array's elements per receiver element; a
|
|
757
|
+
* callback returning a non-array U doesn't flatten (JS pushes it as-is),
|
|
758
|
+
* which IS map — those calls share map's interned helper. A union return
|
|
759
|
+
* mixing array and non-array arms would need a per-value flatten decision
|
|
760
|
+
* — fenced. */
|
|
761
|
+
export function lowerArrayFlatMapCall(lowerer, call, access, elem) {
|
|
762
|
+
const loc = locOf(call);
|
|
763
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
764
|
+
const arrT = arrayOf(elem);
|
|
765
|
+
const argNode = call.arguments[0];
|
|
766
|
+
if (!argNode)
|
|
767
|
+
lowerer.unsupported("SC1090", call, "this call form"); // tsc-guarded
|
|
768
|
+
const { fnArg, arity } = lowerArrayCallback(lowerer, argNode, [arrayValueType(lowerer, elem)], arrT);
|
|
769
|
+
const fnRet = fnArg.type.ret;
|
|
770
|
+
if (fnRet.kind === "dyn" ||
|
|
771
|
+
fnRet.kind === "jsval" ||
|
|
772
|
+
(fnRet.kind === "record" && lowerer.shapes.get(fnRet.shapeId)?.tuple)) {
|
|
773
|
+
return {
|
|
774
|
+
kind: "dynInvoke",
|
|
775
|
+
recv: { kind: "dynFrom", value: receiver, liveRef: true, type: DYN, loc },
|
|
776
|
+
method: "flatMap",
|
|
777
|
+
calleeName: access.getText(),
|
|
778
|
+
args: [{ kind: "dynFrom", value: fnArg, type: DYN, loc }],
|
|
779
|
+
type: DYN,
|
|
780
|
+
loc,
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
if (fnRet.kind === "union") {
|
|
784
|
+
const def = lowerer.unions.get(fnRet.unionId);
|
|
785
|
+
if (def?.arms.some((a) => a.kind === "array")) {
|
|
786
|
+
lowerer.unsupported("SC1090", argNode, "'.flatMap' callbacks returning a union with an array arm (whether one value flattens " +
|
|
787
|
+
"would be a per-element decision — return an array from every path instead)");
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
if (fnRet.kind !== "array") {
|
|
791
|
+
// Scalar results append densely; source holes do not produce output slots.
|
|
792
|
+
if (fnRet.kind === "void" || fnRet.kind === "func")
|
|
793
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
794
|
+
requireProducedArrayElement(lowerer, call, "'.flatMap()'", fnRet);
|
|
795
|
+
const outElem = callbackArrayElement(lowerer, call, fnRet);
|
|
796
|
+
const helper = arrayHofHelper(lowerer, "flatMap", elem, fnRet, arity, loc, outElem);
|
|
797
|
+
return { kind: "call", callee: helper, args: [receiver, fnArg], type: arrayOf(outElem), loc };
|
|
798
|
+
}
|
|
799
|
+
const helper = flatMapHelper(lowerer, elem, fnRet, arity, loc);
|
|
800
|
+
return { kind: "call", callee: helper, args: [receiver, fnArg], type: fnRet, loc };
|
|
801
|
+
}
|
|
802
|
+
/** The flatMap loop (array-returning callback), from existing IR nodes:
|
|
803
|
+
*
|
|
804
|
+
* out = []; n = a.length;
|
|
805
|
+
* for (i = 0; i < n; i++) {
|
|
806
|
+
* r = f(a[i]); m = r.length;
|
|
807
|
+
* for (j = 0; j < m; j++) out.push(r[j]);
|
|
808
|
+
* }
|
|
809
|
+
* return out;
|
|
810
|
+
*/
|
|
811
|
+
function flatMapHelper(lowerer, elem, fnRet, arity, loc) {
|
|
812
|
+
const key = `flatMap:${typeKey(elem)}:${typeKey(fnRet)}:${arity}`;
|
|
813
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
814
|
+
if (existing)
|
|
815
|
+
return existing;
|
|
816
|
+
const name = `%arr.flatMap.${lowerer.arrHofHelpers.size}`;
|
|
817
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
818
|
+
const arrT = arrayOf(elem);
|
|
819
|
+
const inner = fnRet.elem;
|
|
820
|
+
const fnT = funcOf([arrayValueType(lowerer, elem), F64, arrT].slice(0, arity), fnRet);
|
|
821
|
+
const innerLoop = {
|
|
822
|
+
kind: "for",
|
|
823
|
+
init: { kind: "varDecl", localId: "j.0", init: numLit(0, loc), loc },
|
|
824
|
+
cond: {
|
|
825
|
+
kind: "bin",
|
|
826
|
+
op: "<",
|
|
827
|
+
left: varRef("j.0", F64, loc),
|
|
828
|
+
right: varRef("m.0", F64, loc),
|
|
829
|
+
type: BOOL,
|
|
830
|
+
loc,
|
|
831
|
+
},
|
|
832
|
+
update: {
|
|
833
|
+
kind: "assign",
|
|
834
|
+
localId: "j.0",
|
|
835
|
+
value: {
|
|
836
|
+
kind: "bin",
|
|
837
|
+
op: "+",
|
|
838
|
+
left: varRef("j.0", F64, loc),
|
|
839
|
+
right: numLit(1, loc),
|
|
840
|
+
type: F64,
|
|
841
|
+
loc,
|
|
842
|
+
},
|
|
843
|
+
loc,
|
|
844
|
+
},
|
|
845
|
+
body: [
|
|
846
|
+
{
|
|
847
|
+
kind: "if",
|
|
848
|
+
cond: arrayIndexPresent(varRef("r.0", fnRet, loc), varRef("j.0", F64, loc), loc),
|
|
849
|
+
then: [
|
|
850
|
+
{
|
|
851
|
+
kind: "varDecl",
|
|
852
|
+
localId: "inner.0",
|
|
853
|
+
init: arrayValueRead(lowerer, varRef("r.0", fnRet, loc), varRef("j.0", F64, loc), inner, loc),
|
|
854
|
+
loc,
|
|
855
|
+
},
|
|
856
|
+
arrayValueStore(lowerer, varRef("out.0", fnRet, loc), {
|
|
857
|
+
kind: "arrIntrinsic",
|
|
858
|
+
method: "length",
|
|
859
|
+
receiver: varRef("out.0", fnRet, loc),
|
|
860
|
+
args: [],
|
|
861
|
+
type: F64,
|
|
862
|
+
loc,
|
|
863
|
+
}, varRef("inner.0", arrayValueType(lowerer, inner), loc), inner, loc),
|
|
864
|
+
],
|
|
865
|
+
else_: null,
|
|
866
|
+
loc,
|
|
867
|
+
},
|
|
868
|
+
],
|
|
869
|
+
loc,
|
|
870
|
+
};
|
|
871
|
+
const body = [
|
|
872
|
+
{
|
|
873
|
+
kind: "varDecl",
|
|
874
|
+
localId: "out.0",
|
|
875
|
+
init: { kind: "arrayLit", elems: [], type: fnRet, loc },
|
|
876
|
+
loc,
|
|
877
|
+
},
|
|
878
|
+
arrayLengthDeclaration(arrT, loc),
|
|
879
|
+
countedFor(loc, varRef("n.0", F64, loc), () => [
|
|
880
|
+
{
|
|
881
|
+
kind: "if",
|
|
882
|
+
cond: currentArrayIndexPresent(arrT, loc),
|
|
883
|
+
then: [
|
|
884
|
+
{
|
|
885
|
+
kind: "varDecl",
|
|
886
|
+
localId: "r.0",
|
|
887
|
+
init: callArrayCallback(arrT, fnT, fnRet, arity, arrayValueRead(lowerer, varRef("a.0", arrT, loc), varRef("i.0", F64, loc), elem, loc), loc),
|
|
888
|
+
loc,
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
kind: "varDecl",
|
|
892
|
+
localId: "m.0",
|
|
893
|
+
init: {
|
|
894
|
+
kind: "arrIntrinsic",
|
|
895
|
+
method: "length",
|
|
896
|
+
receiver: varRef("r.0", fnRet, loc),
|
|
897
|
+
args: [],
|
|
898
|
+
type: F64,
|
|
899
|
+
loc,
|
|
900
|
+
},
|
|
901
|
+
loc,
|
|
902
|
+
},
|
|
903
|
+
innerLoop,
|
|
904
|
+
],
|
|
905
|
+
else_: null,
|
|
906
|
+
loc,
|
|
907
|
+
},
|
|
908
|
+
]),
|
|
909
|
+
{ kind: "return", value: varRef("out.0", fnRet, loc), loc },
|
|
910
|
+
];
|
|
911
|
+
lowerer.liftedFns.push({
|
|
912
|
+
name,
|
|
913
|
+
params: arrayCallbackParams(arrT, fnT),
|
|
914
|
+
returnType: fnRet,
|
|
915
|
+
locals: [
|
|
916
|
+
...arrayCallbackLocals(arrT, fnT),
|
|
917
|
+
{ id: "out.0", name: "out", type: fnRet, mutable: false },
|
|
918
|
+
{ id: "r.0", name: "r", type: fnRet, mutable: false },
|
|
919
|
+
{ id: "m.0", name: "m", type: F64, mutable: false },
|
|
920
|
+
{ id: "j.0", name: "j", type: F64, mutable: true },
|
|
921
|
+
{ id: "inner.0", name: "inner", type: arrayValueType(lowerer, inner), mutable: false },
|
|
922
|
+
],
|
|
923
|
+
body,
|
|
924
|
+
loc,
|
|
925
|
+
});
|
|
926
|
+
return name;
|
|
927
|
+
}
|
|
928
|
+
/** `a.reduce(f)` / `a.reduce(f, init)` and reduceRight — both declared
|
|
929
|
+
* forms. The accumulator type is the call's own checked result: U with an
|
|
930
|
+
* initial value, the element type without one. The callback may declare
|
|
931
|
+
* any prefix of (acc, element, index, array). Without an initial value an
|
|
932
|
+
* empty receiver throws Node's exact TypeError at runtime. */
|
|
933
|
+
export function lowerArrayReduceCall(lowerer, call, access, method, elem) {
|
|
934
|
+
const loc = locOf(call);
|
|
935
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
936
|
+
const arrT = arrayOf(elem);
|
|
937
|
+
const argNode = call.arguments[0];
|
|
938
|
+
if (!argNode)
|
|
939
|
+
lowerer.unsupported("SC1090", call, "this call form"); // tsc-guarded
|
|
940
|
+
const hasInit = call.arguments.length === 2;
|
|
941
|
+
const accT = lowerer.runtimeOptionalReduceTypes.get(call) ??
|
|
942
|
+
(hasInit ? lowerer.irTypeOf(call) : arrayValueType(lowerer, elem));
|
|
943
|
+
if (accT.kind === "void" || accT.kind === "func")
|
|
944
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
945
|
+
const { fnArg, arity } = lowerArrayCallback(lowerer, argNode, [accT, arrayValueType(lowerer, elem)], arrT, false, accT);
|
|
946
|
+
const helper = reduceHelper(lowerer, method, elem, accT, fnArg.type.ret, arity, hasInit, loc);
|
|
947
|
+
const args = [receiver, fnArg];
|
|
948
|
+
if (hasInit)
|
|
949
|
+
args.push(lowerer.lowerExprExpecting(call.arguments[1], accT));
|
|
950
|
+
return { kind: "call", callee: helper, args, type: accT, loc };
|
|
951
|
+
}
|
|
952
|
+
/** The reduce/reduceRight loops, from existing IR nodes:
|
|
953
|
+
*
|
|
954
|
+
* with init: acc = z; n = a.length; for (...) acc = f(acc, a[i]); return acc;
|
|
955
|
+
* without init: n = a.length;
|
|
956
|
+
* if (n === 0) throw new TypeError("Reduce of empty array with no initial value");
|
|
957
|
+
* acc = a[<first>]; for (<rest>) acc = f(acc, a[i]); return acc;
|
|
958
|
+
*
|
|
959
|
+
* reduce walks 0→n-1, reduceRight n-1→0; the seed without an initial
|
|
960
|
+
* value is a[0] / a[n-1] and the loop starts one past it. The empty-array
|
|
961
|
+
* TypeError message is Node's, byte for byte. */
|
|
962
|
+
function reduceHelper(lowerer, method, elem, accT, fnRet, arity, hasInit, loc) {
|
|
963
|
+
const key = `${method}:${typeKey(elem)}:${typeKey(accT)}:${typeKey(fnRet)}:${arity}:${hasInit ? "init" : "seed"}`;
|
|
964
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
965
|
+
if (existing)
|
|
966
|
+
return existing;
|
|
967
|
+
const name = `%arr.${method}.${lowerer.arrHofHelpers.size}`;
|
|
968
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
969
|
+
const arrT = arrayOf(elem);
|
|
970
|
+
const fnT = funcOf([accT, arrayValueType(lowerer, elem), F64, arrT].slice(0, arity), fnRet);
|
|
971
|
+
const n = varRef("n.0", F64, loc);
|
|
972
|
+
const i = varRef("i.0", F64, loc);
|
|
973
|
+
const right = method === "reduceRight";
|
|
974
|
+
const at = (index) => arrayValueRead(lowerer, varRef("a.0", arrT, loc), index, elem, loc);
|
|
975
|
+
const locals = [
|
|
976
|
+
{ id: "a.0", name: "a", type: arrT, mutable: true },
|
|
977
|
+
{ id: "f.0", name: "f", type: fnT, mutable: true },
|
|
978
|
+
...(hasInit ? [{ id: "z.0", name: "z", type: accT, mutable: true }] : []),
|
|
979
|
+
{ id: "acc.0", name: "acc", type: accT, mutable: true },
|
|
980
|
+
{ id: "n.0", name: "n", type: F64, mutable: false },
|
|
981
|
+
{ id: "i.0", name: "i", type: F64, mutable: true },
|
|
982
|
+
];
|
|
983
|
+
const params = [
|
|
984
|
+
{ localId: "a.0", name: "a", type: arrT },
|
|
985
|
+
{ localId: "f.0", name: "f", type: fnT },
|
|
986
|
+
...(hasInit ? [{ localId: "z.0", name: "z", type: accT }] : []),
|
|
987
|
+
];
|
|
988
|
+
const start = right
|
|
989
|
+
? { kind: "bin", op: "-", left: n, right: numLit(1, loc), type: F64, loc }
|
|
990
|
+
: numLit(0, loc);
|
|
991
|
+
const inRange = right
|
|
992
|
+
? { kind: "bin", op: ">=", left: i, right: numLit(0, loc), type: BOOL, loc }
|
|
993
|
+
: { kind: "bin", op: "<", left: i, right: n, type: BOOL, loc };
|
|
994
|
+
const advance = {
|
|
995
|
+
kind: "assign",
|
|
996
|
+
localId: "i.0",
|
|
997
|
+
value: { kind: "bin", op: right ? "-" : "+", left: i, right: numLit(1, loc), type: F64, loc },
|
|
998
|
+
loc,
|
|
999
|
+
};
|
|
1000
|
+
const seedStmts = [
|
|
1001
|
+
{ kind: "varDecl", localId: "i.0", init: start, loc },
|
|
1002
|
+
...(hasInit
|
|
1003
|
+
? [
|
|
1004
|
+
{
|
|
1005
|
+
kind: "varDecl",
|
|
1006
|
+
localId: "acc.0",
|
|
1007
|
+
init: varRef("z.0", accT, loc),
|
|
1008
|
+
loc,
|
|
1009
|
+
},
|
|
1010
|
+
]
|
|
1011
|
+
: [
|
|
1012
|
+
{
|
|
1013
|
+
kind: "while",
|
|
1014
|
+
cond: {
|
|
1015
|
+
kind: "ternary",
|
|
1016
|
+
cond: inRange,
|
|
1017
|
+
then: {
|
|
1018
|
+
kind: "unary",
|
|
1019
|
+
op: "!",
|
|
1020
|
+
operand: currentArrayIndexPresent(arrT, loc),
|
|
1021
|
+
type: BOOL,
|
|
1022
|
+
loc,
|
|
1023
|
+
},
|
|
1024
|
+
else_: boolLit(false, loc),
|
|
1025
|
+
type: BOOL,
|
|
1026
|
+
loc,
|
|
1027
|
+
},
|
|
1028
|
+
body: [advance],
|
|
1029
|
+
loc,
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
kind: "if",
|
|
1033
|
+
cond: { kind: "unary", op: "!", operand: inRange, type: BOOL, loc },
|
|
1034
|
+
then: [
|
|
1035
|
+
{
|
|
1036
|
+
kind: "throw",
|
|
1037
|
+
value: {
|
|
1038
|
+
kind: "libCall",
|
|
1039
|
+
fn: "error.new",
|
|
1040
|
+
args: [
|
|
1041
|
+
{
|
|
1042
|
+
kind: "strLit",
|
|
1043
|
+
value: "Reduce of empty array with no initial value",
|
|
1044
|
+
type: STRING,
|
|
1045
|
+
loc,
|
|
1046
|
+
},
|
|
1047
|
+
],
|
|
1048
|
+
type: { kind: "object", className: "%TypeError" },
|
|
1049
|
+
loc,
|
|
1050
|
+
},
|
|
1051
|
+
loc,
|
|
1052
|
+
},
|
|
1053
|
+
],
|
|
1054
|
+
else_: null,
|
|
1055
|
+
loc,
|
|
1056
|
+
},
|
|
1057
|
+
{ kind: "varDecl", localId: "acc.0", init: lowerer.coerceToExpected(at(i), accT), loc },
|
|
1058
|
+
advance,
|
|
1059
|
+
]),
|
|
1060
|
+
];
|
|
1061
|
+
const loop = {
|
|
1062
|
+
kind: "for",
|
|
1063
|
+
init: null,
|
|
1064
|
+
cond: right
|
|
1065
|
+
? { kind: "bin", op: ">=", left: i, right: numLit(0, loc), type: BOOL, loc }
|
|
1066
|
+
: { kind: "bin", op: "<", left: i, right: n, type: BOOL, loc },
|
|
1067
|
+
update: {
|
|
1068
|
+
kind: "assign",
|
|
1069
|
+
localId: "i.0",
|
|
1070
|
+
value: { kind: "bin", op: right ? "-" : "+", left: i, right: numLit(1, loc), type: F64, loc },
|
|
1071
|
+
loc,
|
|
1072
|
+
},
|
|
1073
|
+
body: [
|
|
1074
|
+
{
|
|
1075
|
+
kind: "if",
|
|
1076
|
+
cond: currentArrayIndexPresent(arrT, loc),
|
|
1077
|
+
then: [
|
|
1078
|
+
{
|
|
1079
|
+
kind: "assign",
|
|
1080
|
+
localId: "acc.0",
|
|
1081
|
+
value: lowerer.coerceToExpected({
|
|
1082
|
+
kind: "callValue",
|
|
1083
|
+
callee: varRef("f.0", fnT, loc),
|
|
1084
|
+
args: [varRef("acc.0", accT, loc), at(i), i, varRef("a.0", arrT, loc)].slice(0, arity),
|
|
1085
|
+
type: fnRet,
|
|
1086
|
+
loc,
|
|
1087
|
+
}, accT),
|
|
1088
|
+
loc,
|
|
1089
|
+
},
|
|
1090
|
+
],
|
|
1091
|
+
else_: null,
|
|
1092
|
+
loc,
|
|
1093
|
+
},
|
|
1094
|
+
],
|
|
1095
|
+
loc,
|
|
1096
|
+
};
|
|
1097
|
+
const body = [
|
|
1098
|
+
arrayLengthDeclaration(arrT, loc),
|
|
1099
|
+
...seedStmts,
|
|
1100
|
+
loop,
|
|
1101
|
+
{ kind: "return", value: varRef("acc.0", accT, loc), loc },
|
|
1102
|
+
];
|
|
1103
|
+
lowerer.liftedFns.push({ name, params, returnType: accT, locals, body, loc });
|
|
1104
|
+
return name;
|
|
1105
|
+
}
|
|
1106
|
+
/** `a.sort(cmp)` / `a.toSorted(cmp)`, desugared to an interned synthetic
|
|
1107
|
+
* function like the other array HOFs. sort mutates and returns the receiver;
|
|
1108
|
+
* toSorted takes its shallow snapshot INSIDE the helper, after the receiver
|
|
1109
|
+
* and comparator expressions have both been evaluated, then sorts and
|
|
1110
|
+
* returns that copy without touching the receiver. The helper uses a stable
|
|
1111
|
+
* bottom-up merge sort with an ordered-boundary check: ordered inputs use a
|
|
1112
|
+
* linear number of comparator calls, but buffer movement remains O(n log n)
|
|
1113
|
+
* even when every boundary is already ordered. During a merge, an element
|
|
1114
|
+
* moves right only while cmp(left, right) > 0, so a NaN or 0 result keeps
|
|
1115
|
+
* the left element first. Undefined values sink without reaching the user
|
|
1116
|
+
* comparator. The callback sequence differs from V8's TimSort, so exact
|
|
1117
|
+
* order and count parity are not claimed; results agree for consistent
|
|
1118
|
+
* comparators. The comparator-less form lowers for STRING elements only —
|
|
1119
|
+
* JS's default converts every element to string and compares UTF-16 units,
|
|
1120
|
+
* so the interned synthesized comparator selects the runtime's code-unit
|
|
1121
|
+
* ordering rather than scriptc's documented code-point relational
|
|
1122
|
+
* operators. For numbers that default is the notorious string sort
|
|
1123
|
+
* ([10, 9, 1] → [1, 10, 9]), deliberately fenced toward an explicit
|
|
1124
|
+
* comparator. */
|
|
1125
|
+
export function lowerArraySortCall(lowerer, call, access, elem, arrT) {
|
|
1126
|
+
const loc = locOf(call);
|
|
1127
|
+
const method = access.name.text === "toSorted" ? "toSorted" : "sort";
|
|
1128
|
+
const copyFirst = method === "toSorted";
|
|
1129
|
+
if (call.arguments.length === 0 && elem.kind === "string") {
|
|
1130
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
1131
|
+
const cmp = defaultStringCmpHelper(lowerer, loc);
|
|
1132
|
+
const fnT = funcOf([STRING, STRING], F64);
|
|
1133
|
+
const key = `${method}:${typeKey(STRING)}:2`;
|
|
1134
|
+
let helper = lowerer.arrHofHelpers.get(key);
|
|
1135
|
+
if (!helper) {
|
|
1136
|
+
helper = `%arr.${method}.${lowerer.arrHofHelpers.size}`;
|
|
1137
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
1138
|
+
lowerer.liftedFns.push(buildArraySortFn(helper, STRING, 2, copyFirst, null, loc));
|
|
1139
|
+
}
|
|
1140
|
+
const fnArg = { kind: "closure", fnName: cmp, captures: [], type: fnT, loc };
|
|
1141
|
+
return { kind: "call", callee: helper, args: [receiver, fnArg], type: arrT, loc };
|
|
1142
|
+
}
|
|
1143
|
+
if (call.arguments.length !== 1) {
|
|
1144
|
+
lowerer.noLowering(`.${method} with ${call.arguments.length} arguments`, call, "the default string-conversion ordering lowers only for string[] — pass a comparator: " +
|
|
1145
|
+
`${method}((a, b) => a - b) for numbers`);
|
|
1146
|
+
}
|
|
1147
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
1148
|
+
const argNode = call.arguments[0];
|
|
1149
|
+
let fnArg = lowerer.lowerExpr(argNode);
|
|
1150
|
+
// Reusable JS comparators often accept checked values. Adapt the array's
|
|
1151
|
+
// element ABI just as other array callbacks do before sorting.
|
|
1152
|
+
if (fnArg.type.kind === "func" &&
|
|
1153
|
+
fnArg.type.params.length <= 2 &&
|
|
1154
|
+
fnArg.type.params.every((param) => lowerer.coercibleValue(elem, param))) {
|
|
1155
|
+
// Arithmetic on inferred JS values retains a checked result because
|
|
1156
|
+
// it can produce BigInt. The sort callback still requires a number.
|
|
1157
|
+
const result = fnArg.type.ret.kind === "dyn" && isJsSourceFile(argNode.getSourceFile())
|
|
1158
|
+
? F64
|
|
1159
|
+
: fnArg.type.ret;
|
|
1160
|
+
const expected = funcOf(fnArg.type.params.map(() => elem), result);
|
|
1161
|
+
if (!typeEquals(fnArg.type, expected))
|
|
1162
|
+
fnArg = lowerer.coerceToExpected(fnArg, expected);
|
|
1163
|
+
}
|
|
1164
|
+
// The comparator receives exactly (a, b); declaring a prefix is
|
|
1165
|
+
// ordinary TS. Its result must be number (the spec coerces arbitrary
|
|
1166
|
+
// results — no lowering for that).
|
|
1167
|
+
if (fnArg.type.kind !== "func" ||
|
|
1168
|
+
fnArg.type.params.length > 2 ||
|
|
1169
|
+
!fnArg.type.params.every((p) => typeEquals(p, elem)) ||
|
|
1170
|
+
fnArg.type.ret.kind !== "f64") {
|
|
1171
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
1172
|
+
}
|
|
1173
|
+
const arity = fnArg.type.params.length;
|
|
1174
|
+
const key = `${method}:${typeKey(elem)}:${arity}`;
|
|
1175
|
+
let helper = lowerer.arrHofHelpers.get(key);
|
|
1176
|
+
if (!helper) {
|
|
1177
|
+
helper = `%arr.${method}.${lowerer.arrHofHelpers.size}`;
|
|
1178
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
1179
|
+
const undefinedTag = elem.kind === "union" ? lowerer.armTag(elem.unionId, UNDEFINED_T) : -1;
|
|
1180
|
+
lowerer.liftedFns.push(buildArraySortFn(helper, elem, arity, copyFirst, undefinedTag >= 0 ? undefinedTag : null, loc));
|
|
1181
|
+
}
|
|
1182
|
+
return { kind: "call", callee: helper, args: [receiver, fnArg], type: arrT, loc };
|
|
1183
|
+
}
|
|
1184
|
+
/** JS's default sort comparator for STRING elements, interned once:
|
|
1185
|
+
*
|
|
1186
|
+
* (a, b) => a < b ? -1 : a > b ? 1 : 0
|
|
1187
|
+
*
|
|
1188
|
+
* The dedicated UTF-16 comparison flag keeps this exact across
|
|
1189
|
+
* supplementary-plane code points and U+E000..U+FFFF, where the runtime's
|
|
1190
|
+
* ordinary code-point relational order deliberately differs. */
|
|
1191
|
+
function defaultStringCmpHelper(lowerer, loc) {
|
|
1192
|
+
const key = "sortCmpStr";
|
|
1193
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
1194
|
+
if (existing)
|
|
1195
|
+
return existing;
|
|
1196
|
+
const name = `%arr.sortCmpStr`;
|
|
1197
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
1198
|
+
const cmp = (op) => ({
|
|
1199
|
+
kind: "strCmp",
|
|
1200
|
+
op,
|
|
1201
|
+
left: varRef("a.0", STRING, loc),
|
|
1202
|
+
right: varRef("b.0", STRING, loc),
|
|
1203
|
+
utf16: true,
|
|
1204
|
+
type: BOOL,
|
|
1205
|
+
loc,
|
|
1206
|
+
});
|
|
1207
|
+
const body = [
|
|
1208
|
+
{
|
|
1209
|
+
kind: "return",
|
|
1210
|
+
value: {
|
|
1211
|
+
kind: "ternary",
|
|
1212
|
+
cond: cmp("<"),
|
|
1213
|
+
then: numLit(-1, loc),
|
|
1214
|
+
else_: {
|
|
1215
|
+
kind: "ternary",
|
|
1216
|
+
cond: cmp(">"),
|
|
1217
|
+
then: numLit(1, loc),
|
|
1218
|
+
else_: numLit(0, loc),
|
|
1219
|
+
type: F64,
|
|
1220
|
+
loc,
|
|
1221
|
+
},
|
|
1222
|
+
type: F64,
|
|
1223
|
+
loc,
|
|
1224
|
+
},
|
|
1225
|
+
loc,
|
|
1226
|
+
},
|
|
1227
|
+
];
|
|
1228
|
+
lowerer.liftedFns.push({
|
|
1229
|
+
name,
|
|
1230
|
+
params: [
|
|
1231
|
+
{ localId: "a.0", name: "a", type: STRING },
|
|
1232
|
+
{ localId: "b.0", name: "b", type: STRING },
|
|
1233
|
+
],
|
|
1234
|
+
returnType: F64,
|
|
1235
|
+
locals: [
|
|
1236
|
+
{ id: "a.0", name: "a", type: STRING, mutable: true },
|
|
1237
|
+
{ id: "b.0", name: "b", type: STRING, mutable: true },
|
|
1238
|
+
],
|
|
1239
|
+
body,
|
|
1240
|
+
loc,
|
|
1241
|
+
});
|
|
1242
|
+
return name;
|
|
1243
|
+
}
|
|
1244
|
+
/** `d.filter(pred)` on a dyn receiver: the receiver must BE a dyn array
|
|
1245
|
+
* (else the Node-shaped TypeError above); the predicate runs per element
|
|
1246
|
+
* over the dyn value, and each SURVIVOR is validated-extracted into the
|
|
1247
|
+
* result's element type T — the type the checker already committed the
|
|
1248
|
+
* call to (the contextual `RouteMapping[]`/`string[]` slot). Extraction is
|
|
1249
|
+
* the checked-cast machinery: a survivor that doesn't fit T throws the
|
|
1250
|
+
* catchable TypeError instead of misreading (a LYING predicate is the only
|
|
1251
|
+
* way there). The result is a fresh STATIC array of extracted copies —
|
|
1252
|
+
* the dyn boundary's marshal-copy stance (SEMANTICS.md). Null when the
|
|
1253
|
+
* call shape isn't claimable (the method-call fence stays). */
|
|
1254
|
+
export function lowerDynArrayFilterCall(lowerer, call, access, recv) {
|
|
1255
|
+
if (call.arguments.length !== 1)
|
|
1256
|
+
return null;
|
|
1257
|
+
const argNode = call.arguments[0];
|
|
1258
|
+
const loc = locOf(call);
|
|
1259
|
+
// The result element type, from what the call flows INTO: the
|
|
1260
|
+
// contextual array (or the single array arm of a contextual union —
|
|
1261
|
+
// the `string[] | null` return slot), falling back to a type-guard
|
|
1262
|
+
// predicate's target (`(r: unknown) => r is T`). Both are tsc's own
|
|
1263
|
+
// verdicts on the element; the runtime check makes them honest.
|
|
1264
|
+
let elemT = null;
|
|
1265
|
+
const ctx = lowerer.checker.getContextualType(call);
|
|
1266
|
+
const ctxIr = ctx ? lowerer.mapTypeOf(ctx) : null;
|
|
1267
|
+
if (ctxIr?.kind === "array")
|
|
1268
|
+
elemT = ctxIr.elem;
|
|
1269
|
+
if (!elemT && ctxIr?.kind === "union") {
|
|
1270
|
+
const def = lowerer.unions.get(ctxIr.unionId);
|
|
1271
|
+
const arrayArms = def ? def.arms.filter((a) => a.kind === "array") : [];
|
|
1272
|
+
if (arrayArms.length === 1 && arrayArms[0].kind === "array")
|
|
1273
|
+
elemT = arrayArms[0].elem;
|
|
1274
|
+
}
|
|
1275
|
+
if (!elemT) {
|
|
1276
|
+
const sigs = lowerer.checker.getCallSignatures(lowerer.typeOf(argNode));
|
|
1277
|
+
const pred = sigs.length === 1 ? lowerer.checker.getTypePredicateOfSignature(sigs[0]) : undefined;
|
|
1278
|
+
if (pred?.type)
|
|
1279
|
+
elemT = lowerer.mapTypeOf(pred.type);
|
|
1280
|
+
}
|
|
1281
|
+
if (!elemT || !lowerer.jsonSafe(elemT)) {
|
|
1282
|
+
// No JSON-representable destination (`const failed = checks.filter(
|
|
1283
|
+
// fn)` in untyped JS — test/common's runCallChecks): the result
|
|
1284
|
+
// STAYS in the checked-dynamic tree — the runtime prototype dispatch (scr_dyn_invoke)
|
|
1285
|
+
// runs the real filter over the dyn array and the survivors keep
|
|
1286
|
+
// their dyn selves, no extraction needed. The typed-destination path
|
|
1287
|
+
// above stays preferred: it hands back a real T[].
|
|
1288
|
+
return null;
|
|
1289
|
+
}
|
|
1290
|
+
const { fnArg, arity } = lowerArrayCallback(lowerer, argNode, [DYN], DYN);
|
|
1291
|
+
if (fnArg.type.ret.kind !== "bool")
|
|
1292
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
1293
|
+
const helper = dynFilterHelper(lowerer, elemT, arity, loc);
|
|
1294
|
+
return {
|
|
1295
|
+
kind: "call",
|
|
1296
|
+
callee: helper,
|
|
1297
|
+
args: [
|
|
1298
|
+
recv,
|
|
1299
|
+
fnArg,
|
|
1300
|
+
{ kind: "strLit", value: access.name.text, type: STRING, loc },
|
|
1301
|
+
{ kind: "strLit", value: access.getText(), type: STRING, loc },
|
|
1302
|
+
],
|
|
1303
|
+
type: arrayOf(elemT),
|
|
1304
|
+
loc,
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
/** `.flatMap(f)` on a dyn ('unknown'/`any[]`-narrowed) receiver where the
|
|
1308
|
+
* callback returns a STATIC array (`parsed.flatMap((v) => typeof v ===
|
|
1309
|
+
* "string" ? parseTldList(v) : [])` — the tlds-file shape): the checked-dynamic tree
|
|
1310
|
+
* array walks element-by-element, the callback sees each element as the
|
|
1311
|
+
* dyn value `unknown` code sees, and its typed results concatenate —
|
|
1312
|
+
* depth-1 flatten by construction, no validation needed on the results
|
|
1313
|
+
* (they are already typed; only the RECEIVER is dynamic). Non-array
|
|
1314
|
+
* receivers throw the Node-shaped TypeError. Callbacks returning
|
|
1315
|
+
* NON-array values (JS would keep them as single elements) or dynamic
|
|
1316
|
+
* results keep the fence — nothing drives them yet. */
|
|
1317
|
+
export function lowerDynArrayFlatMapCall(lowerer, call, access, recv) {
|
|
1318
|
+
if (call.arguments.length !== 1)
|
|
1319
|
+
return null;
|
|
1320
|
+
const argNode = call.arguments[0];
|
|
1321
|
+
const loc = locOf(call);
|
|
1322
|
+
const { fnArg, arity } = lowerArrayCallback(lowerer, argNode, [DYN], DYN);
|
|
1323
|
+
const ret = fnArg.type.ret;
|
|
1324
|
+
if (ret.kind !== "array") {
|
|
1325
|
+
// A DYNAMIC-returning callback (`plugins.flatMap((plugin) =>
|
|
1326
|
+
// plugin.languages ?? [])` — the getSupportInfo shape, where the
|
|
1327
|
+
// callback's members ride the checked-dynamic tree): the call dispatches on the
|
|
1328
|
+
// RECEIVER's runtime kind (dynInvoke) with the callback boxed —
|
|
1329
|
+
// a wrapped ISLAND receiver runs the ENGINE's own JS-exact
|
|
1330
|
+
// Array.prototype.flatMap (the routed-ops lane), a native dyn
|
|
1331
|
+
// array runs the runtime's flatMap, and non-arrays throw Node's
|
|
1332
|
+
// TypeError. The result stays dyn, checked per use.
|
|
1333
|
+
if (ret.kind === "dyn" || ret.kind === "jsval") {
|
|
1334
|
+
const boxed = { kind: "dynFrom", value: fnArg, type: DYN, loc };
|
|
1335
|
+
return {
|
|
1336
|
+
kind: "dynInvoke",
|
|
1337
|
+
recv,
|
|
1338
|
+
method: "flatMap",
|
|
1339
|
+
calleeName: access.getText(),
|
|
1340
|
+
args: [boxed],
|
|
1341
|
+
type: DYN,
|
|
1342
|
+
loc,
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
lowerer.unsupported("SC1090", call, `'.flatMap' on 'unknown' receivers whose callback returns '${lowerer.fmt(ret)}' ` +
|
|
1346
|
+
`(only callbacks returning a typed ARRAY compile — the results concatenate ` +
|
|
1347
|
+
`without validation; return one-element/empty arrays instead of bare values)`);
|
|
1348
|
+
}
|
|
1349
|
+
const helper = dynFlatMapHelper(lowerer, ret.elem, arity, loc);
|
|
1350
|
+
return {
|
|
1351
|
+
kind: "call",
|
|
1352
|
+
callee: helper,
|
|
1353
|
+
args: [
|
|
1354
|
+
recv,
|
|
1355
|
+
fnArg,
|
|
1356
|
+
{ kind: "strLit", value: access.name.text, type: STRING, loc },
|
|
1357
|
+
{ kind: "strLit", value: access.getText(), type: STRING, loc },
|
|
1358
|
+
],
|
|
1359
|
+
type: arrayOf(ret.elem),
|
|
1360
|
+
loc,
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
/** Interned `%dyn.flatmap.<n>` — one per (element type, callback arity). */
|
|
1364
|
+
function dynFlatMapHelper(lowerer, elemT, arity, loc) {
|
|
1365
|
+
const key = `dynflatmap:${typeKey(elemT)}:${arity}`;
|
|
1366
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
1367
|
+
if (existing)
|
|
1368
|
+
return existing;
|
|
1369
|
+
const name = `%dyn.flatmap.${lowerer.arrHofHelpers.size}`;
|
|
1370
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
1371
|
+
lowerer.liftedFns.push(buildDynFlatMapFn(name, elemT, arity, loc));
|
|
1372
|
+
return name;
|
|
1373
|
+
}
|
|
1374
|
+
/** out = []; n = d.length; for (i..n) { v = d[i]; r = f(v, i, d); for
|
|
1375
|
+
* (j..r.length) out.push(r[j]); } return out; — the receiver-kind gate up
|
|
1376
|
+
* front, the length read once, elements through the canonical-index keyed
|
|
1377
|
+
* read (buildDynFilterFn's discipline). */
|
|
1378
|
+
function buildDynFlatMapFn(name, elemT, arity, loc) {
|
|
1379
|
+
const outT = arrayOf(elemT);
|
|
1380
|
+
const retT = arrayOf(elemT);
|
|
1381
|
+
const fnT = funcOf([DYN, F64, DYN].slice(0, arity), retT);
|
|
1382
|
+
const d = varRef("d.0", DYN, loc);
|
|
1383
|
+
const body = [
|
|
1384
|
+
{
|
|
1385
|
+
kind: "if",
|
|
1386
|
+
cond: { kind: "dynTest", test: "array", negated: true, value: d, type: BOOL, loc },
|
|
1387
|
+
then: dynamicReceiverThrows(d, varRef("m.0", STRING, loc), varRef("full.0", STRING, loc), loc),
|
|
1388
|
+
else_: null,
|
|
1389
|
+
loc,
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
kind: "varDecl",
|
|
1393
|
+
localId: "n.0",
|
|
1394
|
+
init: {
|
|
1395
|
+
kind: "dynCheck",
|
|
1396
|
+
value: {
|
|
1397
|
+
kind: "dynKeyGet",
|
|
1398
|
+
key: { kind: "strLit", value: "length", type: STRING, loc },
|
|
1399
|
+
value: d,
|
|
1400
|
+
type: DYN,
|
|
1401
|
+
loc,
|
|
1402
|
+
},
|
|
1403
|
+
type: F64,
|
|
1404
|
+
loc,
|
|
1405
|
+
},
|
|
1406
|
+
loc,
|
|
1407
|
+
},
|
|
1408
|
+
{
|
|
1409
|
+
kind: "varDecl",
|
|
1410
|
+
localId: "out.0",
|
|
1411
|
+
init: { kind: "arrayLit", elems: [], type: outT, loc },
|
|
1412
|
+
loc,
|
|
1413
|
+
},
|
|
1414
|
+
countedFor(loc, varRef("n.0", F64, loc), () => [
|
|
1415
|
+
{
|
|
1416
|
+
kind: "varDecl",
|
|
1417
|
+
localId: "v.0",
|
|
1418
|
+
init: {
|
|
1419
|
+
kind: "dynKeyGet",
|
|
1420
|
+
key: { kind: "toString", operand: varRef("i.0", F64, loc), type: STRING, loc },
|
|
1421
|
+
value: d,
|
|
1422
|
+
type: DYN,
|
|
1423
|
+
loc,
|
|
1424
|
+
},
|
|
1425
|
+
loc,
|
|
1426
|
+
},
|
|
1427
|
+
{
|
|
1428
|
+
kind: "varDecl",
|
|
1429
|
+
localId: "r.0",
|
|
1430
|
+
init: {
|
|
1431
|
+
kind: "callValue",
|
|
1432
|
+
callee: varRef("f.0", fnT, loc),
|
|
1433
|
+
args: [varRef("v.0", DYN, loc), varRef("i.0", F64, loc), d].slice(0, arity),
|
|
1434
|
+
type: retT,
|
|
1435
|
+
loc,
|
|
1436
|
+
},
|
|
1437
|
+
loc,
|
|
1438
|
+
},
|
|
1439
|
+
{
|
|
1440
|
+
kind: "varDecl",
|
|
1441
|
+
localId: "rn.0",
|
|
1442
|
+
init: {
|
|
1443
|
+
kind: "arrIntrinsic",
|
|
1444
|
+
method: "length",
|
|
1445
|
+
receiver: varRef("r.0", retT, loc),
|
|
1446
|
+
args: [],
|
|
1447
|
+
type: F64,
|
|
1448
|
+
loc,
|
|
1449
|
+
},
|
|
1450
|
+
loc,
|
|
1451
|
+
},
|
|
1452
|
+
{
|
|
1453
|
+
kind: "for",
|
|
1454
|
+
init: { kind: "varDecl", localId: "j.0", init: numLit(0, loc), loc },
|
|
1455
|
+
cond: {
|
|
1456
|
+
kind: "bin",
|
|
1457
|
+
op: "<",
|
|
1458
|
+
left: varRef("j.0", F64, loc),
|
|
1459
|
+
right: varRef("rn.0", F64, loc),
|
|
1460
|
+
type: BOOL,
|
|
1461
|
+
loc,
|
|
1462
|
+
},
|
|
1463
|
+
update: {
|
|
1464
|
+
kind: "assign",
|
|
1465
|
+
localId: "j.0",
|
|
1466
|
+
value: {
|
|
1467
|
+
kind: "bin",
|
|
1468
|
+
op: "+",
|
|
1469
|
+
left: varRef("j.0", F64, loc),
|
|
1470
|
+
right: numLit(1, loc),
|
|
1471
|
+
type: F64,
|
|
1472
|
+
loc,
|
|
1473
|
+
},
|
|
1474
|
+
loc,
|
|
1475
|
+
},
|
|
1476
|
+
body: [
|
|
1477
|
+
{
|
|
1478
|
+
kind: "exprStmt",
|
|
1479
|
+
expr: {
|
|
1480
|
+
kind: "arrIntrinsic",
|
|
1481
|
+
method: "push",
|
|
1482
|
+
receiver: varRef("out.0", outT, loc),
|
|
1483
|
+
args: [
|
|
1484
|
+
{
|
|
1485
|
+
kind: "arrayGet",
|
|
1486
|
+
arr: varRef("r.0", retT, loc),
|
|
1487
|
+
index: varRef("j.0", F64, loc),
|
|
1488
|
+
type: elemT,
|
|
1489
|
+
loc,
|
|
1490
|
+
},
|
|
1491
|
+
],
|
|
1492
|
+
type: F64,
|
|
1493
|
+
loc,
|
|
1494
|
+
},
|
|
1495
|
+
loc,
|
|
1496
|
+
},
|
|
1497
|
+
],
|
|
1498
|
+
loc,
|
|
1499
|
+
},
|
|
1500
|
+
]),
|
|
1501
|
+
{ kind: "return", value: varRef("out.0", outT, loc), loc },
|
|
1502
|
+
];
|
|
1503
|
+
return {
|
|
1504
|
+
name,
|
|
1505
|
+
params: [
|
|
1506
|
+
{ localId: "d.0", name: "d", type: DYN },
|
|
1507
|
+
{ localId: "f.0", name: "f", type: fnT },
|
|
1508
|
+
{ localId: "m.0", name: "m", type: STRING },
|
|
1509
|
+
{ localId: "full.0", name: "full", type: STRING },
|
|
1510
|
+
],
|
|
1511
|
+
returnType: outT,
|
|
1512
|
+
locals: [
|
|
1513
|
+
{ id: "d.0", name: "d", type: DYN, mutable: false },
|
|
1514
|
+
{ id: "f.0", name: "f", type: fnT, mutable: false },
|
|
1515
|
+
{ id: "m.0", name: "m", type: STRING, mutable: false },
|
|
1516
|
+
{ id: "full.0", name: "full", type: STRING, mutable: false },
|
|
1517
|
+
{ id: "n.0", name: "n", type: F64, mutable: false },
|
|
1518
|
+
{ id: "i.0", name: "i", type: F64, mutable: true },
|
|
1519
|
+
{ id: "v.0", name: "v", type: DYN, mutable: false },
|
|
1520
|
+
{ id: "r.0", name: "r", type: retT, mutable: false },
|
|
1521
|
+
{ id: "rn.0", name: "rn", type: F64, mutable: false },
|
|
1522
|
+
{ id: "j.0", name: "j", type: F64, mutable: true },
|
|
1523
|
+
{ id: "out.0", name: "out", type: outT, mutable: false },
|
|
1524
|
+
],
|
|
1525
|
+
body,
|
|
1526
|
+
loc,
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1529
|
+
/** Interned `%dyn.filter.<n>` — one per (element type, callback arity). */
|
|
1530
|
+
function dynFilterHelper(lowerer, elemT, arity, loc) {
|
|
1531
|
+
const key = `dynfilter:${typeKey(elemT)}:${arity}`;
|
|
1532
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
1533
|
+
if (existing)
|
|
1534
|
+
return existing;
|
|
1535
|
+
const name = `%dyn.filter.${lowerer.arrHofHelpers.size}`;
|
|
1536
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
1537
|
+
lowerer.liftedFns.push(buildDynFilterFn(name, elemT, arity, loc));
|
|
1538
|
+
return name;
|
|
1539
|
+
}
|
|
1540
|
+
/** out = []; n = d.length; for (i..n) { v = d[i]; if (f(v, i, d)) out.push(
|
|
1541
|
+
* check<T>(v)); } return out; — with the receiver-kind gate up front. The
|
|
1542
|
+
* length reads ONCE (the checked-dynamic tree is immutable under the static surface), the
|
|
1543
|
+
* element reads through the canonical-index keyed read, the callback gets
|
|
1544
|
+
* whatever prefix of (element, index, receiver) it declares — the element
|
|
1545
|
+
* and receiver as dyn values, exactly what `unknown` code sees. */
|
|
1546
|
+
function buildDynFilterFn(name, elemT, arity, loc) {
|
|
1547
|
+
const outT = arrayOf(elemT);
|
|
1548
|
+
const fnT = funcOf([DYN, F64, DYN].slice(0, arity), BOOL);
|
|
1549
|
+
const d = varRef("d.0", DYN, loc);
|
|
1550
|
+
const body = [
|
|
1551
|
+
{
|
|
1552
|
+
kind: "if",
|
|
1553
|
+
cond: { kind: "dynTest", test: "array", negated: true, value: d, type: BOOL, loc },
|
|
1554
|
+
then: dynamicReceiverThrows(d, varRef("m.0", STRING, loc), varRef("full.0", STRING, loc), loc),
|
|
1555
|
+
else_: null,
|
|
1556
|
+
loc,
|
|
1557
|
+
},
|
|
1558
|
+
{
|
|
1559
|
+
kind: "varDecl",
|
|
1560
|
+
localId: "n.0",
|
|
1561
|
+
init: {
|
|
1562
|
+
kind: "dynCheck",
|
|
1563
|
+
value: {
|
|
1564
|
+
kind: "dynKeyGet",
|
|
1565
|
+
key: { kind: "strLit", value: "length", type: STRING, loc },
|
|
1566
|
+
value: d,
|
|
1567
|
+
type: DYN,
|
|
1568
|
+
loc,
|
|
1569
|
+
},
|
|
1570
|
+
type: F64,
|
|
1571
|
+
loc,
|
|
1572
|
+
},
|
|
1573
|
+
loc,
|
|
1574
|
+
},
|
|
1575
|
+
{
|
|
1576
|
+
kind: "varDecl",
|
|
1577
|
+
localId: "out.0",
|
|
1578
|
+
init: { kind: "arrayLit", elems: [], type: outT, loc },
|
|
1579
|
+
loc,
|
|
1580
|
+
},
|
|
1581
|
+
countedFor(loc, varRef("n.0", F64, loc), () => [
|
|
1582
|
+
{
|
|
1583
|
+
kind: "varDecl",
|
|
1584
|
+
localId: "v.0",
|
|
1585
|
+
init: {
|
|
1586
|
+
kind: "dynKeyGet",
|
|
1587
|
+
key: { kind: "toString", operand: varRef("i.0", F64, loc), type: STRING, loc },
|
|
1588
|
+
value: d,
|
|
1589
|
+
type: DYN,
|
|
1590
|
+
loc,
|
|
1591
|
+
},
|
|
1592
|
+
loc,
|
|
1593
|
+
},
|
|
1594
|
+
{
|
|
1595
|
+
kind: "if",
|
|
1596
|
+
cond: {
|
|
1597
|
+
kind: "callValue",
|
|
1598
|
+
callee: varRef("f.0", fnT, loc),
|
|
1599
|
+
args: [varRef("v.0", DYN, loc), varRef("i.0", F64, loc), d].slice(0, arity),
|
|
1600
|
+
type: BOOL,
|
|
1601
|
+
loc,
|
|
1602
|
+
},
|
|
1603
|
+
then: [
|
|
1604
|
+
{
|
|
1605
|
+
kind: "exprStmt",
|
|
1606
|
+
expr: {
|
|
1607
|
+
kind: "arrIntrinsic",
|
|
1608
|
+
method: "push",
|
|
1609
|
+
receiver: varRef("out.0", outT, loc),
|
|
1610
|
+
args: [{ kind: "dynCheck", value: varRef("v.0", DYN, loc), type: elemT, loc }],
|
|
1611
|
+
type: F64,
|
|
1612
|
+
loc,
|
|
1613
|
+
},
|
|
1614
|
+
loc,
|
|
1615
|
+
},
|
|
1616
|
+
],
|
|
1617
|
+
else_: null,
|
|
1618
|
+
loc,
|
|
1619
|
+
},
|
|
1620
|
+
]),
|
|
1621
|
+
{ kind: "return", value: varRef("out.0", outT, loc), loc },
|
|
1622
|
+
];
|
|
1623
|
+
return {
|
|
1624
|
+
name,
|
|
1625
|
+
params: [
|
|
1626
|
+
{ localId: "d.0", name: "d", type: DYN },
|
|
1627
|
+
{ localId: "f.0", name: "f", type: fnT },
|
|
1628
|
+
{ localId: "m.0", name: "m", type: STRING },
|
|
1629
|
+
{ localId: "full.0", name: "full", type: STRING },
|
|
1630
|
+
],
|
|
1631
|
+
returnType: outT,
|
|
1632
|
+
locals: [
|
|
1633
|
+
{ id: "d.0", name: "d", type: DYN, mutable: false },
|
|
1634
|
+
{ id: "f.0", name: "f", type: fnT, mutable: false },
|
|
1635
|
+
{ id: "m.0", name: "m", type: STRING, mutable: false },
|
|
1636
|
+
{ id: "full.0", name: "full", type: STRING, mutable: false },
|
|
1637
|
+
{ id: "n.0", name: "n", type: F64, mutable: false },
|
|
1638
|
+
{ id: "i.0", name: "i", type: F64, mutable: true },
|
|
1639
|
+
{ id: "v.0", name: "v", type: DYN, mutable: false },
|
|
1640
|
+
{ id: "out.0", name: "out", type: outT, mutable: false },
|
|
1641
|
+
],
|
|
1642
|
+
body,
|
|
1643
|
+
loc,
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
//# sourceMappingURL=array-callbacks.js.map
|