@scriptc/compiler 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +682 -50
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +6 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +11 -0
- package/dist/backend/llvm/classes.js +71 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +58 -8
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.js +1 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +12 -3
- package/dist/backend/llvm/dense-array-access.js +72 -14
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +59 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +28 -4
- package/dist/backend/llvm/dyn.js +293 -178
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1190 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1535 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +58 -0
- package/dist/backend/llvm/emit-statements.js +1964 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +547 -283
- package/dist/backend/llvm/emitter.js +689 -4643
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +71 -53
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +39 -15
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +67 -62
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +121 -25
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +54 -12
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +488 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +189 -23
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +42 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +56 -22
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +90 -50
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +187 -6
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +43 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js +2 -2
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +151 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +64 -6
- package/dist/backend/llvm/nullable-unions.js +103 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +4 -0
- package/dist/backend/llvm/publish.js +14 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +12 -1
- package/dist/backend/llvm/record-results.js +64 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +142 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +9 -6
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +1 -1
- package/dist/backend/llvm/shapes.d.ts +66 -43
- package/dist/backend/llvm/shapes.js +280 -21
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +110 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +7 -0
- package/dist/backend/mangle.js +11 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +4 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +37 -0
- package/dist/backend/native/executable.js +192 -137
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -1
- package/dist/backend/runtime-pack-core.js +10 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +5 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +5 -0
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +8 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +5 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +44 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +11 -1
- package/dist/cli/usage.js +20 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +13 -0
- package/dist/contracts/check.js +24 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -6
- package/dist/diagnostics/diagnostic.js +29 -21
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +17 -0
- package/dist/executable/executable-cache.js +13 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +7 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +63 -5
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +16 -5
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +107 -44
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
- package/dist/frontend/lowering/builtins/crypto.js +211 -37
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +169 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +77 -77
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +232 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +55 -44
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +32 -1
- package/dist/frontend/lowering/builtins/process.js +461 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
- package/dist/frontend/lowering/builtins/readline.js +136 -39
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +16 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +75 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
- package/dist/frontend/lowering/builtins/workers.js +193 -8
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +19 -1
- package/dist/frontend/lowering/call-signatures.js +254 -47
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +528 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +25 -44
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +80 -18
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +261 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +51 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
- package/dist/frontend/lowering/containers/array-from-async.js +159 -14
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +89 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +161 -101
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +54 -25
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
- package/dist/frontend/lowering/cycle-initialization.js +39 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +62 -125
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +703 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2483 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1797 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +253 -85
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
- package/dist/frontend/lowering/expressions/property-access.js +3544 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1679 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +538 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +39 -0
- package/dist/frontend/lowering/generic-functions.js +393 -75
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +32 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1239 -442
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +50 -3
- package/dist/frontend/lowering/lower-classes.js +1473 -468
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +179 -8
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +258 -70
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1481 -12489
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +68 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +29 -16
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +331 -96
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +8 -1
- package/dist/frontend/lowering/lower-mock.js +185 -18
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +267 -61
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +45 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +488 -100
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +151 -109
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
- package/dist/frontend/lowering/lower-stmts.js +1541 -391
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +398 -56
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +437 -62
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +80 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +399 -26
- package/dist/frontend/lowering/lowerer.js +1910 -305
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +10 -10
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +12 -3
- package/dist/frontend/lowering/surfaces.js +252 -41
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.js +13 -6
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
- package/dist/frontend/npm-static-bundled-chunks.js +810 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +768 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +17 -1
- package/dist/frontend/npm-static.js +167 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.js +164 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +92 -2
- package/dist/frontend/program.js +1557 -255
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +36 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +20 -1
- package/dist/frontend/services.js +40 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +5 -1
- package/dist/frontend/ts7/program-host.js +12 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +54 -24
- package/dist/frontend/ts7/semantic-model.js +88 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +11 -11
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2545 -719
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +30 -0
- package/dist/ir/array-length-stability.js +236 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +113 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +103 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +494 -25
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +9 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +97 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/integer-loop-facts.d.ts +2 -0
- package/dist/ir/integer-loop-facts.js +24 -3
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +3 -0
- package/dist/ir/integer-ranges.js +3 -1
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +82 -1
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +221 -58
- package/dist/ir/ir.js +119 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +365 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +148 -33
- package/dist/ir/runtime-features.js +629 -386
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +103 -94
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +175 -68
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +26 -9
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +13 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +2 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/prepare.js +7 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +12 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +21 -20
- package/surface-manifest.json +303 -19
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { isForwardedTupleSpread, lowerForwardingApply } from "./typed-arguments.js";
|
|
1
2
|
import { guardNullProto, nullProtoRecordShape } from "./null-prototype.js";
|
|
3
|
+
import { lowerDynStreamMemberCall } from "./dyn-streams.js";
|
|
4
|
+
import { lowerBuiltinClassCall } from "./builtins/builtin-class-dyn.js";
|
|
5
|
+
import { refuseModuleMemberThis } from "./module-member-this.js";
|
|
2
6
|
import { lowerUnionEquality, tagEqualityMayMissAlias } from "./strict-equality.js";
|
|
3
7
|
import { lowerHashStreamCall } from "./builtins/hash-stream.js";
|
|
8
|
+
import { lowerWebAssemblyValueOf } from "./builtins/webassembly.js";
|
|
9
|
+
import { lowerResponseStaticJson } from "./lower-stdlib.js";
|
|
4
10
|
import { lowerArrayCallbackCall } from "./containers/array-callback-call.js";
|
|
5
11
|
/** Dispatch source calls, builtin members and receiver-specific operations.
|
|
6
12
|
* Signature collection, argument completion and function bodies have their
|
|
@@ -9,20 +15,25 @@ import { dynUndefinedExpr, nodeThrowExpr, countedFor, numLit, varRef } from "../
|
|
|
9
15
|
import { lowerBuiltinCall } from "./builtin-calls.js";
|
|
10
16
|
import { threadsImportOf } from "../threads-import.js";
|
|
11
17
|
import { adaptZeroArgTimerCallback, lowerTimersMemberCall, TIMER_MODULE_MEMBERS, } from "./lower-timers.js";
|
|
18
|
+
import { lowerMockTimersElementCall } from "./lower-test.js";
|
|
12
19
|
import { objectEnumerationReceiver } from "./object-enumeration-receiver.js";
|
|
13
20
|
import { InternalCompilerError } from "../../errors.js";
|
|
14
21
|
import { isFsStreamMember, lowerFsStreamMethodCall } from "./builtins/fs-streams.js";
|
|
15
22
|
import * as ts from "../ts7/adapter.js";
|
|
16
23
|
import { isZlibStreamMember, lowerPromisifiedZlibCall, lowerZlibStreamMethodCall, } from "./builtins/compression.js";
|
|
24
|
+
import { inlineNamespaceRequireOf, lowerInlineRequireValue, lowerUncompiledRequireCall, lowerWithInlineRequireInit, } from "./cjs-inline-require.js";
|
|
25
|
+
import { cjsExportCallIgnoresThis, cjsInFileExportGlobalOf } from "./cjs-exports-object.js";
|
|
17
26
|
import { lowerGenMethodCall } from "./lower-generators.js";
|
|
18
27
|
import { lowerClassSymbolMethodCall } from "./symbol-methods.js";
|
|
28
|
+
import { lowerReadlineDisposeCall } from "./builtins/readline.js";
|
|
19
29
|
import { errorToStringCall } from "./error-methods.js";
|
|
20
30
|
import { lowerClassPrototypeAssign, lowerClassPrototypeDescriptors } from "./class-prototypes.js";
|
|
21
|
-
import { BYTES_ELEMENT_NAME, BIGINT_T, BOOL, CAUGHT, DYN, F64, NULL_T, STRING, SYMBOL_T, UNDEFINED_T, VOID, arrayOf, canBoxFuncIntoDyn, canConvertToDyn, canDynCheckTo, funcOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals, } from "../../ir/ir.js";
|
|
31
|
+
import { BYTES_ELEMENT_NAME, BIGINT_T, BOOL, CAUGHT, DYN, DYN_HANDLE_KINDS, F64, NULL_T, STRING, SYMBOL_T, UNDEFINED_T, VOID, arrayOf, canBoxFuncIntoDyn, canConvertToDyn, canDynCheckTo, funcOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals, RUNTIME_EMITTER_CLASS, } from "../../ir/ir.js";
|
|
22
32
|
import { lowerProtocolMethodCall } from "./class-protocol-dispatch.js";
|
|
23
33
|
import { isJsSourceFile, locOf, requireSpecOf } from "../program.js";
|
|
34
|
+
import { lowerJsonRequireCall } from "./json-require.js";
|
|
24
35
|
import { lowerAssertInstanceCall } from "./assert-instances.js";
|
|
25
|
-
import { isGenericCallableMemberType, typeKey } from "../type-mapper.js";
|
|
36
|
+
import { isGenericCallableMemberType, isOverloadedCallableMemberType, typeKey, } from "../type-mapper.js";
|
|
26
37
|
import { dynFallbackType, jsFuncNameOf, newFnCtx, staticImportNamespaceType } from "./lowerer.js";
|
|
27
38
|
import { NARROW_FIRST, STRING_INDEX_METHODS, STR_METHODS, UTIL_TYPES_KEYS, stdlibGlobalNameOf, } from "./surfaces.js";
|
|
28
39
|
import { dynStringReceiver } from "./containers/dynamic-receivers.js";
|
|
@@ -30,25 +41,30 @@ import { lowerArrayConstructor, lowerArrayFromCall, lowerArrayOfCall, } from "./
|
|
|
30
41
|
import { lowerArrayFromAsyncCall } from "./containers/array-from-async.js";
|
|
31
42
|
import { lowerDynArrayFilterCall, lowerDynArrayFlatMapCall } from "./containers/array-callbacks.js";
|
|
32
43
|
import { lowerGroupByStaticCall } from "./containers/collection-grouping.js";
|
|
33
|
-
import { lowerIteratorHelperCall } from "./containers/iterator-helpers.js";
|
|
44
|
+
import { lowerGeneratorHelperCall, lowerHelperReturnCall, lowerIteratorFromCall, lowerIteratorHelperCall, } from "./containers/iterator-helpers.js";
|
|
34
45
|
import { lowerObjectAssignIndexShape, lowerObjectConstructor, lowerObjectFromEntriesCall, lowerObjectIterOverIndexShape, } from "./containers/indexed-objects.js";
|
|
35
46
|
import { lowerTupleReadMethodCall } from "./containers/array-methods.js";
|
|
36
47
|
import { tryFuseIndexRead } from "./array-values.js";
|
|
37
48
|
import { lowerBytesStaticCall } from "./containers/bytes.js";
|
|
38
|
-
import { lowerRegexMethodCall, lowerStringIndexCall, lowerStringMethodCall, lowerStringPaddingCall, lowerStringSplitCall, } from "./containers/string-and-regexp.js";
|
|
49
|
+
import { lowerRegexMethodCall, lowerStringIndexCall, lowerStringMethodCall, lowerStringPaddingCall, lowerStringSplitCall, isDynPrimitiveKindMethod, lowerDynPrimitiveMethodCall, lowerExtraNumberMethodCall, } from "./containers/string-and-regexp.js";
|
|
39
50
|
import { createRequireSpecOf } from "./builtins/module-bindings.js";
|
|
40
51
|
import { lowerChildStreamMethodCall, lowerChildWriterMethodCall, } from "./builtins/child-process-methods.js";
|
|
41
52
|
import { lowerCreateRequireCall, lowerImportMetaResolveCall, lowerRequireResolveCall, } from "./builtins/module-resolution.js";
|
|
42
|
-
import { lowerCipherMethodCall, lowerCryptoHashMethodCall } from "./builtins/crypto.js";
|
|
53
|
+
import { isWebCryptoReceiver, lowerCipherMethodCall, lowerCryptoGetRandomValues, lowerCryptoHashMethodCall, lowerPromisifiedCryptoCall, } from "./builtins/crypto.js";
|
|
54
|
+
import { lowerErrorIsErrorCall } from "./builtins/errors.js";
|
|
55
|
+
import { lowerPromisifiedDnsCall } from "./lower-dgram.js";
|
|
56
|
+
import { lowerDisposableStackUseCall } from "./builtins/disposable-stack.js";
|
|
43
57
|
import { lowerDirentMethodCall, lowerFileHandleMethodCall, lowerDirMethodCall, lowerWatcherMethodCall, } from "./builtins/filesystem.js";
|
|
44
|
-
import { fencePerfEntryKeyWalk, isPerfEntryType, lowerPerfHooksCall, perfEntryTag, } from "./builtins/performance.js";
|
|
45
|
-
import { lowerProcStreamMethodCall } from "./builtins/process.js";
|
|
58
|
+
import { fencePerfEntryKeyWalk, isPerfEntryType, lowerHistogramMethodCall, lowerPerfHooksCall, perfEntryTag, } from "./builtins/performance.js";
|
|
59
|
+
import { lowerProcStreamMethodCall, lowerProcessBuiltinModuleNamespace, } from "./builtins/process.js";
|
|
46
60
|
import { recordMayKeepSource, throughRecordSource } from "./record-sources.js";
|
|
47
61
|
import { lowerReflectCall } from "./builtins/reflection.js";
|
|
48
|
-
import { lowerAbsenceProbe, lowerOptionalNumber, lowerPromiseAllTupleCall, lowerPromiseRejectCall, lowerToNumberArgument, stringWrapperToString, symbolFieldInfo, templateRawTextOf, } from "./lower-exprs.js";
|
|
62
|
+
import { lowerAbsenceProbe, v8CalleeText, lowerOptionalNumber, lowerPromiseAllTupleCall, lowerPromiseRejectCall, lowerToNumberArgument, stringWrapperToString, symbolFieldInfo, templateRawTextOf, } from "./lower-exprs.js";
|
|
49
63
|
import { isSafeToDiscard } from "./expressions/evaluation-safety.js";
|
|
50
64
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
65
|
+
import { classToNumberConversion } from "./class-to-primitive.js";
|
|
51
66
|
import { hasRuntimeStatics } from "./class-runtime-statics.js";
|
|
67
|
+
import { structuralReadType } from "./class-unions.js";
|
|
52
68
|
import { httpClientFnBindingOf, lowerCompatReqStreamOptionalCall, lowerHttpClientFnCall, } from "./lower-server.js";
|
|
53
69
|
import { EMITTER_API_MEMBERS, exactClassOfReceiver, exactInstanceClassOf, findGenericMethodOn, lowerClassGenericMethodCall, lowerStaticMethodCall, lowerStaticFieldRead, returnsOnlyThis, storedClassValueType, } from "./lower-classes.js";
|
|
54
70
|
import { classCallbackCall, isClassCallback } from "./class-callbacks.js";
|
|
@@ -62,13 +78,17 @@ import { fenceNodeModuleMutationCall, lowerRequireCacheKeys } from "./lower-node
|
|
|
62
78
|
import { defaultAfterUndefined, lowerOptionalArgument, lowerStaticallyUndefinedArgument, positionNumber, } from "./optional-arguments.js";
|
|
63
79
|
import { fenceSymbolFieldCopy } from "./symbol-fields.js";
|
|
64
80
|
import { lowerClassDataDescriptor, lowerClassDescriptorRead } from "./class-descriptors.js";
|
|
81
|
+
import { lowerClassFieldDefine, lowerClassIntegrity } from "./class-attributes.js";
|
|
65
82
|
import { classStaticDataFor } from "./class-static-data.js";
|
|
66
83
|
import { lowerUrlFactory } from "./lower-url.js";
|
|
67
84
|
import { nullishValueUnitOf } from "./binding-analysis.js";
|
|
68
85
|
import { spreadNeedsRuntimeArity, completeFuncValueArgs, lowerSpreadArgsCall, completeArgs, } from "./call-arguments.js";
|
|
69
86
|
import { isThisParameter } from "./call-signatures.js";
|
|
87
|
+
import { lowerStringIteratorValue } from "./iterator-adapters.js";
|
|
70
88
|
import { checkedArmExtraction } from "./coercions/unions.js";
|
|
89
|
+
import { maybePromiseReturnStmt, promiseArmedUnionOf } from "./maybe-promise.js";
|
|
71
90
|
import { requireObjLitGenericReceiver, objLitGenericFnNodeOf, objLitGenericFnInfoOf, genericCallInstance, } from "./generic-functions.js";
|
|
91
|
+
import { codeGenerationCalleeOf, lowerCodeGenerationCall } from "./code-generation.js";
|
|
72
92
|
const ZLIB_STREAM_METHODS = new Set(["flush", "params", "close", "reset"]);
|
|
73
93
|
export function lowerCall(lowerer, expr) {
|
|
74
94
|
const loc = locOf(expr);
|
|
@@ -77,10 +97,46 @@ export function lowerCall(lowerer, expr) {
|
|
|
77
97
|
if (ts.isIdentifier(expr.expression) &&
|
|
78
98
|
expr.expression.text === "Object" &&
|
|
79
99
|
lowerer.isStdlibGlobal(expr.expression, "Object")) {
|
|
80
|
-
const object = lowerObjectConstructor(lowerer, expr.arguments, loc);
|
|
100
|
+
const object = lowerObjectConstructor(lowerer, expr.arguments.nodes, loc);
|
|
81
101
|
if (object)
|
|
82
102
|
return object;
|
|
83
103
|
}
|
|
104
|
+
// `EventEmitter.call(this)` in a constructor function: the untyped
|
|
105
|
+
// EventEmitter constructor initializes the receiver.
|
|
106
|
+
const builtinClassCall = lowerBuiltinClassCall(lowerer, expr);
|
|
107
|
+
if (builtinClassCall)
|
|
108
|
+
return builtinClassCall;
|
|
109
|
+
// require() of a JSON document: the shared parsed object.
|
|
110
|
+
const json = lowerJsonRequireCall(lowerer, expr);
|
|
111
|
+
if (json)
|
|
112
|
+
return json;
|
|
113
|
+
// eval(...) and Function(...): Node's EvalError under
|
|
114
|
+
// --disallow-code-generation-from-strings (code-generation.ts).
|
|
115
|
+
{
|
|
116
|
+
const codeGeneration = codeGenerationCalleeOf(lowerer, expr.expression);
|
|
117
|
+
if (codeGeneration !== null)
|
|
118
|
+
return lowerCodeGenerationCall(lowerer, expr, codeGeneration);
|
|
119
|
+
}
|
|
120
|
+
// Inline require() of a program module (cjs-inline-require.ts): a
|
|
121
|
+
// member call over its export table resolves like a binding's member
|
|
122
|
+
// call after the module's %init at this position; the require itself
|
|
123
|
+
// as a value answers the module's whole-export value.
|
|
124
|
+
if (ts.isPropertyAccessExpression(expr.expression) && !expr.expression.questionDotToken) {
|
|
125
|
+
const req = inlineNamespaceRequireOf(lowerer, expr.expression.expression);
|
|
126
|
+
if (req !== null && !lowerer.inlineRequireInitDone.has(req.call)) {
|
|
127
|
+
// Node calls the member with `this` bound to the module's exports.
|
|
128
|
+
if (ts.isIdentifier(expr.expression.name) &&
|
|
129
|
+
!cjsExportCallIgnoresThis(lowerer, req.dep, expr.expression.name.text)) {
|
|
130
|
+
lowerer.unsupported("SC1090", expr, `calling '${expr.expression.name.text}' through require(${JSON.stringify(req.spec)}) when the function may read 'this' (Node binds it to the module's exports object, which compiles to a static table — bind the module and call a local function instead)`);
|
|
131
|
+
}
|
|
132
|
+
return lowerWithInlineRequireInit(lowerer, req, () => lowerCall(lowerer, expr));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
{
|
|
136
|
+
const inlineValue = lowerInlineRequireValue(lowerer, expr);
|
|
137
|
+
if (inlineValue)
|
|
138
|
+
return inlineValue;
|
|
139
|
+
}
|
|
84
140
|
// A call whose chain ROOTS at an ambient-undefined name (`declare
|
|
85
141
|
// const value: Y | undefined; value?.foo("a")`, `declare function
|
|
86
142
|
// chain...; chain(o).mapValues(f).value()`, a trap binding's read):
|
|
@@ -141,10 +197,21 @@ export function lowerCall(lowerer, expr) {
|
|
|
141
197
|
if (resolved)
|
|
142
198
|
return resolved;
|
|
143
199
|
}
|
|
200
|
+
// Any other require() call of the CommonJS global: MODULE_NOT_FOUND for
|
|
201
|
+
// packages nothing installed resolves, a named refusal otherwise.
|
|
202
|
+
{
|
|
203
|
+
const uncompiled = lowerUncompiledRequireCall(lowerer, expr);
|
|
204
|
+
if (uncompiled)
|
|
205
|
+
return uncompiled;
|
|
206
|
+
}
|
|
144
207
|
// `process.getuid?.()` — intercepted BEFORE the optional-chain
|
|
145
208
|
// machinery (the member always exists on a POSIX target, so the
|
|
146
209
|
// optional call IS the call; `process.getuid` itself has no value
|
|
147
210
|
// lowering for the chain to guard).
|
|
211
|
+
// `h.return!()` / `h.return?.()` on a helper object: the method exists.
|
|
212
|
+
const helperReturn = lowerHelperReturnCall(lowerer, expr);
|
|
213
|
+
if (helperReturn)
|
|
214
|
+
return helperReturn;
|
|
148
215
|
const processOptional = lowerer.lowerProcessOptionalMethodCall(expr);
|
|
149
216
|
if (processOptional)
|
|
150
217
|
return processOptional;
|
|
@@ -189,6 +256,15 @@ export function lowerCall(lowerer, expr) {
|
|
|
189
256
|
}
|
|
190
257
|
return { kind: "libCall", fn: "http2.streamNoop", args: [], type: VOID, loc };
|
|
191
258
|
}
|
|
259
|
+
// `process.getBuiltinModule("node:os")` typed as the module namespace,
|
|
260
|
+
// including pi's cast-and-probe spelling
|
|
261
|
+
// `(process as P).getBuiltinModule?.("node:os")` (the member always
|
|
262
|
+
// exists on Node 24's process object).
|
|
263
|
+
{
|
|
264
|
+
const namespace = lowerProcessBuiltinModuleNamespace(lowerer, expr);
|
|
265
|
+
if (namespace)
|
|
266
|
+
return namespace;
|
|
267
|
+
}
|
|
192
268
|
// Optional-chain call forms: `f?.()` (the token on the call) and
|
|
193
269
|
// `a?.m()` (the token on the member access). The handled markers keep
|
|
194
270
|
// the chain lowering's re-entrant dispatch from looping.
|
|
@@ -281,7 +357,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
281
357
|
if (ts.isIdentifier(expr.expression) &&
|
|
282
358
|
expr.expression.text === "queueMicrotask" &&
|
|
283
359
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
|
|
284
|
-
if (expr.arguments.length === 0) {
|
|
360
|
+
if (expr.arguments.nodes.length === 0) {
|
|
285
361
|
// Node: queueMicrotask() throws ERR_INVALID_ARG_TYPE at runtime
|
|
286
362
|
// (the undefined callback) — the Dyn form delivers exactly that.
|
|
287
363
|
return {
|
|
@@ -292,7 +368,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
292
368
|
loc,
|
|
293
369
|
};
|
|
294
370
|
}
|
|
295
|
-
const raw = expr.arguments[0];
|
|
371
|
+
const raw = expr.arguments.nodes[0];
|
|
296
372
|
const cb = lowerer.lowerExpr(raw);
|
|
297
373
|
if (cb.type.kind === "dyn") {
|
|
298
374
|
return { kind: "libCall", fn: "timers.queueMicrotaskDyn", args: [cb], type: VOID, loc };
|
|
@@ -325,11 +401,11 @@ export function lowerCall(lowerer, expr) {
|
|
|
325
401
|
if (ts.isIdentifier(expr.expression) &&
|
|
326
402
|
expr.expression.text === "structuredClone" &&
|
|
327
403
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
|
|
328
|
-
if (expr.arguments.length === 0) {
|
|
404
|
+
if (expr.arguments.nodes.length === 0) {
|
|
329
405
|
return { kind: "libCall", fn: "dyn.cloneMissing", args: [], type: DYN, loc };
|
|
330
406
|
}
|
|
331
|
-
if (expr.arguments.length > 2) {
|
|
332
|
-
lowerer.noLowering(`structuredClone with ${expr.arguments.length} arguments`, expr);
|
|
407
|
+
if (expr.arguments.nodes.length > 2) {
|
|
408
|
+
lowerer.noLowering(`structuredClone with ${expr.arguments.nodes.length} arguments`, expr);
|
|
333
409
|
}
|
|
334
410
|
const toDynArg = (a) => {
|
|
335
411
|
if (!a)
|
|
@@ -341,26 +417,26 @@ export function lowerCall(lowerer, expr) {
|
|
|
341
417
|
}
|
|
342
418
|
return conv;
|
|
343
419
|
};
|
|
344
|
-
const valueNode = expr.arguments[0];
|
|
420
|
+
const valueNode = expr.arguments.nodes[0];
|
|
345
421
|
// A NON-EMPTY transfer array of static values: nothing static is
|
|
346
422
|
// transferable, so the call is Node's DataCloneError — decided here
|
|
347
423
|
// (the list's values need no dyn representation to fail). An EMPTY
|
|
348
424
|
// literal transfer list is a no-op member and drops.
|
|
349
425
|
{
|
|
350
|
-
let optNode = expr.arguments[1];
|
|
426
|
+
let optNode = expr.arguments.nodes[1];
|
|
351
427
|
while (optNode && ts.isParenthesizedExpression(optNode))
|
|
352
428
|
optNode = optNode.expression;
|
|
353
429
|
if (optNode && ts.isObjectLiteralExpression(optNode)) {
|
|
354
|
-
const tr = optNode.properties.find((p) => ts.isPropertyAssignment(p) &&
|
|
430
|
+
const tr = optNode.properties.nodes.find((p) => ts.isPropertyAssignment(p) &&
|
|
355
431
|
p.name !== undefined &&
|
|
356
432
|
(ts.isIdentifier(p.name) || ts.isStringLiteral(p.name)) &&
|
|
357
433
|
p.name.text === "transfer");
|
|
358
434
|
if (tr &&
|
|
359
435
|
ts.isArrayLiteralExpression(tr.initializer) &&
|
|
360
|
-
tr.initializer.elements.length > 0) {
|
|
436
|
+
tr.initializer.elements.nodes.length > 0) {
|
|
361
437
|
// An ArrayBuffer first member may be a Buffer pool slab, which
|
|
362
438
|
// Node reports as untransferable.
|
|
363
|
-
const first = tr.initializer.elements[0];
|
|
439
|
+
const first = tr.initializer.elements.nodes[0];
|
|
364
440
|
const firstType = ts.isSpreadElement(first) ? undefined : lowerer.typeOf(first);
|
|
365
441
|
const parts = !firstType
|
|
366
442
|
? []
|
|
@@ -369,7 +445,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
369
445
|
: [firstType];
|
|
370
446
|
const isStorage = parts.length > 0 &&
|
|
371
447
|
parts.every((part) => {
|
|
372
|
-
const name = part.getSymbol()
|
|
448
|
+
const name = ts.symbolNameOf(part.getSymbol());
|
|
373
449
|
return name === "ArrayBuffer" || name === "SharedArrayBuffer";
|
|
374
450
|
});
|
|
375
451
|
if (isStorage) {
|
|
@@ -385,7 +461,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
385
461
|
}
|
|
386
462
|
}
|
|
387
463
|
}
|
|
388
|
-
const optsArg = toDynArg(expr.arguments[1]);
|
|
464
|
+
const optsArg = toDynArg(expr.arguments.nodes[1]);
|
|
389
465
|
// A DOMException value clones through its own runtime arm — the
|
|
390
466
|
// typed result keeps the class (instanceof, .code, throwability).
|
|
391
467
|
const valueT = lowerer.mapTypeOf(lowerer.typeOf(valueNode));
|
|
@@ -409,11 +485,20 @@ export function lowerCall(lowerer, expr) {
|
|
|
409
485
|
};
|
|
410
486
|
// The declared result is the value's own type (the generic's T):
|
|
411
487
|
// validate the dyn copy back into it when the type can be checked;
|
|
412
|
-
// dyn-typed and unmappable results stay dyn values (JS files).
|
|
488
|
+
// dyn-typed and unmappable results stay dyn values (JS files). An
|
|
489
|
+
// empty record (`{}` inferred from a JavaScript `payload = {}`
|
|
490
|
+
// default) is the checker's supertype of whatever arrives, not a
|
|
491
|
+
// layout: checking into it would drop every member of the copy.
|
|
413
492
|
const resultT = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
493
|
+
const resultShape = resultT?.kind === "record" ? lowerer.shapes.get(resultT.shapeId) : undefined;
|
|
494
|
+
const emptyRecord = resultShape !== undefined &&
|
|
495
|
+
!resultShape.tuple &&
|
|
496
|
+
resultShape.indexValue === undefined &&
|
|
497
|
+
resultShape.fields.length === 0;
|
|
414
498
|
if (resultT !== null &&
|
|
415
499
|
resultT.kind !== "dyn" &&
|
|
416
500
|
resultT.kind !== "void" &&
|
|
501
|
+
!emptyRecord &&
|
|
417
502
|
canDynCheckTo(resultT, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
418
503
|
return { kind: "dynCheck", value: cloned, type: resultT, loc };
|
|
419
504
|
}
|
|
@@ -438,10 +523,10 @@ export function lowerCall(lowerer, expr) {
|
|
|
438
523
|
// constants ("", false, 0). Wrapper objects stay fenced except where
|
|
439
524
|
// the receiver is immediately converted by a direct String method call.
|
|
440
525
|
if (lowerer.isStdlibGlobal(expr.expression, "BigInt")) {
|
|
441
|
-
if (expr.arguments.length !== 1) {
|
|
442
|
-
lowerer.noLowering(`BigInt with ${expr.arguments.length} arguments`, expr);
|
|
526
|
+
if (expr.arguments.nodes.length !== 1) {
|
|
527
|
+
lowerer.noLowering(`BigInt with ${expr.arguments.nodes.length} arguments`, expr);
|
|
443
528
|
}
|
|
444
|
-
const argNode = expr.arguments[0];
|
|
529
|
+
const argNode = expr.arguments.nodes[0];
|
|
445
530
|
// Captured optional storage can change after TypeScript's guard.
|
|
446
531
|
// BigInt consumes the stored value, including its nullish tag.
|
|
447
532
|
const arg = optionalCallValue(lowerer, argNode) ?? lowerer.lowerExpr(argNode);
|
|
@@ -458,10 +543,10 @@ export function lowerCall(lowerer, expr) {
|
|
|
458
543
|
: lowerer.isStdlibGlobal(expr.expression, "Boolean")
|
|
459
544
|
? "Boolean"
|
|
460
545
|
: "Number";
|
|
461
|
-
if (expr.arguments.length > 1) {
|
|
462
|
-
lowerer.noLowering(`${name} with ${expr.arguments.length} arguments`, expr);
|
|
546
|
+
if (expr.arguments.nodes.length > 1) {
|
|
547
|
+
lowerer.noLowering(`${name} with ${expr.arguments.nodes.length} arguments`, expr);
|
|
463
548
|
}
|
|
464
|
-
const argNode = expr.arguments[0];
|
|
549
|
+
const argNode = expr.arguments.nodes[0];
|
|
465
550
|
if (!argNode) {
|
|
466
551
|
if (name === "String")
|
|
467
552
|
return { kind: "strLit", value: "", type: STRING, loc };
|
|
@@ -516,7 +601,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
516
601
|
(source.type.kind === "dyn" ||
|
|
517
602
|
source.type.kind === "func" ||
|
|
518
603
|
(source.type.kind === "union" &&
|
|
519
|
-
isJsSourceFile(
|
|
604
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
520
605
|
lowerer.dynConvertible(source.type)) ||
|
|
521
606
|
((source.type.kind === "map" || source.type.kind === "set") &&
|
|
522
607
|
lowerer.dynConvertible(source.type)) ||
|
|
@@ -527,8 +612,8 @@ export function lowerCall(lowerer, expr) {
|
|
|
527
612
|
const receiver = varRef(local.id, DYN, loc);
|
|
528
613
|
const key = lowerer.lowerExprExpecting(access.argumentExpression, DYN);
|
|
529
614
|
const callee = { kind: "dynKeyGet", value: receiver, key, type: DYN, loc };
|
|
530
|
-
const args = expr.arguments.map((arg) => lowerer.lowerExprExpecting(ts.isSpreadElement(arg) ? arg.expression : arg, DYN));
|
|
531
|
-
const spreads = expr.arguments.flatMap((arg, index) => ts.isSpreadElement(arg) ? [{ arg: index, what: arg.expression
|
|
615
|
+
const args = expr.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(ts.isSpreadElement(arg) ? arg.expression : arg, DYN));
|
|
616
|
+
const spreads = expr.arguments.nodes.flatMap((arg, index) => ts.isSpreadElement(arg) ? [{ arg: index, what: ts.getTextOfNode(arg.expression) }] : []);
|
|
532
617
|
return {
|
|
533
618
|
kind: "seqExpr",
|
|
534
619
|
stmts: [
|
|
@@ -538,7 +623,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
538
623
|
kind: "dynCall",
|
|
539
624
|
callee,
|
|
540
625
|
receiver,
|
|
541
|
-
calleeName:
|
|
626
|
+
calleeName: ts.getTextOfNode(access),
|
|
542
627
|
args,
|
|
543
628
|
...(spreads.length > 0 ? { spreads } : {}),
|
|
544
629
|
type: DYN,
|
|
@@ -559,7 +644,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
559
644
|
// all (fs.watch, os.cpus, ...) fence with the module-qualified name.
|
|
560
645
|
if (ts.isIdentifier(expr.expression)) {
|
|
561
646
|
if (expr.expression.text === "Array" && lowerer.isStdlibGlobal(expr.expression, "Array")) {
|
|
562
|
-
return lowerArrayConstructor(lowerer, expr, expr.arguments);
|
|
647
|
+
return lowerArrayConstructor(lowerer, expr, expr.arguments.nodes);
|
|
563
648
|
}
|
|
564
649
|
// A call through a compile-time util.promisify projection. execFile
|
|
565
650
|
// keeps its custom result helper; ordinary builtins route through
|
|
@@ -576,6 +661,12 @@ export function lowerCall(lowerer, expr) {
|
|
|
576
661
|
if (projection?.kind === "promisified-zlib") {
|
|
577
662
|
return lowerPromisifiedZlibCall(lowerer, expr, projection.member, loc);
|
|
578
663
|
}
|
|
664
|
+
if (projection?.kind === "promisified-crypto") {
|
|
665
|
+
return lowerPromisifiedCryptoCall(lowerer, expr, projection.member, loc);
|
|
666
|
+
}
|
|
667
|
+
if (projection?.kind === "promisified-dns") {
|
|
668
|
+
return lowerPromisifiedDnsCall(lowerer, expr, projection.member, loc);
|
|
669
|
+
}
|
|
579
670
|
if (projection?.kind === "promisified-builtin") {
|
|
580
671
|
return lowerBuiltinCall(lowerer, expr, { module: projection.module, member: projection.member }, loc);
|
|
581
672
|
}
|
|
@@ -592,9 +683,9 @@ export function lowerCall(lowerer, expr) {
|
|
|
592
683
|
if (threadsImportOf(lowerer.program, expr.expression) === "publish") {
|
|
593
684
|
// @scriptc/threads publish(value): the same value, its graph made
|
|
594
685
|
// immortal and immutable (backend/llvm/publish.ts).
|
|
595
|
-
if (expr.arguments.length !== 1 || ts.isSpreadElement(expr.arguments[0]))
|
|
596
|
-
lowerer.noLowering(`publish with ${expr.arguments.length} arguments`, expr);
|
|
597
|
-
const value = lowerer.lowerExpr(expr.arguments[0]);
|
|
686
|
+
if (expr.arguments.nodes.length !== 1 || ts.isSpreadElement(expr.arguments.nodes[0]))
|
|
687
|
+
lowerer.noLowering(`publish with ${expr.arguments.nodes.length} arguments`, expr);
|
|
688
|
+
const value = lowerer.lowerExpr(expr.arguments.nodes[0]);
|
|
598
689
|
return { kind: "intrinsic", name: "threads.publish", args: [value], type: value.type, loc };
|
|
599
690
|
}
|
|
600
691
|
const bi = lowerer.builtinImportOf(expr.expression);
|
|
@@ -626,10 +717,10 @@ export function lowerCall(lowerer, expr) {
|
|
|
626
717
|
// generic new fence keeps it.
|
|
627
718
|
if (expr.expression.text === "Symbol" &&
|
|
628
719
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
|
|
629
|
-
if (expr.arguments.length > 1) {
|
|
630
|
-
lowerer.noLowering(`Symbol with ${expr.arguments.length} arguments`, expr);
|
|
720
|
+
if (expr.arguments.nodes.length > 1) {
|
|
721
|
+
lowerer.noLowering(`Symbol with ${expr.arguments.nodes.length} arguments`, expr);
|
|
631
722
|
}
|
|
632
|
-
const argNode = expr.arguments[0];
|
|
723
|
+
const argNode = expr.arguments.nodes[0];
|
|
633
724
|
// A literal `undefined` argument IS the no-description form
|
|
634
725
|
// (Symbol(undefined).description is undefined, like Symbol()).
|
|
635
726
|
if (!argNode || (ts.isIdentifier(argNode) && argNode.text === "undefined")) {
|
|
@@ -656,7 +747,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
656
747
|
expr.expression.text === "parseFloat" ||
|
|
657
748
|
expr.expression.text === "isFinite") &&
|
|
658
749
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
|
|
659
|
-
const parsed = lowerStaticNumberGlobal(lowerer, expr.expression.text, expr, expr.arguments, loc);
|
|
750
|
+
const parsed = lowerStaticNumberGlobal(lowerer, expr.expression.text, expr, expr.arguments.nodes, loc);
|
|
660
751
|
if (parsed !== null)
|
|
661
752
|
return parsed;
|
|
662
753
|
}
|
|
@@ -676,11 +767,11 @@ export function lowerCall(lowerer, expr) {
|
|
|
676
767
|
expr.expression.text === "decodeURIComponent") &&
|
|
677
768
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
|
|
678
769
|
const name = expr.expression.text;
|
|
679
|
-
if (expr.arguments.length !== 1) {
|
|
680
|
-
lowerer.noLowering(`${name} with ${expr.arguments.length} argument${expr.arguments.length === 1 ? "" : "s"}`, expr);
|
|
770
|
+
if (expr.arguments.nodes.length !== 1) {
|
|
771
|
+
lowerer.noLowering(`${name} with ${expr.arguments.nodes.length} argument${expr.arguments.nodes.length === 1 ? "" : "s"}`, expr);
|
|
681
772
|
}
|
|
682
773
|
const loc = locOf(expr);
|
|
683
|
-
const argNode = expr.arguments[0];
|
|
774
|
+
const argNode = expr.arguments.nodes[0];
|
|
684
775
|
if (name === "decodeURIComponent" || name === "decodeURI") {
|
|
685
776
|
const d = optionalCallValue(lowerer, argNode) ?? lowerer.lowerExpr(argNode);
|
|
686
777
|
const s = lowerer.ensureString(d, argNode);
|
|
@@ -713,13 +804,13 @@ export function lowerCall(lowerer, expr) {
|
|
|
713
804
|
if ((expr.expression.text === "atob" || expr.expression.text === "btoa") &&
|
|
714
805
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
|
|
715
806
|
const name = expr.expression.text;
|
|
716
|
-
if (expr.arguments.length === 0) {
|
|
807
|
+
if (expr.arguments.nodes.length === 0) {
|
|
717
808
|
return { kind: "libCall", fn: "str.b64Missing", args: [], type: STRING, loc };
|
|
718
809
|
}
|
|
719
|
-
if (expr.arguments.length > 1) {
|
|
720
|
-
lowerer.noLowering(`${name} with ${expr.arguments.length} arguments`, expr);
|
|
810
|
+
if (expr.arguments.nodes.length > 1) {
|
|
811
|
+
lowerer.noLowering(`${name} with ${expr.arguments.nodes.length} arguments`, expr);
|
|
721
812
|
}
|
|
722
|
-
const argNode = expr.arguments[0];
|
|
813
|
+
const argNode = expr.arguments.nodes[0];
|
|
723
814
|
const v = lowerer.lowerExpr(argNode);
|
|
724
815
|
let data;
|
|
725
816
|
if (v.type.kind === "dyn") {
|
|
@@ -743,17 +834,17 @@ export function lowerCall(lowerer, expr) {
|
|
|
743
834
|
// result exits to the declared static type. A user function
|
|
744
835
|
// shadowing the name has a different, non-stdlib symbol.
|
|
745
836
|
const islFn = lowerer.stdlibGlobalFnOf(expr.expression);
|
|
746
|
-
if (islFn && expr.arguments.length !== islFn.args.length) {
|
|
837
|
+
if (islFn && expr.arguments.nodes.length !== islFn.args.length) {
|
|
747
838
|
const name = expr.expression.text;
|
|
748
|
-
lowerer.noLowering(`${name} with ${expr.arguments.length} argument${expr.arguments.length === 1 ? "" : "s"}`, expr);
|
|
839
|
+
lowerer.noLowering(`${name} with ${expr.arguments.nodes.length} argument${expr.arguments.nodes.length === 1 ? "" : "s"}`, expr);
|
|
749
840
|
}
|
|
750
|
-
if (islFn && expr.arguments.length === islFn.args.length) {
|
|
841
|
+
if (islFn && expr.arguments.nodes.length === islFn.args.length) {
|
|
751
842
|
// The static forms above already took the exactly-typed argument
|
|
752
843
|
// (a string for parseFloat, a number for isFinite): name the
|
|
753
844
|
// argument type that refused the call, so the message states the
|
|
754
845
|
// condition rather than reading as if the global itself were
|
|
755
846
|
// unsupported.
|
|
756
|
-
const argText = loweredArgumentText(lowerer, expr.arguments[0]);
|
|
847
|
+
const argText = loweredArgumentText(lowerer, expr.arguments.nodes[0]);
|
|
757
848
|
const exact = expr.expression.text === "isFinite" ? "number" : "string";
|
|
758
849
|
lowerer.refuseUnsupportedApi(`'${expr.expression.text}' with a '${argText}' argument`, expr, exact === "string"
|
|
759
850
|
? "only a string argument compiles statically: convert the argument explicitly first (for example String(x), or narrow the union)"
|
|
@@ -768,8 +859,8 @@ export function lowerCall(lowerer, expr) {
|
|
|
768
859
|
// typeof tests) applies inside it, tsc's call-site narrowing types
|
|
769
860
|
// the guarded branch, and a body construct with no caught lowering
|
|
770
861
|
// fences per site at its own location.
|
|
771
|
-
if (ts.isIdentifier(expr.expression) && expr.arguments.length === 1) {
|
|
772
|
-
const caughtArg = lowerer.caughtLocalOf(expr.arguments[0]);
|
|
862
|
+
if (ts.isIdentifier(expr.expression) && expr.arguments.nodes.length === 1) {
|
|
863
|
+
const caughtArg = lowerer.caughtLocalOf(expr.arguments.nodes[0]);
|
|
773
864
|
if (caughtArg) {
|
|
774
865
|
const inlined = lowerCaughtPredicateCall(lowerer, expr, caughtArg);
|
|
775
866
|
if (inlined)
|
|
@@ -797,7 +888,8 @@ export function lowerCall(lowerer, expr) {
|
|
|
797
888
|
// VALUE path — the runtime-arity lane (lowerSpreadArgsCall) boxes
|
|
798
889
|
// the declaration's value and applies through a runtime-built
|
|
799
890
|
// argument list. Typed .ts spreads keep completeArgs' rest packing.
|
|
800
|
-
const jsSpreadArgs = expr.arguments.some((a) => ts.isSpreadElement(a)) &&
|
|
891
|
+
const jsSpreadArgs = expr.arguments.nodes.some((a) => ts.isSpreadElement(a)) &&
|
|
892
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr));
|
|
801
893
|
if (lowerer.isTopLevelFnSymbol(expr.expression) && !lowerer.peekLocal(expr.expression)) {
|
|
802
894
|
// `import g = N.f; g()` — the alias's own source-order guards
|
|
803
895
|
// (a no-op for every non-import= binding).
|
|
@@ -809,17 +901,18 @@ export function lowerCall(lowerer, expr) {
|
|
|
809
901
|
if (generic && !(jsSpreadArgs && generic.implicitParams))
|
|
810
902
|
return lowerer.lowerGenericCall(expr, generic);
|
|
811
903
|
const sig = generic ? null : lowerer.fnSigOf(expr.expression);
|
|
812
|
-
if (sig &&
|
|
904
|
+
if (sig &&
|
|
905
|
+
!(jsSpreadArgs && spreadNeedsRuntimeArity(lowerer, sig.params, expr.arguments.nodes))) {
|
|
813
906
|
lowerer.noteEdge(sig.name);
|
|
814
|
-
const args = lowerer.completeArgs(expr.arguments, sig.params, loc, expr);
|
|
907
|
+
const args = lowerer.completeArgs(expr.arguments.nodes, sig.params, loc, expr);
|
|
815
908
|
const symbol = lowerer.resolveValueSymbol(expr.expression);
|
|
816
|
-
const declaration = symbol ?
|
|
909
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
817
910
|
// A bare call supplies undefined as this, even inside a callback
|
|
818
911
|
// currently carrying a receiver. The value-call ABI saves and
|
|
819
912
|
// restores that ambient receiver around the function invocation.
|
|
820
913
|
if (declaration &&
|
|
821
914
|
ts.isFunctionDeclaration(declaration) &&
|
|
822
|
-
declaration.parameters.some(isThisParameter)) {
|
|
915
|
+
declaration.parameters.nodes.some(isThisParameter)) {
|
|
823
916
|
const callee = lowerer.lowerExpr(expr.expression);
|
|
824
917
|
return reconcileOverloadReturn(lowerer, expr, {
|
|
825
918
|
kind: "callValue",
|
|
@@ -903,13 +996,14 @@ export function lowerCall(lowerer, expr) {
|
|
|
903
996
|
const memberSym = lowerer.checker.getSymbolAtLocation(nsMember);
|
|
904
997
|
if (memberSym)
|
|
905
998
|
fenceEarlyNsMemberRef(lowerer, expr.expression, memberSym);
|
|
999
|
+
refuseModuleMemberThis(lowerer, expr, nsMember);
|
|
906
1000
|
const generic = lowerer.genericFnOf(nsMember);
|
|
907
1001
|
if (generic)
|
|
908
1002
|
return lowerer.lowerGenericCall(expr, generic);
|
|
909
1003
|
const sig = lowerer.fnSigOf(nsMember);
|
|
910
1004
|
if (sig) {
|
|
911
1005
|
lowerer.noteEdge(sig.name);
|
|
912
|
-
const args = lowerer.completeArgs(expr.arguments, sig.params, loc, expr);
|
|
1006
|
+
const args = lowerer.completeArgs(expr.arguments.nodes, sig.params, loc, expr);
|
|
913
1007
|
return reconcileOverloadReturn(lowerer, expr, {
|
|
914
1008
|
kind: "call",
|
|
915
1009
|
callee: sig.name,
|
|
@@ -967,13 +1061,14 @@ export function lowerCall(lowerer, expr) {
|
|
|
967
1061
|
if (!ts.isIdentifier(nameId)) {
|
|
968
1062
|
lowerer.unsupported("SC1090", nameId, "private-named module members");
|
|
969
1063
|
}
|
|
1064
|
+
refuseModuleMemberThis(lowerer, expr, nameId);
|
|
970
1065
|
const generic = lowerer.genericFnOf(nameId);
|
|
971
1066
|
if (generic)
|
|
972
1067
|
return lowerer.lowerGenericCall(expr, generic);
|
|
973
1068
|
const sig = lowerer.fnSigOf(nameId);
|
|
974
1069
|
if (sig) {
|
|
975
1070
|
lowerer.noteEdge(sig.name);
|
|
976
|
-
const args = lowerer.completeArgs(expr.arguments, sig.params, loc, expr);
|
|
1071
|
+
const args = lowerer.completeArgs(expr.arguments.nodes, sig.params, loc, expr);
|
|
977
1072
|
return reconcileOverloadReturn(lowerer, expr, {
|
|
978
1073
|
kind: "call",
|
|
979
1074
|
callee: sig.name,
|
|
@@ -993,8 +1088,35 @@ export function lowerCall(lowerer, expr) {
|
|
|
993
1088
|
const args = completeFuncValueArgs(lowerer, expr, callee.type, loc);
|
|
994
1089
|
return { kind: "callValue", callee, args, type: callee.type.ret, loc };
|
|
995
1090
|
}
|
|
1091
|
+
// `exports.f(x)` / `module.exports.f(x)` inside the module: a call of
|
|
1092
|
+
// the member's export global (cjs-exports-object.ts), the value every
|
|
1093
|
+
// `exports.f =` statement assigns.
|
|
1094
|
+
if (ts.isPropertyAccessExpression(expr.expression) && !expr.questionDotToken) {
|
|
1095
|
+
const g = cjsInFileExportGlobalOf(lowerer, expr.expression);
|
|
1096
|
+
if (g &&
|
|
1097
|
+
(g.type.kind === "func" || g.type.kind === "dyn") &&
|
|
1098
|
+
!cjsExportCallIgnoresThis(lowerer, ts.getSourceFileOfNode(expr), expr.expression.name.text)) {
|
|
1099
|
+
lowerer.unsupported("SC1090", expr, `calling '${ts.getTextOfNode(expr.expression)}' through the module's exports object when the function may read 'this' (Node binds it to the exports object, which compiles to a static table — call a local function instead)`);
|
|
1100
|
+
}
|
|
1101
|
+
if (g && (g.type.kind === "func" || g.type.kind === "dyn")) {
|
|
1102
|
+
const callee = { kind: "varRef", localId: g.id, type: g.type, loc };
|
|
1103
|
+
const checked = lowerCheckedCallableValue(lowerer, expr, callee, loc);
|
|
1104
|
+
if (checked)
|
|
1105
|
+
return checked;
|
|
1106
|
+
if (callee.type.kind === "func") {
|
|
1107
|
+
const args = completeFuncValueArgs(lowerer, expr, callee.type, loc);
|
|
1108
|
+
return { kind: "callValue", callee, args, type: callee.type.ret, loc };
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
996
1112
|
if (ts.isPropertyAccessExpression(expr.expression)) {
|
|
997
|
-
const intrinsic =
|
|
1113
|
+
const intrinsic =
|
|
1114
|
+
// Checked-dynamic stream slots dispatch per value (dyn-streams.ts).
|
|
1115
|
+
lowerDynStreamMemberCall(lowerer, expr, expr.expression) ??
|
|
1116
|
+
fenceNodeModuleMutationCall(lowerer, expr, expr.expression) ??
|
|
1117
|
+
// `f.apply(thisArg, args)` forwarding a fixed argument tuple (typed
|
|
1118
|
+
// `arguments`, a tuple rest parameter): a direct call.
|
|
1119
|
+
lowerForwardingApply(lowerer, expr, expr.expression) ??
|
|
998
1120
|
// Builtin namespace imports first (`fs.readFileSync(...)` where fs
|
|
999
1121
|
// is `import * as fs from "node:fs"`): the same tables and fences
|
|
1000
1122
|
// as named builtin imports — before anything below tries to lower
|
|
@@ -1006,6 +1128,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
1006
1128
|
// .bind(performance) function value over the runtime's
|
|
1007
1129
|
// process-start-anchored monotonic clock.
|
|
1008
1130
|
lowerPerfHooksCall(lowerer, expr, expr.expression) ??
|
|
1131
|
+
lowerHistogramMethodCall(lowerer, expr, expr.expression) ??
|
|
1009
1132
|
// The composed crypto pattern (randomBytes(n).toString(enc))
|
|
1010
1133
|
// — its receiver is a Buffer-typed CALL no other lowering claims.
|
|
1011
1134
|
lowerer.lowerCryptoComposedCall(expr, expr.expression) ??
|
|
@@ -1099,6 +1222,8 @@ export function lowerCall(lowerer, expr) {
|
|
|
1099
1222
|
// compile-time-known, so a literal key folds to a constant.
|
|
1100
1223
|
lowerClassHasOwnPropertyCall(lowerer, expr, expr.expression) ??
|
|
1101
1224
|
lowerObjectOwnMethodCall(lowerer, expr, expr.expression) ??
|
|
1225
|
+
// Static Response.json(data, init?) builds a native Response.
|
|
1226
|
+
lowerResponseStaticJson(lowerer, expr) ??
|
|
1102
1227
|
// Refuse Response constructor operations before generic-call
|
|
1103
1228
|
// fallbacks can report an unrelated SC1090 diagnostic.
|
|
1104
1229
|
lowerer.fenceUnsupportedFetchConstructorMember(expr.expression) ??
|
|
@@ -1108,7 +1233,11 @@ export function lowerCall(lowerer, expr) {
|
|
|
1108
1233
|
lowerer.fenceStaticResponseMember(expr.expression, "call") ??
|
|
1109
1234
|
lowerer.fenceStaticHeadersMember(expr.expression, "call") ??
|
|
1110
1235
|
lowerer.fenceStaticReadableStreamMember(expr.expression, "call") ??
|
|
1236
|
+
lowerDisposableStackUseCall(lowerer, expr, expr.expression) ??
|
|
1111
1237
|
lowerer.lowerStdlibMethodCall(expr, expr.expression) ??
|
|
1238
|
+
// crypto.getRandomValues on the WebCrypto global (untyped in
|
|
1239
|
+
// fallback builds, so before the dyn receiver path) or webcrypto.
|
|
1240
|
+
lowerWebCryptoGetRandomValues(lowerer, expr, expr.expression) ??
|
|
1112
1241
|
// Dyn receivers (JSON.parse-derived `unknown`/`any` values) —
|
|
1113
1242
|
lowerDynReceiverMethodCall(lowerer, expr, expr.expression) ??
|
|
1114
1243
|
// Narrowing filters (inferred predicates, filter(Boolean)) claim
|
|
@@ -1116,6 +1245,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
1116
1245
|
// by the receiver's own element.
|
|
1117
1246
|
lowerer.lowerFilterNarrowCall(expr, expr.expression) ??
|
|
1118
1247
|
lowerArrayIsArrayCall(lowerer, expr, expr.expression) ??
|
|
1248
|
+
lowerErrorIsErrorCall(lowerer, expr, expr.expression) ??
|
|
1119
1249
|
lowerBigIntMethodCall(lowerer, expr, expr.expression) ??
|
|
1120
1250
|
lowerSymbolStaticCall(lowerer, expr, expr.expression) ??
|
|
1121
1251
|
lowerSymbolMethodCall(lowerer, expr, expr.expression) ??
|
|
@@ -1128,6 +1258,8 @@ export function lowerCall(lowerer, expr) {
|
|
|
1128
1258
|
// array method paths (the terminal names collide with array
|
|
1129
1259
|
// methods, but only iterator-typed receivers reach this).
|
|
1130
1260
|
lowerIteratorHelperCall(lowerer, expr, expr.expression) ??
|
|
1261
|
+
// Helper calls on generators and other iterator objects.
|
|
1262
|
+
lowerGeneratorHelperCall(lowerer, expr, expr.expression) ??
|
|
1131
1263
|
lowerIteratorStaticFence(lowerer, expr, expr.expression) ??
|
|
1132
1264
|
lowerObjectStaticCall(lowerer, expr, expr.expression) ??
|
|
1133
1265
|
lowerObjectFromEntriesCall(lowerer, expr, expr.expression) ??
|
|
@@ -1151,15 +1283,20 @@ export function lowerCall(lowerer, expr) {
|
|
|
1151
1283
|
lowerObjLitGenericMethodCall(lowerer, expr, expr.expression);
|
|
1152
1284
|
if (intrinsic)
|
|
1153
1285
|
return intrinsic;
|
|
1154
|
-
|
|
1286
|
+
{
|
|
1287
|
+
const boxed = lowerDynReceiverMethodCall(lowerer, expr, expr.expression, true);
|
|
1288
|
+
if (boxed)
|
|
1289
|
+
return boxed;
|
|
1290
|
+
}
|
|
1291
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
1155
1292
|
const staticField = lowerStaticFieldRead(lowerer, expr.expression);
|
|
1156
|
-
if (staticField?.type.kind === "dyn" && !expr.arguments.some(ts.isSpreadElement)) {
|
|
1293
|
+
if (staticField?.type.kind === "dyn" && !expr.arguments.nodes.some(ts.isSpreadElement)) {
|
|
1157
1294
|
return {
|
|
1158
1295
|
kind: "dynCall",
|
|
1159
1296
|
callee: staticField,
|
|
1160
1297
|
receiver: lowerer.lowerExprExpecting(expr.expression.expression, DYN),
|
|
1161
|
-
calleeName: expr.expression
|
|
1162
|
-
args: expr.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
1298
|
+
calleeName: v8CalleeText(expr.expression),
|
|
1299
|
+
args: expr.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
1163
1300
|
type: DYN,
|
|
1164
1301
|
loc: locOf(expr),
|
|
1165
1302
|
};
|
|
@@ -1172,12 +1309,13 @@ export function lowerCall(lowerer, expr) {
|
|
|
1172
1309
|
const args = completeFuncValueArgs(lowerer, expr, callee.type, locOf(expr));
|
|
1173
1310
|
return { kind: "callValue", callee, args, type: callee.type.ret, loc: locOf(expr) };
|
|
1174
1311
|
}
|
|
1175
|
-
if (callee.type.kind === "dyn" &&
|
|
1176
|
-
|
|
1312
|
+
if (callee.type.kind === "dyn" &&
|
|
1313
|
+
!expr.arguments.nodes.some((arg) => ts.isSpreadElement(arg))) {
|
|
1314
|
+
const args = expr.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN));
|
|
1177
1315
|
return {
|
|
1178
1316
|
kind: "dynCall",
|
|
1179
1317
|
callee,
|
|
1180
|
-
calleeName: expr.expression
|
|
1318
|
+
calleeName: v8CalleeText(expr.expression),
|
|
1181
1319
|
args,
|
|
1182
1320
|
type: DYN,
|
|
1183
1321
|
loc: locOf(expr),
|
|
@@ -1214,7 +1352,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
1214
1352
|
{
|
|
1215
1353
|
const recvT = lowerer.typeOf(expr.expression.expression);
|
|
1216
1354
|
if (recvT.isIntersectionType() && lowerer.checker.getCallSignatures(recvT).length > 0) {
|
|
1217
|
-
lowerer.unsupported("SC1090", expr, `calls through function-with-properties values ('${expr.expression.expression
|
|
1355
|
+
lowerer.unsupported("SC1090", expr, `calls through function-with-properties values ('${ts.getTextOfNode(expr.expression.expression)}' is callable AND carries members — the chalk shape; no hybrid representation exists yet: export the base and the property as separate functions)`);
|
|
1218
1356
|
}
|
|
1219
1357
|
}
|
|
1220
1358
|
// A GENERIC method no lowering above claimed — an ambient `declare
|
|
@@ -1229,14 +1367,29 @@ export function lowerCall(lowerer, expr) {
|
|
|
1229
1367
|
lowerer.unsupported("SC1090", expr, `calls of the generic method '${expr.expression.name.text}' through this receiver (no compiled declaration with a body resolves statically here — ambient 'declare class' and interface-only methods are signature-only, and only class, static, and object-literal generic methods with bodies monomorphize)`);
|
|
1230
1368
|
}
|
|
1231
1369
|
}
|
|
1232
|
-
lowerer.unsupported("SC1090", expr, `method calls like '${expr.expression
|
|
1370
|
+
lowerer.unsupported("SC1090", expr, `method calls like '${ts.getTextOfNode(expr.expression)}'`);
|
|
1371
|
+
}
|
|
1372
|
+
// `s[Symbol.iterator]()` on a string: the string iterator as a value.
|
|
1373
|
+
if (ts.isElementAccessExpression(expr.expression) &&
|
|
1374
|
+
!expr.expression.questionDotToken &&
|
|
1375
|
+
!expr.questionDotToken &&
|
|
1376
|
+
expr.arguments.nodes.length === 0) {
|
|
1377
|
+
const iterator = lowerStringIteratorCall(lowerer, expr, expr.expression);
|
|
1378
|
+
if (iterator)
|
|
1379
|
+
return iterator;
|
|
1233
1380
|
}
|
|
1234
1381
|
// The element spelling of an unsupported native Web method must fence
|
|
1235
1382
|
// before lowering the callee into a checked-dynamic keyed read.
|
|
1236
1383
|
if (ts.isElementAccessExpression(expr.expression)) {
|
|
1384
|
+
const timersDispose = lowerMockTimersElementCall(lowerer, expr, expr.expression);
|
|
1385
|
+
if (timersDispose)
|
|
1386
|
+
return timersDispose;
|
|
1237
1387
|
const symbolMethod = lowerClassSymbolMethodCall(lowerer, expr);
|
|
1238
1388
|
if (symbolMethod)
|
|
1239
1389
|
return symbolMethod;
|
|
1390
|
+
const readlineDispose = lowerReadlineDisposeCall(lowerer, expr);
|
|
1391
|
+
if (readlineDispose)
|
|
1392
|
+
return readlineDispose;
|
|
1240
1393
|
lowerer.fenceUnsupportedFetchConstructorMember(expr.expression);
|
|
1241
1394
|
lowerer.fenceStaticResponseMember(expr.expression, "call");
|
|
1242
1395
|
lowerer.fenceStaticHeadersMember(expr.expression, "call");
|
|
@@ -1250,7 +1403,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
1250
1403
|
!symbolFieldInfo(lowerer, expr.expression)) {
|
|
1251
1404
|
const access = expr.expression;
|
|
1252
1405
|
const value = tryLowerExpression(lowerer, access.expression);
|
|
1253
|
-
if (value?.type.kind === "array" && !isJsSourceFile(
|
|
1406
|
+
if (value?.type.kind === "array" && !isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
1254
1407
|
const callback = lowerArrayCallbackCall(lowerer, expr, access, value);
|
|
1255
1408
|
if (callback)
|
|
1256
1409
|
return callback;
|
|
@@ -1270,7 +1423,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
1270
1423
|
const raw = lowerer.lowerExpr(access.argumentExpression);
|
|
1271
1424
|
const key = raw.type.kind === "string" ? raw : lowerer.coerceInto(access.argumentExpression, raw, DYN);
|
|
1272
1425
|
const callee = { kind: "dynKeyGet", value: receiver, key, type: DYN, loc };
|
|
1273
|
-
const spread = expr.arguments.some(ts.isSpreadElement)
|
|
1426
|
+
const spread = expr.arguments.nodes.some(ts.isSpreadElement)
|
|
1274
1427
|
? lowerSpreadArgsCall(lowerer, expr, callee, loc)
|
|
1275
1428
|
: null;
|
|
1276
1429
|
if (spread && spread.kind !== "dynCall")
|
|
@@ -1281,8 +1434,8 @@ export function lowerCall(lowerer, expr) {
|
|
|
1281
1434
|
kind: "dynCall",
|
|
1282
1435
|
callee,
|
|
1283
1436
|
receiver,
|
|
1284
|
-
calleeName:
|
|
1285
|
-
args: expr.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
1437
|
+
calleeName: ts.getTextOfNode(access),
|
|
1438
|
+
args: expr.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
1286
1439
|
type: DYN,
|
|
1287
1440
|
loc,
|
|
1288
1441
|
};
|
|
@@ -1323,7 +1476,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
1323
1476
|
else
|
|
1324
1477
|
lowerer.noteEdge(`%${found.declarer.def.name}.${memberName}`);
|
|
1325
1478
|
const receiver = lowerer.lowerExpr(expr.expression.expression);
|
|
1326
|
-
const args = lowerer.completeArgs(expr.arguments, found.sig.params, locOf(expr), expr);
|
|
1479
|
+
const args = lowerer.completeArgs(expr.arguments.nodes, found.sig.params, locOf(expr), expr);
|
|
1327
1480
|
const callArgs = [
|
|
1328
1481
|
lowerer.upcastTo(receiver, virtual ? info.def.name : found.declarer.def.name),
|
|
1329
1482
|
...args,
|
|
@@ -1374,7 +1527,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
1374
1527
|
// function" TypeError. The result is dyn (checked per use like every
|
|
1375
1528
|
// any-origin value). Spread arguments keep their fence.
|
|
1376
1529
|
if (callee.type.kind === "dyn") {
|
|
1377
|
-
if (expr.arguments.some((a) => ts.isSpreadElement(a))) {
|
|
1530
|
+
if (expr.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
1378
1531
|
// The runtime-arity lane: a dyn callee is already boxed — the
|
|
1379
1532
|
// spread-marked dynCall applies through a fresh dyn argument
|
|
1380
1533
|
// array (lowerSpreadArgsCall). Sources outside it keep the fence.
|
|
@@ -1383,10 +1536,10 @@ export function lowerCall(lowerer, expr) {
|
|
|
1383
1536
|
return spreadServed;
|
|
1384
1537
|
lowerer.unsupported("SC1090", expr, "spread arguments in calls through 'unknown' values");
|
|
1385
1538
|
}
|
|
1386
|
-
const args = expr.arguments.map((a) => lowerer.lowerExprExpecting(a, DYN));
|
|
1539
|
+
const args = expr.arguments.nodes.map((a) => lowerer.lowerExprExpecting(a, DYN));
|
|
1387
1540
|
const calleeName = ts.isPropertyAccessExpression(expr.expression) ||
|
|
1388
1541
|
ts.isElementAccessExpression(expr.expression)
|
|
1389
|
-
? expr.expression
|
|
1542
|
+
? ts.getTextOfNode(expr.expression)
|
|
1390
1543
|
: ts.isIdentifier(expr.expression)
|
|
1391
1544
|
? expr.expression.text
|
|
1392
1545
|
: "value";
|
|
@@ -1398,8 +1551,8 @@ export function lowerCall(lowerer, expr) {
|
|
|
1398
1551
|
return {
|
|
1399
1552
|
kind: "dynCall",
|
|
1400
1553
|
callee: lowerer.coerceToExpected(callee, DYN),
|
|
1401
|
-
calleeName: expr.expression
|
|
1402
|
-
args: expr.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
1554
|
+
calleeName: v8CalleeText(expr.expression),
|
|
1555
|
+
args: expr.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
1403
1556
|
type: DYN,
|
|
1404
1557
|
loc,
|
|
1405
1558
|
};
|
|
@@ -1420,7 +1573,16 @@ export function lowerCall(lowerer, expr) {
|
|
|
1420
1573
|
// or marshals the callee and applies through a runtime-built argument
|
|
1421
1574
|
// list (lowerSpreadArgsCall). Shapes outside its lanes fall through
|
|
1422
1575
|
// to the historical fences.
|
|
1423
|
-
|
|
1576
|
+
// Forwarded fixed tuples (`fn(...args)` over a tuple rest parameter or a
|
|
1577
|
+
// typed `arguments`) have a compile-time arity: complete them into the
|
|
1578
|
+
// callee's positional slots directly, without the runtime-arity lane.
|
|
1579
|
+
if (callee.type.rest !== true &&
|
|
1580
|
+
expr.arguments.nodes.some(ts.isSpreadElement) &&
|
|
1581
|
+
expr.arguments.nodes.every((a) => !ts.isSpreadElement(a) || isForwardedTupleSpread(lowerer, a.expression))) {
|
|
1582
|
+
const args = completeFuncValueArgs(lowerer, expr, callee.type, loc);
|
|
1583
|
+
return { kind: "callValue", callee, args, type: callee.type.ret, loc };
|
|
1584
|
+
}
|
|
1585
|
+
if (expr.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
1424
1586
|
const spreadServed = lowerSpreadArgsCall(lowerer, expr, callee, loc);
|
|
1425
1587
|
if (spreadServed)
|
|
1426
1588
|
return spreadServed;
|
|
@@ -1431,12 +1593,12 @@ export function lowerCall(lowerer, expr) {
|
|
|
1431
1593
|
// checked-dynamic boundary — box the callee, dynCall — which delivers
|
|
1432
1594
|
// JS arity exactly (the thunk ignores extras). Result dyn, checked
|
|
1433
1595
|
// per use like every any-origin value.
|
|
1434
|
-
if ((expr.arguments.length > callee.type.params.length || callee.type.rest === true) &&
|
|
1435
|
-
(isJsSourceFile(
|
|
1596
|
+
if ((expr.arguments.nodes.length > callee.type.params.length || callee.type.rest === true) &&
|
|
1597
|
+
(isJsSourceFile(ts.getSourceFileOfNode(expr)) ||
|
|
1436
1598
|
(callee.type.rest === true && callee.type.restAbi === undefined)) &&
|
|
1437
|
-
!expr.arguments.some((a) => ts.isSpreadElement(a)) &&
|
|
1599
|
+
!expr.arguments.nodes.some((a) => ts.isSpreadElement(a)) &&
|
|
1438
1600
|
canBoxFuncIntoDyn(callee.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
1439
|
-
const args = expr.arguments.map((a) => lowerer.lowerExprExpecting(a, DYN));
|
|
1601
|
+
const args = expr.arguments.nodes.map((a) => lowerer.lowerExprExpecting(a, DYN));
|
|
1440
1602
|
const calleeName = ts.isIdentifier(expr.expression) ? expr.expression.text : "value";
|
|
1441
1603
|
const boxed = { kind: "dynFrom", value: callee, type: DYN, loc };
|
|
1442
1604
|
return { kind: "dynCall", callee: boxed, calleeName, args, type: DYN, loc };
|
|
@@ -1451,12 +1613,13 @@ function lowerCheckedCallableValue(lowerer, call, value, loc) {
|
|
|
1451
1613
|
if (callee.type.kind !== "dyn") {
|
|
1452
1614
|
if (callee.type.kind !== "func" ||
|
|
1453
1615
|
!((callee.type.rest === true && callee.type.restAbi === undefined) ||
|
|
1454
|
-
(isJsSourceFile(
|
|
1616
|
+
(isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
1617
|
+
call.arguments.nodes.length > callee.type.params.length)) ||
|
|
1455
1618
|
!lowerer.dynConvertible(callee.type))
|
|
1456
1619
|
return null;
|
|
1457
1620
|
callee = { kind: "dynFrom", value: callee, type: DYN, loc };
|
|
1458
1621
|
}
|
|
1459
|
-
if (call.arguments.some(ts.isSpreadElement)) {
|
|
1622
|
+
if (call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
1460
1623
|
const spread = lowerSpreadArgsCall(lowerer, call, callee, loc);
|
|
1461
1624
|
if (spread)
|
|
1462
1625
|
return spread;
|
|
@@ -1465,8 +1628,8 @@ function lowerCheckedCallableValue(lowerer, call, value, loc) {
|
|
|
1465
1628
|
return {
|
|
1466
1629
|
kind: "dynCall",
|
|
1467
1630
|
callee,
|
|
1468
|
-
calleeName: call.expression
|
|
1469
|
-
args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
1631
|
+
calleeName: v8CalleeText(call.expression),
|
|
1632
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
1470
1633
|
type: DYN,
|
|
1471
1634
|
loc,
|
|
1472
1635
|
};
|
|
@@ -1475,19 +1638,19 @@ function lowerRegexMethodCallWithOptionalArg(lowerer, call, access) {
|
|
|
1475
1638
|
const lowered = lowerer.lowerRegexMethodCall(call, access);
|
|
1476
1639
|
if (lowered?.kind !== "regexIntrinsic" ||
|
|
1477
1640
|
lowered.method !== "test" ||
|
|
1478
|
-
call.arguments.length !== 1)
|
|
1641
|
+
call.arguments.nodes.length !== 1)
|
|
1479
1642
|
return lowered;
|
|
1480
1643
|
const subject = lowered.args[0];
|
|
1481
1644
|
if (subject?.type.kind !== "union" || lowerer.armTag(subject.type.unionId, UNDEFINED_T) < 0)
|
|
1482
1645
|
return lowered;
|
|
1483
|
-
if (lowerer.mapTypeOf(lowerer.typeOf(call.arguments[0]))?.kind !== "string")
|
|
1646
|
+
if (lowerer.mapTypeOf(lowerer.typeOf(call.arguments.nodes[0]))?.kind !== "string")
|
|
1484
1647
|
return lowered;
|
|
1485
1648
|
const present = lowerer.stripUndefinedArm(subject.type);
|
|
1486
1649
|
if (present.kind !== "string")
|
|
1487
1650
|
return lowered;
|
|
1488
1651
|
return {
|
|
1489
1652
|
...lowered,
|
|
1490
|
-
args: [lowerer.ensureString(subject, call.arguments[0])],
|
|
1653
|
+
args: [lowerer.ensureString(subject, call.arguments.nodes[0])],
|
|
1491
1654
|
};
|
|
1492
1655
|
}
|
|
1493
1656
|
function optionalCallValue(lowerer, node) {
|
|
@@ -1504,17 +1667,17 @@ function lowerBufferStaticCallWithNarrowedArg(lowerer, call, access) {
|
|
|
1504
1667
|
// A callback can store a wider union than the checker sees at this use
|
|
1505
1668
|
// (including an added undefined arm). Extract the exact arm proven by
|
|
1506
1669
|
// control-flow narrowing, not merely the union with undefined removed.
|
|
1507
|
-
const narrowed = lowerer.mapTypeOf(lowerer.typeOf(call.arguments[0]));
|
|
1670
|
+
const narrowed = lowerer.mapTypeOf(lowerer.typeOf(call.arguments.nodes[0]));
|
|
1508
1671
|
if (!narrowed ||
|
|
1509
1672
|
!(narrowed.kind === "f64" ||
|
|
1510
1673
|
(narrowed.kind === "array" && narrowed.elem.kind === "f64") ||
|
|
1511
1674
|
(narrowed.kind === "bytes" && narrowed.elem === "u8")) ||
|
|
1512
1675
|
lowerer.armTag(lowered.source.type.unionId, narrowed) < 0) {
|
|
1513
|
-
lowerer.unsupported("SC1090", call.arguments[0], "a Buffer constructor argument whose narrowed type is not a stored source arm");
|
|
1676
|
+
lowerer.unsupported("SC1090", call.arguments.nodes[0], "a Buffer constructor argument whose narrowed type is not a stored source arm");
|
|
1514
1677
|
}
|
|
1515
1678
|
const helper = lowerer.narrowedArmHelper(lowered.source.type.unionId, narrowed, lowered.source.loc);
|
|
1516
1679
|
if (!helper) {
|
|
1517
|
-
lowerer.unsupported("SC1090", call.arguments[0], "a Buffer constructor argument whose narrowed type is not a stored source arm");
|
|
1680
|
+
lowerer.unsupported("SC1090", call.arguments.nodes[0], "a Buffer constructor argument whose narrowed type is not a stored source arm");
|
|
1518
1681
|
}
|
|
1519
1682
|
const narrowedValue = {
|
|
1520
1683
|
...lowered,
|
|
@@ -1575,7 +1738,7 @@ function lowerOptionalNumberDefault(lowerer, value, dflt, loc) {
|
|
|
1575
1738
|
}
|
|
1576
1739
|
return { kind: "call", callee: helper, args: [value], type: F64, loc };
|
|
1577
1740
|
}
|
|
1578
|
-
function lowerStringMethodCallWithOptionalArgs(lowerer, call, access, receiver, argumentNodes = call.arguments) {
|
|
1741
|
+
function lowerStringMethodCallWithOptionalArgs(lowerer, call, access, receiver, argumentNodes = call.arguments.nodes) {
|
|
1579
1742
|
const lowered = lowerStringMethodCall(lowerer, call, access, receiver, argumentNodes);
|
|
1580
1743
|
if (lowered?.kind !== "strIntrinsic")
|
|
1581
1744
|
return lowered;
|
|
@@ -1672,6 +1835,10 @@ function lowerNumberConstructorValue(lowerer, argNode, loc) {
|
|
|
1672
1835
|
const optionalNumber = lowerOptionalStringNumber(lowerer, arg, loc);
|
|
1673
1836
|
if (optionalNumber)
|
|
1674
1837
|
return optionalNumber;
|
|
1838
|
+
// A program class instance converts through its own methods.
|
|
1839
|
+
const classNumber = classToNumberConversion(lowerer, arg, argNode);
|
|
1840
|
+
if (classNumber)
|
|
1841
|
+
return classNumber;
|
|
1675
1842
|
const scalarUnionNumber = lowerScalarUnionNumber(lowerer, arg, argNode, loc);
|
|
1676
1843
|
if (scalarUnionNumber)
|
|
1677
1844
|
return scalarUnionNumber;
|
|
@@ -1777,7 +1944,7 @@ function immediatePrimitiveWrapperToString(lowerer, node) {
|
|
|
1777
1944
|
if ((name !== "Boolean" && name !== "Number") ||
|
|
1778
1945
|
!lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(wrapped.expression) ?? undefined))
|
|
1779
1946
|
return null;
|
|
1780
|
-
const args = wrapped.arguments ?? [];
|
|
1947
|
+
const args = wrapped.arguments?.nodes ?? [];
|
|
1781
1948
|
if (args.length > 1 || args.some(ts.isSpreadElement))
|
|
1782
1949
|
return null;
|
|
1783
1950
|
const loc = locOf(wrapped);
|
|
@@ -1844,7 +2011,7 @@ function immediateObjectTagReceiver(lowerer, node) {
|
|
|
1844
2011
|
if ((ts.isCallExpression(value) || ts.isNewExpression(value)) &&
|
|
1845
2012
|
ts.isIdentifier(value.expression) &&
|
|
1846
2013
|
(value.expression.text === "Array" || value.expression.text === "Error") &&
|
|
1847
|
-
(value.arguments?.length ?? 0) === 0 &&
|
|
2014
|
+
(value.arguments?.nodes.length ?? 0) === 0 &&
|
|
1848
2015
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(value.expression) ?? undefined)) {
|
|
1849
2016
|
return { tag: value.expression.text, effect: { kind: "numLit", value: 0, type: F64, loc } };
|
|
1850
2017
|
}
|
|
@@ -1852,7 +2019,7 @@ function immediateObjectTagReceiver(lowerer, node) {
|
|
|
1852
2019
|
ts.isIdentifier(value.expression) &&
|
|
1853
2020
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(value.expression) ?? undefined)) {
|
|
1854
2021
|
const name = value.expression.text;
|
|
1855
|
-
const args = value.arguments ?? [];
|
|
2022
|
+
const args = value.arguments?.nodes ?? [];
|
|
1856
2023
|
// JavaScript dates use checked native handles, so their IR type alone
|
|
1857
2024
|
// cannot recover the tag through an immediate Object(...) wrapper.
|
|
1858
2025
|
if (name === "Date")
|
|
@@ -1883,7 +2050,7 @@ function immediateObjectTagReceiver(lowerer, node) {
|
|
|
1883
2050
|
ts.isIdentifier(value.expression) &&
|
|
1884
2051
|
value.expression.text === "Object" &&
|
|
1885
2052
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(value.expression) ?? undefined)) {
|
|
1886
|
-
const args = value.arguments ?? [];
|
|
2053
|
+
const args = value.arguments?.nodes ?? [];
|
|
1887
2054
|
if (args.some(ts.isSpreadElement))
|
|
1888
2055
|
return null;
|
|
1889
2056
|
const first = args[0];
|
|
@@ -1938,12 +2105,12 @@ const ARRAY_BORROW_METHODS = new Set([
|
|
|
1938
2105
|
"some",
|
|
1939
2106
|
]);
|
|
1940
2107
|
function lowerArrayPrototypeBorrowCall(lowerer, call, access) {
|
|
1941
|
-
if (!isJsSourceFile(
|
|
2108
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(call)) ||
|
|
1942
2109
|
call.questionDotToken ||
|
|
1943
2110
|
access.questionDotToken ||
|
|
1944
2111
|
access.name.text !== "call" ||
|
|
1945
2112
|
!ts.isPropertyAccessExpression(access.expression) ||
|
|
1946
|
-
call.arguments.some(ts.isSpreadElement))
|
|
2113
|
+
call.arguments.nodes.some(ts.isSpreadElement))
|
|
1947
2114
|
return null;
|
|
1948
2115
|
const method = access.expression;
|
|
1949
2116
|
if (method.questionDotToken ||
|
|
@@ -1955,10 +2122,10 @@ function lowerArrayPrototypeBorrowCall(lowerer, call, access) {
|
|
|
1955
2122
|
!lowerer.isStdlibMember(method))
|
|
1956
2123
|
return null;
|
|
1957
2124
|
const loc = locOf(call);
|
|
1958
|
-
const receiver = call.arguments[0]
|
|
1959
|
-
? lowerer.lowerExprExpecting(call.arguments[0], DYN)
|
|
2125
|
+
const receiver = call.arguments.nodes[0]
|
|
2126
|
+
? lowerer.lowerExprExpecting(call.arguments.nodes[0], DYN)
|
|
1960
2127
|
: dynUndefinedExpr(loc);
|
|
1961
|
-
const args = call.arguments.slice(1).map((arg) => lowerer.lowerExprExpecting(arg, DYN));
|
|
2128
|
+
const args = call.arguments.nodes.slice(1).map((arg) => lowerer.lowerExprExpecting(arg, DYN));
|
|
1962
2129
|
return {
|
|
1963
2130
|
kind: "libCall",
|
|
1964
2131
|
fn: "dyn.arrayProtoCall",
|
|
@@ -1983,23 +2150,23 @@ function lowerObjectOwnPrototypeCall(lowerer, call, access) {
|
|
|
1983
2150
|
prototype.name.text !== "prototype" ||
|
|
1984
2151
|
!lowerer.isStdlibGlobal(prototype.expression, "Object") ||
|
|
1985
2152
|
!lowerer.isStdlibMember(method) ||
|
|
1986
|
-
call.arguments.some(ts.isSpreadElement))
|
|
2153
|
+
call.arguments.nodes.some(ts.isSpreadElement))
|
|
1987
2154
|
return null;
|
|
1988
|
-
return lowerObjectOwnCall(lowerer, call, call.arguments[0], call.arguments[1], call.arguments.slice(2), method.name.text);
|
|
2155
|
+
return lowerObjectOwnCall(lowerer, call, call.arguments.nodes[0], call.arguments.nodes[1], call.arguments.nodes.slice(2), method.name.text);
|
|
1989
2156
|
}
|
|
1990
2157
|
function lowerObjectOwnMethodCall(lowerer, call, access) {
|
|
1991
2158
|
const method = access.name.text;
|
|
1992
2159
|
if (call.questionDotToken ||
|
|
1993
2160
|
access.questionDotToken ||
|
|
1994
2161
|
(method !== "hasOwnProperty" && method !== "propertyIsEnumerable") ||
|
|
1995
|
-
call.arguments.some(ts.isSpreadElement))
|
|
2162
|
+
call.arguments.nodes.some(ts.isSpreadElement))
|
|
1996
2163
|
return null;
|
|
1997
2164
|
if (!lowerer.isStdlibMember(access)) {
|
|
1998
2165
|
const receiver = tryLowerExpression(lowerer, access.expression);
|
|
1999
2166
|
if (receiver?.type.kind !== "dyn")
|
|
2000
2167
|
return null;
|
|
2001
2168
|
}
|
|
2002
|
-
return lowerObjectOwnCall(lowerer, call, access.expression, call.arguments[0], call.arguments.slice(1), method, access);
|
|
2169
|
+
return lowerObjectOwnCall(lowerer, call, access.expression, call.arguments.nodes[0], call.arguments.nodes.slice(1), method, access);
|
|
2003
2170
|
}
|
|
2004
2171
|
/** ToPropertyKey for the scalar keys represented by native own-key
|
|
2005
2172
|
* probes. A lowered array-loop key may carry an undefined arm even when
|
|
@@ -2110,7 +2277,7 @@ methodAccess = null) {
|
|
|
2110
2277
|
loc,
|
|
2111
2278
|
};
|
|
2112
2279
|
if (methodAccess && nullProtoRecordShape(lowerer, type)) {
|
|
2113
|
-
result = guardNullProto(receiverRef, type.shapeId, `${
|
|
2280
|
+
result = guardNullProto(receiverRef, type.shapeId, `${ts.getTextOfNode(methodAccess)} is not a function`, result, loc);
|
|
2114
2281
|
}
|
|
2115
2282
|
}
|
|
2116
2283
|
else if (type.kind === "dyn") {
|
|
@@ -2225,16 +2392,17 @@ function lowerObjectPrototypeCall(lowerer, call, access) {
|
|
|
2225
2392
|
prototype.name.text !== "prototype" ||
|
|
2226
2393
|
!lowerer.isStdlibGlobal(prototype.expression, "Object") ||
|
|
2227
2394
|
!lowerer.isStdlibMember(method) ||
|
|
2228
|
-
call.arguments.some(ts.isSpreadElement))
|
|
2395
|
+
call.arguments.nodes.some(ts.isSpreadElement))
|
|
2229
2396
|
return null;
|
|
2230
2397
|
const loc = locOf(call);
|
|
2231
|
-
if (call.arguments.length === 0)
|
|
2398
|
+
if (call.arguments.nodes.length === 0)
|
|
2232
2399
|
return { kind: "strLit", value: "[object Undefined]", type: STRING, loc };
|
|
2233
|
-
const receiverNode = call.arguments[0];
|
|
2400
|
+
const receiverNode = call.arguments.nodes[0];
|
|
2234
2401
|
const immediate = immediateObjectTagReceiver(lowerer, receiverNode);
|
|
2235
2402
|
const receiver = immediate?.effect ?? lowerer.lowerExpr(receiverNode);
|
|
2236
2403
|
const tag = immediate?.tag ?? objectToStringTag(lowerer, receiver.type);
|
|
2237
|
-
|
|
2404
|
+
// A generator object answers its tag through its checked capsule.
|
|
2405
|
+
if (tag === null && receiver.type.kind !== "dyn" && receiver.type.kind !== "generator") {
|
|
2238
2406
|
lowerer.noLowering("Object.prototype.toString.call over a " + lowerer.fmt(receiver.type) + " receiver", receiverNode);
|
|
2239
2407
|
}
|
|
2240
2408
|
const stmts = [];
|
|
@@ -2248,11 +2416,17 @@ function lowerObjectPrototypeCall(lowerer, call, access) {
|
|
|
2248
2416
|
stmts.push({ kind: "varDecl", localId: local.id, init: receiver, loc });
|
|
2249
2417
|
ref = varRef(local.id, receiver.type, loc);
|
|
2250
2418
|
}
|
|
2251
|
-
for (const extra of call.arguments.slice(1)) {
|
|
2419
|
+
for (const extra of call.arguments.nodes.slice(1)) {
|
|
2252
2420
|
stmts.push({ kind: "exprStmt", expr: lowerer.lowerExpr(extra), loc: locOf(extra) });
|
|
2253
2421
|
}
|
|
2254
2422
|
const result = tag === null
|
|
2255
|
-
? {
|
|
2423
|
+
? {
|
|
2424
|
+
kind: "libCall",
|
|
2425
|
+
fn: "dyn.objectTag",
|
|
2426
|
+
args: [ref.type.kind === "generator" ? lowerer.coerceToExpected(ref, DYN) : ref],
|
|
2427
|
+
type: STRING,
|
|
2428
|
+
loc,
|
|
2429
|
+
}
|
|
2256
2430
|
: { kind: "strLit", value: "[object " + tag + "]", type: STRING, loc };
|
|
2257
2431
|
return { kind: "seqExpr", stmts, result, type: STRING, loc };
|
|
2258
2432
|
}
|
|
@@ -2274,7 +2448,7 @@ function lowerDynamicStringPrototypeCall(lowerer, call, methodAccess, receiver,
|
|
|
2274
2448
|
};
|
|
2275
2449
|
const overrides = [];
|
|
2276
2450
|
try {
|
|
2277
|
-
for (const node of call.arguments.slice(1)) {
|
|
2451
|
+
for (const node of call.arguments.nodes.slice(1)) {
|
|
2278
2452
|
const undefinedValue = lowerStaticallyUndefinedArgument(lowerer, node);
|
|
2279
2453
|
const value = undefinedValue ?? lowerer.lowerExpr(node);
|
|
2280
2454
|
let ref;
|
|
@@ -2296,7 +2470,7 @@ function lowerDynamicStringPrototypeCall(lowerer, call, methodAccess, receiver,
|
|
|
2296
2470
|
overrides.push({ node, previous: lowerer.chainRecvByNode.get(node) });
|
|
2297
2471
|
lowerer.chainRecvByNode.set(node, ref);
|
|
2298
2472
|
}
|
|
2299
|
-
const result = lowerStringMethodCallWithOptionalArgs(lowerer, call, methodAccess, () => converted, call.arguments.slice(1));
|
|
2473
|
+
const result = lowerStringMethodCallWithOptionalArgs(lowerer, call, methodAccess, () => converted, call.arguments.nodes.slice(1));
|
|
2300
2474
|
return result ? { kind: "seqExpr", stmts, result, type: result.type, loc } : null;
|
|
2301
2475
|
}
|
|
2302
2476
|
finally {
|
|
@@ -2321,7 +2495,7 @@ function lowerStringPrototypeCall(lowerer, call, access) {
|
|
|
2321
2495
|
!STRING_INDEX_METHODS.has(methodAccess.name.text)) ||
|
|
2322
2496
|
!lowerer.isStdlibMember(methodAccess))
|
|
2323
2497
|
return null;
|
|
2324
|
-
if (call.arguments.some(ts.isSpreadElement))
|
|
2498
|
+
if (call.arguments.nodes.some(ts.isSpreadElement))
|
|
2325
2499
|
return null;
|
|
2326
2500
|
const entry = STR_METHODS[methodAccess.name.text];
|
|
2327
2501
|
const indexMethod = STRING_INDEX_METHODS.has(methodAccess.name.text)
|
|
@@ -2339,12 +2513,12 @@ function lowerStringPrototypeCall(lowerer, call, access) {
|
|
|
2339
2513
|
: methodAccess.name.text;
|
|
2340
2514
|
const loc = locOf(call);
|
|
2341
2515
|
const nullishError = nodeThrowExpr(1, "", `String.prototype.${method} called on null or undefined`, resultType, loc);
|
|
2342
|
-
const receiverNode = call.arguments[0];
|
|
2516
|
+
const receiverNode = call.arguments.nodes[0];
|
|
2343
2517
|
if (!receiverNode)
|
|
2344
2518
|
return nullishError;
|
|
2345
2519
|
// Receiver coercion runs after .call has evaluated its arguments; keep
|
|
2346
2520
|
// contextual wrapper lowering on forms without later method arguments.
|
|
2347
|
-
const immediateWrapper = entry?.maxArgs === 0 && call.arguments.length === 1
|
|
2521
|
+
const immediateWrapper = entry?.maxArgs === 0 && call.arguments.nodes.length === 1
|
|
2348
2522
|
? immediatePrimitiveWrapperToString(lowerer, receiverNode)
|
|
2349
2523
|
: null;
|
|
2350
2524
|
const receiverValue = immediateWrapper ?? lowerer.lowerExpr(receiverNode);
|
|
@@ -2357,7 +2531,10 @@ function lowerStringPrototypeCall(lowerer, call, access) {
|
|
|
2357
2531
|
?.arms.every((arm) => isUnitType(arm) || arm.kind === "void") ??
|
|
2358
2532
|
false));
|
|
2359
2533
|
if (nullish) {
|
|
2360
|
-
const values = [
|
|
2534
|
+
const values = [
|
|
2535
|
+
receiverValue,
|
|
2536
|
+
...call.arguments.nodes.slice(1).map((arg) => lowerer.lowerExpr(arg)),
|
|
2537
|
+
];
|
|
2361
2538
|
return {
|
|
2362
2539
|
kind: "seqExpr",
|
|
2363
2540
|
stmts: values
|
|
@@ -2387,28 +2564,28 @@ function lowerStringPrototypeCall(lowerer, call, access) {
|
|
|
2387
2564
|
// Other methods convert object receivers before lowering their arguments;
|
|
2388
2565
|
// padding uses a helper that delays conversion until every argument is ready.
|
|
2389
2566
|
const objectWithoutMethodArgs = entry?.maxArgs === 0 &&
|
|
2390
|
-
call.arguments.length === 1 &&
|
|
2567
|
+
call.arguments.nodes.length === 1 &&
|
|
2391
2568
|
(receiverType.kind === "record" ||
|
|
2392
2569
|
receiverType.kind === "array" ||
|
|
2393
2570
|
receiverType.kind === "object");
|
|
2394
2571
|
if (padding && !scalar && lowerer.dynConvertible(receiverType)) {
|
|
2395
|
-
return lowerStringPaddingCall(lowerer, call, entry.method, lowerer.coerceToExpected(receiverValue, DYN), receiverNode, call.arguments.slice(1));
|
|
2572
|
+
return lowerStringPaddingCall(lowerer, call, entry.method, lowerer.coerceToExpected(receiverValue, DYN), receiverNode, call.arguments.nodes.slice(1));
|
|
2396
2573
|
}
|
|
2397
2574
|
if (!scalar && !objectWithoutMethodArgs) {
|
|
2398
2575
|
lowerer.noLowering(`String.prototype.${methodAccess.name.text}.call with ${lowerer.fmt(receiverType)} receivers`, call);
|
|
2399
2576
|
}
|
|
2400
2577
|
if (indexMethod)
|
|
2401
|
-
return lowerStringIndexCall(lowerer, call, indexMethod, receiverValue, receiverNode, call.arguments.slice(1));
|
|
2578
|
+
return lowerStringIndexCall(lowerer, call, indexMethod, receiverValue, receiverNode, call.arguments.nodes.slice(1));
|
|
2402
2579
|
if (!entry)
|
|
2403
2580
|
return null;
|
|
2404
2581
|
if (padding) {
|
|
2405
|
-
return lowerStringPaddingCall(lowerer, call, entry.method, receiverValue, receiverNode, call.arguments.slice(1));
|
|
2582
|
+
return lowerStringPaddingCall(lowerer, call, entry.method, receiverValue, receiverNode, call.arguments.nodes.slice(1));
|
|
2406
2583
|
}
|
|
2407
2584
|
if (entry.method === "split") {
|
|
2408
|
-
return lowerStringSplitCall(lowerer, call, receiverValue, receiverNode, call.arguments.slice(1));
|
|
2585
|
+
return lowerStringSplitCall(lowerer, call, receiverValue, receiverNode, call.arguments.nodes.slice(1));
|
|
2409
2586
|
}
|
|
2410
2587
|
const receiver = lowerer.ensureString(receiverValue, receiverNode);
|
|
2411
|
-
return lowerStringMethodCallWithOptionalArgs(lowerer, call, methodAccess, () => receiver, call.arguments.slice(1));
|
|
2588
|
+
return lowerStringMethodCallWithOptionalArgs(lowerer, call, methodAccess, () => receiver, call.arguments.nodes.slice(1));
|
|
2412
2589
|
}
|
|
2413
2590
|
function lowerScalarUnionNumber(lowerer, arg, node, loc) {
|
|
2414
2591
|
if (arg.type.kind !== "union" ||
|
|
@@ -2523,9 +2700,29 @@ function lowerOptionalStringNumber(lowerer, arg, loc, fn = "num.fromString", lab
|
|
|
2523
2700
|
}
|
|
2524
2701
|
return { kind: "call", callee: helper, args: [arg], type: F64, loc };
|
|
2525
2702
|
}
|
|
2526
|
-
/**
|
|
2527
|
-
*
|
|
2528
|
-
|
|
2703
|
+
/** `s[Symbol.iterator]()` on a string-typed receiver: the generator over
|
|
2704
|
+
* its code points. Null for other element calls. */
|
|
2705
|
+
function lowerStringIteratorCall(lowerer, call, access) {
|
|
2706
|
+
let key = access.argumentExpression;
|
|
2707
|
+
while (ts.isParenthesizedExpression(key))
|
|
2708
|
+
key = key.expression;
|
|
2709
|
+
if (!ts.isPropertyAccessExpression(key) ||
|
|
2710
|
+
lowerer.stdlibGlobalMember(key, "Symbol") !== "iterator")
|
|
2711
|
+
return null;
|
|
2712
|
+
if (lowerer.mapTypeOf(lowerer.typeOf(access.expression))?.kind !== "string")
|
|
2713
|
+
return null;
|
|
2714
|
+
const type = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
2715
|
+
if (type?.kind !== "generator")
|
|
2716
|
+
return null;
|
|
2717
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
2718
|
+
const value = lowerStringIteratorValue(lowerer, receiver, type, locOf(call));
|
|
2719
|
+
if (!value)
|
|
2720
|
+
lowerer.unsupported("SC1090", call, "this string iterator type");
|
|
2721
|
+
return value;
|
|
2722
|
+
}
|
|
2723
|
+
/** Iterator types with checked runtime receivers, whose helper calls lower
|
|
2724
|
+
* in lowerGeneratorHelperCall. */
|
|
2725
|
+
const CHECKED_ITERATOR_TYPES = new Set(["MapIterator", "SetIterator"]);
|
|
2529
2726
|
const ITERATOR_HELPER_METHODS = new Set([
|
|
2530
2727
|
"map",
|
|
2531
2728
|
"filter",
|
|
@@ -2539,6 +2736,13 @@ const ITERATOR_HELPER_METHODS = new Set([
|
|
|
2539
2736
|
"every",
|
|
2540
2737
|
"find",
|
|
2541
2738
|
]);
|
|
2739
|
+
/** A call expression, through parentheses: its value has no other holder. */
|
|
2740
|
+
function isFreshCallResult(node) {
|
|
2741
|
+
let e = node;
|
|
2742
|
+
while (ts.isParenthesizedExpression(e))
|
|
2743
|
+
e = e.expression;
|
|
2744
|
+
return ts.isCallExpression(e);
|
|
2745
|
+
}
|
|
2542
2746
|
/** METHOD calls on dyn receivers (`pkg.name.replace(...)`, `rawName.split`,
|
|
2543
2747
|
* `ws.packages.filter(...)` — JSON.parse-derived values): validate the
|
|
2544
2748
|
* receiver's dyn kind, extract, and ride the STATIC method machinery — the
|
|
@@ -2552,7 +2756,7 @@ const ITERATOR_HELPER_METHODS = new Set([
|
|
|
2552
2756
|
* the dyn array and validated-extracts the survivors into the element type
|
|
2553
2757
|
* the checker committed the result to. Null when the receiver isn't a dyn
|
|
2554
2758
|
* value or the method isn't claimable (the method-call fence stays). */
|
|
2555
|
-
function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
2759
|
+
function lowerDynReceiverMethodCall(lowerer, call, access, boxTypedTemporary = false) {
|
|
2556
2760
|
if (lowerer.chainBlocked(call, access))
|
|
2557
2761
|
return null;
|
|
2558
2762
|
if (stdlibGlobalNameOf(lowerer, access.expression) !== null) {
|
|
@@ -2570,7 +2774,12 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2570
2774
|
// array — scalar narrowings bridge through maybeNarrow's dynCheck and
|
|
2571
2775
|
// take the ordinary typed paths, but there is no static home for an
|
|
2572
2776
|
// any-elemented array). Typed receivers keep their own lowerings.
|
|
2573
|
-
|
|
2777
|
+
// An optional step the chain already guarded (`s?.m(x)`) has a receiver
|
|
2778
|
+
// proven non-nullish.
|
|
2779
|
+
const rawRecvTs = lowerer.typeOf(access.expression);
|
|
2780
|
+
const recvTs = access.questionDotToken !== undefined && lowerer.chainHandled.has(access)
|
|
2781
|
+
? lowerer.checker.getNonNullableType(rawRecvTs)
|
|
2782
|
+
: rawRecvTs;
|
|
2574
2783
|
if (lowerer.classImplementedProtocol(recvTs)) {
|
|
2575
2784
|
const property = lowerer.checker.getPropertyOfType(recvTs, access.name.text);
|
|
2576
2785
|
if (property &&
|
|
@@ -2579,15 +2788,14 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2579
2788
|
}
|
|
2580
2789
|
const recvSymbol = recvTs.getSymbol();
|
|
2581
2790
|
if (recvSymbol &&
|
|
2582
|
-
|
|
2791
|
+
CHECKED_ITERATOR_TYPES.has(ts.symbolName(recvSymbol)) &&
|
|
2583
2792
|
lowerer.isStdlibSymbol(recvSymbol) &&
|
|
2584
2793
|
ITERATOR_HELPER_METHODS.has(access.name.text) &&
|
|
2585
2794
|
lowerer.isStdlibMember(access)) {
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
lowerer.noLowering(`${recvSymbol.name}.${access.name.text}`, call, "iterator helpers lower on chains from arr.values() or arr.entries() that end in a terminal (toArray, forEach, reduce, some, every, find) — spread the string first: [...s].values()");
|
|
2795
|
+
const helper = lowerGeneratorHelperCall(lowerer, call, access);
|
|
2796
|
+
if (helper)
|
|
2797
|
+
return helper;
|
|
2798
|
+
lowerer.noLowering(`collection iterator .${access.name.text}()`, call, "iterator helpers on Map/Set iterators are called directly on the iterator, without optional chaining");
|
|
2591
2799
|
}
|
|
2592
2800
|
const arrayReceiver = lowerer.checker.isArrayType(recvTs);
|
|
2593
2801
|
const anyArray = arrayReceiver &&
|
|
@@ -2627,7 +2835,7 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2627
2835
|
type: DYN,
|
|
2628
2836
|
loc,
|
|
2629
2837
|
};
|
|
2630
|
-
if (call.arguments.some(ts.isSpreadElement)) {
|
|
2838
|
+
if (call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
2631
2839
|
lowerer.unsupported("SC1090", call, "spread arguments in callable property calls");
|
|
2632
2840
|
}
|
|
2633
2841
|
return {
|
|
@@ -2637,8 +2845,8 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2637
2845
|
kind: "dynCall",
|
|
2638
2846
|
callee: member,
|
|
2639
2847
|
receiver,
|
|
2640
|
-
calleeName:
|
|
2641
|
-
args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
2848
|
+
calleeName: ts.getTextOfNode(access),
|
|
2849
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
2642
2850
|
type: DYN,
|
|
2643
2851
|
loc,
|
|
2644
2852
|
},
|
|
@@ -2651,8 +2859,14 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2651
2859
|
if (info)
|
|
2652
2860
|
return lowerStaticMethodCall(lowerer, call, access);
|
|
2653
2861
|
}
|
|
2862
|
+
// A possibly missing element of a class-typed array (`items[i]`) is
|
|
2863
|
+
// the receiver's class or undefined. The class method call checks for
|
|
2864
|
+
// undefined itself, as it does in TypeScript.
|
|
2865
|
+
const presentArm = probed?.type.kind === "union" ? lowerer.stripUndefinedArm(probed.type) : null;
|
|
2866
|
+
if (presentArm?.kind === "object" && typeEquals(presentArm, lowerer.mapTypeOf(recvTs) ?? DYN))
|
|
2867
|
+
return null;
|
|
2654
2868
|
if (probed?.type.kind === "union" &&
|
|
2655
|
-
isJsSourceFile(
|
|
2869
|
+
isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
2656
2870
|
lowerer.unions
|
|
2657
2871
|
.get(probed.type.unionId)
|
|
2658
2872
|
?.arms.every((arm) => isUnitType(arm) ||
|
|
@@ -2687,13 +2901,47 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2687
2901
|
return (lowerRegexMethodCall(lowerer, call, access, () => recv) ??
|
|
2688
2902
|
lowerStringMethodCall(lowerer, call, access, () => recv));
|
|
2689
2903
|
}
|
|
2904
|
+
// A checker-untyped JS binding holding `string | undefined` (string-
|
|
2905
|
+
// width's `const visibleSegment = baseVisible(segment)` after an
|
|
2906
|
+
// `=== undefined` guard the checker cannot see through): no typed
|
|
2907
|
+
// lowering claims the union, so a String method boxes it and takes the
|
|
2908
|
+
// dyn receiver path, whose undefined/null arms throw Node's read errors.
|
|
2909
|
+
if (checkerUntyped &&
|
|
2910
|
+
recv.type.kind === "union" &&
|
|
2911
|
+
isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
2912
|
+
isStringMethodName(access.name.text) &&
|
|
2913
|
+
lowerer.unions
|
|
2914
|
+
.get(recv.type.unionId)
|
|
2915
|
+
?.arms.every((arm) => arm.kind === "string" || isUnitType(arm)) === true &&
|
|
2916
|
+
lowerer.dynConvertible(recv.type)) {
|
|
2917
|
+
recv = lowerer.coerceToExpected(recv, DYN);
|
|
2918
|
+
}
|
|
2919
|
+
// A native handle read through `as any` (`(hash as any).update(x)`)
|
|
2920
|
+
// dispatches through the handle, as the same value held in an
|
|
2921
|
+
// 'unknown' slot does.
|
|
2922
|
+
if (checkerUntyped && DYN_HANDLE_KINDS.has(recv.type.kind))
|
|
2923
|
+
recv = lowerer.coerceToExpected(recv, DYN);
|
|
2924
|
+
// The last-resort retry (boxTypedTemporary — every other lowering
|
|
2925
|
+
// already declined): a checker-`any` receiver whose value is a FRESH
|
|
2926
|
+
// typed result of an earlier step in the chain (`out.split("\n")`
|
|
2927
|
+
// extracted the string and answered a native string[]) has no typed
|
|
2928
|
+
// home under its `any` spelling, so it boxes into the checked-dynamic
|
|
2929
|
+
// tree and the call dispatches on the runtime kind — `.map`, `.pop`,
|
|
2930
|
+
// `.filter` on that array run JS-exact. Only call results qualify:
|
|
2931
|
+
// the box copies, and a temporary has no other holder to observe it.
|
|
2932
|
+
if (boxTypedTemporary &&
|
|
2933
|
+
checkerUntyped &&
|
|
2934
|
+
recv.type.kind !== "dyn" &&
|
|
2935
|
+
isFreshCallResult(access.expression) &&
|
|
2936
|
+
lowerer.dynConvertible(recv.type))
|
|
2937
|
+
recv = lowerer.coerceToExpected(recv, DYN);
|
|
2690
2938
|
if (recv.type.kind !== "dyn")
|
|
2691
2939
|
return null;
|
|
2692
2940
|
if (access.name.text === "normalize" &&
|
|
2693
|
-
call.arguments.length <= 1 &&
|
|
2694
|
-
!call.arguments.some(ts.isSpreadElement)) {
|
|
2941
|
+
call.arguments.nodes.length <= 1 &&
|
|
2942
|
+
!call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
2695
2943
|
const loc = locOf(call);
|
|
2696
|
-
const hasArgument = call.arguments.length === 1;
|
|
2944
|
+
const hasArgument = call.arguments.nodes.length === 1;
|
|
2697
2945
|
const name = `%dyn.string.normalize:${hasArgument ? 1 : 0}`;
|
|
2698
2946
|
if (!lowerer.liftedFns.some((fn) => fn.name === name)) {
|
|
2699
2947
|
const value = varRef("receiver", DYN, loc);
|
|
@@ -2742,7 +2990,7 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2742
2990
|
kind: "dynInvoke",
|
|
2743
2991
|
recv: value,
|
|
2744
2992
|
method: "normalize",
|
|
2745
|
-
calleeName:
|
|
2993
|
+
calleeName: ts.getTextOfNode(access),
|
|
2746
2994
|
args: hasArgument ? [argument] : [],
|
|
2747
2995
|
type: DYN,
|
|
2748
2996
|
loc,
|
|
@@ -2757,8 +3005,8 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2757
3005
|
callee: name,
|
|
2758
3006
|
args: [
|
|
2759
3007
|
recv,
|
|
2760
|
-
call.arguments[0]
|
|
2761
|
-
? lowerer.lowerExprExpecting(call.arguments[0], DYN)
|
|
3008
|
+
call.arguments.nodes[0]
|
|
3009
|
+
? lowerer.lowerExprExpecting(call.arguments.nodes[0], DYN)
|
|
2762
3010
|
: dynUndefinedExpr(loc),
|
|
2763
3011
|
],
|
|
2764
3012
|
type: DYN,
|
|
@@ -2777,9 +3025,7 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2777
3025
|
// Those are not stored members of a checked-dynamic object, so
|
|
2778
3026
|
// dynKeyGet cannot stand in for JavaScript's prototype lookup. Only
|
|
2779
3027
|
// an authored declaration can justify the own-member path.
|
|
2780
|
-
const authored = lowerer.
|
|
2781
|
-
.declarationsOf(prop)
|
|
2782
|
-
.some((decl) => !lowerer.isStdlibFile(decl.getSourceFile()));
|
|
3028
|
+
const authored = prop.declarations.some((decl) => !lowerer.isStdlibFile(ts.getSourceFileOfNode(decl)));
|
|
2783
3029
|
return (authored &&
|
|
2784
3030
|
lowerer.checker.getCallSignatures(lowerer.checker.getTypeOfSymbol(prop)).length > 0);
|
|
2785
3031
|
})();
|
|
@@ -2803,22 +3049,53 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2803
3049
|
return (lowerRegexMethodCall(lowerer, call, access, checked) ??
|
|
2804
3050
|
lowerStringMethodCall(lowerer, call, access, checked));
|
|
2805
3051
|
}
|
|
3052
|
+
// String/Number methods the runtime dispatch has no answer for
|
|
3053
|
+
// (codePointAt, substr, toLocaleLowerCase, toPrecision, ...): a string
|
|
3054
|
+
// or number receiver runs the typed lowering, every other kind keeps the
|
|
3055
|
+
// runtime dispatch.
|
|
3056
|
+
if (!ownCallable &&
|
|
3057
|
+
!call.questionDotToken &&
|
|
3058
|
+
!access.questionDotToken &&
|
|
3059
|
+
isDynPrimitiveKindMethod(access.name.text) &&
|
|
3060
|
+
!lowerer.chainBlocked(access, call)) {
|
|
3061
|
+
const primitive = lowerDynPrimitiveMethodCall(lowerer, call, access.name.text, ts.getTextOfNode(access), recv);
|
|
3062
|
+
if (primitive)
|
|
3063
|
+
return primitive;
|
|
3064
|
+
}
|
|
2806
3065
|
// The argument is a radix for bigint and an encoding for Buffer.
|
|
2807
3066
|
// Preserve its runtime value so receiver dispatch can choose correctly.
|
|
2808
|
-
if (access.name.text === "toString" && call.arguments.length <= 1) {
|
|
2809
|
-
const argument = call.arguments[0];
|
|
3067
|
+
if (access.name.text === "toString" && call.arguments.nodes.length <= 1) {
|
|
3068
|
+
const argument = call.arguments.nodes[0];
|
|
2810
3069
|
return {
|
|
2811
3070
|
kind: "libCall",
|
|
2812
3071
|
fn: "dyn.toString",
|
|
2813
3072
|
args: [
|
|
2814
3073
|
recv,
|
|
2815
3074
|
argument ? lowerer.lowerExprExpecting(argument, DYN) : dynUndefinedExpr(locOf(call)),
|
|
2816
|
-
{ kind: "strLit", value:
|
|
3075
|
+
{ kind: "strLit", value: ts.getTextOfNode(access), type: STRING, loc: locOf(call) },
|
|
2817
3076
|
],
|
|
2818
3077
|
type: STRING,
|
|
2819
3078
|
loc: locOf(call),
|
|
2820
3079
|
};
|
|
2821
3080
|
}
|
|
3081
|
+
// Every dyn kind's prototype chain declares valueOf, and the runtime
|
|
3082
|
+
// answers each kind's own: primitives and plain objects themselves, a
|
|
3083
|
+
// Date its time value, an own or inherited valueOf member its result.
|
|
3084
|
+
if (access.name.text === "valueOf" && call.arguments.nodes.length === 0) {
|
|
3085
|
+
const webAssembly = lowerWebAssemblyValueOf(lowerer, access.expression, recv, locOf(call));
|
|
3086
|
+
if (webAssembly !== null)
|
|
3087
|
+
return webAssembly;
|
|
3088
|
+
return {
|
|
3089
|
+
kind: "libCall",
|
|
3090
|
+
fn: "dyn.valueOf",
|
|
3091
|
+
args: [
|
|
3092
|
+
recv,
|
|
3093
|
+
{ kind: "strLit", value: ts.getTextOfNode(access), type: STRING, loc: locOf(call) },
|
|
3094
|
+
],
|
|
3095
|
+
type: DYN,
|
|
3096
|
+
loc: locOf(call),
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
2822
3099
|
// SHARED prototype names with a runtime dispatch (scr_dyn_invoke):
|
|
2823
3100
|
// push/slice/join/forEach/map/apply/... dispatch on the receiver's
|
|
2824
3101
|
// RUNTIME kind — the honest answer for names more than one dyn-
|
|
@@ -2840,9 +3117,7 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2840
3117
|
lowerer.classes.get(arm.className)?.fields.has(access.name.text)))
|
|
2841
3118
|
return true;
|
|
2842
3119
|
return (prop !== undefined &&
|
|
2843
|
-
|
|
2844
|
-
.declarationsOf(prop)
|
|
2845
|
-
.some((decl) => ts.isPropertyDeclaration(decl) || ts.isPropertySignature(decl)));
|
|
3120
|
+
prop.declarations.some((decl) => ts.isPropertyDeclaration(decl) || ts.isPropertySignature(decl)));
|
|
2846
3121
|
})();
|
|
2847
3122
|
// Protocol methods keep their static signature: instances of the
|
|
2848
3123
|
// implementing classes call the native method.
|
|
@@ -2872,7 +3147,19 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2872
3147
|
// its name overlaps a primitive prototype (`colors.bold(...)`): the
|
|
2873
3148
|
// source value was compiled from that object shape, while genuinely
|
|
2874
3149
|
// untyped/any receivers retain the runtime-kind ambiguity and fence.
|
|
2875
|
-
|
|
3150
|
+
// A name only String.prototype declares (`bold`, `italics`, `link`,
|
|
3151
|
+
// ...) on a checker-untyped receiver: every other dyn kind answers its
|
|
3152
|
+
// own or inherited member exactly like a non-prototype name (chalk's
|
|
3153
|
+
// `chalk.red.bold(...)` reads a prototype getter of a function), so
|
|
3154
|
+
// only a string receiver keeps the refusal, deferred to run time.
|
|
3155
|
+
// The same holds when only the MEMBER is checker-untyped: TypeScript
|
|
3156
|
+
// importing chalk's JavaScript source types the default export as a
|
|
3157
|
+
// plain function, so `chalk.bold` reads as `any` on a typed receiver.
|
|
3158
|
+
const stringOnlyName = (checkerUntyped ||
|
|
3159
|
+
(lowerer.typeOf(access).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0) &&
|
|
3160
|
+
!ownCallable &&
|
|
3161
|
+
DYN_STRING_PROTO_ONLY_NAMES.has(access.name.text);
|
|
3162
|
+
if (DYN_PROTO_METHOD_NAMES.has(access.name.text) && !ownCallable && !stringOnlyName)
|
|
2876
3163
|
return null;
|
|
2877
3164
|
// Optional forms (`obj.cb?.()`, `obj?.cb()`) belong to the chain
|
|
2878
3165
|
// machinery's short-circuit semantics — not modeled here yet.
|
|
@@ -2881,6 +3168,22 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2881
3168
|
const loc = locOf(call);
|
|
2882
3169
|
const receiverLocal = lowerer.declareHiddenLocal("%dynCallReceiver", DYN);
|
|
2883
3170
|
const receiver = { kind: "varRef", localId: receiverLocal.id, type: DYN, loc };
|
|
3171
|
+
// The string refusal throws in place of the member read (a seqExpr
|
|
3172
|
+
// statement cannot leave the expression).
|
|
3173
|
+
const stringRefusal = (read) => {
|
|
3174
|
+
if (!stringOnlyName)
|
|
3175
|
+
return read;
|
|
3176
|
+
const sf = ts.getSourceFileOfNode(call);
|
|
3177
|
+
const line = ts.getLineAndCharacterOfPosition(sf, ts.tokenStartOfNode(call)).line + 1;
|
|
3178
|
+
return {
|
|
3179
|
+
kind: "ternary",
|
|
3180
|
+
cond: { kind: "dynTest", test: "string", value: receiver, type: BOOL, loc },
|
|
3181
|
+
then: nodeThrowExpr(0, "SC1090", `method calls like '${ts.getTextOfNode(access)}' on a string are not supported yet [SC1090 at ${sf.fileName}:${line}]`, DYN, loc),
|
|
3182
|
+
else_: read,
|
|
3183
|
+
type: DYN,
|
|
3184
|
+
loc,
|
|
3185
|
+
};
|
|
3186
|
+
};
|
|
2884
3187
|
const member = {
|
|
2885
3188
|
kind: "dynKeyGet",
|
|
2886
3189
|
key: { kind: "strLit", value: access.name.text, type: STRING, loc: locOf(access) },
|
|
@@ -2892,15 +3195,15 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2892
3195
|
const callee = varRef(calleeLocal.id, DYN, loc);
|
|
2893
3196
|
const stmts = [
|
|
2894
3197
|
{ kind: "varDecl", localId: receiverLocal.id, init: recv, loc },
|
|
2895
|
-
{ kind: "varDecl", localId: calleeLocal.id, init: member, loc },
|
|
3198
|
+
{ kind: "varDecl", localId: calleeLocal.id, init: stringRefusal(member), loc },
|
|
2896
3199
|
];
|
|
2897
|
-
if (call.arguments.some(ts.isSpreadElement)) {
|
|
3200
|
+
if (call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
2898
3201
|
const spread = lowerSpreadArgsCall(lowerer, call, callee, loc);
|
|
2899
3202
|
if (spread?.kind === "dynCall")
|
|
2900
3203
|
return { kind: "seqExpr", stmts, result: { ...spread, receiver }, type: DYN, loc };
|
|
2901
3204
|
lowerer.unsupported("SC1090", call, "spread arguments in calls through 'unknown' values");
|
|
2902
3205
|
}
|
|
2903
|
-
const args = call.arguments.map((a) => lowerer.lowerExprExpecting(a, DYN));
|
|
3206
|
+
const args = call.arguments.nodes.map((a) => lowerer.lowerExprExpecting(a, DYN));
|
|
2904
3207
|
return {
|
|
2905
3208
|
kind: "seqExpr",
|
|
2906
3209
|
stmts,
|
|
@@ -2908,7 +3211,7 @@ function lowerDynReceiverMethodCall(lowerer, call, access) {
|
|
|
2908
3211
|
kind: "dynCall",
|
|
2909
3212
|
callee,
|
|
2910
3213
|
receiver,
|
|
2911
|
-
calleeName:
|
|
3214
|
+
calleeName: ts.getTextOfNode(access),
|
|
2912
3215
|
args,
|
|
2913
3216
|
type: DYN,
|
|
2914
3217
|
loc,
|
|
@@ -2999,6 +3302,30 @@ const DYN_PROTO_METHOD_NAMES = new Set([
|
|
|
2999
3302
|
"toFixed",
|
|
3000
3303
|
"toPrecision",
|
|
3001
3304
|
]);
|
|
3305
|
+
/** The DYN_PROTO_METHOD_NAMES that only String.prototype declares among
|
|
3306
|
+
* the dyn-representable kinds' prototypes. */
|
|
3307
|
+
const DYN_STRING_PROTO_ONLY_NAMES = new Set([
|
|
3308
|
+
"anchor",
|
|
3309
|
+
"big",
|
|
3310
|
+
"blink",
|
|
3311
|
+
"bold",
|
|
3312
|
+
"codePointAt",
|
|
3313
|
+
"fixed",
|
|
3314
|
+
"fontcolor",
|
|
3315
|
+
"fontsize",
|
|
3316
|
+
"isWellFormed",
|
|
3317
|
+
"italics",
|
|
3318
|
+
"link",
|
|
3319
|
+
"localeCompare",
|
|
3320
|
+
"normalize",
|
|
3321
|
+
"small",
|
|
3322
|
+
"strike",
|
|
3323
|
+
"sub",
|
|
3324
|
+
"sup",
|
|
3325
|
+
"toLocaleLowerCase",
|
|
3326
|
+
"toLocaleUpperCase",
|
|
3327
|
+
"toWellFormed",
|
|
3328
|
+
]);
|
|
3002
3329
|
/** The SHARED prototype names scr_dyn_invoke dispatches at runtime (the
|
|
3003
3330
|
* subset of DYN_PROTO_METHOD_NAMES with a receiver-kind dispatch): the
|
|
3004
3331
|
* runtime runs the real method for the receiver's kind, throws Node's
|
|
@@ -3163,10 +3490,10 @@ const DYN_DISPATCH_METHODS = new Set([
|
|
|
3163
3490
|
]);
|
|
3164
3491
|
export function lowerDynDispatchMethodCall(lowerer, call, access, recv, arrayReceiver) {
|
|
3165
3492
|
const method = access.name.text;
|
|
3166
|
-
if ((!DYN_DISPATCH_METHODS.has(method) && !isJsSourceFile(
|
|
3493
|
+
if ((!DYN_DISPATCH_METHODS.has(method) && !isJsSourceFile(ts.getSourceFileOfNode(call))) ||
|
|
3167
3494
|
lowerer.chainBlocked(call, access))
|
|
3168
3495
|
return null;
|
|
3169
|
-
if (call.arguments.some((arg) => ts.isSpreadElement(arg))) {
|
|
3496
|
+
if (call.arguments.nodes.some((arg) => ts.isSpreadElement(arg))) {
|
|
3170
3497
|
const loc = locOf(call);
|
|
3171
3498
|
const local = lowerer.declareHiddenLocal("%spreadReceiver", DYN);
|
|
3172
3499
|
const receiver = varRef(local.id, DYN, loc);
|
|
@@ -3195,9 +3522,11 @@ export function lowerDynDispatchMethodCall(lowerer, call, access, recv, arrayRec
|
|
|
3195
3522
|
};
|
|
3196
3523
|
lowerer.unsupported("SC1090", call, "spread arguments in calls through 'unknown' values");
|
|
3197
3524
|
}
|
|
3198
|
-
const predicate = method === "filter" && call.arguments
|
|
3525
|
+
const predicate = method === "filter" && call.arguments.nodes[0]
|
|
3526
|
+
? lowerer.lowerExpr(call.arguments.nodes[0])
|
|
3527
|
+
: null;
|
|
3199
3528
|
if (arrayReceiver && predicate?.type.kind === "func" && predicate.type.ret.kind === "void") {
|
|
3200
|
-
lowerer.unsupported("SC1090", call.arguments[0], "'.filter()' with a void-returning predicate (the callback return value is erased before its truthiness can be tested)");
|
|
3529
|
+
lowerer.unsupported("SC1090", call.arguments.nodes[0], "'.filter()' with a void-returning predicate (the callback return value is erased before its truthiness can be tested)");
|
|
3201
3530
|
}
|
|
3202
3531
|
// A dynamic argument array consumed immediately by the fixed-arity arrow
|
|
3203
3532
|
// apply lowering below never exposes its surplus tail. Keep a pushed
|
|
@@ -3206,14 +3535,14 @@ export function lowerDynDispatchMethodCall(lowerer, call, access, recv, arrayRec
|
|
|
3206
3535
|
// invented. If the slot falls inside the typed prefix, its dynCheck fails
|
|
3207
3536
|
// at the callback boundary; valid callers preserve the original prefix.
|
|
3208
3537
|
if (method === "push" &&
|
|
3209
|
-
call.arguments.length === 1 &&
|
|
3538
|
+
call.arguments.nodes.length === 1 &&
|
|
3210
3539
|
ts.isIdentifier(access.expression) &&
|
|
3211
3540
|
ts.isExpressionStatement(call.parent) &&
|
|
3212
3541
|
ts.isBlock(call.parent.parent)) {
|
|
3213
3542
|
const receiverSymbol = lowerer.checker.getSymbolAtLocation(access.expression);
|
|
3214
3543
|
const block = call.parent.parent;
|
|
3215
|
-
const statementIndex = block.statements.indexOf(call.parent);
|
|
3216
|
-
const next = statementIndex >= 0 ? block.statements[statementIndex + 1] : undefined;
|
|
3544
|
+
const statementIndex = block.statements.nodes.indexOf(call.parent);
|
|
3545
|
+
const next = statementIndex >= 0 ? block.statements.nodes[statementIndex + 1] : undefined;
|
|
3217
3546
|
let returned = next && ts.isReturnStatement(next) ? next.expression : undefined;
|
|
3218
3547
|
while (returned && ts.isParenthesizedExpression(returned))
|
|
3219
3548
|
returned = returned.expression;
|
|
@@ -3223,7 +3552,7 @@ export function lowerDynDispatchMethodCall(lowerer, call, access, recv, arrayRec
|
|
|
3223
3552
|
returned.expression.name.text === "apply"
|
|
3224
3553
|
? returned
|
|
3225
3554
|
: null;
|
|
3226
|
-
const argsNode = apply?.arguments[1];
|
|
3555
|
+
const argsNode = apply?.arguments?.nodes[1];
|
|
3227
3556
|
const sameArgs = receiverSymbol !== undefined &&
|
|
3228
3557
|
argsNode !== undefined &&
|
|
3229
3558
|
ts.isIdentifier(argsNode) &&
|
|
@@ -3237,7 +3566,7 @@ export function lowerDynDispatchMethodCall(lowerer, call, access, recv, arrayRec
|
|
|
3237
3566
|
arrow !== null &&
|
|
3238
3567
|
targetParams !== null &&
|
|
3239
3568
|
targetParams.every((param) => canDynCheckTo(param, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id)))) {
|
|
3240
|
-
const value = lowerer.lowerExpr(call.arguments[0]);
|
|
3569
|
+
const value = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
3241
3570
|
if (value.type.kind !== "dyn" && !lowerer.dynConvertible(value.type)) {
|
|
3242
3571
|
const saved = lowerer.declareHiddenLocal("%applyTail", DYN);
|
|
3243
3572
|
return {
|
|
@@ -3250,8 +3579,8 @@ export function lowerDynDispatchMethodCall(lowerer, call, access, recv, arrayRec
|
|
|
3250
3579
|
kind: "dynInvoke",
|
|
3251
3580
|
recv: { kind: "varRef", localId: saved.id, type: DYN, loc: locOf(access.expression) },
|
|
3252
3581
|
method,
|
|
3253
|
-
calleeName:
|
|
3254
|
-
args: [dynUndefinedExpr(locOf(call.arguments[0]))],
|
|
3582
|
+
calleeName: ts.getTextOfNode(access),
|
|
3583
|
+
args: [dynUndefinedExpr(locOf(call.arguments.nodes[0]))],
|
|
3255
3584
|
type: DYN,
|
|
3256
3585
|
loc: locOf(call),
|
|
3257
3586
|
},
|
|
@@ -3261,7 +3590,7 @@ export function lowerDynDispatchMethodCall(lowerer, call, access, recv, arrayRec
|
|
|
3261
3590
|
}
|
|
3262
3591
|
}
|
|
3263
3592
|
}
|
|
3264
|
-
const args = call.arguments.map((arg, i) => {
|
|
3593
|
+
const args = call.arguments.nodes.map((arg, i) => {
|
|
3265
3594
|
if (i === 0 && predicate)
|
|
3266
3595
|
return lowerer.coerceInto(arg, predicate, DYN);
|
|
3267
3596
|
const undefinedArg = lowerStaticallyUndefinedArgument(lowerer, arg);
|
|
@@ -3273,12 +3602,22 @@ export function lowerDynDispatchMethodCall(lowerer, call, access, recv, arrayRec
|
|
|
3273
3602
|
kind: "dynInvoke",
|
|
3274
3603
|
recv,
|
|
3275
3604
|
method,
|
|
3276
|
-
calleeName:
|
|
3605
|
+
calleeName: ts.getTextOfNode(access),
|
|
3277
3606
|
args,
|
|
3278
3607
|
type: DYN,
|
|
3279
3608
|
loc: locOf(call),
|
|
3280
3609
|
};
|
|
3281
3610
|
}
|
|
3611
|
+
/** Every String.prototype method name a typed or dyn string lowering
|
|
3612
|
+
* answers. */
|
|
3613
|
+
function isStringMethodName(name) {
|
|
3614
|
+
return (Object.hasOwn(STR_METHODS, name) ||
|
|
3615
|
+
STRING_INDEX_METHODS.has(name) ||
|
|
3616
|
+
DYN_STRING_ONLY_METHODS.has(name) ||
|
|
3617
|
+
isDynPrimitiveKindMethod(name) ||
|
|
3618
|
+
name === "normalize" ||
|
|
3619
|
+
name === "lastIndexOf");
|
|
3620
|
+
}
|
|
3282
3621
|
/** STR_METHODS ∪ the regex-form names, MINUS everything Array (or any
|
|
3283
3622
|
* other dyn kind's prototype) also declares. */
|
|
3284
3623
|
const DYN_STRING_ONLY_METHODS = new Set([
|
|
@@ -3314,9 +3653,9 @@ function lowerArrayIsArrayCall(lowerer, call, access) {
|
|
|
3314
3653
|
return null;
|
|
3315
3654
|
if (lowerer.stdlibGlobalMember(access, "Array") !== "isArray")
|
|
3316
3655
|
return null;
|
|
3317
|
-
if (call.arguments.length !== 1)
|
|
3656
|
+
if (call.arguments.nodes.length !== 1)
|
|
3318
3657
|
return null; // the stdlib chokepoint fences
|
|
3319
|
-
const argNode = call.arguments[0];
|
|
3658
|
+
const argNode = call.arguments.nodes[0];
|
|
3320
3659
|
const arg = lowerer.lowerExpr(argNode);
|
|
3321
3660
|
const loc = locOf(call);
|
|
3322
3661
|
if (arg.type.kind === "dyn") {
|
|
@@ -3388,22 +3727,26 @@ function lowerCaughtPredicateCall(lowerer, call, caughtLocal) {
|
|
|
3388
3727
|
if (!ts.isIdentifier(callee))
|
|
3389
3728
|
return null;
|
|
3390
3729
|
const symbol = lowerer.resolveValueSymbol(callee);
|
|
3391
|
-
const decl = symbol
|
|
3392
|
-
? lowerer.checker.declarationsOf(symbol).find(ts.isFunctionDeclaration)
|
|
3393
|
-
: undefined;
|
|
3730
|
+
const decl = symbol ? symbol.declarations.find(ts.isFunctionDeclaration) : undefined;
|
|
3394
3731
|
if (!symbol || !decl || !decl.body)
|
|
3395
3732
|
return null;
|
|
3396
3733
|
if (!decl.type || !ts.isTypePredicateNode(decl.type))
|
|
3397
3734
|
return null;
|
|
3398
|
-
if (decl.parameters.length !== 1)
|
|
3735
|
+
if (decl.parameters.nodes.length !== 1)
|
|
3399
3736
|
return null;
|
|
3400
|
-
const param = decl.parameters[0];
|
|
3737
|
+
const param = decl.parameters.nodes[0];
|
|
3401
3738
|
if (!ts.isIdentifier(param.name) || param.initializer || param.dotDotDotToken)
|
|
3402
3739
|
return null;
|
|
3403
3740
|
const paramSymbol = lowerer.checker.getSymbolAtLocation(param.name);
|
|
3404
3741
|
if (!paramSymbol)
|
|
3405
3742
|
return null;
|
|
3406
|
-
const ret = decl.body.statements.length === 1 ? decl.body.statements[0] : undefined;
|
|
3743
|
+
const ret = decl.body.statements.nodes.length === 1 ? decl.body.statements.nodes[0] : undefined;
|
|
3744
|
+
// A longer guard whose parameter is `unknown` (or `any`) takes the caught
|
|
3745
|
+
// value as an ordinary checked-dynamic argument: the call path converts
|
|
3746
|
+
// the binding, and the narrowed binding reads through the same value.
|
|
3747
|
+
if ((!ret || !ts.isReturnStatement(ret) || !ret.expression) &&
|
|
3748
|
+
lowerer.mapTypeOf(lowerer.checker.getTypeOfSymbol(paramSymbol))?.kind === "dyn")
|
|
3749
|
+
return null;
|
|
3407
3750
|
if (!ret || !ts.isReturnStatement(ret) || !ret.expression) {
|
|
3408
3751
|
lowerer.unsupported("SC1090", call, `the type-guard '${callee.text}' on a catch binding (only single-'return' guard bodies inline over the caught value)`);
|
|
3409
3752
|
}
|
|
@@ -3433,8 +3776,8 @@ function lowerNumberToStringCall(lowerer, call, access) {
|
|
|
3433
3776
|
if (lowerer.chainBlocked(call, access))
|
|
3434
3777
|
return null;
|
|
3435
3778
|
if (access.name.text !== "toString" ||
|
|
3436
|
-
call.arguments.length > 1 ||
|
|
3437
|
-
call.arguments.some(ts.isSpreadElement))
|
|
3779
|
+
call.arguments.nodes.length > 1 ||
|
|
3780
|
+
call.arguments.nodes.some(ts.isSpreadElement))
|
|
3438
3781
|
return null;
|
|
3439
3782
|
const recvKind = lowerer.mapTypeOf(lowerer.typeOf(access.expression))?.kind;
|
|
3440
3783
|
if (recvKind !== "f64" && recvKind !== "bool" && recvKind !== "string")
|
|
@@ -3451,22 +3794,44 @@ function lowerNumberToStringCall(lowerer, call, access) {
|
|
|
3451
3794
|
fn: "dyn.toString",
|
|
3452
3795
|
args: [
|
|
3453
3796
|
operand,
|
|
3454
|
-
call.arguments[0]
|
|
3455
|
-
? lowerer.lowerExprExpecting(call.arguments[0], DYN)
|
|
3797
|
+
call.arguments.nodes[0]
|
|
3798
|
+
? lowerer.lowerExprExpecting(call.arguments.nodes[0], DYN)
|
|
3456
3799
|
: dynUndefinedExpr(locOf(call)),
|
|
3457
|
-
{ kind: "strLit", value:
|
|
3800
|
+
{ kind: "strLit", value: ts.getTextOfNode(access), type: STRING, loc: locOf(call) },
|
|
3458
3801
|
],
|
|
3459
3802
|
type: STRING,
|
|
3460
3803
|
loc: locOf(call),
|
|
3461
3804
|
};
|
|
3462
3805
|
}
|
|
3463
|
-
if (call.arguments.length === 1) {
|
|
3806
|
+
if (call.arguments.nodes.length === 1) {
|
|
3464
3807
|
if (operand.type.kind !== "f64")
|
|
3465
3808
|
return null;
|
|
3809
|
+
const arg = call.arguments.nodes[0];
|
|
3810
|
+
// A number radix needs no box: ToIntegerOrInfinity of a number is a
|
|
3811
|
+
// truncation, which the typed entry point applies itself.
|
|
3812
|
+
if (!ts.isSpreadElement(arg) && lowerer.mapTypeOf(lowerer.typeOf(arg))?.kind === "f64") {
|
|
3813
|
+
const radix = lowerer.lowerExpr(arg);
|
|
3814
|
+
if (radix.type.kind === "f64") {
|
|
3815
|
+
return {
|
|
3816
|
+
kind: "libCall",
|
|
3817
|
+
fn: "num.toStringRadixF64",
|
|
3818
|
+
args: [operand, radix],
|
|
3819
|
+
type: STRING,
|
|
3820
|
+
loc: locOf(call),
|
|
3821
|
+
};
|
|
3822
|
+
}
|
|
3823
|
+
return {
|
|
3824
|
+
kind: "libCall",
|
|
3825
|
+
fn: "num.toStringRadix",
|
|
3826
|
+
args: [operand, lowerer.coerceToExpected(radix, DYN)],
|
|
3827
|
+
type: STRING,
|
|
3828
|
+
loc: locOf(call),
|
|
3829
|
+
};
|
|
3830
|
+
}
|
|
3466
3831
|
return {
|
|
3467
3832
|
kind: "libCall",
|
|
3468
3833
|
fn: "num.toStringRadix",
|
|
3469
|
-
args: [operand, lowerer.lowerExprExpecting(
|
|
3834
|
+
args: [operand, lowerer.lowerExprExpecting(arg, DYN)],
|
|
3470
3835
|
type: STRING,
|
|
3471
3836
|
loc: locOf(call),
|
|
3472
3837
|
};
|
|
@@ -3488,7 +3853,7 @@ function lowerNumberToStringCall(lowerer, call, access) {
|
|
|
3488
3853
|
function lowerUnionToStringCall(lowerer, call, access) {
|
|
3489
3854
|
if (call.questionDotToken || access.questionDotToken)
|
|
3490
3855
|
return null;
|
|
3491
|
-
if (access.name.text !== "toString" || call.arguments.length !== 0)
|
|
3856
|
+
if (access.name.text !== "toString" || call.arguments.nodes.length !== 0)
|
|
3492
3857
|
return null;
|
|
3493
3858
|
const recvT = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
3494
3859
|
if (recvT?.kind !== "union")
|
|
@@ -3502,9 +3867,17 @@ function lowerUnionToStringCall(lowerer, call, access) {
|
|
|
3502
3867
|
(a.kind === "bytes" && a.elem === "u8"));
|
|
3503
3868
|
if (!stringable)
|
|
3504
3869
|
return null;
|
|
3505
|
-
|
|
3870
|
+
let operand = lowerer.lowerExpr(access.expression);
|
|
3506
3871
|
if (operand.type.kind !== "union")
|
|
3507
3872
|
return null;
|
|
3873
|
+
// A flow-narrowed read keeps its wider storage union (`string | number`
|
|
3874
|
+
// after `!Array.isArray(h.host)` over a `string | number | string[]`
|
|
3875
|
+
// slot): retag it to the proven union before the per-union helper.
|
|
3876
|
+
if (operand.type.unionId !== recvT.unionId) {
|
|
3877
|
+
operand = lowerer.coerceInto(access.expression, operand, recvT);
|
|
3878
|
+
if (operand.type.kind !== "union" || operand.type.unionId !== recvT.unionId)
|
|
3879
|
+
return null;
|
|
3880
|
+
}
|
|
3508
3881
|
return { kind: "toString", operand, type: STRING, loc: locOf(call) };
|
|
3509
3882
|
}
|
|
3510
3883
|
/** `x.toString()` resolving to Object.prototype.toString (stdlib
|
|
@@ -3519,7 +3892,7 @@ function lowerUnionToStringCall(lowerer, call, access) {
|
|
|
3519
3892
|
function lowerDefaultToStringCall(lowerer, call, access) {
|
|
3520
3893
|
if (call.questionDotToken || access.questionDotToken)
|
|
3521
3894
|
return null;
|
|
3522
|
-
if (access.name.text !== "toString" || call.arguments.length !== 0)
|
|
3895
|
+
if (access.name.text !== "toString" || call.arguments.nodes.length !== 0)
|
|
3523
3896
|
return null;
|
|
3524
3897
|
if (!lowerer.isStdlibMember(access))
|
|
3525
3898
|
return null;
|
|
@@ -3553,7 +3926,7 @@ function lowerDefaultToStringCall(lowerer, call, access) {
|
|
|
3553
3926
|
// A null-prototype record (Object.groupBy) has no toString: Node
|
|
3554
3927
|
// throws "<callee> is not a function".
|
|
3555
3928
|
const nullProtoT = nullProtoRecordShape(lowerer, recvT);
|
|
3556
|
-
const missing = nullProtoT ? `${
|
|
3929
|
+
const missing = nullProtoT ? `${ts.getTextOfNode(access)} is not a function` : null;
|
|
3557
3930
|
if (!missing && pureObjectToStringReceiver(access.expression))
|
|
3558
3931
|
return constant;
|
|
3559
3932
|
const recv = lowerer.lowerExpr(access.expression);
|
|
@@ -3593,7 +3966,7 @@ function pureObjectToStringReceiver(node) {
|
|
|
3593
3966
|
ts.isTypeAssertion(e)) {
|
|
3594
3967
|
e = e.expression;
|
|
3595
3968
|
}
|
|
3596
|
-
if (ts.isObjectLiteralExpression(e) && e.properties.length === 0)
|
|
3969
|
+
if (ts.isObjectLiteralExpression(e) && e.properties.nodes.length === 0)
|
|
3597
3970
|
return true;
|
|
3598
3971
|
return pureReceiverNode(e);
|
|
3599
3972
|
}
|
|
@@ -3606,11 +3979,11 @@ function pureObjectToStringReceiver(node) {
|
|
|
3606
3979
|
function lowerClassHasOwnPropertyCall(lowerer, call, access) {
|
|
3607
3980
|
if (call.questionDotToken || access.questionDotToken)
|
|
3608
3981
|
return null;
|
|
3609
|
-
if (access.name.text !== "hasOwnProperty" || call.arguments.length !== 1)
|
|
3982
|
+
if (access.name.text !== "hasOwnProperty" || call.arguments.nodes.length !== 1)
|
|
3610
3983
|
return null;
|
|
3611
3984
|
if (!ts.isIdentifier(access.expression))
|
|
3612
3985
|
return null;
|
|
3613
|
-
const argNode = call.arguments[0];
|
|
3986
|
+
const argNode = call.arguments.nodes[0];
|
|
3614
3987
|
if (!ts.isStringLiteralLike(argNode))
|
|
3615
3988
|
return null;
|
|
3616
3989
|
if (!lowerer.isStdlibMember(access))
|
|
@@ -3621,7 +3994,7 @@ function lowerClassHasOwnPropertyCall(lowerer, call, access) {
|
|
|
3621
3994
|
return null; // builtin/runtime classes keep the fence
|
|
3622
3995
|
const key = argNode.text;
|
|
3623
3996
|
const own = new Set(["prototype", "name", "length"]);
|
|
3624
|
-
for (const m of info.decl.members) {
|
|
3997
|
+
for (const m of info.decl.members.nodes) {
|
|
3625
3998
|
const isStatic = ts.canHaveModifiers(m) &&
|
|
3626
3999
|
(ts.getModifiers(m) ?? []).some((mod) => mod.kind === ts.SyntaxKind.StaticKeyword);
|
|
3627
4000
|
if (!isStatic)
|
|
@@ -3692,26 +4065,52 @@ function lowerPrimitiveProtoCall(lowerer, call, recv, name, memberSym) {
|
|
|
3692
4065
|
return null;
|
|
3693
4066
|
const recvKind = lowerer.mapTypeOf(lowerer.typeOf(recv))?.kind;
|
|
3694
4067
|
if ((name === "toFixed" || name === "toExponential") &&
|
|
3695
|
-
call.arguments.length <= 1 &&
|
|
3696
|
-
!call.arguments.some(ts.isSpreadElement) &&
|
|
3697
|
-
isJsSourceFile(
|
|
4068
|
+
call.arguments.nodes.length <= 1 &&
|
|
4069
|
+
!call.arguments.nodes.some(ts.isSpreadElement) &&
|
|
4070
|
+
isJsSourceFile(ts.getSourceFileOfNode(call))) {
|
|
3698
4071
|
const operand = lowerer.lowerExpr(recv);
|
|
4072
|
+
if (name === "toExponential" &&
|
|
4073
|
+
call.arguments.nodes.length === 1 &&
|
|
4074
|
+
(operand.type.kind === "dyn" ||
|
|
4075
|
+
(operand.type.kind === "union" && lowerer.dynConvertible(operand.type)))) {
|
|
4076
|
+
const dispatched = lowerDynPrimitiveMethodCall(lowerer, call, name, `${ts.getTextOfNode(recv)}.${name}`, lowerer.coerceToExpected(operand, DYN));
|
|
4077
|
+
if (dispatched)
|
|
4078
|
+
return dispatched;
|
|
4079
|
+
}
|
|
3699
4080
|
if (operand.type.kind === "dyn" ||
|
|
3700
4081
|
(operand.type.kind === "union" && lowerer.dynConvertible(operand.type)))
|
|
3701
4082
|
return {
|
|
3702
4083
|
kind: "dynInvoke",
|
|
3703
4084
|
recv: lowerer.coerceToExpected(operand, DYN),
|
|
3704
4085
|
method: name,
|
|
3705
|
-
calleeName: `${
|
|
3706
|
-
args: call.arguments.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
|
|
4086
|
+
calleeName: `${ts.getTextOfNode(recv)}.${name}`,
|
|
4087
|
+
args: call.arguments.nodes.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
|
|
3707
4088
|
type: DYN,
|
|
3708
4089
|
loc: locOf(call),
|
|
3709
4090
|
};
|
|
3710
4091
|
}
|
|
4092
|
+
if (name === "toPrecision" &&
|
|
4093
|
+
call.arguments.nodes.length <= 1 &&
|
|
4094
|
+
!call.arguments.nodes.some(ts.isSpreadElement) &&
|
|
4095
|
+
isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
4096
|
+
recvKind === "union") {
|
|
4097
|
+
const operand = lowerer.lowerExpr(recv);
|
|
4098
|
+
if (operand.type.kind === "union" && lowerer.dynConvertible(operand.type)) {
|
|
4099
|
+
const dispatched = lowerDynPrimitiveMethodCall(lowerer, call, name, `${ts.getTextOfNode(recv)}.${name}`, lowerer.coerceToExpected(operand, DYN));
|
|
4100
|
+
if (dispatched)
|
|
4101
|
+
return dispatched;
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
4104
|
+
if (recvKind === "f64" &&
|
|
4105
|
+
(name === "toPrecision" || (name === "toExponential" && call.arguments.nodes.length === 1))) {
|
|
4106
|
+
const typed = lowerExtraNumberMethodCall(lowerer, call, name, lowerer.lowerExpr(recv));
|
|
4107
|
+
if (typed)
|
|
4108
|
+
return typed;
|
|
4109
|
+
}
|
|
3711
4110
|
if (recvKind !== "f64" && recvKind !== "bool" && recvKind !== "string")
|
|
3712
4111
|
return null;
|
|
3713
4112
|
const loc = locOf(call);
|
|
3714
|
-
if (name === "toString" && call.arguments.length === 0) {
|
|
4113
|
+
if (name === "toString" && call.arguments.nodes.length === 0) {
|
|
3715
4114
|
const operand = lowerer.lowerExpr(recv);
|
|
3716
4115
|
if (operand.type.kind === "string")
|
|
3717
4116
|
return operand; // identity
|
|
@@ -3721,16 +4120,16 @@ function lowerPrimitiveProtoCall(lowerer, call, recv, name, memberSym) {
|
|
|
3721
4120
|
}
|
|
3722
4121
|
if ((name === "toExponential" || name === "toFixed") &&
|
|
3723
4122
|
recvKind === "f64" &&
|
|
3724
|
-
call.arguments.length === 0) {
|
|
4123
|
+
call.arguments.nodes.length === 0) {
|
|
3725
4124
|
const operand = lowerer.lowerExpr(recv);
|
|
3726
4125
|
if (operand.type.kind !== "f64")
|
|
3727
4126
|
return null;
|
|
3728
4127
|
const fn = name === "toExponential" ? "num.toExponential" : "num.toFixed0";
|
|
3729
4128
|
return { kind: "libCall", fn, args: [operand], type: STRING, loc };
|
|
3730
4129
|
}
|
|
3731
|
-
if (name === "toFixed" && recvKind === "f64" && call.arguments.length === 1) {
|
|
4130
|
+
if (name === "toFixed" && recvKind === "f64" && call.arguments.nodes.length === 1) {
|
|
3732
4131
|
const operand = lowerer.lowerExpr(recv);
|
|
3733
|
-
let digits = lowerer.lowerExpr(call.arguments[0]);
|
|
4132
|
+
let digits = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
3734
4133
|
// The optional parameter also admits undefined. Exact unit values
|
|
3735
4134
|
// become the default 0 after preserving any evaluation effects; an
|
|
3736
4135
|
// optional number selects 0 at runtime through the same narrowed
|
|
@@ -3769,15 +4168,15 @@ function lowerPrimitiveProtoCall(lowerer, call, recv, name, memberSym) {
|
|
|
3769
4168
|
// host environment's default, which a compiled binary cannot carry),
|
|
3770
4169
|
// other locales (ICU data the binary does not embed), options bags.
|
|
3771
4170
|
if (name === "toLocaleString" && recvKind === "f64") {
|
|
3772
|
-
if (call.arguments.length === 0) {
|
|
4171
|
+
if (call.arguments.nodes.length === 0) {
|
|
3773
4172
|
lowerer.noLowering("Number.prototype.toLocaleString without a locale", call, "the default locale is the host environment's, which a compiled binary cannot carry — " +
|
|
3774
4173
|
'pass it explicitly: x.toLocaleString("en-US")');
|
|
3775
4174
|
}
|
|
3776
|
-
if (call.arguments.length > 1) {
|
|
4175
|
+
if (call.arguments.nodes.length > 1) {
|
|
3777
4176
|
lowerer.noLowering("Number.prototype.toLocaleString with an options bag", call, "the embedded data covers DEFAULT options only (decimal notation, up to 3 fraction " +
|
|
3778
4177
|
'digits, grouping) — x.toLocaleString("en-US")');
|
|
3779
4178
|
}
|
|
3780
|
-
const locNode = call.arguments[0];
|
|
4179
|
+
const locNode = call.arguments.nodes[0];
|
|
3781
4180
|
if (ts.isSpreadElement(locNode) ||
|
|
3782
4181
|
!ts.isStringLiteralLike(locNode) ||
|
|
3783
4182
|
locNode.text !== "en-US") {
|
|
@@ -3793,17 +4192,17 @@ function lowerPrimitiveProtoCall(lowerer, call, recv, name, memberSym) {
|
|
|
3793
4192
|
}
|
|
3794
4193
|
if (name === "charAt" &&
|
|
3795
4194
|
recvKind === "string" &&
|
|
3796
|
-
call.arguments.length === 1 &&
|
|
3797
|
-
!ts.isSpreadElement(call.arguments[0])) {
|
|
4195
|
+
call.arguments.nodes.length === 1 &&
|
|
4196
|
+
!ts.isSpreadElement(call.arguments.nodes[0])) {
|
|
3798
4197
|
const receiver = lowerer.lowerExpr(recv);
|
|
3799
4198
|
if (receiver.type.kind !== "string")
|
|
3800
4199
|
return null;
|
|
3801
|
-
const idx = lowerer.lowerExprExpecting(call.arguments[0], F64);
|
|
4200
|
+
const idx = lowerer.lowerExprExpecting(call.arguments.nodes[0], F64);
|
|
3802
4201
|
return { kind: "strIntrinsic", method: "charAt", receiver, args: [idx], type: STRING, loc };
|
|
3803
4202
|
}
|
|
3804
|
-
if (name !== "hasOwnProperty" || call.arguments.length !== 1)
|
|
4203
|
+
if (name !== "hasOwnProperty" || call.arguments.nodes.length !== 1)
|
|
3805
4204
|
return null;
|
|
3806
|
-
const argNode = call.arguments[0];
|
|
4205
|
+
const argNode = call.arguments.nodes[0];
|
|
3807
4206
|
if (!ts.isStringLiteralLike(argNode))
|
|
3808
4207
|
return null;
|
|
3809
4208
|
const key = argNode.text;
|
|
@@ -3850,7 +4249,7 @@ function lowerPrimitiveProtoCall(lowerer, call, recv, name, memberSym) {
|
|
|
3850
4249
|
function implicitReceiverOverloadReturn(lowerer, expr) {
|
|
3851
4250
|
if (!ts.isCallExpression(expr) ||
|
|
3852
4251
|
!ts.isPropertyAccessExpression(expr.expression) ||
|
|
3853
|
-
expr.arguments.some(ts.isSpreadElement)) {
|
|
4252
|
+
expr.arguments.nodes.some(ts.isSpreadElement)) {
|
|
3854
4253
|
return null;
|
|
3855
4254
|
}
|
|
3856
4255
|
const access = expr.expression;
|
|
@@ -3865,14 +4264,14 @@ function implicitReceiverOverloadReturn(lowerer, expr) {
|
|
|
3865
4264
|
return null;
|
|
3866
4265
|
const signatures = lowerer.checker.getCallSignatures(lowerer.checker.getTypeOfSymbol(member));
|
|
3867
4266
|
const matches = signatures.filter((signature) => {
|
|
3868
|
-
const decl =
|
|
4267
|
+
const decl = signature.declaration;
|
|
3869
4268
|
if (!decl || !(ts.isFunctionDeclaration(decl) || ts.isMethodDeclaration(decl)) || decl.body) {
|
|
3870
4269
|
return false;
|
|
3871
4270
|
}
|
|
3872
|
-
const params = decl.parameters.filter((param) => !isThisParameter(param));
|
|
4271
|
+
const params = decl.parameters.nodes.filter((param) => !isThisParameter(param));
|
|
3873
4272
|
const required = params.filter((param) => !param.questionToken && !param.initializer && !param.dotDotDotToken).length;
|
|
3874
4273
|
const maximum = params.some((param) => param.dotDotDotToken) ? Infinity : params.length;
|
|
3875
|
-
return expr.arguments.length >= required && expr.arguments.length <= maximum;
|
|
4274
|
+
return expr.arguments.nodes.length >= required && expr.arguments.nodes.length <= maximum;
|
|
3876
4275
|
});
|
|
3877
4276
|
if (matches.length !== 1)
|
|
3878
4277
|
return null;
|
|
@@ -3906,21 +4305,38 @@ function isSoleAbstractMethod(decl) {
|
|
|
3906
4305
|
const owner = decl.parent;
|
|
3907
4306
|
if (!ts.isClassDeclaration(owner) && !ts.isClassExpression(owner))
|
|
3908
4307
|
return false;
|
|
3909
|
-
const name = decl.name
|
|
3910
|
-
return !owner.members.some((member) => member !== decl && ts.isMethodDeclaration(member) && member.name
|
|
4308
|
+
const name = ts.getTextOfNode(decl.name);
|
|
4309
|
+
return !owner.members.nodes.some((member) => member !== decl && ts.isMethodDeclaration(member) && ts.getTextOfNode(member.name) === name);
|
|
3911
4310
|
}
|
|
3912
4311
|
function reconcileOverloadReturn(lowerer, expr, call) {
|
|
3913
4312
|
const rsig = lowerer.checker.getResolvedSignature(expr);
|
|
3914
|
-
const rdecl = rsig ?
|
|
4313
|
+
const rdecl = rsig ? rsig.declaration : undefined;
|
|
3915
4314
|
// Nominal covariant overrides share the base's return ABI, but retain
|
|
3916
4315
|
// their declared subclass result at the call site. Unannotated fluent
|
|
3917
4316
|
// JS overrides use the same bridge for their proven receiver result.
|
|
3918
4317
|
if (call.type.kind === "object" &&
|
|
3919
4318
|
rdecl &&
|
|
3920
4319
|
ts.isMethodDeclaration(rdecl) &&
|
|
3921
|
-
(!isJsSourceFile(
|
|
4320
|
+
(!isJsSourceFile(ts.getSourceFileOfNode(rdecl)) || returnsOnlyThis(rdecl))) {
|
|
3922
4321
|
call = lowerer.maybeNarrow(call, expr);
|
|
3923
4322
|
}
|
|
4323
|
+
// An override narrowed to part of its base's union return shares the
|
|
4324
|
+
// union ABI; a call resolved to that override narrows the result back.
|
|
4325
|
+
if (call.type.kind === "union" &&
|
|
4326
|
+
rsig &&
|
|
4327
|
+
rdecl &&
|
|
4328
|
+
ts.isMethodDeclaration(rdecl) &&
|
|
4329
|
+
lowerer.unionReturnOverrides.has(rdecl)) {
|
|
4330
|
+
const declared = lowerer.mapTypeOf(lowerer.checker.getReturnTypeOfSignature(rsig));
|
|
4331
|
+
if (declared && !typeEquals(declared, call.type)) {
|
|
4332
|
+
if (declared.kind !== "union") {
|
|
4333
|
+
const helper = lowerer.narrowedArmHelper(call.type.unionId, declared, call.loc);
|
|
4334
|
+
if (helper)
|
|
4335
|
+
return lowerer.checkedNarrowCall(helper, call, declared, call.loc);
|
|
4336
|
+
}
|
|
4337
|
+
return lowerer.coerceInto(expr, call, declared);
|
|
4338
|
+
}
|
|
4339
|
+
}
|
|
3924
4340
|
const resolvedOverload = rsig &&
|
|
3925
4341
|
rdecl &&
|
|
3926
4342
|
(ts.isFunctionDeclaration(rdecl) || ts.isMethodDeclaration(rdecl)) &&
|
|
@@ -4000,7 +4416,7 @@ export function lowerTaggedTemplate(lowerer, expr) {
|
|
|
4000
4416
|
const loc = locOf(expr);
|
|
4001
4417
|
const pieces = ts.isNoSubstitutionTemplateLiteral(expr.template)
|
|
4002
4418
|
? [expr.template]
|
|
4003
|
-
: [expr.template.head, ...expr.template.templateSpans.map((s) => s.literal)];
|
|
4419
|
+
: [expr.template.head, ...expr.template.templateSpans.nodes.map((s) => s.literal)];
|
|
4004
4420
|
for (const p of pieces) {
|
|
4005
4421
|
if (!templateEscapesValid(templateRawTextOf(p))) {
|
|
4006
4422
|
lowerer.unsupported("SC1090", p, "tagged templates with invalid escape sequences (the span cooks to undefined, which the strings array cannot carry)");
|
|
@@ -4009,7 +4425,7 @@ export function lowerTaggedTemplate(lowerer, expr) {
|
|
|
4009
4425
|
const strings = () => loweredTemplateStrings(lowerer, expr, pieces.map((piece) => piece.text), loc);
|
|
4010
4426
|
const values = ts.isNoSubstitutionTemplateLiteral(expr.template)
|
|
4011
4427
|
? []
|
|
4012
|
-
: expr.template.templateSpans.map((s) => s.expression);
|
|
4428
|
+
: expr.template.templateSpans.nodes.map((s) => s.expression);
|
|
4013
4429
|
// Direct call of a top-level declared function — the plain-call fast
|
|
4014
4430
|
// path with the strings array as the leading completed argument.
|
|
4015
4431
|
if (ts.isIdentifier(expr.tag) && !lowerer.isSelfReference(expr.tag)) {
|
|
@@ -4054,7 +4470,7 @@ export function lowerTaggedTemplate(lowerer, expr) {
|
|
|
4054
4470
|
// tag throws Node's catchable "<name> is not a function" TypeError.
|
|
4055
4471
|
let callee = lowerer.lowerExpr(expr.tag);
|
|
4056
4472
|
if (callee.type.kind === "func" &&
|
|
4057
|
-
isJsSourceFile(
|
|
4473
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
4058
4474
|
lowerer.dynConvertible(callee.type)) {
|
|
4059
4475
|
callee = { kind: "dynFrom", value: callee, type: DYN, loc };
|
|
4060
4476
|
}
|
|
@@ -4064,7 +4480,7 @@ export function lowerTaggedTemplate(lowerer, expr) {
|
|
|
4064
4480
|
...values.map((a) => lowerer.lowerExprExpecting(a, DYN)),
|
|
4065
4481
|
];
|
|
4066
4482
|
const calleeName = ts.isPropertyAccessExpression(expr.tag) || ts.isElementAccessExpression(expr.tag)
|
|
4067
|
-
? expr.tag
|
|
4483
|
+
? ts.getTextOfNode(expr.tag)
|
|
4068
4484
|
: ts.isIdentifier(expr.tag)
|
|
4069
4485
|
? expr.tag.text
|
|
4070
4486
|
: "value";
|
|
@@ -4123,7 +4539,7 @@ function loweredTemplateStrings(lowerer, expr, cooked, loc, raw) {
|
|
|
4123
4539
|
loc,
|
|
4124
4540
|
})
|
|
4125
4541
|
: null;
|
|
4126
|
-
const key = `templateStringsGlobal:${loc.file}:${expr.template
|
|
4542
|
+
const key = `templateStringsGlobal:${loc.file}:${ts.tokenStartOfNode(expr.template)}:${raw ? "checked" : "typed"}`;
|
|
4127
4543
|
let getter = lowerer.valueHelpers.get(key);
|
|
4128
4544
|
if (!getter) {
|
|
4129
4545
|
const site = lowerer.globalsList.length;
|
|
@@ -4228,7 +4644,7 @@ function markModuleNsHandlerParams(lowerer, handler, type) {
|
|
|
4228
4644
|
e = e.expression;
|
|
4229
4645
|
if (!ts.isArrowFunction(e) && !ts.isFunctionExpression(e))
|
|
4230
4646
|
return;
|
|
4231
|
-
for (const p of e.parameters) {
|
|
4647
|
+
for (const p of e.parameters.nodes) {
|
|
4232
4648
|
if (ts.isIdentifier(p.name) && !p.dotDotDotToken && !p.initializer) {
|
|
4233
4649
|
lowerer.moduleNsParamOverrides.set(p, type);
|
|
4234
4650
|
}
|
|
@@ -4269,12 +4685,12 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4269
4685
|
e.text === "undefined" &&
|
|
4270
4686
|
(lowerer.typeOf(e).flags & ts.TypeFlags.Undefined) !== 0));
|
|
4271
4687
|
};
|
|
4272
|
-
const passthrough = call.arguments.length === 0 ||
|
|
4273
|
-
(call.arguments.length === 1 && isAbsentHandler(call.arguments[0]));
|
|
4274
|
-
if (call.arguments.length !== 1 &&
|
|
4688
|
+
const passthrough = call.arguments.nodes.length === 0 ||
|
|
4689
|
+
(call.arguments.nodes.length === 1 && isAbsentHandler(call.arguments.nodes[0]));
|
|
4690
|
+
if (call.arguments.nodes.length !== 1 &&
|
|
4275
4691
|
!passthrough &&
|
|
4276
|
-
!(member === "then" && call.arguments.length === 2)) {
|
|
4277
|
-
lowerer.noLowering(`${member} with ${call.arguments.length} arguments`, call, member === "then"
|
|
4692
|
+
!(member === "then" && call.arguments.nodes.length === 2)) {
|
|
4693
|
+
lowerer.noLowering(`${member} with ${call.arguments.nodes.length} arguments`, call, member === "then"
|
|
4278
4694
|
? "the supported form takes a fulfillment handler and an optional rejection handler"
|
|
4279
4695
|
: `the supported form takes exactly one ${member === "catch" ? "inline handler" : "callback"}`);
|
|
4280
4696
|
}
|
|
@@ -4343,9 +4759,9 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4343
4759
|
}
|
|
4344
4760
|
}
|
|
4345
4761
|
if (member === "then") {
|
|
4346
|
-
if (call.arguments.length === 2) {
|
|
4347
|
-
const fulfilledNode = call.arguments[0];
|
|
4348
|
-
const rejectedNode = call.arguments[1];
|
|
4762
|
+
if (call.arguments.nodes.length === 2) {
|
|
4763
|
+
const fulfilledNode = call.arguments.nodes[0];
|
|
4764
|
+
const rejectedNode = call.arguments.nodes[1];
|
|
4349
4765
|
const fulfilledAbsent = isAbsentHandler(fulfilledNode);
|
|
4350
4766
|
const rejectedAbsent = isAbsentHandler(rejectedNode);
|
|
4351
4767
|
const resultT = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
@@ -4412,6 +4828,9 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4412
4828
|
const resultOf = (value, returnsPromise = false) => {
|
|
4413
4829
|
if (value.type.kind === "promise")
|
|
4414
4830
|
return [lowerer.adoptingReturn(value, R, (e) => lowerer.coerceInto(call, e, R))];
|
|
4831
|
+
const flattened = maybePromiseHandlerResult(lowerer, call, value, R);
|
|
4832
|
+
if (flattened)
|
|
4833
|
+
return [flattened];
|
|
4415
4834
|
if (returnsPromise) {
|
|
4416
4835
|
// A boxed handler's promise result adopts too: the then job's
|
|
4417
4836
|
// turn after the call, then the await of the returned value.
|
|
@@ -4562,8 +4981,8 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4562
4981
|
// contextual type spelled (a module-namespace type has no mapping —
|
|
4563
4982
|
// the handle is the value's only story, isIslandExpr's local rule).
|
|
4564
4983
|
if (inner.kind === "moduleNs")
|
|
4565
|
-
markModuleNsHandlerParams(lowerer, call.arguments[0], inner);
|
|
4566
|
-
let cb = lowerer.lowerExpr(call.arguments[0]);
|
|
4984
|
+
markModuleNsHandlerParams(lowerer, call.arguments.nodes[0], inner);
|
|
4985
|
+
let cb = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
4567
4986
|
// A TYPED handler on a DYN-settling promise (the tracePromise
|
|
4568
4987
|
// result's `.then((value) => ...)` — the checker's generic
|
|
4569
4988
|
// instantiation typed the parameter, but the settled value is a
|
|
@@ -4592,7 +5011,7 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4592
5011
|
if (canConvertToDyn(v.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
4593
5012
|
return { kind: "dynFrom", value: v, type: DYN, loc };
|
|
4594
5013
|
}
|
|
4595
|
-
lowerer.unsupported("SC1090", call.arguments[0], `then handlers receiving '${lowerer.fmt(v.type)}' values through an untyped handler (the settled value cannot cross the checked-dynamic tree boundary)`);
|
|
5014
|
+
lowerer.unsupported("SC1090", call.arguments.nodes[0], `then handlers receiving '${lowerer.fmt(v.type)}' values through an untyped handler (the settled value cannot cross the checked-dynamic tree boundary)`);
|
|
4596
5015
|
};
|
|
4597
5016
|
const resultT = { kind: "promise", inner: DYN };
|
|
4598
5017
|
const fnName = `%fn${lowerer.lambdaCounter++}_then`;
|
|
@@ -4629,7 +5048,7 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4629
5048
|
value: {
|
|
4630
5049
|
kind: "dynCall",
|
|
4631
5050
|
callee: { kind: "varRef", localId: cbLocal.id, type: DYN, loc },
|
|
4632
|
-
calleeName: jsFuncNameOf(call.arguments[0], lowerer) ?? "onFulfilled",
|
|
5051
|
+
calleeName: jsFuncNameOf(call.arguments.nodes[0], lowerer) ?? "onFulfilled",
|
|
4633
5052
|
args: handlerArgs,
|
|
4634
5053
|
type: DYN,
|
|
4635
5054
|
loc,
|
|
@@ -4665,13 +5084,13 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4665
5084
|
}
|
|
4666
5085
|
}
|
|
4667
5086
|
if (cb.type.kind !== "func" || cb.type.params.length > 1) {
|
|
4668
|
-
lowerer.unsupported("SC1090", call.arguments[0], "then handlers with more than one parameter (the two-argument onRejected form has no lowering — chain .catch(...) instead)");
|
|
5087
|
+
lowerer.unsupported("SC1090", call.arguments.nodes[0], "then handlers with more than one parameter (the two-argument onRejected form has no lowering — chain .catch(...) instead)");
|
|
4669
5088
|
}
|
|
4670
5089
|
const param = cb.type.params[0];
|
|
4671
5090
|
if (param !== undefined &&
|
|
4672
5091
|
!typeEquals(param, inner) &&
|
|
4673
5092
|
!(param.kind === "dyn" && (inner.kind === "void" || lowerer.dynConvertible(inner)))) {
|
|
4674
|
-
lowerer.unsupported("SC1090", call.arguments[0], `then handlers whose parameter is not the settled value's type (expected '${lowerer.fmt(inner)}', got '${lowerer.fmt(param)}')`);
|
|
5093
|
+
lowerer.unsupported("SC1090", call.arguments.nodes[0], `then handlers whose parameter is not the settled value's type (expected '${lowerer.fmt(inner)}', got '${lowerer.fmt(param)}')`);
|
|
4675
5094
|
}
|
|
4676
5095
|
const resultT = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
4677
5096
|
if (resultT?.kind !== "promise") {
|
|
@@ -4723,7 +5142,11 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4723
5142
|
// The handler's result: promise returns flatten exactly like
|
|
4724
5143
|
// `return p` in any async body (the spec's thenable adoption);
|
|
4725
5144
|
// everything else coerces into R.
|
|
4726
|
-
|
|
5145
|
+
const flattened = maybePromiseHandlerResult(lowerer, call, handlerCall, R);
|
|
5146
|
+
if (flattened) {
|
|
5147
|
+
body.push(flattened);
|
|
5148
|
+
}
|
|
5149
|
+
else if (handlerCall.type.kind === "promise" && R.kind !== "promise") {
|
|
4727
5150
|
body.push(lowerer.adoptingReturn(handlerCall, R, (e) => lowerer.coerceInto(call, e, R)));
|
|
4728
5151
|
}
|
|
4729
5152
|
else if (R.kind === "void") {
|
|
@@ -4762,13 +5185,13 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4762
5185
|
}
|
|
4763
5186
|
}
|
|
4764
5187
|
if (member === "finally") {
|
|
4765
|
-
const cb = lowerer.lowerExpr(call.arguments[0]);
|
|
5188
|
+
const cb = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
4766
5189
|
if (lowerer.dynConvertible(promT) && lowerer.dynConvertible(cb.type)) {
|
|
4767
5190
|
const result = {
|
|
4768
5191
|
kind: "dynInvoke",
|
|
4769
5192
|
recv: lowerer.coerceToExpected(receiver, DYN),
|
|
4770
5193
|
method: "finally",
|
|
4771
|
-
calleeName:
|
|
5194
|
+
calleeName: ts.getTextOfNode(access),
|
|
4772
5195
|
args: [lowerer.coerceToExpected(cb, DYN)],
|
|
4773
5196
|
type: DYN,
|
|
4774
5197
|
loc,
|
|
@@ -4776,7 +5199,7 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4776
5199
|
return lowerer.coerceToExpected(result, promT);
|
|
4777
5200
|
}
|
|
4778
5201
|
if (cb.type.kind !== "func" || cb.type.params.length !== 0 || cb.type.ret.kind !== "void") {
|
|
4779
|
-
lowerer.unsupported("SC1090", call.arguments[0], "finally callbacks with parameters or a return value (use () => { ... })");
|
|
5202
|
+
lowerer.unsupported("SC1090", call.arguments.nodes[0], "finally callbacks with parameters or a return value (use () => { ... })");
|
|
4780
5203
|
}
|
|
4781
5204
|
const fnName = `%fn${lowerer.lambdaCounter++}_finally`;
|
|
4782
5205
|
const funcType = {
|
|
@@ -4865,9 +5288,9 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4865
5288
|
// snapshot (the dyn-then desugar's catch twin).
|
|
4866
5289
|
if (member === "catch" &&
|
|
4867
5290
|
(inner.kind === "dyn" ||
|
|
4868
|
-
(isJsSourceFile(
|
|
5291
|
+
(isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
4869
5292
|
(inner.kind === "void" || lowerer.dynConvertible(inner))))) {
|
|
4870
|
-
let cb = lowerer.lowerExpr(call.arguments[0]);
|
|
5293
|
+
let cb = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
4871
5294
|
if (cb.type.kind === "func" &&
|
|
4872
5295
|
canBoxFuncIntoDyn(cb.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
4873
5296
|
cb = { kind: "dynFrom", value: cb, type: DYN, loc };
|
|
@@ -4912,7 +5335,7 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4912
5335
|
value: {
|
|
4913
5336
|
kind: "dynCall",
|
|
4914
5337
|
callee: { kind: "varRef", localId: cbLocal.id, type: DYN, loc },
|
|
4915
|
-
calleeName: jsFuncNameOf(call.arguments[0], lowerer) ?? "onRejected",
|
|
5338
|
+
calleeName: jsFuncNameOf(call.arguments.nodes[0], lowerer) ?? "onRejected",
|
|
4916
5339
|
args: [
|
|
4917
5340
|
{
|
|
4918
5341
|
kind: "caughtToDyn",
|
|
@@ -4961,20 +5384,20 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
4961
5384
|
}
|
|
4962
5385
|
// .catch: the handler must be INLINE — its parameter becomes the
|
|
4963
5386
|
// catch binding.
|
|
4964
|
-
let handlerNode = call.arguments[0];
|
|
5387
|
+
let handlerNode = call.arguments.nodes[0];
|
|
4965
5388
|
while (ts.isParenthesizedExpression(handlerNode))
|
|
4966
5389
|
handlerNode = handlerNode.expression;
|
|
4967
5390
|
if (!ts.isArrowFunction(handlerNode) && !ts.isFunctionExpression(handlerNode)) {
|
|
4968
|
-
lowerer.unsupported("SC1090", call.arguments[0], "catch handlers that are not inline function literals (the handler's parameter " +
|
|
5391
|
+
lowerer.unsupported("SC1090", call.arguments.nodes[0], "catch handlers that are not inline function literals (the handler's parameter " +
|
|
4969
5392
|
"becomes a typed-catch binding, which only an inline `(e) => ...` can receive)");
|
|
4970
5393
|
}
|
|
4971
|
-
if (handlerNode.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword)) {
|
|
5394
|
+
if (handlerNode.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword)) {
|
|
4972
5395
|
lowerer.unsupported("SC1090", handlerNode, "async catch handlers");
|
|
4973
5396
|
}
|
|
4974
|
-
if (handlerNode.parameters.length > 1) {
|
|
5397
|
+
if (handlerNode.parameters.nodes.length > 1) {
|
|
4975
5398
|
lowerer.unsupported("SC1090", handlerNode, "catch handlers with more than one parameter");
|
|
4976
5399
|
}
|
|
4977
|
-
const param = handlerNode.parameters[0];
|
|
5400
|
+
const param = handlerNode.parameters.nodes[0];
|
|
4978
5401
|
if (param && (!ts.isIdentifier(param.name) || param.dotDotDotToken || param.initializer)) {
|
|
4979
5402
|
lowerer.unsupported("SC1062", param);
|
|
4980
5403
|
}
|
|
@@ -5021,7 +5444,7 @@ export function lowerPromiseMethodCall(lowerer, call, access) {
|
|
|
5021
5444
|
}
|
|
5022
5445
|
const hb = handlerNode.body;
|
|
5023
5446
|
if (ts.isBlock(hb)) {
|
|
5024
|
-
catchBody = lowerer.lowerStmts(hb.statements);
|
|
5447
|
+
catchBody = lowerer.lowerStmts(hb.statements.nodes);
|
|
5025
5448
|
}
|
|
5026
5449
|
else if (R.kind === "void") {
|
|
5027
5450
|
catchBody = [{ kind: "exprStmt", expr: lowerer.lowerExpr(hb), loc: locOf(hb) }];
|
|
@@ -5119,10 +5542,10 @@ export function lowerFilterNarrowCall(lowerer, call, access) {
|
|
|
5119
5542
|
return null;
|
|
5120
5543
|
if (!lowerer.isStdlibMember(access))
|
|
5121
5544
|
return null;
|
|
5122
|
-
if (call.arguments.length !== 1)
|
|
5545
|
+
if (call.arguments.nodes.length !== 1)
|
|
5123
5546
|
return null; // the generic path's arity fence
|
|
5124
5547
|
const elem = receiverIr.elem;
|
|
5125
|
-
const argNode = call.arguments[0];
|
|
5548
|
+
const argNode = call.arguments.nodes[0];
|
|
5126
5549
|
const loc = locOf(call);
|
|
5127
5550
|
const isBooleanArg = ts.isIdentifier(argNode) &&
|
|
5128
5551
|
argNode.text === "Boolean" &&
|
|
@@ -5324,19 +5747,19 @@ function lowerSymbolStaticCall(lowerer, call, access) {
|
|
|
5324
5747
|
const member = access.name.text;
|
|
5325
5748
|
const loc = locOf(call);
|
|
5326
5749
|
if (member === "for") {
|
|
5327
|
-
if (call.arguments.length !== 1) {
|
|
5328
|
-
lowerer.noLowering(`Symbol.for with ${call.arguments.length} arguments`, call);
|
|
5750
|
+
if (call.arguments.nodes.length !== 1) {
|
|
5751
|
+
lowerer.noLowering(`Symbol.for with ${call.arguments.nodes.length} arguments`, call);
|
|
5329
5752
|
}
|
|
5330
|
-
const key = lowerer.lowerExprExpecting(call.arguments[0], STRING);
|
|
5753
|
+
const key = lowerer.lowerExprExpecting(call.arguments.nodes[0], STRING);
|
|
5331
5754
|
return { kind: "libCall", fn: "sym.for", args: [key], type: SYMBOL_T, loc };
|
|
5332
5755
|
}
|
|
5333
5756
|
if (member === "keyFor") {
|
|
5334
|
-
if (call.arguments.length !== 1) {
|
|
5335
|
-
lowerer.noLowering(`Symbol.keyFor with ${call.arguments.length} arguments`, call);
|
|
5757
|
+
if (call.arguments.nodes.length !== 1) {
|
|
5758
|
+
lowerer.noLowering(`Symbol.keyFor with ${call.arguments.nodes.length} arguments`, call);
|
|
5336
5759
|
}
|
|
5337
|
-
const sym = lowerer.lowerExpr(call.arguments[0]);
|
|
5760
|
+
const sym = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
5338
5761
|
if (sym.type.kind !== "symbol") {
|
|
5339
|
-
lowerer.noLowering(`Symbol.keyFor of a '${lowerer.fmt(sym.type)}' value`, call.arguments[0], "the argument must be symbol-typed");
|
|
5762
|
+
lowerer.noLowering(`Symbol.keyFor of a '${lowerer.fmt(sym.type)}' value`, call.arguments.nodes[0], "the argument must be symbol-typed");
|
|
5340
5763
|
}
|
|
5341
5764
|
// The checker types the call `string | undefined`, which interns
|
|
5342
5765
|
// the result union (the map.get pattern); the backend builds the
|
|
@@ -5357,12 +5780,12 @@ function lowerBigIntStaticCall(lowerer, call, access) {
|
|
|
5357
5780
|
const name = access.name.text;
|
|
5358
5781
|
if (name !== "asUintN" && name !== "asIntN")
|
|
5359
5782
|
return null;
|
|
5360
|
-
if (call.arguments.length !== 2) {
|
|
5361
|
-
lowerer.noLowering(`BigInt.${name} with ${call.arguments.length} arguments`, call);
|
|
5783
|
+
if (call.arguments.nodes.length !== 2) {
|
|
5784
|
+
lowerer.noLowering(`BigInt.${name} with ${call.arguments.nodes.length} arguments`, call);
|
|
5362
5785
|
}
|
|
5363
5786
|
const loc = locOf(call);
|
|
5364
|
-
const bits = lowerer.lowerExprExpecting(call.arguments[0], F64);
|
|
5365
|
-
const value = lowerer.lowerExprExpecting(call.arguments[1], BIGINT_T);
|
|
5787
|
+
const bits = lowerer.lowerExprExpecting(call.arguments.nodes[0], F64);
|
|
5788
|
+
const value = lowerer.lowerExprExpecting(call.arguments.nodes[1], BIGINT_T);
|
|
5366
5789
|
return {
|
|
5367
5790
|
kind: "libCall",
|
|
5368
5791
|
fn: name === "asUintN" ? "bigint.asUintN" : "bigint.asIntN",
|
|
@@ -5381,12 +5804,12 @@ function lowerBigIntMethodCall(lowerer, call, access) {
|
|
|
5381
5804
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
5382
5805
|
if (receiver.type.kind !== "bigint")
|
|
5383
5806
|
return null;
|
|
5384
|
-
if (name === "valueOf" && call.arguments.length === 0)
|
|
5807
|
+
if (name === "valueOf" && call.arguments.nodes.length === 0)
|
|
5385
5808
|
return receiver;
|
|
5386
|
-
if (name === "toString" && call.arguments.length <= 1) {
|
|
5809
|
+
if (name === "toString" && call.arguments.nodes.length <= 1) {
|
|
5387
5810
|
const defaultRadix = { kind: "numLit", value: 10, type: F64, loc };
|
|
5388
|
-
const radix = call.arguments[0]
|
|
5389
|
-
? lowerOptionalArgument(lowerer, call.arguments[0], F64, defaultRadix)
|
|
5811
|
+
const radix = call.arguments.nodes[0]
|
|
5812
|
+
? lowerOptionalArgument(lowerer, call.arguments.nodes[0], F64, defaultRadix)
|
|
5390
5813
|
: defaultRadix;
|
|
5391
5814
|
return { kind: "libCall", fn: "bigint.toString", args: [receiver, radix], type: STRING, loc };
|
|
5392
5815
|
}
|
|
@@ -5404,13 +5827,13 @@ function lowerSymbolMethodCall(lowerer, call, access) {
|
|
|
5404
5827
|
return null;
|
|
5405
5828
|
const name = access.name.text;
|
|
5406
5829
|
const loc = locOf(call);
|
|
5407
|
-
if (name === "toString" && call.arguments.length === 0) {
|
|
5830
|
+
if (name === "toString" && call.arguments.nodes.length === 0) {
|
|
5408
5831
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
5409
5832
|
if (receiver.type.kind !== "symbol")
|
|
5410
5833
|
return null;
|
|
5411
5834
|
return { kind: "libCall", fn: "sym.toString", args: [receiver], type: STRING, loc };
|
|
5412
5835
|
}
|
|
5413
|
-
if (name === "valueOf" && call.arguments.length === 0) {
|
|
5836
|
+
if (name === "valueOf" && call.arguments.nodes.length === 0) {
|
|
5414
5837
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
5415
5838
|
if (receiver.type.kind !== "symbol")
|
|
5416
5839
|
return null;
|
|
@@ -5427,6 +5850,7 @@ function lowerSymbolMethodCall(lowerer, call, access) {
|
|
|
5427
5850
|
* for-in iterates exactly the keys Object.keys answers. */
|
|
5428
5851
|
export function recordKeysArrayCall(lowerer, receiver, argIr, shape, loc) {
|
|
5429
5852
|
const resultT = arrayOf(STRING);
|
|
5853
|
+
lowerer.keyOrder.observe(argIr);
|
|
5430
5854
|
const key = `obj.keys:${argIr.shapeId}:${typeKey(resultT)}`;
|
|
5431
5855
|
let helper = lowerer.arrHofHelpers.get(key);
|
|
5432
5856
|
if (!helper) {
|
|
@@ -5542,6 +5966,90 @@ function recordHasOwnHelper(lowerer, shapeId, loc) {
|
|
|
5542
5966
|
});
|
|
5543
5967
|
return helper;
|
|
5544
5968
|
}
|
|
5969
|
+
/** Whether `Object.assign(instance, record)` can copy every field of the
|
|
5970
|
+
* record shape into a field the class declares with the same type: a plain
|
|
5971
|
+
* record (no tuple, index signature or accessor slots) and a compiled
|
|
5972
|
+
* class whose chain has no builtin or runtime-provided storage and no
|
|
5973
|
+
* accessor for the written names. */
|
|
5974
|
+
function classAssignPlan(lowerer, className, srcShapeId) {
|
|
5975
|
+
const info = lowerer.classes.get(className);
|
|
5976
|
+
const shape = lowerer.shapes.get(srcShapeId);
|
|
5977
|
+
if (!info || !shape || shape.tuple || shape.indexValue || shapeHasAccessorSlots(shape))
|
|
5978
|
+
return false;
|
|
5979
|
+
for (let c = info; c; c = c.base) {
|
|
5980
|
+
if (c.builtinError || c.builtinEmitter || c.builtinStream !== undefined || c.def.runtime)
|
|
5981
|
+
return false;
|
|
5982
|
+
}
|
|
5983
|
+
return shape.fields.every((f) => {
|
|
5984
|
+
const declared = info.fields.get(f.name);
|
|
5985
|
+
return (declared !== undefined &&
|
|
5986
|
+
(typeEquals(declared, f.type) || lowerer.widthLiftPlan(f.type, declared) !== null) &&
|
|
5987
|
+
!lowerer.findMethodOn(info, f.name) &&
|
|
5988
|
+
!lowerer.findMethodOn(info, `get:${f.name}`) &&
|
|
5989
|
+
!lowerer.findMethodOn(info, `set:${f.name}`));
|
|
5990
|
+
});
|
|
5991
|
+
}
|
|
5992
|
+
/** Interned `%obj.assignClass.<n>(o, s)` — Object.assign's per-field
|
|
5993
|
+
* write of a record into a class instance (classAssignPlan's gate):
|
|
5994
|
+
* optional source fields write only when present, and the instance
|
|
5995
|
+
* returns. */
|
|
5996
|
+
function classAssignHelper(lowerer, className, srcShapeId, loc) {
|
|
5997
|
+
if (!classAssignPlan(lowerer, className, srcShapeId))
|
|
5998
|
+
return null;
|
|
5999
|
+
const key = `obj.assignClass:${className}:${srcShapeId}`;
|
|
6000
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
6001
|
+
if (existing)
|
|
6002
|
+
return existing;
|
|
6003
|
+
const helper = `%obj.assignClass.${lowerer.arrHofHelpers.size}`;
|
|
6004
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
6005
|
+
const sShape = lowerer.shapes.get(srcShapeId);
|
|
6006
|
+
const oT = { kind: "object", className };
|
|
6007
|
+
const sT = { kind: "record", shapeId: srcShapeId };
|
|
6008
|
+
const oRef = { kind: "varRef", localId: "o.0", type: oT, loc };
|
|
6009
|
+
const sRef = { kind: "varRef", localId: "s.0", type: sT, loc };
|
|
6010
|
+
const body = [];
|
|
6011
|
+
const info = lowerer.classes.get(className);
|
|
6012
|
+
for (const f of sShape.fields) {
|
|
6013
|
+
const declared = info.fields.get(f.name);
|
|
6014
|
+
const read = {
|
|
6015
|
+
kind: "recordGet",
|
|
6016
|
+
obj: sRef,
|
|
6017
|
+
shapeId: srcShapeId,
|
|
6018
|
+
field: f.name,
|
|
6019
|
+
type: f.type,
|
|
6020
|
+
loc,
|
|
6021
|
+
};
|
|
6022
|
+
const lift = typeEquals(declared, f.type) ? null : lowerer.widthLiftPlan(f.type, declared);
|
|
6023
|
+
const set = {
|
|
6024
|
+
kind: "fieldSet",
|
|
6025
|
+
obj: oRef,
|
|
6026
|
+
className,
|
|
6027
|
+
field: f.name,
|
|
6028
|
+
value: lift === null ? read : lowerer.applyWidthLift(lift, read, declared, loc),
|
|
6029
|
+
loc,
|
|
6030
|
+
};
|
|
6031
|
+
const present = lowerer.recordFieldPresent(sRef, srcShapeId, f.name, loc);
|
|
6032
|
+
body.push(present.kind === "recordHas"
|
|
6033
|
+
? { kind: "if", cond: present, then: [set], else_: null, loc }
|
|
6034
|
+
: set);
|
|
6035
|
+
}
|
|
6036
|
+
body.push({ kind: "return", value: oRef, loc });
|
|
6037
|
+
lowerer.liftedFns.push({
|
|
6038
|
+
name: helper,
|
|
6039
|
+
params: [
|
|
6040
|
+
{ localId: "o.0", name: "o", type: oT },
|
|
6041
|
+
{ localId: "s.0", name: "s", type: sT },
|
|
6042
|
+
],
|
|
6043
|
+
returnType: oT,
|
|
6044
|
+
locals: [
|
|
6045
|
+
{ id: "o.0", name: "o", type: oT, mutable: true },
|
|
6046
|
+
{ id: "s.0", name: "s", type: sT, mutable: true },
|
|
6047
|
+
],
|
|
6048
|
+
body,
|
|
6049
|
+
loc,
|
|
6050
|
+
});
|
|
6051
|
+
return helper;
|
|
6052
|
+
}
|
|
5545
6053
|
/** Interned `%obj.assign.<n>(t, s)` — Object.assign's per-field copy
|
|
5546
6054
|
* over signature-free records (every source field lands on a same-named,
|
|
5547
6055
|
* same-typed target field — the caller's gate): optional source fields
|
|
@@ -5556,6 +6064,7 @@ function recordAssignHelper(lowerer, targetShapeId, srcShapeId, loc) {
|
|
|
5556
6064
|
const helper = `%obj.assign.${lowerer.arrHofHelpers.size}`;
|
|
5557
6065
|
lowerer.arrHofHelpers.set(key, helper);
|
|
5558
6066
|
const sShape = lowerer.shapes.get(srcShapeId);
|
|
6067
|
+
const tShape = lowerer.shapes.get(targetShapeId);
|
|
5559
6068
|
const tT = { kind: "record", shapeId: targetShapeId };
|
|
5560
6069
|
const sT = { kind: "record", shapeId: srcShapeId };
|
|
5561
6070
|
const tRef = { kind: "varRef", localId: "t.0", type: tT, loc };
|
|
@@ -5570,12 +6079,13 @@ function recordAssignHelper(lowerer, targetShapeId, srcShapeId, loc) {
|
|
|
5570
6079
|
type: f.type,
|
|
5571
6080
|
loc,
|
|
5572
6081
|
};
|
|
6082
|
+
const targetType = tShape.fields.find((x) => x.name === f.name).type;
|
|
5573
6083
|
const set = {
|
|
5574
6084
|
kind: "recordSet",
|
|
5575
6085
|
obj: tRef,
|
|
5576
6086
|
shapeId: targetShapeId,
|
|
5577
6087
|
field: f.name,
|
|
5578
|
-
value: get,
|
|
6088
|
+
value: typeEquals(targetType, f.type) ? get : lowerer.coerceToExpected(get, targetType),
|
|
5579
6089
|
loc,
|
|
5580
6090
|
};
|
|
5581
6091
|
const present = lowerer.recordFieldPresent(sRef, srcShapeId, f.name, loc);
|
|
@@ -5600,17 +6110,22 @@ function recordAssignHelper(lowerer, targetShapeId, srcShapeId, loc) {
|
|
|
5600
6110
|
});
|
|
5601
6111
|
return helper;
|
|
5602
6112
|
}
|
|
5603
|
-
/** The `Iterator` global's statics (ES2025
|
|
5604
|
-
*
|
|
5605
|
-
*
|
|
5606
|
-
*
|
|
6113
|
+
/** The `Iterator` global's statics (ES2025): `Iterator.from` over a typed
|
|
6114
|
+
* built-in iterable lowers (lowerIteratorFromCall); every other member,
|
|
6115
|
+
* and other arguments, fence with the working spelling named instead of
|
|
6116
|
+
* the generic-method fence's monomorphization wording. */
|
|
5607
6117
|
function lowerIteratorStaticFence(lowerer, call, access) {
|
|
5608
6118
|
if (!lowerer.isStdlibGlobal(access.expression, "Iterator"))
|
|
5609
6119
|
return null;
|
|
5610
6120
|
if (!lowerer.isStdlibMember(access))
|
|
5611
6121
|
return null;
|
|
5612
|
-
lowerer
|
|
5613
|
-
|
|
6122
|
+
const from = lowerIteratorFromCall(lowerer, call, access);
|
|
6123
|
+
if (from)
|
|
6124
|
+
return from;
|
|
6125
|
+
lowerer.noLowering(`Iterator.${access.name.text}`, call, access.name.text === "from"
|
|
6126
|
+
? "Iterator.from accepts arrays, strings, typed arrays, Sets, Maps and iterator objects such as generators"
|
|
6127
|
+
: "iterator helpers apply directly to generators and to array, Map and Set iterators: " +
|
|
6128
|
+
"arr.values().map(f).take(n).toArray()");
|
|
5614
6129
|
}
|
|
5615
6130
|
/** `RegExp.escape(s)` (ES2025) — the one RegExp static with a lowering:
|
|
5616
6131
|
* a total string→string libCall (scr_regexp_escape). The lib pins the
|
|
@@ -5626,12 +6141,12 @@ function lowerRegExpStaticCall(lowerer, call, access) {
|
|
|
5626
6141
|
return null;
|
|
5627
6142
|
if (!lowerer.isStdlibMember(access))
|
|
5628
6143
|
return null;
|
|
5629
|
-
if (call.arguments.length !== 1 || ts.isSpreadElement(call.arguments[0])) {
|
|
5630
|
-
lowerer.noLowering(`RegExp.escape with ${call.arguments.length} arguments`, call);
|
|
6144
|
+
if (call.arguments.nodes.length !== 1 || ts.isSpreadElement(call.arguments.nodes[0])) {
|
|
6145
|
+
lowerer.noLowering(`RegExp.escape with ${call.arguments.nodes.length} arguments`, call);
|
|
5631
6146
|
}
|
|
5632
|
-
const arg = lowerer.lowerExprExpecting(call.arguments[0], STRING);
|
|
6147
|
+
const arg = lowerer.lowerExprExpecting(call.arguments.nodes[0], STRING);
|
|
5633
6148
|
if (arg.type.kind !== "string")
|
|
5634
|
-
lowerer.badType(call.arguments[0], lowerer.typeOf(call.arguments[0]));
|
|
6149
|
+
lowerer.badType(call.arguments.nodes[0], lowerer.typeOf(call.arguments.nodes[0]));
|
|
5635
6150
|
return { kind: "libCall", fn: "regexp.escape", args: [arg], type: STRING, loc: locOf(call) };
|
|
5636
6151
|
}
|
|
5637
6152
|
/** The composed en-US Intl.NumberFormat form: `new Intl.NumberFormat(
|
|
@@ -5663,7 +6178,7 @@ function lowerIntlNumberFormatCall(lowerer, call, access) {
|
|
|
5663
6178
|
!lowerer.isStdlibGlobal(ctor.expression, "Intl")) {
|
|
5664
6179
|
return null;
|
|
5665
6180
|
}
|
|
5666
|
-
ctorArgs = recv.arguments ?? [];
|
|
6181
|
+
ctorArgs = recv.arguments?.nodes ?? [];
|
|
5667
6182
|
}
|
|
5668
6183
|
else {
|
|
5669
6184
|
return null;
|
|
@@ -5684,10 +6199,10 @@ function lowerIntlNumberFormatCall(lowerer, call, access) {
|
|
|
5684
6199
|
: "Intl.NumberFormat with a non-literal locale", locArg, '"en-US" (Node\'s default-build locale) is the one locale whose data the runtime embeds — ' +
|
|
5685
6200
|
"everything else is ICU data the binary does not carry");
|
|
5686
6201
|
}
|
|
5687
|
-
if (call.arguments.length !== 1 || ts.isSpreadElement(call.arguments[0])) {
|
|
5688
|
-
lowerer.noLowering(`Intl.NumberFormat("en-US").format with ${call.arguments.length} arguments`, call);
|
|
6202
|
+
if (call.arguments.nodes.length !== 1 || ts.isSpreadElement(call.arguments.nodes[0])) {
|
|
6203
|
+
lowerer.noLowering(`Intl.NumberFormat("en-US").format with ${call.arguments.nodes.length} arguments`, call);
|
|
5689
6204
|
}
|
|
5690
|
-
const argNode = call.arguments[0];
|
|
6205
|
+
const argNode = call.arguments.nodes[0];
|
|
5691
6206
|
if (lowerer.mapTypeOf(lowerer.typeOf(argNode))?.kind !== "f64") {
|
|
5692
6207
|
lowerer.noLowering(`Intl.NumberFormat("en-US").format over a '${lowerer.checker.typeToString(lowerer.typeOf(argNode))}'`, argNode, "a number argument is the lowered form (bigint and numeric-string inputs have no representation)");
|
|
5693
6208
|
}
|
|
@@ -5730,9 +6245,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
5730
6245
|
if ((member === "getOwnPropertyNames" ||
|
|
5731
6246
|
member === "getOwnPropertySymbols" ||
|
|
5732
6247
|
member === "getOwnPropertyDescriptors") &&
|
|
5733
|
-
call.arguments.length === 1 &&
|
|
5734
|
-
!call.arguments.some(ts.isSpreadElement)) {
|
|
5735
|
-
let object = lowerer.lowerExpr(call.arguments[0]);
|
|
6248
|
+
call.arguments.nodes.length === 1 &&
|
|
6249
|
+
!call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
6250
|
+
let object = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
5736
6251
|
if (object.type.kind === "string" ||
|
|
5737
6252
|
object.type.kind === "f64" ||
|
|
5738
6253
|
object.type.kind === "bool" ||
|
|
@@ -5752,11 +6267,11 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
5752
6267
|
};
|
|
5753
6268
|
}
|
|
5754
6269
|
if ((member === "getPrototypeOf" || member === "setPrototypeOf") &&
|
|
5755
|
-
call.arguments.length === (member === "getPrototypeOf" ? 1 : 2) &&
|
|
5756
|
-
!call.arguments.some(ts.isSpreadElement)) {
|
|
5757
|
-
let object = lowerer.lowerExpr(call.arguments[0]);
|
|
6270
|
+
call.arguments.nodes.length === (member === "getPrototypeOf" ? 1 : 2) &&
|
|
6271
|
+
!call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
6272
|
+
let object = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
5758
6273
|
if (object.type.kind === "func") {
|
|
5759
|
-
const fnName = jsFuncNameOf(call.arguments[0], lowerer);
|
|
6274
|
+
const fnName = jsFuncNameOf(call.arguments.nodes[0], lowerer);
|
|
5760
6275
|
object = {
|
|
5761
6276
|
kind: "dynFrom",
|
|
5762
6277
|
value: object,
|
|
@@ -5767,7 +6282,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
5767
6282
|
}
|
|
5768
6283
|
if (object.type.kind !== "dyn" &&
|
|
5769
6284
|
canConvertToDyn(object.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id)))
|
|
5770
|
-
object = lowerer.coerceInto(call.arguments[0], object, DYN);
|
|
6285
|
+
object = lowerer.coerceInto(call.arguments.nodes[0], object, DYN);
|
|
5771
6286
|
if (object.type.kind === "dyn") {
|
|
5772
6287
|
const loc = locOf(call);
|
|
5773
6288
|
if (member === "getPrototypeOf") {
|
|
@@ -5789,7 +6304,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
5789
6304
|
...(identityOnly ? { prototypeIdentityOnly: true } : {}),
|
|
5790
6305
|
};
|
|
5791
6306
|
}
|
|
5792
|
-
const prototype = lowerer.lowerExprExpecting(call.arguments[1], DYN);
|
|
6307
|
+
const prototype = lowerer.lowerExprExpecting(call.arguments.nodes[1], DYN);
|
|
5793
6308
|
if (prototype.type.kind === "dyn")
|
|
5794
6309
|
return {
|
|
5795
6310
|
kind: "libCall",
|
|
@@ -5800,8 +6315,8 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
5800
6315
|
};
|
|
5801
6316
|
}
|
|
5802
6317
|
}
|
|
5803
|
-
if (member === "getOwnPropertyDescriptor" && call.arguments.length === 2) {
|
|
5804
|
-
const [receiver, key] = call.arguments;
|
|
6318
|
+
if (member === "getOwnPropertyDescriptor" && call.arguments.nodes.length === 2) {
|
|
6319
|
+
const [receiver, key] = call.arguments.nodes;
|
|
5805
6320
|
if (receiver &&
|
|
5806
6321
|
key &&
|
|
5807
6322
|
ts.isPropertyAccessExpression(receiver) &&
|
|
@@ -5834,12 +6349,13 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
5834
6349
|
// with the operands still evaluated (tsc admits any pair — Object.is
|
|
5835
6350
|
// is (any, any) — and JS evaluates the arguments either way).
|
|
5836
6351
|
if (member === "is") {
|
|
5837
|
-
if (call.arguments.length !== 2 ||
|
|
5838
|
-
|
|
6352
|
+
if (call.arguments.nodes.length !== 2 ||
|
|
6353
|
+
call.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
6354
|
+
lowerer.noLowering(`Object.is with ${call.arguments.nodes.length} arguments`, call, "exactly two arguments are the lowered form (JS treats a missing one as undefined — pass it explicitly)");
|
|
5839
6355
|
}
|
|
5840
6356
|
const loc = locOf(call);
|
|
5841
|
-
const leftNode = call.arguments[0];
|
|
5842
|
-
const rightNode = call.arguments[1];
|
|
6357
|
+
const leftNode = call.arguments.nodes[0];
|
|
6358
|
+
const rightNode = call.arguments.nodes[1];
|
|
5843
6359
|
const left = lowerer.lowerExpr(leftNode);
|
|
5844
6360
|
const right = lowerer.lowerExpr(rightNode);
|
|
5845
6361
|
const lk = left.type.kind;
|
|
@@ -5945,18 +6461,18 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
5945
6461
|
// Native checked objects retain a live prototype and can install an
|
|
5946
6462
|
// own-property descriptor table during creation.
|
|
5947
6463
|
if (member === "create") {
|
|
5948
|
-
if (call.arguments.some((a) => ts.isSpreadElement(a))) {
|
|
6464
|
+
if (call.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
5949
6465
|
lowerer.noLowering("Object.create with spread arguments", call);
|
|
5950
6466
|
}
|
|
5951
|
-
if (call.arguments.length < 1 || call.arguments.length > 2) {
|
|
5952
|
-
lowerer.noLowering(`Object.create with ${call.arguments.length} arguments`, call);
|
|
6467
|
+
if (call.arguments.nodes.length < 1 || call.arguments.nodes.length > 2) {
|
|
6468
|
+
lowerer.noLowering(`Object.create with ${call.arguments.nodes.length} arguments`, call);
|
|
5953
6469
|
}
|
|
5954
6470
|
const loc = locOf(call);
|
|
5955
|
-
let protoNode = call.arguments[0];
|
|
6471
|
+
let protoNode = call.arguments.nodes[0];
|
|
5956
6472
|
while (ts.isParenthesizedExpression(protoNode))
|
|
5957
6473
|
protoNode = protoNode.expression;
|
|
5958
6474
|
const nullProto = protoNode.kind === ts.SyntaxKind.NullKeyword;
|
|
5959
|
-
if (nullProto && call.arguments.length === 1) {
|
|
6475
|
+
if (nullProto && call.arguments.nodes.length === 1) {
|
|
5960
6476
|
return { kind: "libCall", fn: "dyn.objCreateNullProto", args: [], type: DYN, loc };
|
|
5961
6477
|
}
|
|
5962
6478
|
let proto = nullProto
|
|
@@ -5981,9 +6497,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
5981
6497
|
canConvertToDyn(proto.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id)))
|
|
5982
6498
|
proto = lowerer.coerceInto(protoNode, proto, DYN);
|
|
5983
6499
|
if (proto.type.kind === "dyn") {
|
|
5984
|
-
if (call.arguments.length === 1)
|
|
6500
|
+
if (call.arguments.nodes.length === 1)
|
|
5985
6501
|
return { kind: "libCall", fn: "dyn.objCreate", args: [proto], type: DYN, loc };
|
|
5986
|
-
const descriptors = lowerer.lowerExprExpecting(call.arguments[1], DYN);
|
|
6502
|
+
const descriptors = lowerer.lowerExprExpecting(call.arguments.nodes[1], DYN);
|
|
5987
6503
|
if (descriptors.type.kind === "dyn")
|
|
5988
6504
|
return {
|
|
5989
6505
|
kind: "libCall",
|
|
@@ -6001,10 +6517,10 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6001
6517
|
const prototype = lowerClassPrototypeAssign(lowerer, call);
|
|
6002
6518
|
if (prototype)
|
|
6003
6519
|
return prototype;
|
|
6004
|
-
if (isJsSourceFile(
|
|
6005
|
-
call.arguments.length > 0 &&
|
|
6006
|
-
!call.arguments.some(ts.isSpreadElement)) {
|
|
6007
|
-
const target = tryLowerExpression(lowerer, call.arguments[0]);
|
|
6520
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
6521
|
+
call.arguments.nodes.length > 0 &&
|
|
6522
|
+
!call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
6523
|
+
const target = tryLowerExpression(lowerer, call.arguments.nodes[0]);
|
|
6008
6524
|
if (target &&
|
|
6009
6525
|
((target.type.kind === "func" && lowerer.dynConvertible(target.type)) ||
|
|
6010
6526
|
(target.type.kind === "object" && lowerer.dynConvertible(target.type)))) {
|
|
@@ -6016,7 +6532,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6016
6532
|
lowerer.coerceToExpected(target, DYN),
|
|
6017
6533
|
{
|
|
6018
6534
|
kind: "dynArrLit",
|
|
6019
|
-
elems: call.arguments.
|
|
6535
|
+
elems: call.arguments.nodes
|
|
6536
|
+
.slice(1)
|
|
6537
|
+
.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
6020
6538
|
type: DYN,
|
|
6021
6539
|
loc,
|
|
6022
6540
|
},
|
|
@@ -6026,6 +6544,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6026
6544
|
};
|
|
6027
6545
|
}
|
|
6028
6546
|
}
|
|
6547
|
+
const onError = lowerObjectAssignOntoError(lowerer, call);
|
|
6548
|
+
if (onError)
|
|
6549
|
+
return onError;
|
|
6029
6550
|
const hybrid = lowerObjectAssignHybrid(lowerer, call);
|
|
6030
6551
|
if (hybrid)
|
|
6031
6552
|
return hybrid;
|
|
@@ -6034,15 +6555,16 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6034
6555
|
// exactly the source literal's properties, which IS the source
|
|
6035
6556
|
// literal evaluated (both fresh, no alias can tell them apart).
|
|
6036
6557
|
// Everything else keeps the spread hint (stdlibMemberFence).
|
|
6037
|
-
if (call.arguments.length === 2 &&
|
|
6038
|
-
|
|
6558
|
+
if (call.arguments.nodes.length === 2 &&
|
|
6559
|
+
!call.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
6560
|
+
let target = call.arguments.nodes[0];
|
|
6039
6561
|
while (ts.isParenthesizedExpression(target))
|
|
6040
6562
|
target = target.expression;
|
|
6041
|
-
let source = call.arguments[1];
|
|
6563
|
+
let source = call.arguments.nodes[1];
|
|
6042
6564
|
while (ts.isParenthesizedExpression(source))
|
|
6043
6565
|
source = source.expression;
|
|
6044
6566
|
if (ts.isObjectLiteralExpression(target) &&
|
|
6045
|
-
target.properties.length === 0 &&
|
|
6567
|
+
target.properties.nodes.length === 0 &&
|
|
6046
6568
|
ts.isObjectLiteralExpression(source)) {
|
|
6047
6569
|
return lowerer.lowerExpr(source);
|
|
6048
6570
|
}
|
|
@@ -6062,22 +6584,40 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6062
6584
|
// optional field must not erase the target's value — Node copies own
|
|
6063
6585
|
// keys only — while an explicit `k: undefined` does). Everything
|
|
6064
6586
|
// else keeps the spread hint.
|
|
6065
|
-
if (call.arguments.length === 2 &&
|
|
6066
|
-
|
|
6067
|
-
const
|
|
6587
|
+
if (call.arguments.nodes.length === 2 &&
|
|
6588
|
+
!call.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
6589
|
+
const tProbe = tryLowerExpression(lowerer, call.arguments.nodes[0]);
|
|
6590
|
+
const sProbe = tryLowerExpression(lowerer, call.arguments.nodes[1]);
|
|
6068
6591
|
// CHECKED-DYNAMIC target and source (the JS file-scope
|
|
6069
6592
|
// object-literal identity story): the runtime dyn copy — own
|
|
6070
6593
|
// members of the source land on the target, which returns.
|
|
6071
6594
|
if (tProbe?.type.kind === "dyn") {
|
|
6072
6595
|
const loc = locOf(call);
|
|
6073
|
-
const target = lowerer.lowerExpr(call.arguments[0]);
|
|
6074
|
-
const rawSource = lowerer.lowerExpr(call.arguments[1]);
|
|
6075
|
-
fenceSymbolFieldCopy(lowerer, call.arguments[1], rawSource.type);
|
|
6596
|
+
const target = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
6597
|
+
const rawSource = lowerer.lowerExpr(call.arguments.nodes[1]);
|
|
6598
|
+
fenceSymbolFieldCopy(lowerer, call.arguments.nodes[1], rawSource.type);
|
|
6076
6599
|
const source = lowerer.coerceToExpected(rawSource, DYN);
|
|
6077
6600
|
if (target.type.kind === "dyn" && source.type.kind === "dyn") {
|
|
6078
6601
|
return { kind: "libCall", fn: "dyn.assign", args: [target, source], type: DYN, loc };
|
|
6079
6602
|
}
|
|
6080
6603
|
}
|
|
6604
|
+
// A CLASS-INSTANCE target and a plain record source whose fields are
|
|
6605
|
+
// all fields the class declares with the same types
|
|
6606
|
+
// (`Object.assign(this, { retries: 3 })`): the per-field write into
|
|
6607
|
+
// the instance, returning it — the instance mutates in place.
|
|
6608
|
+
if (tProbe?.type.kind === "object" && sProbe?.type.kind === "record") {
|
|
6609
|
+
const helper = classAssignPlan(lowerer, tProbe.type.className, sProbe.type.shapeId);
|
|
6610
|
+
if (helper) {
|
|
6611
|
+
const loc = locOf(call);
|
|
6612
|
+
const target = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
6613
|
+
const source = lowerer.lowerExpr(call.arguments.nodes[1]);
|
|
6614
|
+
if (target.type.kind === "object" && source.type.kind === "record") {
|
|
6615
|
+
const name = classAssignHelper(lowerer, target.type.className, source.type.shapeId, loc);
|
|
6616
|
+
if (name)
|
|
6617
|
+
return { kind: "call", callee: name, args: [target, source], type: target.type, loc };
|
|
6618
|
+
}
|
|
6619
|
+
}
|
|
6620
|
+
}
|
|
6081
6621
|
if (tProbe?.type.kind === "record" && sProbe?.type.kind === "record") {
|
|
6082
6622
|
const tShape = lowerer.shapes.get(tProbe.type.shapeId);
|
|
6083
6623
|
const sShape = lowerer.shapes.get(sProbe.type.shapeId);
|
|
@@ -6091,12 +6631,15 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6091
6631
|
!shapeHasAccessorSlots(sShape) &&
|
|
6092
6632
|
sShape.fields.every((sf) => {
|
|
6093
6633
|
const tf = tShape.fields.find((x) => x.name === sf.name);
|
|
6094
|
-
|
|
6634
|
+
// A source value converts into a wider target field (`{ bail:
|
|
6635
|
+
// true }` into `bail?: boolean`).
|
|
6636
|
+
return (tf !== undefined &&
|
|
6637
|
+
(typeEquals(tf.type, sf.type) || lowerer.coercibleValue(sf.type, tf.type)));
|
|
6095
6638
|
});
|
|
6096
6639
|
if (ok) {
|
|
6097
6640
|
const loc = locOf(call);
|
|
6098
|
-
const target = lowerer.lowerExpr(call.arguments[0]);
|
|
6099
|
-
const source = lowerer.lowerExpr(call.arguments[1]);
|
|
6641
|
+
const target = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
6642
|
+
const source = lowerer.lowerExpr(call.arguments.nodes[1]);
|
|
6100
6643
|
if (target.type.kind === "record" && source.type.kind === "record") {
|
|
6101
6644
|
const helper = recordAssignHelper(lowerer, target.type.shapeId, source.type.shapeId, loc);
|
|
6102
6645
|
return { kind: "call", callee: helper, args: [target, source], type: target.type, loc };
|
|
@@ -6104,6 +6647,34 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6104
6647
|
}
|
|
6105
6648
|
}
|
|
6106
6649
|
}
|
|
6650
|
+
// `throw Object.assign(record, { extra })`: an error-shaped record given
|
|
6651
|
+
// a member its type lacks, thrown at once. A fixed record cannot grow
|
|
6652
|
+
// the member, so the throw carries a checked-dynamic copy of the target
|
|
6653
|
+
// with the source's members added. The copy is unobservable: control
|
|
6654
|
+
// leaves with the throw, so nothing on that path reads the target again.
|
|
6655
|
+
{
|
|
6656
|
+
let parent = call.parent;
|
|
6657
|
+
while (parent && ts.isParenthesizedExpression(parent))
|
|
6658
|
+
parent = parent.parent;
|
|
6659
|
+
const argNodes = call.arguments.nodes;
|
|
6660
|
+
if (parent &&
|
|
6661
|
+
ts.isThrowStatement(parent) &&
|
|
6662
|
+
argNodes.length === 2 &&
|
|
6663
|
+
!argNodes.some((a) => ts.isSpreadElement(a))) {
|
|
6664
|
+
const tProbe = tryLowerExpression(lowerer, argNodes[0]);
|
|
6665
|
+
const sProbe = tryLowerExpression(lowerer, argNodes[1]);
|
|
6666
|
+
if (tProbe?.type.kind === "record" &&
|
|
6667
|
+
lowerer.dynConvertible(tProbe.type) &&
|
|
6668
|
+
sProbe &&
|
|
6669
|
+
(sProbe.type.kind === "dyn" || lowerer.dynConvertible(sProbe.type))) {
|
|
6670
|
+
const loc = locOf(call);
|
|
6671
|
+
const target = lowerer.coerceToExpected(lowerer.lowerExpr(argNodes[0]), DYN);
|
|
6672
|
+
const source = lowerer.coerceToExpected(lowerer.lowerExpr(argNodes[1]), DYN);
|
|
6673
|
+
if (target.type.kind === "dyn" && source.type.kind === "dyn")
|
|
6674
|
+
return { kind: "libCall", fn: "dyn.assign", args: [target, source], type: DYN, loc };
|
|
6675
|
+
}
|
|
6676
|
+
}
|
|
6677
|
+
}
|
|
6107
6678
|
// `Object.assign(target, ...sources)` over a CHECKED-DYNAMIC target
|
|
6108
6679
|
// — the n-ary/spread form (`Object.assign({}, ...plugins.map(p =>
|
|
6109
6680
|
// p.options), coreOptions)`, support.js's option-table merge). The
|
|
@@ -6123,16 +6694,18 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6123
6694
|
// unobservable), or a nullish unit (Node's ToObject TypeError
|
|
6124
6695
|
// throws at the call, catchably); aliased record targets keep the
|
|
6125
6696
|
// fence — their identity could not survive the conversion.
|
|
6126
|
-
if (call.arguments.length >= 1 && !ts.isSpreadElement(call.arguments[0])) {
|
|
6127
|
-
let targetNode = call.arguments[0];
|
|
6697
|
+
if (call.arguments.nodes.length >= 1 && !ts.isSpreadElement(call.arguments.nodes[0])) {
|
|
6698
|
+
let targetNode = call.arguments.nodes[0];
|
|
6128
6699
|
while (ts.isParenthesizedExpression(targetNode))
|
|
6129
6700
|
targetNode = targetNode.expression;
|
|
6130
6701
|
const freshLiteralTarget = ts.isObjectLiteralExpression(targetNode);
|
|
6131
|
-
const tProbe = freshLiteralTarget
|
|
6702
|
+
const tProbe = freshLiteralTarget
|
|
6703
|
+
? null
|
|
6704
|
+
: tryLowerExpression(lowerer, call.arguments.nodes[0]);
|
|
6132
6705
|
const tKind = tProbe?.type.kind;
|
|
6133
6706
|
if (freshLiteralTarget || tKind === "dyn" || tKind === "nullT" || tKind === "undefinedT") {
|
|
6134
6707
|
const loc = locOf(call);
|
|
6135
|
-
const target = lowerer.lowerExprExpecting(call.arguments[0], DYN);
|
|
6708
|
+
const target = lowerer.lowerExprExpecting(call.arguments.nodes[0], DYN);
|
|
6136
6709
|
if (target.type.kind === "dyn") {
|
|
6137
6710
|
const t = lowerer.declareHiddenLocal("%oat", DYN);
|
|
6138
6711
|
const p = lowerer.declareHiddenLocal("%oap", DYN);
|
|
@@ -6152,7 +6725,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6152
6725
|
// SINGLE LAST argument; every other spread position drives
|
|
6153
6726
|
// the real iterator protocol, whose failure describes the
|
|
6154
6727
|
// value — the two runtime variants, picked here by position.
|
|
6155
|
-
const sources = call.arguments.slice(1);
|
|
6728
|
+
const sources = call.arguments.nodes.slice(1);
|
|
6156
6729
|
const spreadCount = sources.filter((a) => ts.isSpreadElement(a)).length;
|
|
6157
6730
|
let ok = true;
|
|
6158
6731
|
for (let i = 0; i < sources.length; i++) {
|
|
@@ -6161,6 +6734,19 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6161
6734
|
const srcNode = spread ? argNode.expression : argNode;
|
|
6162
6735
|
const rawSource = lowerer.lowerExpr(srcNode);
|
|
6163
6736
|
fenceSymbolFieldCopy(lowerer, srcNode, rawSource.type, spread);
|
|
6737
|
+
// A class instance copied into a fresh object
|
|
6738
|
+
// (`Object.assign({}, instance)`): the result is a plain
|
|
6739
|
+
// object holding the instance's own fields, never an
|
|
6740
|
+
// instance, so a result the checker types as the class has
|
|
6741
|
+
// no representation (the checked cast would throw).
|
|
6742
|
+
if (rawSource.type.kind === "object" &&
|
|
6743
|
+
freshLiteralTarget &&
|
|
6744
|
+
!ts.isExpressionStatement(call.parent)) {
|
|
6745
|
+
const resultT = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
6746
|
+
if (resultT !== null && resultT.kind === "object") {
|
|
6747
|
+
lowerer.unsupported("SC1090", srcNode, `Object.assign copying a '${lowerer.fmt(rawSource.type)}' instance into a fresh object typed as the class (the copy is a plain object holding the instance's own fields, not an instance — build the object literal from the fields you need)`);
|
|
6748
|
+
}
|
|
6749
|
+
}
|
|
6164
6750
|
const src = lowerer.coerceToExpected(rawSource, DYN);
|
|
6165
6751
|
if (src.type.kind !== "dyn") {
|
|
6166
6752
|
ok = false;
|
|
@@ -6178,7 +6764,12 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6178
6764
|
args: [
|
|
6179
6765
|
pRef(),
|
|
6180
6766
|
src,
|
|
6181
|
-
{
|
|
6767
|
+
{
|
|
6768
|
+
kind: "strLit",
|
|
6769
|
+
value: ts.getTextOfNode(srcNode),
|
|
6770
|
+
type: STRING,
|
|
6771
|
+
loc: argLoc,
|
|
6772
|
+
},
|
|
6182
6773
|
],
|
|
6183
6774
|
type: VOID,
|
|
6184
6775
|
loc: argLoc,
|
|
@@ -6220,24 +6811,29 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6220
6811
|
}
|
|
6221
6812
|
return null;
|
|
6222
6813
|
}
|
|
6223
|
-
if ((member === "defineProperty" && call.arguments.length === 3) ||
|
|
6224
|
-
(member === "getOwnPropertyDescriptor" && call.arguments.length === 2)) {
|
|
6225
|
-
if (call.arguments.some((a) => ts.isSpreadElement(a)))
|
|
6814
|
+
if ((member === "defineProperty" && call.arguments.nodes.length === 3) ||
|
|
6815
|
+
(member === "getOwnPropertyDescriptor" && call.arguments.nodes.length === 2)) {
|
|
6816
|
+
if (call.arguments.nodes.some((a) => ts.isSpreadElement(a)))
|
|
6226
6817
|
return null;
|
|
6227
|
-
let target = tryLowerExpression(lowerer, call.arguments[0]);
|
|
6228
|
-
const targetNode = call.arguments[0];
|
|
6818
|
+
let target = tryLowerExpression(lowerer, call.arguments.nodes[0]);
|
|
6819
|
+
const targetNode = call.arguments.nodes[0];
|
|
6229
6820
|
// The checker gives C.prototype the instance type, but its lowered
|
|
6230
6821
|
// value is the shared prototype table, not an instance to unbox.
|
|
6231
6822
|
const prototypeTarget = ts.isPropertyAccessExpression(targetNode) &&
|
|
6232
6823
|
targetNode.name.text === "prototype" &&
|
|
6233
6824
|
(exactClassOfReceiver(lowerer, targetNode.expression) !== null ||
|
|
6234
6825
|
storedClassValueType(lowerer, targetNode.expression)?.kind === "classval");
|
|
6235
|
-
const declaredTarget = target?.type.kind === "dyn" &&
|
|
6826
|
+
const declaredTarget = target?.type.kind === "dyn" &&
|
|
6827
|
+
!prototypeTarget &&
|
|
6828
|
+
!isJsSourceFile(ts.getSourceFileOfNode(targetNode))
|
|
6236
6829
|
? lowerer.mapTypeOf(lowerer.typeOf(targetNode))
|
|
6237
6830
|
: null;
|
|
6238
6831
|
if (target && declaredTarget && isDynTypedRefType(declaredTarget))
|
|
6239
6832
|
target = lowerer.coerceToExpected(target, declaredTarget);
|
|
6240
6833
|
if (target && member === "defineProperty") {
|
|
6834
|
+
const field = lowerClassFieldDefine(lowerer, call, target);
|
|
6835
|
+
if (field)
|
|
6836
|
+
return field;
|
|
6241
6837
|
const native = lowerClassDataDescriptor(lowerer, call, member, target);
|
|
6242
6838
|
if (native)
|
|
6243
6839
|
return native;
|
|
@@ -6249,7 +6845,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6249
6845
|
target = lowerer.coerceToExpected(target, DYN);
|
|
6250
6846
|
}
|
|
6251
6847
|
// Error instances share a live property table with their checked view.
|
|
6252
|
-
const keyNode = call.arguments[1];
|
|
6848
|
+
const keyNode = call.arguments.nodes[1];
|
|
6253
6849
|
if (target?.type.kind === "object" &&
|
|
6254
6850
|
target.type.className !== "%DOMException" &&
|
|
6255
6851
|
lowerer.errorHierarchyClassOf(target.type.className) &&
|
|
@@ -6258,12 +6854,12 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6258
6854
|
target = lowerer.coerceToExpected(target, DYN);
|
|
6259
6855
|
}
|
|
6260
6856
|
if (target?.type.kind === "func" && lowerer.dynConvertible(target.type)) {
|
|
6261
|
-
const fnName = jsFuncNameOf(call.arguments[0], lowerer);
|
|
6857
|
+
const fnName = jsFuncNameOf(call.arguments.nodes[0], lowerer);
|
|
6262
6858
|
target = {
|
|
6263
6859
|
kind: "dynFrom",
|
|
6264
6860
|
value: target,
|
|
6265
6861
|
type: DYN,
|
|
6266
|
-
loc: locOf(call.arguments[0]),
|
|
6862
|
+
loc: locOf(call.arguments.nodes[0]),
|
|
6267
6863
|
...(fnName !== null ? { fnName } : {}),
|
|
6268
6864
|
};
|
|
6269
6865
|
}
|
|
@@ -6273,8 +6869,8 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6273
6869
|
if (!target || (target.type.kind !== "dyn" && !isUnitType(target.type) && !descriptorPrimitive))
|
|
6274
6870
|
return null;
|
|
6275
6871
|
if (target.type.kind !== "dyn")
|
|
6276
|
-
target = { kind: "dynFrom", value: target, type: DYN, loc: locOf(call.arguments[0]) };
|
|
6277
|
-
const key = lowerer.lowerExprExpecting(call.arguments[1], DYN);
|
|
6872
|
+
target = { kind: "dynFrom", value: target, type: DYN, loc: locOf(call.arguments.nodes[0]) };
|
|
6873
|
+
const key = lowerer.lowerExprExpecting(call.arguments.nodes[1], DYN);
|
|
6278
6874
|
if (key.type.kind !== "dyn")
|
|
6279
6875
|
return null;
|
|
6280
6876
|
if (member === "getOwnPropertyDescriptor") {
|
|
@@ -6286,7 +6882,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6286
6882
|
loc: locOf(call),
|
|
6287
6883
|
};
|
|
6288
6884
|
}
|
|
6289
|
-
const descriptor = lowerer.lowerExprExpecting(call.arguments[2], DYN);
|
|
6885
|
+
const descriptor = lowerer.lowerExprExpecting(call.arguments.nodes[2], DYN);
|
|
6290
6886
|
if (descriptor.type.kind !== "dyn")
|
|
6291
6887
|
return null;
|
|
6292
6888
|
return {
|
|
@@ -6305,12 +6901,12 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6305
6901
|
// The result is the target, like JS. Typed targets keep the fence:
|
|
6306
6902
|
// static shapes have no property table to extend.
|
|
6307
6903
|
if (member === "defineProperties" &&
|
|
6308
|
-
call.arguments.length === 2 &&
|
|
6309
|
-
!call.arguments.some((a) => ts.isSpreadElement(a))) {
|
|
6904
|
+
call.arguments.nodes.length === 2 &&
|
|
6905
|
+
!call.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
6310
6906
|
const prototype = lowerClassPrototypeDescriptors(lowerer, call, member);
|
|
6311
6907
|
if (prototype)
|
|
6312
6908
|
return prototype;
|
|
6313
|
-
let target = tryLowerExpression(lowerer, call.arguments[0]);
|
|
6909
|
+
let target = tryLowerExpression(lowerer, call.arguments.nodes[0]);
|
|
6314
6910
|
if (target) {
|
|
6315
6911
|
const native = lowerClassDataDescriptor(lowerer, call, member, target);
|
|
6316
6912
|
if (native)
|
|
@@ -6323,20 +6919,20 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6323
6919
|
if (target &&
|
|
6324
6920
|
target.type.kind === "func" &&
|
|
6325
6921
|
canBoxFuncIntoDyn(target.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
6326
|
-
const fnName = jsFuncNameOf(call.arguments[0], lowerer);
|
|
6922
|
+
const fnName = jsFuncNameOf(call.arguments.nodes[0], lowerer);
|
|
6327
6923
|
target = {
|
|
6328
6924
|
kind: "dynFrom",
|
|
6329
6925
|
value: target,
|
|
6330
6926
|
type: DYN,
|
|
6331
|
-
loc: locOf(call.arguments[0]),
|
|
6927
|
+
loc: locOf(call.arguments.nodes[0]),
|
|
6332
6928
|
...(fnName !== null ? { fnName } : {}),
|
|
6333
6929
|
};
|
|
6334
6930
|
}
|
|
6335
6931
|
if (target && isUnitType(target.type)) {
|
|
6336
|
-
target = { kind: "dynFrom", value: target, type: DYN, loc: locOf(call.arguments[0]) };
|
|
6932
|
+
target = { kind: "dynFrom", value: target, type: DYN, loc: locOf(call.arguments.nodes[0]) };
|
|
6337
6933
|
}
|
|
6338
6934
|
if (target?.type.kind === "dyn") {
|
|
6339
|
-
const descs = lowerer.lowerExprExpecting(call.arguments[1], DYN);
|
|
6935
|
+
const descs = lowerer.lowerExprExpecting(call.arguments.nodes[1], DYN);
|
|
6340
6936
|
if (descs.type.kind === "dyn") {
|
|
6341
6937
|
return {
|
|
6342
6938
|
kind: "libCall",
|
|
@@ -6350,9 +6946,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6350
6946
|
return null;
|
|
6351
6947
|
}
|
|
6352
6948
|
if (["preventExtensions", "isExtensible", "seal", "isSealed"].includes(member) &&
|
|
6353
|
-
call.arguments.length === 1 &&
|
|
6354
|
-
!ts.isSpreadElement(call.arguments[0])) {
|
|
6355
|
-
const value = lowerer.lowerExpr(call.arguments[0]);
|
|
6949
|
+
call.arguments.nodes.length === 1 &&
|
|
6950
|
+
!ts.isSpreadElement(call.arguments.nodes[0])) {
|
|
6951
|
+
const value = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
6356
6952
|
if (value.type.kind === "string" ||
|
|
6357
6953
|
value.type.kind === "f64" ||
|
|
6358
6954
|
value.type.kind === "bool" ||
|
|
@@ -6372,6 +6968,21 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6372
6968
|
loc,
|
|
6373
6969
|
};
|
|
6374
6970
|
}
|
|
6971
|
+
if (member === "preventExtensions" || member === "seal") {
|
|
6972
|
+
const integrity = lowerClassIntegrity(lowerer, call, member, value);
|
|
6973
|
+
if (integrity)
|
|
6974
|
+
return integrity;
|
|
6975
|
+
}
|
|
6976
|
+
else if (isDynTypedRefType(value.type)) {
|
|
6977
|
+
// The instance's checked view carries its integrity state.
|
|
6978
|
+
return {
|
|
6979
|
+
kind: "libCall",
|
|
6980
|
+
fn: member === "isSealed" ? "dyn.isSealed" : "dyn.isExtensible",
|
|
6981
|
+
args: [lowerer.coerceToExpected(value, DYN)],
|
|
6982
|
+
type: BOOL,
|
|
6983
|
+
loc: locOf(call),
|
|
6984
|
+
};
|
|
6985
|
+
}
|
|
6375
6986
|
if (value.type.kind === "dyn") {
|
|
6376
6987
|
const operation = {
|
|
6377
6988
|
preventExtensions: "dyn.preventExtensions",
|
|
@@ -6395,19 +7006,19 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6395
7006
|
// other reference can write). Primitives pass through per ES2015.
|
|
6396
7007
|
// Aliased objects keep a fence: a later write through the original
|
|
6397
7008
|
// reference would need the runtime frozen bit (strict mode throws).
|
|
6398
|
-
if (member === "isFrozen" && call.arguments.length === 1) {
|
|
6399
|
-
const value = lowerer.lowerExprExpecting(call.arguments[0], DYN);
|
|
7009
|
+
if (member === "isFrozen" && call.arguments.nodes.length === 1) {
|
|
7010
|
+
const value = lowerer.lowerExprExpecting(call.arguments.nodes[0], DYN);
|
|
6400
7011
|
return { kind: "libCall", fn: "dyn.isFrozen", args: [value], type: BOOL, loc: locOf(call) };
|
|
6401
7012
|
}
|
|
6402
7013
|
if (member === "freeze") {
|
|
6403
|
-
if (call.arguments.length !== 1 || ts.isSpreadElement(call.arguments[0])) {
|
|
6404
|
-
lowerer.noLowering(`Object.freeze with ${call.arguments.length} arguments`, call);
|
|
7014
|
+
if (call.arguments.nodes.length !== 1 || ts.isSpreadElement(call.arguments.nodes[0])) {
|
|
7015
|
+
lowerer.noLowering(`Object.freeze with ${call.arguments.nodes.length} arguments`, call);
|
|
6405
7016
|
}
|
|
6406
|
-
const argNode = call.arguments[0];
|
|
7017
|
+
const argNode = call.arguments.nodes[0];
|
|
6407
7018
|
let inner = argNode;
|
|
6408
7019
|
while (ts.isParenthesizedExpression(inner) || ts.isAsExpression(inner))
|
|
6409
7020
|
inner = inner.expression;
|
|
6410
|
-
const value = isJsSourceFile(
|
|
7021
|
+
const value = isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
6411
7022
|
(ts.isObjectLiteralExpression(inner) || ts.isArrayLiteralExpression(inner))
|
|
6412
7023
|
? lowerer.lowerExprExpecting(argNode, DYN)
|
|
6413
7024
|
: lowerer.lowerExpr(argNode);
|
|
@@ -6434,6 +7045,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6434
7045
|
arm.kind === "string" ||
|
|
6435
7046
|
arm.kind === "symbol"))
|
|
6436
7047
|
return value;
|
|
7048
|
+
const integrity = lowerClassIntegrity(lowerer, call, "freeze", value);
|
|
7049
|
+
if (integrity)
|
|
7050
|
+
return integrity;
|
|
6437
7051
|
lowerer.noLowering("Object.freeze of a possibly-aliased value", call, "freeze of a FRESH object/array literal (and of primitives) compiles — frozen-ness is unobservable there; an aliased target's later writes would need the runtime frozen bit");
|
|
6438
7052
|
}
|
|
6439
7053
|
// `Object.hasOwn(r, k)` over a RECORD receiver: a record's own-key set
|
|
@@ -6445,10 +7059,10 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6445
7059
|
// records additionally probe the overflow map; non-record receivers
|
|
6446
7060
|
// do too.
|
|
6447
7061
|
if (member === "hasOwn" &&
|
|
6448
|
-
call.arguments.length === 2 &&
|
|
6449
|
-
!call.arguments.some((a) => ts.isSpreadElement(a))) {
|
|
6450
|
-
const recvNode = call.arguments[0];
|
|
6451
|
-
const keyNode = call.arguments[1];
|
|
7062
|
+
call.arguments.nodes.length === 2 &&
|
|
7063
|
+
!call.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
7064
|
+
const recvNode = call.arguments.nodes[0];
|
|
7065
|
+
const keyNode = call.arguments.nodes[1];
|
|
6452
7066
|
const probed = tryLowerExpression(lowerer, recvNode);
|
|
6453
7067
|
const arrayKey = probed?.type.kind === "array" ? lowerer.lowerExpr(keyNode) : null;
|
|
6454
7068
|
if (probed?.type.kind === "array" && arrayKey?.type.kind === "f64") {
|
|
@@ -6507,9 +7121,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6507
7121
|
}
|
|
6508
7122
|
if (member !== "keys" && member !== "values" && member !== "entries")
|
|
6509
7123
|
return null;
|
|
6510
|
-
if (call.arguments.length !== 1 || ts.isSpreadElement(call.arguments[0]))
|
|
7124
|
+
if (call.arguments.nodes.length !== 1 || ts.isSpreadElement(call.arguments.nodes[0]))
|
|
6511
7125
|
return null;
|
|
6512
|
-
const argNode = call.arguments[0];
|
|
7126
|
+
const argNode = call.arguments.nodes[0];
|
|
6513
7127
|
// util.types and node:util/types list Node's pinned key census
|
|
6514
7128
|
// (UTIL_TYPES_KEYS): the object's own keys in Node's order, or the module
|
|
6515
7129
|
// namespace's export names sorted with "default". values/entries would
|
|
@@ -6524,7 +7138,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6524
7138
|
? lowerer.checker.getSymbolAtLocation(argNode)
|
|
6525
7139
|
: undefined;
|
|
6526
7140
|
const namespace = symbol
|
|
6527
|
-
?
|
|
7141
|
+
? symbol.declarations.some((decl) => ts.isNamespaceImport(decl))
|
|
6528
7142
|
: false;
|
|
6529
7143
|
const names = namespace ? [...UTIL_TYPES_KEYS, "default"].sort() : UTIL_TYPES_KEYS;
|
|
6530
7144
|
const loc = locOf(call);
|
|
@@ -6599,7 +7213,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6599
7213
|
probed.type.kind === "f64" ||
|
|
6600
7214
|
probed.type.kind === "bool");
|
|
6601
7215
|
const isJsUnion = probed?.type.kind === "union" &&
|
|
6602
|
-
isJsSourceFile(
|
|
7216
|
+
isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
6603
7217
|
lowerer.dynConvertible(probed.type);
|
|
6604
7218
|
if (isDyn ||
|
|
6605
7219
|
isPrimitive ||
|
|
@@ -6618,7 +7232,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6618
7232
|
// entries as a native [string, any][]: the checker keeps every later
|
|
6619
7233
|
// write to the arrays well typed. JavaScript may store anything into
|
|
6620
7234
|
// them, so it keeps the checked-dynamic arrays.
|
|
6621
|
-
const resultT = member !== "values" && !isJsSourceFile(
|
|
7235
|
+
const resultT = member !== "values" && !isJsSourceFile(ts.getSourceFileOfNode(call))
|
|
6622
7236
|
? lowerer.mapTypeOf(lowerer.typeOf(call))
|
|
6623
7237
|
: null;
|
|
6624
7238
|
if (member === "keys" && resultT?.kind === "array" && resultT.elem.kind === "string")
|
|
@@ -6641,7 +7255,9 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6641
7255
|
// program only iterates or indexes the result, or passes it to a
|
|
6642
7256
|
// read-only array method, a native vector of the checked values skips
|
|
6643
7257
|
// building that array and, for for-of, the iterator protocol.
|
|
6644
|
-
if (member === "values" &&
|
|
7258
|
+
if (member === "values" &&
|
|
7259
|
+
!isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
7260
|
+
consumesValueList(call))
|
|
6645
7261
|
return {
|
|
6646
7262
|
kind: "libCall",
|
|
6647
7263
|
fn: "dyn.objValueList",
|
|
@@ -6676,7 +7292,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6676
7292
|
const enumerationType = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
6677
7293
|
if ((member === "values" || member === "entries") &&
|
|
6678
7294
|
(enumerationType?.kind === "dyn" ||
|
|
6679
|
-
(enumerationType === null && isJsSourceFile(
|
|
7295
|
+
(enumerationType === null && isJsSourceFile(ts.getSourceFileOfNode(call))))) {
|
|
6680
7296
|
let receiver = lowerer.coerceToExpected(lowerer.lowerExpr(argNode), DYN);
|
|
6681
7297
|
if (receiver.type.kind !== "dyn")
|
|
6682
7298
|
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
@@ -6744,6 +7360,7 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
6744
7360
|
lowerer.badType(call, lowerer.typeOf(call));
|
|
6745
7361
|
valueT = tupleShape.fields.find((f) => f.name === "1").type;
|
|
6746
7362
|
}
|
|
7363
|
+
lowerer.keyOrder.observe(argIr);
|
|
6747
7364
|
const key = `obj.${member}:${argIr.shapeId}:${typeKey(resultT)}`;
|
|
6748
7365
|
let helper = lowerer.arrHofHelpers.get(key);
|
|
6749
7366
|
if (!helper) {
|
|
@@ -7048,19 +7665,19 @@ function lowerObjectAssignHybrid(lowerer, call) {
|
|
|
7048
7665
|
const callField = shape?.fields.find((f) => f.name === "%call");
|
|
7049
7666
|
if (!shape || !callField || callField.type.kind !== "func")
|
|
7050
7667
|
return null;
|
|
7051
|
-
if (call.arguments.length < 2 || call.arguments.some((a) => ts.isSpreadElement(a)))
|
|
7668
|
+
if (call.arguments.nodes.length < 2 || call.arguments.nodes.some((a) => ts.isSpreadElement(a)))
|
|
7052
7669
|
return null;
|
|
7053
7670
|
const loc = locOf(call);
|
|
7054
7671
|
const values = new Map();
|
|
7055
|
-
values.set("%call", lowerer.lowerExprExpecting(call.arguments[0], callField.type));
|
|
7056
|
-
for (const argNode of call.arguments.slice(1)) {
|
|
7672
|
+
values.set("%call", lowerer.lowerExprExpecting(call.arguments.nodes[0], callField.type));
|
|
7673
|
+
for (const argNode of call.arguments.nodes.slice(1)) {
|
|
7057
7674
|
let src = argNode;
|
|
7058
7675
|
while (ts.isParenthesizedExpression(src) || ts.isAsExpression(src) || ts.isTypeAssertion(src))
|
|
7059
7676
|
src = src.expression;
|
|
7060
7677
|
if (!ts.isObjectLiteralExpression(src)) {
|
|
7061
7678
|
lowerer.unsupported("SC1090", argNode, "Object.assign sources other than plain object literals when building a function-with-properties value");
|
|
7062
7679
|
}
|
|
7063
|
-
for (const prop of src.properties) {
|
|
7680
|
+
for (const prop of src.properties.nodes) {
|
|
7064
7681
|
const nameOk = (ts.isPropertyAssignment(prop) || ts.isShorthandPropertyAssignment(prop)) &&
|
|
7065
7682
|
(ts.isIdentifier(prop.name) || ts.isStringLiteral(prop.name));
|
|
7066
7683
|
if (!nameOk) {
|
|
@@ -7092,6 +7709,25 @@ function lowerObjectAssignHybrid(lowerer, call) {
|
|
|
7092
7709
|
}
|
|
7093
7710
|
return { kind: "recordLit", fields, type: mapped, loc };
|
|
7094
7711
|
}
|
|
7712
|
+
/** The accessed member is an overload set (isOverloadedCallableMemberType),
|
|
7713
|
+
* also under an optional chain whose access still spells `| undefined`. */
|
|
7714
|
+
function isOverloadedMemberAccess(lowerer, access) {
|
|
7715
|
+
return isOverloadedCallableMemberType(lowerer.checker.getNonNullableType(lowerer.typeOf(access)), lowerer.checker);
|
|
7716
|
+
}
|
|
7717
|
+
/** The result type of the overload a call through an overloaded member
|
|
7718
|
+
* resolved to: the erased slot's result converts to it. A non-generic
|
|
7719
|
+
* overload answers through its declaration, because the resolved signature
|
|
7720
|
+
* of an optional-chain call (`api?.m(x)`) also carries the chain's
|
|
7721
|
+
* undefined; a generic one answers through its instantiation. */
|
|
7722
|
+
function resolvedOverloadResultType(lowerer, call) {
|
|
7723
|
+
const { checker } = lowerer;
|
|
7724
|
+
const signature = checker.getResolvedSignature(call);
|
|
7725
|
+
const decl = signature ? signature.declaration : undefined;
|
|
7726
|
+
const declared = decl ? checker.getSignatureFromDeclaration(decl) : undefined;
|
|
7727
|
+
const source = declared && declared.getTypeParameters().length === 0 ? declared : signature;
|
|
7728
|
+
const result = source ? lowerer.mapTypeOf(checker.getReturnTypeOfSignature(source)) : null;
|
|
7729
|
+
return result ?? lowerer.irTypeOf(call);
|
|
7730
|
+
}
|
|
7095
7731
|
export function lowerRecordFieldCall(lowerer, call, access) {
|
|
7096
7732
|
if (lowerer.chainBlocked(call))
|
|
7097
7733
|
return null;
|
|
@@ -7117,11 +7753,22 @@ export function lowerRecordFieldCall(lowerer, call, access) {
|
|
|
7117
7753
|
if (callee?.type.kind !== "func")
|
|
7118
7754
|
return null;
|
|
7119
7755
|
const args = completeFuncValueArgs(lowerer, call, callee.type, locOf(call));
|
|
7120
|
-
|
|
7756
|
+
const value = {
|
|
7757
|
+
kind: "callValue",
|
|
7758
|
+
callee,
|
|
7759
|
+
args,
|
|
7760
|
+
type: callee.type.ret,
|
|
7761
|
+
loc: locOf(call),
|
|
7762
|
+
};
|
|
7763
|
+
// An overloaded member's erased result converts to the resolved
|
|
7764
|
+
// overload's type, as on a single record receiver below.
|
|
7765
|
+
return isOverloadedMemberAccess(lowerer, access)
|
|
7766
|
+
? lowerer.coerceInto(call, value, resolvedOverloadResultType(lowerer, call))
|
|
7767
|
+
: value;
|
|
7121
7768
|
}
|
|
7122
7769
|
const target = lowerer.fieldTarget(access);
|
|
7123
7770
|
const loc = locOf(call);
|
|
7124
|
-
const receiverLocal = target && isJsSourceFile(
|
|
7771
|
+
const receiverLocal = target && isJsSourceFile(ts.getSourceFileOfNode(call))
|
|
7125
7772
|
? lowerer.declareHiddenLocal("%callReceiver", target.obj.type)
|
|
7126
7773
|
: null;
|
|
7127
7774
|
const init = target && receiverLocal
|
|
@@ -7142,10 +7789,10 @@ export function lowerRecordFieldCall(lowerer, call, access) {
|
|
|
7142
7789
|
// TypeScript reaches here for callable library types that are checked
|
|
7143
7790
|
// values (util.DebugLogger).
|
|
7144
7791
|
if (callee.type.kind === "dyn" &&
|
|
7145
|
-
(isJsSourceFile(
|
|
7792
|
+
(isJsSourceFile(ts.getSourceFileOfNode(call)) ||
|
|
7146
7793
|
lowerer.checker.getCallSignatures(lowerer.typeOf(access)).length > 0)) {
|
|
7147
7794
|
const receiver = target && receiverLocal ? lowerer.coerceToExpected(target.obj, DYN) : undefined;
|
|
7148
|
-
const spread = call.arguments.some(ts.isSpreadElement)
|
|
7795
|
+
const spread = call.arguments.nodes.some(ts.isSpreadElement)
|
|
7149
7796
|
? lowerSpreadArgsCall(lowerer, call, callee, loc)
|
|
7150
7797
|
: null;
|
|
7151
7798
|
if (spread && spread.kind !== "dynCall")
|
|
@@ -7158,13 +7805,17 @@ export function lowerRecordFieldCall(lowerer, call, access) {
|
|
|
7158
7805
|
kind: "dynCall",
|
|
7159
7806
|
callee,
|
|
7160
7807
|
...(receiver ? { receiver } : {}),
|
|
7161
|
-
calleeName:
|
|
7162
|
-
args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7808
|
+
calleeName: ts.getTextOfNode(access),
|
|
7809
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7163
7810
|
type: DYN,
|
|
7164
7811
|
loc,
|
|
7165
7812
|
};
|
|
7166
7813
|
return init ? { kind: "seqExpr", stmts: [init], result, type: result.type, loc } : result;
|
|
7167
7814
|
}
|
|
7815
|
+
// An optional callback field the checker narrowed at this call
|
|
7816
|
+
// (`o.cb ? o.cb(x) : …`, `if (o.cb) o.cb(x)`): extract the func arm.
|
|
7817
|
+
if (callee.type.kind === "union")
|
|
7818
|
+
callee = lowerer.maybeNarrow(callee, access);
|
|
7168
7819
|
if (callee.type.kind !== "func")
|
|
7169
7820
|
lowerer.badType(access, lowerer.typeOf(access));
|
|
7170
7821
|
// JavaScript passes the record as `this`. A record with no dynamic form
|
|
@@ -7180,7 +7831,7 @@ export function lowerRecordFieldCall(lowerer, call, access) {
|
|
|
7180
7831
|
}
|
|
7181
7832
|
}
|
|
7182
7833
|
const args = completeFuncValueArgs(lowerer, call, callee.type, locOf(call));
|
|
7183
|
-
|
|
7834
|
+
let result = {
|
|
7184
7835
|
kind: "callValue",
|
|
7185
7836
|
callee,
|
|
7186
7837
|
...(receiver ? { receiver } : {}),
|
|
@@ -7188,6 +7839,14 @@ export function lowerRecordFieldCall(lowerer, call, access) {
|
|
|
7188
7839
|
type: callee.type.ret,
|
|
7189
7840
|
loc,
|
|
7190
7841
|
};
|
|
7842
|
+
// A generic member's field holds its erased instance, and an overloaded
|
|
7843
|
+
// member's field its erased function (the overloads joined): the result
|
|
7844
|
+
// converts to this call's instantiated or resolved return type.
|
|
7845
|
+
const memberType = lowerer.typeOf(access);
|
|
7846
|
+
if (isGenericCallableMemberType(memberType, lowerer.checker))
|
|
7847
|
+
result = lowerer.coerceInto(call, result, lowerer.irTypeOf(call));
|
|
7848
|
+
else if (isOverloadedMemberAccess(lowerer, access))
|
|
7849
|
+
result = lowerer.coerceInto(call, result, resolvedOverloadResultType(lowerer, call));
|
|
7191
7850
|
return init ? { kind: "seqExpr", stmts: [init], result, type: result.type, loc } : result;
|
|
7192
7851
|
}
|
|
7193
7852
|
/** `o.m(args)` where `m` is an object-literal GENERIC method (own type
|
|
@@ -7213,12 +7872,12 @@ function lowerUrlStaticCall(lowerer, call, callee) {
|
|
|
7213
7872
|
if (!ts.isIdentifier(callee.expression))
|
|
7214
7873
|
return null;
|
|
7215
7874
|
const sym = lowerer.resolveValueSymbol(callee.expression);
|
|
7216
|
-
if (!sym || !lowerer.isStdlibSymbol(sym) || sym
|
|
7875
|
+
if (!sym || !lowerer.isStdlibSymbol(sym) || ts.symbolName(sym) !== "URL")
|
|
7217
7876
|
return null;
|
|
7218
7877
|
if (callee.name.text === "canParse" || callee.name.text === "parse") {
|
|
7219
7878
|
return lowerUrlFactory(lowerer, call, callee.name.text);
|
|
7220
7879
|
}
|
|
7221
|
-
if (callee.name.text !== "revokeObjectURL" || call.arguments.length !== 0)
|
|
7880
|
+
if (callee.name.text !== "revokeObjectURL" || call.arguments.nodes.length !== 0)
|
|
7222
7881
|
return null;
|
|
7223
7882
|
return nodeThrowExpr(1, "ERR_MISSING_ARGS", 'The "url" argument must be specified', VOID, locOf(call));
|
|
7224
7883
|
}
|
|
@@ -7240,7 +7899,7 @@ function arrowSignatureOf(lowerer, node) {
|
|
|
7240
7899
|
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(node));
|
|
7241
7900
|
if (signatures.length !== 1)
|
|
7242
7901
|
return null;
|
|
7243
|
-
const declaration =
|
|
7902
|
+
const declaration = signatures[0].declaration;
|
|
7244
7903
|
return declaration !== undefined && ts.isArrowFunction(declaration) ? signatures[0] : null;
|
|
7245
7904
|
}
|
|
7246
7905
|
/** An inline arrow has lexical `this` and no observable own properties
|
|
@@ -7249,8 +7908,8 @@ function arrowSignatureOf(lowerer, node) {
|
|
|
7249
7908
|
* other receivers and rest/preset-argument forms on the named fence. */
|
|
7250
7909
|
function lowerInlineArrowBind(lowerer, call, access) {
|
|
7251
7910
|
if (access.name.text !== "bind" ||
|
|
7252
|
-
call.arguments.length > 1 ||
|
|
7253
|
-
call.arguments.some(ts.isSpreadElement))
|
|
7911
|
+
call.arguments.nodes.length > 1 ||
|
|
7912
|
+
call.arguments.nodes.some(ts.isSpreadElement))
|
|
7254
7913
|
return null;
|
|
7255
7914
|
let arrow = access.expression;
|
|
7256
7915
|
while (ts.isParenthesizedExpression(arrow))
|
|
@@ -7264,8 +7923,8 @@ function lowerInlineArrowBind(lowerer, call, access) {
|
|
|
7264
7923
|
return null;
|
|
7265
7924
|
const type = callee.type;
|
|
7266
7925
|
const loc = locOf(call);
|
|
7267
|
-
const firstDefault = arrow.parameters.findIndex((p) => p.initializer !== undefined);
|
|
7268
|
-
const length = firstDefault < 0 ? arrow.parameters.length : firstDefault;
|
|
7926
|
+
const firstDefault = arrow.parameters.nodes.findIndex((p) => p.initializer !== undefined);
|
|
7927
|
+
const length = firstDefault < 0 ? arrow.parameters.nodes.length : firstDefault;
|
|
7269
7928
|
const key = `arrow.bind:${typeKey(type)}:${length}`;
|
|
7270
7929
|
const existing = lowerer.arrHofHelpers.get(key);
|
|
7271
7930
|
const name = existing ?? `%arrow.bind.${lowerer.arrHofHelpers.size}`;
|
|
@@ -7358,8 +8017,8 @@ function lowerInlineArrowBind(lowerer, call, access) {
|
|
|
7358
8017
|
const stmts = [{ kind: "varDecl", localId: saved.id, init: callee, loc }];
|
|
7359
8018
|
// The receiver is ignored by the arrow, but its effects and throws
|
|
7360
8019
|
// happen after creating the arrow and before returning the bound value.
|
|
7361
|
-
if (call.arguments[0])
|
|
7362
|
-
stmts.push(lowerer.lowerExprStatement(call.arguments[0]));
|
|
8020
|
+
if (call.arguments.nodes[0])
|
|
8021
|
+
stmts.push(lowerer.lowerExprStatement(call.arguments.nodes[0]));
|
|
7363
8022
|
const result = {
|
|
7364
8023
|
kind: "call",
|
|
7365
8024
|
callee: name,
|
|
@@ -7374,8 +8033,8 @@ function lowerInlineArrowBind(lowerer, call, access) {
|
|
|
7374
8033
|
* parameters validate from the dynamic array in order. */
|
|
7375
8034
|
function lowerArrowFunctionApply(lowerer, call, access) {
|
|
7376
8035
|
if (access.name.text !== "apply" ||
|
|
7377
|
-
call.arguments.length !== 2 ||
|
|
7378
|
-
call.arguments.some(ts.isSpreadElement) ||
|
|
8036
|
+
call.arguments.nodes.length !== 2 ||
|
|
8037
|
+
call.arguments.nodes.some(ts.isSpreadElement) ||
|
|
7379
8038
|
arrowSignatureOf(lowerer, access.expression) === null) {
|
|
7380
8039
|
return null;
|
|
7381
8040
|
}
|
|
@@ -7385,7 +8044,7 @@ function lowerArrowFunctionApply(lowerer, call, access) {
|
|
|
7385
8044
|
if (!callee.type.params.every((param) => canDynCheckTo(param, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id)))) {
|
|
7386
8045
|
return null;
|
|
7387
8046
|
}
|
|
7388
|
-
const argsList = lowerer.lowerExpr(call.arguments[1]);
|
|
8047
|
+
const argsList = lowerer.lowerExpr(call.arguments.nodes[1]);
|
|
7389
8048
|
if (argsList.type.kind !== "dyn")
|
|
7390
8049
|
return null;
|
|
7391
8050
|
const loc = locOf(call);
|
|
@@ -7393,7 +8052,7 @@ function lowerArrowFunctionApply(lowerer, call, access) {
|
|
|
7393
8052
|
const savedArgs = lowerer.declareHiddenLocal("%applyArgs", DYN);
|
|
7394
8053
|
const stmts = [
|
|
7395
8054
|
{ kind: "varDecl", localId: savedCallee.id, init: callee, loc },
|
|
7396
|
-
{ kind: "exprStmt", expr: lowerer.lowerExpr(call.arguments[0]), loc },
|
|
8055
|
+
{ kind: "exprStmt", expr: lowerer.lowerExpr(call.arguments.nodes[0]), loc },
|
|
7397
8056
|
{ kind: "varDecl", localId: savedArgs.id, init: argsList, loc },
|
|
7398
8057
|
];
|
|
7399
8058
|
const args = callee.type.params.map((param, index) => {
|
|
@@ -7404,7 +8063,7 @@ function lowerArrowFunctionApply(lowerer, call, access) {
|
|
|
7404
8063
|
type: DYN,
|
|
7405
8064
|
loc,
|
|
7406
8065
|
};
|
|
7407
|
-
return lowerer.coerceInto(call.arguments[1], read, param);
|
|
8066
|
+
return lowerer.coerceInto(call.arguments.nodes[1], read, param);
|
|
7408
8067
|
});
|
|
7409
8068
|
const invoked = {
|
|
7410
8069
|
kind: "callValue",
|
|
@@ -7440,7 +8099,7 @@ function lowerObjLitGenericMethodCall(lowerer, call, access) {
|
|
|
7440
8099
|
lowerer.mapTypeOf(lowerer.typeOf(access.expression.expression))?.kind === "searchParams" &&
|
|
7441
8100
|
SP_BRAND_METHODS.has(access.expression.name.text) &&
|
|
7442
8101
|
lowerer.isStdlibMember(access.expression)) {
|
|
7443
|
-
const thisArg = call.arguments[0];
|
|
8102
|
+
const thisArg = call.arguments.nodes[0];
|
|
7444
8103
|
const thisT = thisArg
|
|
7445
8104
|
? lowerer.mapTypeOf(lowerer.typeOf(thisArg))
|
|
7446
8105
|
: { kind: "undefinedT" };
|
|
@@ -7460,7 +8119,7 @@ function lowerObjLitGenericMethodCall(lowerer, call, access) {
|
|
|
7460
8119
|
const propSym = lowerer.checker.getPropertyOfType(recvT, name);
|
|
7461
8120
|
if (!propSym)
|
|
7462
8121
|
return null;
|
|
7463
|
-
const propertyDecl =
|
|
8122
|
+
const propertyDecl = propSym.valueDeclaration;
|
|
7464
8123
|
if (propertyDecl &&
|
|
7465
8124
|
ts.isShorthandPropertyAssignment(propertyDecl) &&
|
|
7466
8125
|
ts.isIdentifier(propertyDecl.name) &&
|
|
@@ -7480,9 +8139,7 @@ function lowerObjLitGenericMethodCall(lowerer, call, access) {
|
|
|
7480
8139
|
// CLASS members belong to the class path (lowerClassGenericMethodCall
|
|
7481
8140
|
// claimed compilable ones; a class that failed collection keeps its
|
|
7482
8141
|
// own diagnostics and the generic method-call fence downstream).
|
|
7483
|
-
if (
|
|
7484
|
-
.declarationsOf(propSym)
|
|
7485
|
-
.some((d) => d.parent !== undefined &&
|
|
8142
|
+
if (propSym.declarations.some((d) => d.parent !== undefined &&
|
|
7486
8143
|
(ts.isClassDeclaration(d.parent) || ts.isClassExpression(d.parent)))) {
|
|
7487
8144
|
return null;
|
|
7488
8145
|
}
|
|
@@ -7519,19 +8176,19 @@ function lowerObjLitGenericMethodCall(lowerer, call, access) {
|
|
|
7519
8176
|
const value = tryLowerExpression(lowerer, access.expression);
|
|
7520
8177
|
if (value?.type.kind === "func" &&
|
|
7521
8178
|
lowerer.dynConvertible(value.type) &&
|
|
7522
|
-
!call.arguments.some(ts.isSpreadElement)) {
|
|
8179
|
+
!call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
7523
8180
|
const loc = locOf(call);
|
|
7524
8181
|
return {
|
|
7525
8182
|
kind: "dynInvoke",
|
|
7526
8183
|
recv: { kind: "dynFrom", value, type: DYN, loc },
|
|
7527
8184
|
method: name,
|
|
7528
|
-
calleeName:
|
|
7529
|
-
args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
8185
|
+
calleeName: ts.getTextOfNode(access),
|
|
8186
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7530
8187
|
type: DYN,
|
|
7531
8188
|
loc,
|
|
7532
8189
|
};
|
|
7533
8190
|
}
|
|
7534
|
-
lowerer.unsupported("SC1090", call, `Function.prototype.${name} on a function whose signature cannot cross the checked-value boundary (call '${access.expression
|
|
8191
|
+
lowerer.unsupported("SC1090", call, `Function.prototype.${name} on a function whose signature cannot cross the checked-value boundary (call '${ts.getTextOfNode(access.expression)}(...)' directly)`);
|
|
7535
8192
|
}
|
|
7536
8193
|
// STANDARD-LIBRARY generic members (Promise.then, Object.
|
|
7537
8194
|
// defineProperty, Array-augmentation methods) are the lib fence's
|
|
@@ -7544,9 +8201,27 @@ function lowerObjLitGenericMethodCall(lowerer, call, access) {
|
|
|
7544
8201
|
// receiver's runtime class must be provable — name that discipline
|
|
7545
8202
|
// instead of the object-literal wording when the method lives on an
|
|
7546
8203
|
// interface.
|
|
7547
|
-
const onInterface =
|
|
7548
|
-
|
|
7549
|
-
|
|
8204
|
+
const onInterface = propSym.declarations.some((d) => d.parent !== undefined && ts.isInterfaceDeclaration(d.parent));
|
|
8205
|
+
// A receiver held as a checked-dynamic value (a class-backed interface)
|
|
8206
|
+
// dispatches by name to the runtime object's member, which a generic
|
|
8207
|
+
// method answers with its erased instance; the result converts to this
|
|
8208
|
+
// call's instantiated return type.
|
|
8209
|
+
if (onInterface && !call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
8210
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
8211
|
+
if (receiver.type.kind === "dyn") {
|
|
8212
|
+
const loc = locOf(call);
|
|
8213
|
+
const invoked = {
|
|
8214
|
+
kind: "dynInvoke",
|
|
8215
|
+
recv: receiver,
|
|
8216
|
+
method: name,
|
|
8217
|
+
calleeName: ts.getTextOfNode(access),
|
|
8218
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
8219
|
+
type: DYN,
|
|
8220
|
+
loc,
|
|
8221
|
+
};
|
|
8222
|
+
return lowerer.coerceInto(call, invoked, lowerer.irTypeOf(call));
|
|
8223
|
+
}
|
|
8224
|
+
}
|
|
7550
8225
|
if (onInterface) {
|
|
7551
8226
|
lowerer.unsupported("SC1090", call, `calls of the generic method '${name}' through this receiver (the interface declaration is signature-only and generic methods dispatch statically, so the receiver's runtime class must be provable — bind the receiver to a const initialized with its 'new' expression, e.g. 'const r: ${lowerer.checker.typeToString(recvT)} = new C(...)')`);
|
|
7552
8227
|
}
|
|
@@ -7556,7 +8231,7 @@ function lowerObjLitGenericMethodCall(lowerer, call, access) {
|
|
|
7556
8231
|
const info = objLitGenericFnInfoOf(lowerer, call, name, found);
|
|
7557
8232
|
const instance = genericCallInstance(lowerer, call, info);
|
|
7558
8233
|
const loc = locOf(call);
|
|
7559
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
8234
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
7560
8235
|
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
7561
8236
|
}
|
|
7562
8237
|
/** `obj.method(args)` — whole-program devirtualization decides the form:
|
|
@@ -7568,7 +8243,17 @@ function lowerObjLitGenericMethodCall(lowerer, call, access) {
|
|
|
7568
8243
|
export function lowerObjectMethodCall(lowerer, call, access) {
|
|
7569
8244
|
if (lowerer.chainBlocked(access, call))
|
|
7570
8245
|
return null;
|
|
7571
|
-
let mappedReceiver = lowerer.
|
|
8246
|
+
let mappedReceiver = lowerer.receiverTypeOverrides.get(access.expression) ??
|
|
8247
|
+
structuralReadType(lowerer, access.expression) ??
|
|
8248
|
+
lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
8249
|
+
// EventEmitter's static side (the class, a value of it, or the events
|
|
8250
|
+
// module, which is the class) keeps its static surface on the emitter
|
|
8251
|
+
// dispatch (`EventEmitter.setMaxListeners(n)`), which tells the statics
|
|
8252
|
+
// apart by the receiver's construct signatures. The stream classes
|
|
8253
|
+
// inherit the same statics.
|
|
8254
|
+
if (mappedReceiver?.kind === "classval" && mappedReceiver.className === RUNTIME_EMITTER_CLASS) {
|
|
8255
|
+
mappedReceiver = { kind: "object", className: RUNTIME_EMITTER_CLASS };
|
|
8256
|
+
}
|
|
7572
8257
|
// A specialized JS parameter can expose a native field whose checker
|
|
7573
8258
|
// type still belongs to the unspecialized body (plane.normal.dot()).
|
|
7574
8259
|
// Use the lowered receiver's representation and retain its evaluation.
|
|
@@ -7576,7 +8261,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7576
8261
|
(lowerer.implicitParamTypes !== null ||
|
|
7577
8262
|
lowerer.classImplementedProtocol(lowerer.typeOf(access.expression)) ||
|
|
7578
8263
|
ts.isNewExpression(access.expression) ||
|
|
7579
|
-
isJsSourceFile(
|
|
8264
|
+
isJsSourceFile(ts.getSourceFileOfNode(call)))
|
|
7580
8265
|
? ts.isNewExpression(access.expression)
|
|
7581
8266
|
? lowerer.lowerExpr(access.expression)
|
|
7582
8267
|
: tryLowerExpression(lowerer, access.expression)
|
|
@@ -7594,7 +8279,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7594
8279
|
if (dispatched)
|
|
7595
8280
|
return dispatched;
|
|
7596
8281
|
const arms = lowerer.unions.get(mappedReceiver.unionId)?.arms;
|
|
7597
|
-
if (isJsSourceFile(
|
|
8282
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
7598
8283
|
arms?.every((arm) => arm.kind === "object" && !lowerer.classes.get(arm.className)?.def.runtime) &&
|
|
7599
8284
|
lowerer.dynConvertible(mappedReceiver)) {
|
|
7600
8285
|
return lowerDynReceiverMethodCall(lowerer, call, access);
|
|
@@ -7664,7 +8349,13 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7664
8349
|
// The EventEmitter surface: API-named calls on emitter-rooted
|
|
7665
8350
|
// receivers lower through the emitter spoke (subclass members with
|
|
7666
8351
|
// these names are fenced at collection, so `found` never shadows).
|
|
7667
|
-
if (info &&
|
|
8352
|
+
if (info &&
|
|
8353
|
+
!found &&
|
|
8354
|
+
(EMITTER_API_MEMBERS.has(access.name.text) ||
|
|
8355
|
+
// A static with no instance twin (events.getEventListeners).
|
|
8356
|
+
(access.name.text === "getEventListeners" &&
|
|
8357
|
+
lowerer.checker.getConstructSignatures(lowerer.typeOf(access.expression)).length > 0)) &&
|
|
8358
|
+
emitterRooted(lowerer, info)) {
|
|
7668
8359
|
return lowerEmitterMethodCall(lowerer, call, access, info);
|
|
7669
8360
|
}
|
|
7670
8361
|
// The inherited EventTarget/Event methods of a class rooted at those
|
|
@@ -7723,7 +8414,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7723
8414
|
let callee = target ? lowerer.fieldGetExpr(target, locOf(access), access) : null;
|
|
7724
8415
|
if (callee?.type.kind === "union" && callableType !== null) {
|
|
7725
8416
|
// Calling a cleared callback field throws Node's call TypeError.
|
|
7726
|
-
const inPlace = checkedArmExtraction(lowerer, callee, lowerer.armTag(callee.type.unionId, callableType), callableType, () => `${
|
|
8417
|
+
const inPlace = checkedArmExtraction(lowerer, callee, lowerer.armTag(callee.type.unionId, callableType), callableType, () => `${ts.getTextOfNode(access)} is not a function`);
|
|
7727
8418
|
const helper = inPlace
|
|
7728
8419
|
? null
|
|
7729
8420
|
: lowerer.narrowedArmHelper(callee.type.unionId, callableType, locOf(access));
|
|
@@ -7735,19 +8426,19 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7735
8426
|
}
|
|
7736
8427
|
if (callee?.type.kind === "func") {
|
|
7737
8428
|
if (((callee.type.rest === true && callee.type.restAbi === undefined) ||
|
|
7738
|
-
call.arguments.length > callee.type.params.length) &&
|
|
7739
|
-
isJsSourceFile(
|
|
8429
|
+
call.arguments.nodes.length > callee.type.params.length) &&
|
|
8430
|
+
isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
7740
8431
|
lowerer.dynConvertible(callee.type)) {
|
|
7741
8432
|
const boxed = { kind: "dynFrom", value: callee, type: DYN, loc };
|
|
7742
8433
|
const spread = lowerSpreadArgsCall(lowerer, call, boxed, loc);
|
|
7743
8434
|
if (spread?.kind === "dynCall")
|
|
7744
8435
|
return finish({ ...spread, ...receiver });
|
|
7745
|
-
const args = call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN));
|
|
8436
|
+
const args = call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN));
|
|
7746
8437
|
return finish({
|
|
7747
8438
|
kind: "dynCall",
|
|
7748
8439
|
callee: boxed,
|
|
7749
8440
|
...receiver,
|
|
7750
|
-
calleeName:
|
|
8441
|
+
calleeName: ts.getTextOfNode(access),
|
|
7751
8442
|
args,
|
|
7752
8443
|
type: DYN,
|
|
7753
8444
|
loc,
|
|
@@ -7757,15 +8448,15 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7757
8448
|
return finish({ kind: "callValue", callee, ...receiver, args, type: callee.type.ret, loc });
|
|
7758
8449
|
}
|
|
7759
8450
|
if (callee?.type.kind === "dyn") {
|
|
7760
|
-
if (call.arguments.some((a) => ts.isSpreadElement(a))) {
|
|
8451
|
+
if (call.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
7761
8452
|
lowerer.unsupported("SC1090", call, "spread arguments in calls through 'unknown' values");
|
|
7762
8453
|
}
|
|
7763
|
-
const args = call.arguments.map((a) => lowerer.lowerExprExpecting(a, DYN));
|
|
8454
|
+
const args = call.arguments.nodes.map((a) => lowerer.lowerExprExpecting(a, DYN));
|
|
7764
8455
|
return finish({
|
|
7765
8456
|
kind: "dynCall",
|
|
7766
8457
|
callee,
|
|
7767
8458
|
...receiver,
|
|
7768
|
-
calleeName:
|
|
8459
|
+
calleeName: ts.getTextOfNode(access),
|
|
7769
8460
|
args,
|
|
7770
8461
|
type: DYN,
|
|
7771
8462
|
loc,
|
|
@@ -7773,7 +8464,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7773
8464
|
}
|
|
7774
8465
|
}
|
|
7775
8466
|
if (!fieldType &&
|
|
7776
|
-
isJsSourceFile(
|
|
8467
|
+
isJsSourceFile(ts.getSourceFileOfNode(call)) &&
|
|
7777
8468
|
!info.def.runtime &&
|
|
7778
8469
|
!info.builtinError &&
|
|
7779
8470
|
!info.builtinEmitter &&
|
|
@@ -7790,7 +8481,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7790
8481
|
type: DYN,
|
|
7791
8482
|
loc,
|
|
7792
8483
|
};
|
|
7793
|
-
const spread = call.arguments.some(ts.isSpreadElement)
|
|
8484
|
+
const spread = call.arguments.nodes.some(ts.isSpreadElement)
|
|
7794
8485
|
? lowerSpreadArgsCall(lowerer, call, callee, loc)
|
|
7795
8486
|
: null;
|
|
7796
8487
|
if (spread && spread.kind !== "dynCall")
|
|
@@ -7801,8 +8492,8 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7801
8492
|
kind: "dynCall",
|
|
7802
8493
|
callee,
|
|
7803
8494
|
receiver,
|
|
7804
|
-
calleeName:
|
|
7805
|
-
args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
8495
|
+
calleeName: ts.getTextOfNode(access),
|
|
8496
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7806
8497
|
type: DYN,
|
|
7807
8498
|
loc,
|
|
7808
8499
|
};
|
|
@@ -7824,7 +8515,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7824
8515
|
const receiver = lowerReceiver();
|
|
7825
8516
|
const local = lowerer.declareHiddenLocal("%callbackReceiver", receiver.type);
|
|
7826
8517
|
const value = { kind: "varRef", localId: local.id, type: receiver.type, loc };
|
|
7827
|
-
const args = lowerer.completeArgs(call.arguments, found.sig.params, loc, call);
|
|
8518
|
+
const args = lowerer.completeArgs(call.arguments.nodes, found.sig.params, loc, call);
|
|
7828
8519
|
const virtual = lowerer.overrideBelow(info, method);
|
|
7829
8520
|
if (virtual)
|
|
7830
8521
|
lowerer.noteVirtualEdge(info, method);
|
|
@@ -7846,7 +8537,7 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7846
8537
|
type: found.sig.ret,
|
|
7847
8538
|
loc,
|
|
7848
8539
|
};
|
|
7849
|
-
const result = classCallbackCall(lowerer, value, method, call.arguments, fallback, loc,
|
|
8540
|
+
const result = classCallbackCall(lowerer, value, method, call.arguments.nodes, fallback, loc, ts.getTextOfNode(access));
|
|
7850
8541
|
return {
|
|
7851
8542
|
kind: "seqExpr",
|
|
7852
8543
|
stmts: [{ kind: "varDecl", localId: local.id, init: receiver, loc }],
|
|
@@ -7867,12 +8558,34 @@ export function lowerObjectMethodCall(lowerer, call, access) {
|
|
|
7867
8558
|
if (found.sig.abstract === true && !lowerer.overrideBelow(info, method)) {
|
|
7868
8559
|
lowerer.unsupported("SC1090", call, `calls of the abstract method '${method}' with no concrete implementation below the receiver's static class`);
|
|
7869
8560
|
}
|
|
8561
|
+
// The static receiver's nearest declaration is an override adapted to
|
|
8562
|
+
// the inherited ABI, and nothing below overrides it: call its body
|
|
8563
|
+
// directly under its declared signature (exact parameters and result).
|
|
8564
|
+
// The slot function stays reachable; it lifts the body.
|
|
8565
|
+
const adapted = found.declarer.returnAdapters?.get(method);
|
|
8566
|
+
// A TypeScript override's own entry answers its declared result. A
|
|
8567
|
+
// JavaScript body's result is inferred, so its callers keep the slot.
|
|
8568
|
+
const declarerDecl = found.declarer.decl;
|
|
8569
|
+
if (adapted &&
|
|
8570
|
+
!(declarerDecl && isJsSourceFile(ts.getSourceFileOfNode(declarerDecl))) &&
|
|
8571
|
+
!lowerer.overrideBelow(info, method)) {
|
|
8572
|
+
lowerer.noteEdge(`%${found.declarer.def.name}.${method}`);
|
|
8573
|
+
const receiver = lowerReceiver();
|
|
8574
|
+
const args = lowerer.completeArgs(call.arguments.nodes, adapted.params, locOf(call), call);
|
|
8575
|
+
return {
|
|
8576
|
+
kind: "call",
|
|
8577
|
+
callee: `%${found.declarer.def.name}.${method}$own`,
|
|
8578
|
+
args: [lowerer.upcastTo(receiver, found.declarer.def.name), ...args],
|
|
8579
|
+
type: adapted.ret,
|
|
8580
|
+
loc: locOf(call),
|
|
8581
|
+
};
|
|
8582
|
+
}
|
|
7870
8583
|
if (lowerer.overrideBelow(info, method))
|
|
7871
8584
|
lowerer.noteVirtualEdge(info, method);
|
|
7872
8585
|
else
|
|
7873
8586
|
lowerer.noteEdge(`%${found.declarer.def.name}.${method}`);
|
|
7874
8587
|
const receiver = lowerReceiver();
|
|
7875
|
-
const args = lowerer.completeArgs(call.arguments, found.sig.params, locOf(call), call);
|
|
8588
|
+
const args = lowerer.completeArgs(call.arguments.nodes, found.sig.params, locOf(call), call);
|
|
7876
8589
|
if (lowerer.overrideBelow(info, method)) {
|
|
7877
8590
|
return reconcileOverloadReturn(lowerer, call, {
|
|
7878
8591
|
kind: "virtualCall",
|
|
@@ -7926,7 +8639,7 @@ function lowerUnionObjectMethodCall(lowerer, call, access, receiverT) {
|
|
|
7926
8639
|
type: DYN,
|
|
7927
8640
|
loc,
|
|
7928
8641
|
};
|
|
7929
|
-
const spread = call.arguments.some(ts.isSpreadElement)
|
|
8642
|
+
const spread = call.arguments.nodes.some(ts.isSpreadElement)
|
|
7930
8643
|
? lowerSpreadArgsCall(lowerer, call, callee, loc)
|
|
7931
8644
|
: null;
|
|
7932
8645
|
if (spread && spread.kind !== "dynCall")
|
|
@@ -7937,8 +8650,8 @@ function lowerUnionObjectMethodCall(lowerer, call, access, receiverT) {
|
|
|
7937
8650
|
kind: "dynCall",
|
|
7938
8651
|
callee,
|
|
7939
8652
|
receiver,
|
|
7940
|
-
calleeName:
|
|
7941
|
-
args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
8653
|
+
calleeName: ts.getTextOfNode(access),
|
|
8654
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7942
8655
|
type: DYN,
|
|
7943
8656
|
loc,
|
|
7944
8657
|
};
|
|
@@ -7966,7 +8679,7 @@ function lowerUnionObjectMethodCall(lowerer, call, access, receiverT) {
|
|
|
7966
8679
|
return null;
|
|
7967
8680
|
const loc = locOf(call);
|
|
7968
8681
|
const receiver = lowerer.coerceInto(access.expression, lowerer.lowerExpr(access.expression), receiverT);
|
|
7969
|
-
const args = lowerer.completeArgs(call.arguments, shapes, loc, call);
|
|
8682
|
+
const args = lowerer.completeArgs(call.arguments.nodes, shapes, loc, call);
|
|
7970
8683
|
const helper = unionObjectMethodHelper(lowerer, call, receiverT, method, plans, shapes, resultT, loc);
|
|
7971
8684
|
return { kind: "call", callee: helper, args: [receiver, ...args], type: resultT, loc };
|
|
7972
8685
|
}
|
|
@@ -7998,7 +8711,7 @@ function lowerUnionObjectDynFieldCall(lowerer, call, access, receiverT) {
|
|
|
7998
8711
|
return null;
|
|
7999
8712
|
plans.push({ arm, info });
|
|
8000
8713
|
}
|
|
8001
|
-
if (call.arguments.some(ts.isSpreadElement)) {
|
|
8714
|
+
if (call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
8002
8715
|
lowerer.unsupported("SC1090", call, "spread arguments in calls through 'unknown' values");
|
|
8003
8716
|
}
|
|
8004
8717
|
const loc = locOf(call);
|
|
@@ -8066,7 +8779,7 @@ function lowerUnionObjectDynFieldCall(lowerer, call, access, receiverT) {
|
|
|
8066
8779
|
lowerer.liftedFns.push({ name: helper, params, returnType: DYN, locals, body, loc });
|
|
8067
8780
|
}
|
|
8068
8781
|
const callee = { kind: "call", callee: helper, args: [receiverRef], type: DYN, loc };
|
|
8069
|
-
const args = call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN));
|
|
8782
|
+
const args = call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN));
|
|
8070
8783
|
return {
|
|
8071
8784
|
kind: "seqExpr",
|
|
8072
8785
|
stmts: [{ kind: "varDecl", localId: receiverLocal.id, init: receiver, loc }],
|
|
@@ -8074,7 +8787,7 @@ function lowerUnionObjectDynFieldCall(lowerer, call, access, receiverT) {
|
|
|
8074
8787
|
kind: "dynCall",
|
|
8075
8788
|
callee,
|
|
8076
8789
|
receiver: lowerer.coerceToExpected(receiverRef, DYN),
|
|
8077
|
-
calleeName:
|
|
8790
|
+
calleeName: ts.getTextOfNode(access),
|
|
8078
8791
|
args,
|
|
8079
8792
|
type: DYN,
|
|
8080
8793
|
loc,
|
|
@@ -8090,6 +8803,18 @@ function unionObjectMethodHelper(lowerer, sourceCall, receiverT, method, plans,
|
|
|
8090
8803
|
return existing;
|
|
8091
8804
|
const name = `%union.call.${lowerer.unionCallHelpers.size}`;
|
|
8092
8805
|
lowerer.unionCallHelpers.set(key, name);
|
|
8806
|
+
// A probe that catches a refusal while the body lowers must not leave
|
|
8807
|
+
// the name registered for a helper that was never emitted.
|
|
8808
|
+
try {
|
|
8809
|
+
lowerer.liftedFns.push(unionObjectMethodFunction(lowerer, name, sourceCall, receiverT, method, plans, shapes, resultT, loc));
|
|
8810
|
+
}
|
|
8811
|
+
catch (e) {
|
|
8812
|
+
lowerer.unionCallHelpers.delete(key);
|
|
8813
|
+
throw e;
|
|
8814
|
+
}
|
|
8815
|
+
return name;
|
|
8816
|
+
}
|
|
8817
|
+
function unionObjectMethodFunction(lowerer, name, sourceCall, receiverT, method, plans, shapes, resultT, loc) {
|
|
8093
8818
|
const receiver = varRef("this.0", receiverT, loc);
|
|
8094
8819
|
const argRefs = shapes.map((shape, i) => varRef(`a.${i}`, shape.type, loc));
|
|
8095
8820
|
const branch = (plan) => {
|
|
@@ -8166,8 +8891,7 @@ function unionObjectMethodHelper(lowerer, sourceCall, receiverT, method, plans,
|
|
|
8166
8891
|
type: param.type,
|
|
8167
8892
|
mutable: false,
|
|
8168
8893
|
}));
|
|
8169
|
-
|
|
8170
|
-
return name;
|
|
8894
|
+
return { name, params, returnType: resultT, locals, body, loc };
|
|
8171
8895
|
}
|
|
8172
8896
|
/** The argument's lowered type for a message (what the static form saw),
|
|
8173
8897
|
* or the checker's text when the argument itself does not lower. */
|
|
@@ -8337,4 +9061,77 @@ export function lowerStaticNumberGlobal(lowerer, name, call, args, loc) {
|
|
|
8337
9061
|
}
|
|
8338
9062
|
return null;
|
|
8339
9063
|
}
|
|
9064
|
+
/** `crypto.getRandomValues(view)` on the WebCrypto global or webcrypto. */
|
|
9065
|
+
function lowerWebCryptoGetRandomValues(lowerer, call, access) {
|
|
9066
|
+
if (access.name.text !== "getRandomValues" ||
|
|
9067
|
+
call.questionDotToken ||
|
|
9068
|
+
access.questionDotToken ||
|
|
9069
|
+
!isWebCryptoReceiver(lowerer, access.expression))
|
|
9070
|
+
return null;
|
|
9071
|
+
return lowerCryptoGetRandomValues(lowerer, call);
|
|
9072
|
+
}
|
|
9073
|
+
/** A then handler's promise-armed result (`.then(() => cached ?? load())`
|
|
9074
|
+
* typed `T | Promise<T>`, or a `Promise<void> | void` callback's result):
|
|
9075
|
+
* the lifted async body adopts the promise arm and fulfills with the
|
|
9076
|
+
* others, like `return u` in an async function. Null for other results. */
|
|
9077
|
+
function maybePromiseHandlerResult(lowerer, call, value, R) {
|
|
9078
|
+
const mp = promiseArmedUnionOf(lowerer, value.type);
|
|
9079
|
+
if (!mp || promiseArmedUnionOf(lowerer, R))
|
|
9080
|
+
return null;
|
|
9081
|
+
const stmt = maybePromiseReturnStmt(lowerer, value, mp, R, (e) => lowerer.coerceInto(call, e, R));
|
|
9082
|
+
if (stmt === null) {
|
|
9083
|
+
lowerer.unsupported("SC1090", call, `then handlers returning '${lowerer.fmt(value.type)}' into '${lowerer.fmt(R)}' (an arm does not convert to the result)`);
|
|
9084
|
+
}
|
|
9085
|
+
return stmt;
|
|
9086
|
+
}
|
|
9087
|
+
/** `Object.assign(err, ...sources)` in TypeScript onto an error-hierarchy
|
|
9088
|
+
* target (`Object.assign(new Error(message), details)`): the sources'
|
|
9089
|
+
* own members land on the error — the runtime copy over its
|
|
9090
|
+
* checked-dynamic node, whose name, message, stack, cause and code feed
|
|
9091
|
+
* back into the typed slots — and the call answers the error itself.
|
|
9092
|
+
* Null for every other target. */
|
|
9093
|
+
function lowerObjectAssignOntoError(lowerer, call) {
|
|
9094
|
+
const argNodes = call.arguments.nodes;
|
|
9095
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(call)) ||
|
|
9096
|
+
argNodes.length < 2 ||
|
|
9097
|
+
argNodes.some((a) => ts.isSpreadElement(a)))
|
|
9098
|
+
return null;
|
|
9099
|
+
const probe = tryLowerExpression(lowerer, argNodes[0]);
|
|
9100
|
+
if (probe?.type.kind !== "object" || !lowerer.isErrorRootedClass(probe.type.className))
|
|
9101
|
+
return null;
|
|
9102
|
+
const loc = locOf(call);
|
|
9103
|
+
const target = lowerer.lowerExpr(argNodes[0]);
|
|
9104
|
+
const slot = lowerer.declareHiddenLocal("%assignErr", target.type);
|
|
9105
|
+
const sources = [];
|
|
9106
|
+
for (const node of argNodes.slice(1)) {
|
|
9107
|
+
const raw = lowerer.lowerExpr(node);
|
|
9108
|
+
fenceSymbolFieldCopy(lowerer, node, raw.type);
|
|
9109
|
+
const source = lowerer.coerceToExpected(raw, DYN);
|
|
9110
|
+
if (source.type.kind !== "dyn") {
|
|
9111
|
+
lowerer.unsupported("SC1090", node, `Object.assign onto an Error from a '${lowerer.fmt(raw.type)}' source (sources enter the error's dynamic properties)`);
|
|
9112
|
+
}
|
|
9113
|
+
sources.push(source);
|
|
9114
|
+
}
|
|
9115
|
+
const ref = () => ({ kind: "varRef", localId: slot.id, type: target.type, loc });
|
|
9116
|
+
return {
|
|
9117
|
+
kind: "seqExpr",
|
|
9118
|
+
stmts: [
|
|
9119
|
+
{ kind: "varDecl", localId: slot.id, init: target, loc },
|
|
9120
|
+
{
|
|
9121
|
+
kind: "exprStmt",
|
|
9122
|
+
expr: {
|
|
9123
|
+
kind: "libCall",
|
|
9124
|
+
fn: "error.assign",
|
|
9125
|
+
args: [ref(), { kind: "dynArrLit", elems: sources, type: DYN, loc }],
|
|
9126
|
+
type: VOID,
|
|
9127
|
+
loc,
|
|
9128
|
+
},
|
|
9129
|
+
loc,
|
|
9130
|
+
},
|
|
9131
|
+
],
|
|
9132
|
+
result: ref(),
|
|
9133
|
+
type: target.type,
|
|
9134
|
+
loc,
|
|
9135
|
+
};
|
|
9136
|
+
}
|
|
8340
9137
|
//# sourceMappingURL=lower-calls.js.map
|