@scriptc/compiler 0.3.6 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +717 -55
- 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 +20 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +9 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/link-plan-core.d.ts +2 -0
- package/dist/backend/link-plan-core.js +2 -0
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan.d.ts +1 -0
- package/dist/backend/link-plan.js +1 -0
- package/dist/backend/link-plan.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.js +3 -1
- package/dist/backend/llvm/array-search.js.map +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 +38 -1
- package/dist/backend/llvm/classes.js +185 -35
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +79 -17
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +21 -3
- package/dist/backend/llvm/common.js +51 -3
- 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 +15 -4
- package/dist/backend/llvm/dense-array-access.js +125 -44
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +63 -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 +37 -4
- package/dist/backend/llvm/dyn.js +354 -183
- 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 +1193 -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 +1557 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +59 -0
- package/dist/backend/llvm/emit-statements.js +2041 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +566 -291
- package/dist/backend/llvm/emitter.js +728 -4671
- 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 +87 -56
- 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 +45 -24
- 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 +113 -66
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +124 -28
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +57 -2
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- 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 +65 -27
- 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.js +3 -3
- package/dist/backend/llvm/integer-clones.js.map +1 -1
- 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/js-ic.d.ts +18 -0
- package/dist/backend/llvm/js-ic.js +712 -0
- package/dist/backend/llvm/js-ic.js.map +1 -0
- 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 +616 -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 +94 -53
- 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 +209 -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 +42 -33
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- 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.d.ts +20 -4
- package/dist/backend/llvm/map-number-lookup.js +45 -9
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- 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 +215 -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 +7 -0
- package/dist/backend/llvm/publish.js +50 -19
- 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 +10 -7
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +8 -2
- package/dist/backend/llvm/regions.test.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +74 -45
- package/dist/backend/llvm/shapes.js +289 -28
- 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/speculative-integers.d.ts +20 -1
- package/dist/backend/llvm/speculative-integers.js +94 -6
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.test.js +55 -1
- package/dist/backend/llvm/speculative-integers.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-reads.d.ts +1 -1
- package/dist/backend/llvm/string-reads.js +4 -4
- package/dist/backend/llvm/string-reads.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 +111 -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 +12 -0
- package/dist/backend/mangle.js +18 -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 +57 -0
- package/dist/backend/native/executable.js +211 -139
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +2 -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-codegen.d.ts +6 -0
- package/dist/backend/native-codegen.js +19 -0
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +27 -0
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +48 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-profile.d.ts +32 -0
- package/dist/backend/native-profile.js +39 -0
- package/dist/backend/native-profile.js.map +1 -0
- package/dist/backend/native-profile.test.d.ts +1 -0
- package/dist/backend/native-profile.test.js +58 -0
- package/dist/backend/native-profile.test.js.map +1 -0
- package/dist/backend/native-tools.d.ts +14 -0
- package/dist/backend/native-tools.js +13 -0
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +13 -1
- package/dist/backend/runtime-pack-core.js +14 -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 +9 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +9 -1
- 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 +15 -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 +8 -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 +106 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +3 -0
- package/dist/cli/output-options.d.ts +2 -0
- package/dist/cli/output-options.js +9 -0
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/usage.d.ts +21 -1
- package/dist/cli/usage.js +43 -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 +22 -0
- package/dist/contracts/check.js +25 -8
- 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 +27 -0
- package/dist/executable/executable-cache.js +19 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +12 -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/arguments-usage.d.ts +8 -0
- package/dist/frontend/arguments-usage.js +98 -0
- package/dist/frontend/arguments-usage.js.map +1 -1
- package/dist/frontend/arguments-usage.test.d.ts +1 -0
- package/dist/frontend/arguments-usage.test.js +32 -0
- package/dist/frontend/arguments-usage.test.js.map +1 -0
- 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/builtin-package-aliases.d.ts +24 -0
- package/dist/frontend/builtin-package-aliases.js +133 -0
- package/dist/frontend/builtin-package-aliases.js.map +1 -0
- package/dist/frontend/builtin-package-aliases.test.d.ts +1 -0
- package/dist/frontend/builtin-package-aliases.test.js +48 -0
- package/dist/frontend/builtin-package-aliases.test.js.map +1 -0
- 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/dts-paths.d.ts +4 -0
- package/dist/frontend/dts-paths.js +9 -1
- package/dist/frontend/dts-paths.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 +31 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +205 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +17 -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 +22 -0
- package/dist/frontend/lowering/builtins/crypto.js +215 -38
- 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/ecdh.d.ts +10 -0
- package/dist/frontend/lowering/builtins/ecdh.js +208 -0
- package/dist/frontend/lowering/builtins/ecdh.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 +284 -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 +41 -1
- package/dist/frontend/lowering/builtins/process.js +505 -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 +40 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +338 -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 +42 -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 +79 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/typed-array-members.d.ts +7 -0
- package/dist/frontend/lowering/builtins/typed-array-members.js +160 -0
- package/dist/frontend/lowering/builtins/typed-array-members.js.map +1 -0
- 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 +23 -1
- package/dist/frontend/lowering/call-signatures.js +379 -55
- 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 +561 -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 +1124 -90
- 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.d.ts +10 -0
- package/dist/frontend/lowering/class-protocols.js +76 -45
- 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 +86 -19
- 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 +264 -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/fresh-spread.d.ts +13 -0
- package/dist/frontend/lowering/coercions/fresh-spread.js +95 -0
- package/dist/frontend/lowering/coercions/fresh-spread.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +239 -68
- 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 +17 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +287 -118
- 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 +58 -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 +94 -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.d.ts +9 -0
- package/dist/frontend/lowering/containers/bytes.js +649 -113
- 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 +126 -28
- 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 +455 -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 +30 -10
- package/dist/frontend/lowering/cycle-initialization.js +191 -35
- 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 +723 -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 +2557 -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 +1804 -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 +52 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +307 -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 +1337 -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 +301 -86
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -2
- package/dist/frontend/lowering/expressions/optional-chains.js +103 -17
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +115 -0
- package/dist/frontend/lowering/expressions/property-access.js +3787 -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 +1724 -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 +551 -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-delegation.d.ts +8 -0
- package/dist/frontend/lowering/generator-delegation.js +191 -1
- package/dist/frontend/lowering/generator-delegation.js.map +1 -1
- 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 +43 -0
- package/dist/frontend/lowering/generic-functions.js +593 -118
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/handle-properties.d.ts +24 -0
- package/dist/frontend/lowering/handle-properties.js +281 -0
- package/dist/frontend/lowering/handle-properties.js.map +1 -0
- 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/iterable-spelling.d.ts +7 -0
- package/dist/frontend/lowering/iterable-spelling.js +38 -0
- package/dist/frontend/lowering/iterable-spelling.js.map +1 -0
- 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-array-sort.d.ts +33 -15
- package/dist/frontend/lowering/lower-array-sort.js +117 -21
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.test.js +93 -14
- package/dist/frontend/lowering/lower-array-sort.test.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 +33 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1404 -448
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +54 -3
- package/dist/frontend/lowering/lower-classes.js +1529 -472
- 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 +241 -21
- 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 +1509 -12486
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +72 -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 +39 -20
- 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 +900 -107
- 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.d.ts +11 -3
- package/dist/frontend/lowering/lower-modules.js +445 -94
- 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 +65 -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 +514 -101
- 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 +179 -118
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +30 -7
- package/dist/frontend/lowering/lower-stmts.js +1950 -433
- 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 +96 -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 +424 -27
- package/dist/frontend/lowering/lowerer.js +2062 -310
- 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/rebindable-functions.d.ts +8 -0
- package/dist/frontend/lowering/rebindable-functions.js +54 -0
- package/dist/frontend/lowering/rebindable-functions.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/static-typeof.d.ts +26 -0
- package/dist/frontend/lowering/static-typeof.js +133 -0
- package/dist/frontend/lowering/static-typeof.js.map +1 -0
- 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 +13 -12
- 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 +282 -45
- 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/thenables.d.ts +16 -0
- package/dist/frontend/lowering/thenables.js +124 -0
- package/dist/frontend/lowering/thenables.js.map +1 -0
- 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-builtin-aliases.d.ts +8 -0
- package/dist/frontend/npm-static-builtin-aliases.js +65 -0
- package/dist/frontend/npm-static-builtin-aliases.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.d.ts +58 -0
- package/dist/frontend/npm-static-bundled-chunks.js +981 -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 +399 -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 +988 -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 +336 -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-enum-iife.d.ts +6 -0
- package/dist/frontend/npm-static-enum-iife.js +280 -0
- package/dist/frontend/npm-static-enum-iife.js.map +1 -0
- package/dist/frontend/npm-static-enum-iife.test.d.ts +1 -0
- package/dist/frontend/npm-static-enum-iife.test.js +116 -0
- package/dist/frontend/npm-static-enum-iife.test.js.map +1 -0
- 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 +25 -1
- package/dist/frontend/npm-static.js +212 -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/npm.js +13 -0
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/package-shims.d.ts +47 -0
- package/dist/frontend/package-shims.js +300 -0
- package/dist/frontend/package-shims.js.map +1 -0
- package/dist/frontend/pipeline.js +230 -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 +100 -2
- package/dist/frontend/program.js +1627 -262
- 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 +49 -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 +26 -1
- package/dist/frontend/services.js +59 -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 +10 -5
- package/dist/frontend/ts7/program-host.js +19 -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 +57 -24
- package/dist/frontend/ts7/semantic-model.js +114 -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 +30 -15
- 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 +2735 -723
- 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 +4 -1
- package/dist/index.js +87 -8
- 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 +31 -0
- package/dist/ir/array-length-stability.js +249 -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 +134 -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 +116 -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 +540 -29
- 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 +7 -0
- package/dist/ir/integer-loop-facts.js +103 -17
- 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 +13 -1
- package/dist/ir/integer-ranges.js +125 -26
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +273 -2
- 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 +127 -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/js-ic.d.ts +52 -0
- package/dist/ir/js-ic.js +199 -0
- package/dist/ir/js-ic.js.map +1 -0
- package/dist/ir/js-ic.test.d.ts +1 -0
- package/dist/ir/js-ic.test.js +148 -0
- package/dist/ir/js-ic.test.js.map +1 -0
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +399 -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 +183 -33
- package/dist/ir/runtime-features.js +795 -422
- 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 +201 -150
- 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 +196 -76
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +41 -11
- 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 +14 -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 +22 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +35 -6
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/executable-cache.js +3 -0
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/prepare.js +10 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +19 -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 +22 -20
- package/shims/fs-extra/core/api.ts +1192 -0
- package/shims/fs-extra/index.ts +9 -0
- package/shims/undici/core/agent.ts +163 -0
- package/shims/undici/core/api.ts +93 -0
- package/shims/undici/core/client.ts +1304 -0
- package/shims/undici/core/connector.ts +157 -0
- package/shims/undici/core/diagnostics-types.ts +68 -0
- package/shims/undici/core/diagnostics.ts +16 -0
- package/shims/undici/core/dispatcher.ts +574 -0
- package/shims/undici/core/errors-v5.ts +22 -0
- package/shims/undici/core/errors-v7.ts +25 -0
- package/shims/undici/core/errors.ts +255 -0
- package/shims/undici/core/fetch.ts +635 -0
- package/shims/undici/core/pool.ts +280 -0
- package/shims/undici/core/readable.ts +268 -0
- package/shims/undici/core/request.ts +313 -0
- package/shims/undici/core/timers.ts +80 -0
- package/shims/undici/core/types.ts +167 -0
- package/shims/undici/core/util.ts +67 -0
- package/shims/undici/v5.ts +119 -0
- package/shims/undici/v7.ts +119 -0
- package/surface-manifest.json +304 -22
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { lowerTupleAliasDecl, stripTypeWrappers } from "./typed-arguments.js";
|
|
2
|
+
import { declaredMemberOf, isPromisePrototypeRead } from "./expressions/property-access.js";
|
|
3
|
+
import { hostsAll } from "./expressions/hosted-narrowing.js";
|
|
4
|
+
import { requestGeneralStreamSurface } from "./general-streams.js";
|
|
5
|
+
import { lowerForAwaitDynStream } from "./dyn-streams.js";
|
|
6
|
+
import { lowerChildPropertyWrite } from "./handle-properties.js";
|
|
7
|
+
import { matchAllRowsReadByElements, storedMatchAllRowsReadByElements, } from "./containers/match-row-uses.js";
|
|
8
|
+
import { dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../ir/build.js";
|
|
9
|
+
import { runtimeKeyPatternRead } from "./expressions/keyed-field-targets.js";
|
|
10
|
+
import { declaresHoistedBinding, staticCondition } from "./static-typeof.js";
|
|
11
|
+
import { lowerCollectionSpread } from "./containers/collection-methods.js";
|
|
2
12
|
import { lowerEventObjectPropertyWrite } from "./lower-event-target.js";
|
|
3
13
|
import { lowerDynObjectLiteral } from "./expressions/object-literals.js";
|
|
4
14
|
import { importMetaBindingSource } from "./import-meta.js";
|
|
5
15
|
import { iteratorCanStep, iteratorValue } from "./iterator-consumption.js";
|
|
16
|
+
import { notIterableSpelling } from "./iterable-spelling.js";
|
|
6
17
|
import { isPrivateSplitConsumer } from "./split-consumers.js";
|
|
7
18
|
import { InternalCompilerError } from "../../errors.js";
|
|
8
19
|
/* Statement lowering: the statement dispatch (lowerStmt), variable
|
|
@@ -10,23 +21,32 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
10
21
|
* flow (if/while/for/for-of/do, switch, try/catch, abrupt completions),
|
|
11
22
|
* explicit resource management, and blocked-binding poisoning. */
|
|
12
23
|
import * as ts from "../ts7/adapter.js";
|
|
24
|
+
import { processDataMemberValue, programReadsExitCode } from "./builtins/process.js";
|
|
25
|
+
import { requireInitFlagStmt } from "./require-initialization.js";
|
|
26
|
+
import { isJsonRequireDecl } from "./json-require.js";
|
|
13
27
|
import { bindingSource } from "../binding-source.js";
|
|
28
|
+
import { lowerConstructorReturn } from "./constructor-returns.js";
|
|
29
|
+
import { cjsExportValueByName, cjsNamespaceDestructureOf, cjsTableMethodEntry, inlineProgramRequireOf, requireNestedPatternsOf, } from "./cjs-inline-require.js";
|
|
30
|
+
import { cjsExportMemberWriteGlobalOf, isCjsExportsIdentifier, isCjsModuleExports, isFreshExportsReset, } from "./cjs-exports-object.js";
|
|
31
|
+
import { isDeadTscHelperDecl, tscInteropBindingOfDecl } from "./cjs-tsc-interop.js";
|
|
14
32
|
import { arrayValueRead, arrayValueStore, arrayValueType, unionArrayValueRead, lowerSafeIndexRead, } from "./array-values.js";
|
|
15
33
|
import { lowerForAwaitGenerator, lowerForOfGenerator, lowerYieldStarStatement, } from "./lower-generators.js";
|
|
16
|
-
import { lowerForAwaitBuiltin } from "./lower-async-iteration.js";
|
|
34
|
+
import { classAsyncGeneratorIterator, lowerForAwaitBuiltin } from "./lower-async-iteration.js";
|
|
17
35
|
import { BOOL, BYTES_U8, CAUGHT, DYN, F64, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals, } from "../../ir/ir.js";
|
|
18
36
|
import { PoisonError, boundIdentifiersOf, dynFallbackType, neverTaintedJsType, staticImportNamespaceType, } from "./lowerer.js";
|
|
19
37
|
import { enforceLibBoundary, lowerSurplusCalls } from "./lib-boundary.js";
|
|
20
|
-
import { cjsExportAssignmentOf, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile,
|
|
21
|
-
import {
|
|
38
|
+
import { cjsExportAssignmentOf, cjsExportChainOf, cjsVoidInitPreambleReals, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile, locOf, requireEarlyReference, requireSpecOf, } from "../program.js";
|
|
39
|
+
import { isStrictCode } from "./strict-mode.js";
|
|
40
|
+
import { COMPOUND_ASSIGN_OPS, STR_METHODS, UNSUPPORTED_STMT, isStdlibMember, sideEffectFreeOptionValue, stdlibGlobalAliasDecl, stdlibGlobalAliasNameOf, bufferNamespaceMember, stdlibGlobalNameOf, } from "./surfaces.js";
|
|
22
41
|
import { isNativeBuiltinValueInitializer } from "./lower-builtin-values.js";
|
|
23
42
|
import { isProvenanceSourceFile } from "../provenance-registry.js";
|
|
24
43
|
import { ambientUndefVarRootOf, lowerImportEquals, nsUndefRead, nsWritableTarget, trapDeclRootOf, } from "./lower-namespaces.js";
|
|
25
44
|
import { expandoWritableTarget, lowerExpandoAssignStmt } from "./lower-expando.js";
|
|
26
45
|
import { lowerForOfArrayIter, lowerForOfMap, lowerForOfSearchParams, lowerForOfSet, } from "./containers/for-of.js";
|
|
46
|
+
import { lowerForOfHelperChain } from "./containers/iterator-helpers.js";
|
|
27
47
|
import { objectIterOverIndexShape } from "./containers/indexed-objects.js";
|
|
28
48
|
import { strCharsCall } from "./containers/array-construction.js";
|
|
29
|
-
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, } from "./generic-functions.js";
|
|
49
|
+
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, genericLocalClassBinding, } from "./generic-functions.js";
|
|
30
50
|
import { bindingNeverReassigned, deadUnmappableBinding, nullishExprUnitOf, nullishGenericBindingUnitOf, } from "./binding-analysis.js";
|
|
31
51
|
import { hasExplicitJsDocReturn } from "./function-returns.js";
|
|
32
52
|
import { recordKeysArrayCall } from "./lower-calls.js";
|
|
@@ -47,11 +67,14 @@ import { isTimersPromisesIntervalCall } from "./builtins/timers.js";
|
|
|
47
67
|
import { isNativeFfiRequire, builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, } from "./builtins/module-bindings.js";
|
|
48
68
|
import { lowerNodeModuleCall } from "./builtins/module-resolution.js";
|
|
49
69
|
import { registerBuiltinCallableAlias } from "./builtins/callable-aliases.js";
|
|
70
|
+
import { builtinClassAliasOwnsNoSlot, registerBuiltinClassAlias } from "./builtins/class-values.js";
|
|
50
71
|
import { lowerEnumDeclaration } from "./lower-enums.js";
|
|
51
|
-
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerCompoundValueToTarget, lowerElementCompoundStatement, lowerIncDec, lowerIncDecTarget, lowerGroupsProjection, matchResultNamedGroupsOf, runtimeOptionalGuardIds, runtimeOptionalTrueIds, symbolFieldInfo, withRuntimeOptionalNarrowed, } from "./lower-exprs.js";
|
|
72
|
+
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerCompoundValueToTarget, lowerElementCompoundStatement, lowerIncDec, lowerIncDecTarget, lowerOptionalNumber, lowerGroupsProjection, matchResultNamedGroupsOf, runtimeOptionalGuardIds, runtimeOptionalTrueIds, symbolFieldInfo, withRuntimeOptionalNarrowed, } from "./lower-exprs.js";
|
|
52
73
|
import { globalSymbolKey } from "./expressions/global-symbols.js";
|
|
74
|
+
import { identifiersNamed } from "./identifier-uses.js";
|
|
53
75
|
import { lowerShortCircuitAssignment } from "./expressions/nullish-assignment.js";
|
|
54
|
-
import { lowerEnvironmentKey, lowerNativeFunctionAssignment } from "./lower-exprs.js";
|
|
76
|
+
import { builtinGlobalValue, jsHoldsDynObject, lowerEnvironmentKey, lowerNativeFunctionAssignment, lowerStrictEquality, } from "./lower-exprs.js";
|
|
77
|
+
import { keptIdentityAssertion } from "./assertion-identity.js";
|
|
55
78
|
import { isNativeProxyInitializer } from "./expressions/native-proxy.js";
|
|
56
79
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
57
80
|
import { lowerUnionFieldWrite } from "./expressions/union-fields.js";
|
|
@@ -64,6 +87,7 @@ import { constituentTypes } from "../ts7/checker.js";
|
|
|
64
87
|
import { npmStaticPackageOfPath } from "../npm-static.js";
|
|
65
88
|
import { fenceNodeModuleMutation } from "./lower-node-module.js";
|
|
66
89
|
import { fencePerfEntryKeyWalk } from "./builtins/performance.js";
|
|
90
|
+
import { classGeneratorIterable } from "./class-iterables.js";
|
|
67
91
|
/** An opted package's directly-returned empty array may take the function's
|
|
68
92
|
* explicit static return element type. This is the common JS accumulator
|
|
69
93
|
* shape (`const result = []; result.push(value); return result`) and is
|
|
@@ -72,9 +96,9 @@ function npmStaticReturnedEmptyArrayType(lowerer, decl) {
|
|
|
72
96
|
if (!ts.isIdentifier(decl.name) ||
|
|
73
97
|
decl.initializer === undefined ||
|
|
74
98
|
!ts.isArrayLiteralExpression(decl.initializer) ||
|
|
75
|
-
decl.initializer.elements.length !== 0 ||
|
|
76
|
-
!isJsSourceFile(
|
|
77
|
-
npmStaticPackageOfPath(
|
|
99
|
+
decl.initializer.elements.nodes.length !== 0 ||
|
|
100
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
101
|
+
npmStaticPackageOfPath(ts.getSourceFileOfNode(decl).fileName) === null ||
|
|
78
102
|
lowerer.ctx.returnType.kind !== "array") {
|
|
79
103
|
return null;
|
|
80
104
|
}
|
|
@@ -112,8 +136,8 @@ function npmStaticReturnedEmptyArrayType(lowerer, decl) {
|
|
|
112
136
|
* the assignment, narrows it. */
|
|
113
137
|
function npmStaticOptionalSelfWriteType(lowerer, decl, initial) {
|
|
114
138
|
if (!ts.isIdentifier(decl.name) ||
|
|
115
|
-
!isJsSourceFile(
|
|
116
|
-
npmStaticPackageOfPath(
|
|
139
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
140
|
+
npmStaticPackageOfPath(ts.getSourceFileOfNode(decl).fileName) === null ||
|
|
117
141
|
initial.kind === "union") {
|
|
118
142
|
return null;
|
|
119
143
|
}
|
|
@@ -173,8 +197,9 @@ function stdlibTypeNamed(lowerer, node, name) {
|
|
|
173
197
|
if (t.flags & ts.TypeFlags.Union)
|
|
174
198
|
return constituentTypes(t).some(visit);
|
|
175
199
|
const sym = t.getAliasSymbol() ?? t.getSymbol();
|
|
176
|
-
return (sym
|
|
177
|
-
|
|
200
|
+
return (sym !== undefined &&
|
|
201
|
+
ts.symbolName(sym) === name &&
|
|
202
|
+
sym.declarations.some((d) => lowerer.isStdlibFile(ts.getSourceFileOfNode(d))));
|
|
178
203
|
};
|
|
179
204
|
return visit(lowerer.typeOf(node));
|
|
180
205
|
}
|
|
@@ -356,7 +381,7 @@ function lowerUsingStatement(lowerer, stmt) {
|
|
|
356
381
|
lowerer.unsupported("SC1090", stmt, "'await using' outside an async function or top-level-await module");
|
|
357
382
|
}
|
|
358
383
|
const registrations = [];
|
|
359
|
-
for (const decl of stmt.declarationList.declarations) {
|
|
384
|
+
for (const decl of stmt.declarationList.declarations.nodes) {
|
|
360
385
|
if (!ts.isIdentifier(decl.name))
|
|
361
386
|
lowerer.unsupported("SC1031", decl.name);
|
|
362
387
|
if (decl.initializer === undefined)
|
|
@@ -386,14 +411,14 @@ function pureAnnotatedDeadConst(stmt, sf) {
|
|
|
386
411
|
return false;
|
|
387
412
|
if ((stmt.declarationList.flags & ts.NodeFlags.Const) === 0)
|
|
388
413
|
return false;
|
|
389
|
-
const decls = stmt.declarationList.declarations;
|
|
414
|
+
const decls = stmt.declarationList.declarations.nodes;
|
|
390
415
|
if (decls.length === 0)
|
|
391
416
|
return false;
|
|
392
417
|
return decls.every((d) => {
|
|
393
418
|
let init = d.initializer;
|
|
394
419
|
if (init === undefined)
|
|
395
420
|
return false;
|
|
396
|
-
const trivia = sf.text.slice(init.pos,
|
|
421
|
+
const trivia = sf.text.slice(init.pos, ts.tokenStartOfNode(init));
|
|
397
422
|
if (!trivia.includes("@__PURE__") && !trivia.includes("#__PURE__"))
|
|
398
423
|
return false;
|
|
399
424
|
// `as` casts are type-world wrappers (`(() => {...})() as unknown as
|
|
@@ -421,7 +446,7 @@ function pureAnnotatedDeadConst(stmt, sf) {
|
|
|
421
446
|
* probes that would otherwise claim (and diagnose) the call-initializer
|
|
422
447
|
* shape. */
|
|
423
448
|
export function provenanceElidedConstDecl(lowerer, decl) {
|
|
424
|
-
const sf =
|
|
449
|
+
const sf = ts.getSourceFileOfNode(decl);
|
|
425
450
|
if (!isProvenanceSourceFile(sf.fileName))
|
|
426
451
|
return false;
|
|
427
452
|
const stmt = decl.parent?.parent;
|
|
@@ -468,7 +493,7 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
468
493
|
// runtimeFence — a catchable, SC-coded throw at the statement's
|
|
469
494
|
// position — instead of failing the whole build). TypeScript keeps
|
|
470
495
|
// compile fences. ICEs (SC9001) always stay compile errors.
|
|
471
|
-
const sf = stmts[0]
|
|
496
|
+
const sf = stmts.length === 0 ? undefined : ts.getSourceFileOfNode(stmts[0]);
|
|
472
497
|
const deferFences = sf !== undefined && isJsSourceFile(sf);
|
|
473
498
|
// Register this list as open for the forward-capture machinery: a
|
|
474
499
|
// nested function lowering mid-list may pre-declare a LATER const of
|
|
@@ -482,16 +507,20 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
482
507
|
out,
|
|
483
508
|
};
|
|
484
509
|
lowerer.activeStmtLists.push(entry);
|
|
510
|
+
const inFunction = stmts.length > 0 && enclosedByFunction(stmts[0]);
|
|
511
|
+
let unreachable = false;
|
|
485
512
|
try {
|
|
486
513
|
for (let i = 0; i < stmts.length; i++) {
|
|
487
514
|
const stmt = stmts[i];
|
|
488
515
|
entry.index = i;
|
|
489
|
-
if (
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
516
|
+
if (unreachable && skipsWhenUnreachable(stmt))
|
|
517
|
+
continue;
|
|
518
|
+
if (inFunction && isAbruptStatement(stmt))
|
|
519
|
+
unreachable = true;
|
|
520
|
+
if (!lowerer.suppressStats)
|
|
521
|
+
lowerer.countStatement(stmt, sf?.fileName);
|
|
494
522
|
const diagsBefore = lowerer.diags.length;
|
|
523
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
495
524
|
try {
|
|
496
525
|
let lowered;
|
|
497
526
|
let appended = false;
|
|
@@ -558,11 +587,8 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
558
587
|
else if (!(e instanceof PoisonError)) {
|
|
559
588
|
throw e;
|
|
560
589
|
}
|
|
561
|
-
if (!lowerer.suppressStats)
|
|
562
|
-
lowerer.
|
|
563
|
-
if (sf !== undefined)
|
|
564
|
-
lowerer.bumpFileStat(sf.fileName, "failed");
|
|
565
|
-
}
|
|
590
|
+
if (!lowerer.suppressStats)
|
|
591
|
+
lowerer.countStatementFailed(stmt, sf?.fileName);
|
|
566
592
|
lowerer.noteBlockedBindings(stmt);
|
|
567
593
|
// The runtime-fence conversion (JS sources, direct diagnostics
|
|
568
594
|
// only — a capture wrapper in force means collection owns the
|
|
@@ -583,6 +609,13 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
583
609
|
if (fence)
|
|
584
610
|
out.push(fence);
|
|
585
611
|
}
|
|
612
|
+
else if (deferFences) {
|
|
613
|
+
// Inside a capture buffer the owner keeps the diagnostics, but
|
|
614
|
+
// the statement still must not vanish from a result it keeps.
|
|
615
|
+
const fence = lowerer.capturedRuntimeFence(sinkMark, stmt);
|
|
616
|
+
if (fence)
|
|
617
|
+
out.push(fence);
|
|
618
|
+
}
|
|
586
619
|
}
|
|
587
620
|
}
|
|
588
621
|
// Each acquisition protects the remainder of its lexical statement
|
|
@@ -608,6 +641,48 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
608
641
|
}
|
|
609
642
|
return out;
|
|
610
643
|
}
|
|
644
|
+
/** Whether a statement list belongs to a function body (at any block
|
|
645
|
+
* depth) rather than to a module's top level. */
|
|
646
|
+
function enclosedByFunction(stmt) {
|
|
647
|
+
let owner = stmt.parent;
|
|
648
|
+
while (owner !== undefined && !ts.isFunctionLike(owner) && !ts.isSourceFile(owner))
|
|
649
|
+
owner = owner.parent;
|
|
650
|
+
return owner !== undefined && ts.isFunctionLike(owner);
|
|
651
|
+
}
|
|
652
|
+
/** `return`, `throw`, `break` and `continue`: the rest of the enclosing
|
|
653
|
+
* statement list never runs. */
|
|
654
|
+
function isAbruptStatement(stmt) {
|
|
655
|
+
return (ts.isReturnStatement(stmt) ||
|
|
656
|
+
ts.isThrowStatement(stmt) ||
|
|
657
|
+
ts.isBreakStatement(stmt) ||
|
|
658
|
+
ts.isContinueStatement(stmt));
|
|
659
|
+
}
|
|
660
|
+
/** Statements after an abrupt statement in a function body that lowering
|
|
661
|
+
* skips: they never execute, so neither their unsupported constructs nor the
|
|
662
|
+
* functions they reference become part of the program (production builds of
|
|
663
|
+
* libraries keep development-only code behind `throw` stubs this way).
|
|
664
|
+
* Hoisting keeps its meaning: a reference above the abrupt statement to a
|
|
665
|
+
* later function declaration lowers that declaration eagerly
|
|
666
|
+
* (predeclareForwardFnDecl), and references to a later `var`, `let` or
|
|
667
|
+
* `const` binding resolve through the forward-hoisting machinery to its
|
|
668
|
+
* undefined or TDZ state, which skipping its initializer preserves. Class,
|
|
669
|
+
* enum, module and import/export declarations and generic function
|
|
670
|
+
* declarations still lower. */
|
|
671
|
+
function skipsWhenUnreachable(stmt) {
|
|
672
|
+
if (ts.isFunctionDeclaration(stmt))
|
|
673
|
+
return stmt.typeParameters === undefined;
|
|
674
|
+
if (ts.isVariableStatement(stmt))
|
|
675
|
+
return !(stmt.modifiers?.nodes ?? []).some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
676
|
+
return !(ts.isClassDeclaration(stmt) ||
|
|
677
|
+
ts.isEnumDeclaration(stmt) ||
|
|
678
|
+
ts.isModuleDeclaration(stmt) ||
|
|
679
|
+
ts.isImportDeclaration(stmt) ||
|
|
680
|
+
ts.isImportEqualsDeclaration(stmt) ||
|
|
681
|
+
ts.isExportDeclaration(stmt) ||
|
|
682
|
+
ts.isExportAssignment(stmt) ||
|
|
683
|
+
ts.isInterfaceDeclaration(stmt) ||
|
|
684
|
+
ts.isTypeAliasDeclaration(stmt));
|
|
685
|
+
}
|
|
611
686
|
const TDZ_KINDS = new Set([
|
|
612
687
|
"func",
|
|
613
688
|
"string",
|
|
@@ -661,7 +736,7 @@ const TDZ_KINDS = new Set([
|
|
|
661
736
|
* is empty. Mutable bindings also guard writes; only the declaration's
|
|
662
737
|
* initializing assignment may leave the temporal dead zone. */
|
|
663
738
|
export function predeclareForwardCapture(lowerer, symbol) {
|
|
664
|
-
const decl =
|
|
739
|
+
const decl = symbol.valueDeclaration;
|
|
665
740
|
if (!decl ||
|
|
666
741
|
!ts.isVariableDeclaration(decl) ||
|
|
667
742
|
decl.name === undefined ||
|
|
@@ -672,6 +747,10 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
672
747
|
const flags = ts.getCombinedNodeFlags(decl);
|
|
673
748
|
if ((flags & ts.NodeFlags.BlockScoped) === 0 || (flags & ts.NodeFlags.Using) !== 0)
|
|
674
749
|
return false;
|
|
750
|
+
// `const E = EventEmitter` has no storage to box: uses resolve at
|
|
751
|
+
// compile time (builtinClassAliasOf).
|
|
752
|
+
if (builtinClassAliasOwnsNoSlot(lowerer, symbol))
|
|
753
|
+
return false;
|
|
675
754
|
// MODULE-scope bindings are pre-registered globals (collectGlobals):
|
|
676
755
|
// references resolve through globalOf after the local search fails, so
|
|
677
756
|
// a TDZ box here would SHADOW the global and never fill (the top-level
|
|
@@ -697,7 +776,7 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
697
776
|
if (idx < entry.index || entry.ctx === lowerer.ctx || entry.ctx.tdzPredeclared.has(symbol))
|
|
698
777
|
return false;
|
|
699
778
|
let type = lowerer.irTypeOf(decl.name);
|
|
700
|
-
if (isJsSourceFile(
|
|
779
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
701
780
|
!decl.type &&
|
|
702
781
|
!hasJsTypeAnnotation(decl) &&
|
|
703
782
|
(ts.isObjectLiteralExpression(decl.initializer) ||
|
|
@@ -739,8 +818,8 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
739
818
|
* lower the declaration under the owning statement list's context, then
|
|
740
819
|
* resume the caller and thread its captures normally. */
|
|
741
820
|
export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
742
|
-
const decl =
|
|
743
|
-
if (!decl || !ts.isFunctionDeclaration(decl) || !decl.body || decl.typeParameters)
|
|
821
|
+
const decl = symbol.valueDeclaration;
|
|
822
|
+
if (!decl || !ts.isFunctionDeclaration(decl) || !decl.body || decl.typeParameters?.nodes)
|
|
744
823
|
return false;
|
|
745
824
|
for (let i = lowerer.activeStmtLists.length - 1; i >= 0; i--) {
|
|
746
825
|
const entry = lowerer.activeStmtLists[i];
|
|
@@ -765,14 +844,26 @@ export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
|
765
844
|
entry.ctx.hoistedFnDecls.add(decl);
|
|
766
845
|
const fnTail = lowerer.fnStack.splice(depth + 1);
|
|
767
846
|
const scopeTail = entry.ctx.scopes.splice(frameIdx + 1);
|
|
847
|
+
// The hoisted function is kept even when the reference lowers inside
|
|
848
|
+
// a speculative attempt (a probe's temporary diagnostic sink): lower
|
|
849
|
+
// it without that sink, so its failing JS statements keep their
|
|
850
|
+
// runtime fences instead of vanishing from a body that is kept. A
|
|
851
|
+
// declaration that fails as a whole is not kept: its diagnostics go
|
|
852
|
+
// back to the probe.
|
|
853
|
+
const previousSink = lowerer.diagSink;
|
|
854
|
+
const diagsBefore = lowerer.diags.length;
|
|
855
|
+
lowerer.diagSink = null;
|
|
768
856
|
try {
|
|
769
857
|
entry.out.push(lowerer.lowerNestedFunctionDecl(decl));
|
|
770
858
|
}
|
|
771
859
|
catch (e) {
|
|
772
860
|
entry.ctx.hoistedFnDecls.delete(decl);
|
|
861
|
+
if (previousSink !== null)
|
|
862
|
+
previousSink.push(...lowerer.diags.splice(diagsBefore));
|
|
773
863
|
throw e;
|
|
774
864
|
}
|
|
775
865
|
finally {
|
|
866
|
+
lowerer.diagSink = previousSink;
|
|
776
867
|
entry.ctx.scopes.push(...scopeTail);
|
|
777
868
|
lowerer.fnStack.push(...fnTail);
|
|
778
869
|
}
|
|
@@ -804,16 +895,108 @@ function hostVariableDeclarationOf(name) {
|
|
|
804
895
|
* iteration), and it persists after the loop. Returns the write target
|
|
805
896
|
* (a module global for top-level loops, the hoisted function slot
|
|
806
897
|
* otherwise); null when the binding isn't a `var` identifier. */
|
|
807
|
-
export function forOfVarTarget(lowerer, decl) {
|
|
898
|
+
export function forOfVarTarget(lowerer, decl, valueType) {
|
|
808
899
|
if (!ts.isIdentifier(decl.name) || !isVarDeclared(decl))
|
|
809
900
|
return null;
|
|
810
901
|
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
811
902
|
if (!symbol)
|
|
812
903
|
return null;
|
|
813
904
|
const g = lowerer.globalsBySymbol.get(symbol);
|
|
814
|
-
if (g)
|
|
905
|
+
if (g) {
|
|
906
|
+
if (valueType?.kind === "dyn" && jsBindingKeepsCheckedObject(lowerer, decl.name, g.type))
|
|
907
|
+
g.type = DYN;
|
|
815
908
|
return g;
|
|
816
|
-
|
|
909
|
+
}
|
|
910
|
+
return hoistVarBinding(lowerer, symbol, decl.name, valueType);
|
|
911
|
+
}
|
|
912
|
+
/** JavaScript: whether an unannotated variable binding whose static type
|
|
913
|
+
* is `type` keeps a checked-dynamic value unconverted. The checker types
|
|
914
|
+
* such a binding by the object it receives (an element of an evolving
|
|
915
|
+
* `[]`, a `find` result, a member of a checked-dynamic object), but the
|
|
916
|
+
* value is an existing checked-dynamic object or array: a record- or
|
|
917
|
+
* array-typed slot would hold a converted copy, so writes through the
|
|
918
|
+
* binding would miss the object other references see, and `===` against
|
|
919
|
+
* them would fail. Block-scoped bindings with an identifier name keep such
|
|
920
|
+
* values by the same rule in lowerVarDecl (preservesObjectIdentity). */
|
|
921
|
+
function jsBindingKeepsCheckedObject(lowerer, nameNode, type) {
|
|
922
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(nameNode)))
|
|
923
|
+
return false;
|
|
924
|
+
const host = hostVariableDeclarationOf(nameNode);
|
|
925
|
+
if (!host || host.type || hasJsTypeAnnotation(host))
|
|
926
|
+
return false;
|
|
927
|
+
const arms = type.kind === "union" ? (lowerer.unions.get(type.unionId)?.arms ?? []) : [type];
|
|
928
|
+
return (arms.some((arm) => arm.kind === "record" || arm.kind === "array") &&
|
|
929
|
+
arms.every((arm) => arm.kind === "record" || arm.kind === "array" || isUnitType(arm)));
|
|
930
|
+
}
|
|
931
|
+
/** Whether `node` mentions the binding `symbol` anywhere, nested functions
|
|
932
|
+
* included. */
|
|
933
|
+
function mentionsSymbol(lowerer, node, symbol) {
|
|
934
|
+
if (ts.isIdentifier(node))
|
|
935
|
+
return lowerer.checker.getSymbolAtLocation(node) === symbol;
|
|
936
|
+
return (ts.forEachChild(node, (child) => mentionsSymbol(lowerer, child, symbol) ? true : undefined) === true);
|
|
937
|
+
}
|
|
938
|
+
/** Whether `node` evaluates to an existing value rather than constructing
|
|
939
|
+
* one whose layout a destination directs: not a literal, `new`, function
|
|
940
|
+
* or class expression, nor a conditional with such an arm (an arm that
|
|
941
|
+
* is `null` or `undefined` constructs nothing). */
|
|
942
|
+
function existingValueForm(node, armOfConditional = false) {
|
|
943
|
+
while (ts.isParenthesizedExpression(node))
|
|
944
|
+
node = node.expression;
|
|
945
|
+
if (ts.isConditionalExpression(node))
|
|
946
|
+
return existingValueForm(node.whenTrue, true) && existingValueForm(node.whenFalse, true);
|
|
947
|
+
if (armOfConditional &&
|
|
948
|
+
(node.kind === ts.SyntaxKind.NullKeyword ||
|
|
949
|
+
(ts.isIdentifier(node) && node.text === "undefined")))
|
|
950
|
+
return true;
|
|
951
|
+
return !(ts.isObjectLiteralExpression(node) ||
|
|
952
|
+
ts.isArrayLiteralExpression(node) ||
|
|
953
|
+
ts.isNewExpression(node) ||
|
|
954
|
+
ts.isFunctionExpression(node) ||
|
|
955
|
+
ts.isArrowFunction(node) ||
|
|
956
|
+
ts.isClassExpression(node) ||
|
|
957
|
+
ts.isLiteralExpression(node) ||
|
|
958
|
+
node.kind === ts.SyntaxKind.NullKeyword);
|
|
959
|
+
}
|
|
960
|
+
/** JavaScript `var x = e` whose binding could hold an existing
|
|
961
|
+
* checked-dynamic object (jsBindingKeepsCheckedObject): lowers `e` BEFORE
|
|
962
|
+
* minting the hoisted slot, as a block-scoped declaration does, so a
|
|
963
|
+
* checked-dynamic value gets a checked-dynamic slot instead of a converted
|
|
964
|
+
* copy. Other values coerce into the planned slot exactly as
|
|
965
|
+
* lowerExprExpecting would. Null when the declaration does not qualify:
|
|
966
|
+
* the slot already exists, the initializer is fresh construction whose
|
|
967
|
+
* layout the slot type directs (existingValueForm; a literal holding an
|
|
968
|
+
* existing checked-dynamic object qualifies), or it refers to the binding
|
|
969
|
+
* itself (hoist-before-init resolves that reference). */
|
|
970
|
+
function lowerJsVarFromExisting(lowerer, decl, symbol) {
|
|
971
|
+
if (!ts.isIdentifier(decl.name) || !decl.initializer)
|
|
972
|
+
return null;
|
|
973
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(decl)) || lowerer.ctx.hoistedVars.has(symbol))
|
|
974
|
+
return null;
|
|
975
|
+
if (lowerer.bindingIn(lowerer.ctx, symbol))
|
|
976
|
+
return null;
|
|
977
|
+
let node = decl.initializer;
|
|
978
|
+
while (ts.isParenthesizedExpression(node) || ts.isSatisfiesExpression(node))
|
|
979
|
+
node = node.expression;
|
|
980
|
+
// A literal holding an existing checked-dynamic object builds as a
|
|
981
|
+
// checked-dynamic literal without a destination (lowerArrayLiteral,
|
|
982
|
+
// lowerObjectLiteral): a record- or array-typed slot would copy it.
|
|
983
|
+
const holdsChecked = (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) &&
|
|
984
|
+
jsHoldsDynObject(lowerer, node);
|
|
985
|
+
if (!holdsChecked && !existingValueForm(node))
|
|
986
|
+
return null;
|
|
987
|
+
const planned = varBindingType(lowerer, decl.name);
|
|
988
|
+
if (!planned || !jsBindingKeepsCheckedObject(lowerer, decl.name, planned))
|
|
989
|
+
return null;
|
|
990
|
+
if (mentionsSymbol(lowerer, node, symbol))
|
|
991
|
+
return null;
|
|
992
|
+
const value = lowerer.lowerExpr(node);
|
|
993
|
+
const local = hoistVarBinding(lowerer, symbol, decl.name, value.type.kind === "dyn" ? DYN : undefined);
|
|
994
|
+
return {
|
|
995
|
+
kind: "assign",
|
|
996
|
+
localId: local.id,
|
|
997
|
+
value: lowerer.coerceExistingInto(node, value, local.type),
|
|
998
|
+
loc: locOf(decl),
|
|
999
|
+
};
|
|
817
1000
|
}
|
|
818
1001
|
/** The `var` symbol's function-scoped binding TYPE — the declared type at
|
|
819
1002
|
* the binding name, with the JS-source fallbacks every mutable binding
|
|
@@ -825,12 +1008,16 @@ function varBindingType(lowerer, nameNode) {
|
|
|
825
1008
|
if (ts.isVariableDeclaration(nameNode.parent) &&
|
|
826
1009
|
isNativeProxyInitializer(lowerer, nameNode.parent.initializer))
|
|
827
1010
|
return DYN;
|
|
828
|
-
if (isJsSourceFile(
|
|
1011
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(nameNode)) &&
|
|
829
1012
|
ts.isVariableDeclaration(nameNode.parent) &&
|
|
830
1013
|
isNativeBuiltinValueInitializer(lowerer, nameNode.parent.initializer))
|
|
831
1014
|
return DYN;
|
|
1015
|
+
if (ts.isVariableDeclaration(nameNode.parent) &&
|
|
1016
|
+
!nameNode.parent.type &&
|
|
1017
|
+
isPromisePrototypeRead(lowerer, nameNode.parent.initializer))
|
|
1018
|
+
return DYN;
|
|
832
1019
|
let type = lowerer.mapTypeOf(lowerer.typeOf(nameNode));
|
|
833
|
-
if (type?.kind === "record" && isJsSourceFile(
|
|
1020
|
+
if (type?.kind === "record" && isJsSourceFile(ts.getSourceFileOfNode(nameNode))) {
|
|
834
1021
|
const shape = lowerer.shapes.get(type.shapeId);
|
|
835
1022
|
if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
|
|
836
1023
|
type = DYN;
|
|
@@ -866,7 +1053,7 @@ function varBindingType(lowerer, nameNode) {
|
|
|
866
1053
|
* a loop re-ASSIGNS the one binding per pass and never resets it — the
|
|
867
1054
|
* classic capture semantics fall out: closures made in a loop share the
|
|
868
1055
|
* single boxed binding, where `let` gets a fresh box per iteration. */
|
|
869
|
-
function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
1056
|
+
function hoistVarBinding(lowerer, symbol, nameNode, valueType) {
|
|
870
1057
|
const existing = lowerer.ctx.hoistedVars.get(symbol);
|
|
871
1058
|
if (existing)
|
|
872
1059
|
return existing;
|
|
@@ -876,7 +1063,15 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
876
1063
|
lowerer.ctx.hoistedVars.set(symbol, bound);
|
|
877
1064
|
return bound;
|
|
878
1065
|
}
|
|
879
|
-
|
|
1066
|
+
let type = varBindingType(lowerer, nameNode);
|
|
1067
|
+
// The first value stored is an existing checked-dynamic object: keep it
|
|
1068
|
+
// (jsBindingKeepsCheckedObject). A checked-dynamic slot holds undefined
|
|
1069
|
+
// natively, so no runtime-optional widening applies.
|
|
1070
|
+
const keepsChecked = valueType?.kind === "dyn" &&
|
|
1071
|
+
type !== null &&
|
|
1072
|
+
jsBindingKeepsCheckedObject(lowerer, nameNode, type);
|
|
1073
|
+
if (keepsChecked)
|
|
1074
|
+
type = DYN;
|
|
880
1075
|
if (!type)
|
|
881
1076
|
lowerer.badType(nameNode, lowerer.typeOf(nameNode));
|
|
882
1077
|
const root = lowerer.activeStmtLists.find((e) => e.ctx === lowerer.ctx);
|
|
@@ -894,7 +1089,8 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
894
1089
|
};
|
|
895
1090
|
lowerer.ctx.locals.push(local);
|
|
896
1091
|
lowerer.ctx.scopes[0].set(symbol, local);
|
|
897
|
-
|
|
1092
|
+
if (!keepsChecked)
|
|
1093
|
+
noteEarlyReadVar(lowerer, symbol, local);
|
|
898
1094
|
// A checked-dynamic slot holds the dyn undefined (a NULL dyn is a
|
|
899
1095
|
// trap); everything else rides unassignedSlotInit (interned union arm,
|
|
900
1096
|
const wrapped = type.kind === "dyn"
|
|
@@ -921,7 +1117,7 @@ export function predeclareForwardVar(lowerer, symbol) {
|
|
|
921
1117
|
// Module-scope vars already have their global storage.
|
|
922
1118
|
if (lowerer.globalsBySymbol.has(symbol))
|
|
923
1119
|
return false;
|
|
924
|
-
const decl =
|
|
1120
|
+
const decl = symbol.valueDeclaration;
|
|
925
1121
|
if (!decl || !ts.isVariableDeclaration(decl) || !isVarDeclared(decl))
|
|
926
1122
|
return false;
|
|
927
1123
|
const nameNode = ts.isIdentifier(decl.name) ? decl.name : null;
|
|
@@ -1001,7 +1197,7 @@ export function noteBlockedBindings(lowerer, stmt) {
|
|
|
1001
1197
|
}
|
|
1002
1198
|
if (!list)
|
|
1003
1199
|
return;
|
|
1004
|
-
for (const decl of list.declarations) {
|
|
1200
|
+
for (const decl of list.declarations.nodes) {
|
|
1005
1201
|
for (const nameNode of boundIdentifiersOf(decl.name)) {
|
|
1006
1202
|
const symbol = lowerer.checker.getSymbolAtLocation(nameNode);
|
|
1007
1203
|
if (symbol)
|
|
@@ -1026,7 +1222,7 @@ export function isBlockedBinding(lowerer, symbol) {
|
|
|
1026
1222
|
export function lowerScopedBlock(lowerer, stmt) {
|
|
1027
1223
|
lowerer.scopes.push(new Map());
|
|
1028
1224
|
try {
|
|
1029
|
-
return withRuntimeOptionalScope(lowerer, () => ts.isBlock(stmt) ? lowerer.lowerStmts(stmt.statements) : lowerer.lowerStmts([stmt]));
|
|
1225
|
+
return withRuntimeOptionalScope(lowerer, () => ts.isBlock(stmt) ? lowerer.lowerStmts(stmt.statements.nodes) : lowerer.lowerStmts([stmt]));
|
|
1030
1226
|
}
|
|
1031
1227
|
finally {
|
|
1032
1228
|
lowerer.scopes.pop();
|
|
@@ -1084,7 +1280,20 @@ function lowerLabeled(lowerer, stmt) {
|
|
|
1084
1280
|
const body = lowerer.inCtl("block", () => lowerer.lowerScopedBlock(inner), labels);
|
|
1085
1281
|
return { kind: "block", body, labels, loc: locOf(stmt) };
|
|
1086
1282
|
}
|
|
1283
|
+
// Value kinds a `throw` converts to a checked-dynamic value, so the catch
|
|
1284
|
+
// binding sees the thrown object rather than a type-erased reference.
|
|
1285
|
+
const THROWN_AS_DYN = new Set([
|
|
1286
|
+
"array",
|
|
1287
|
+
"union",
|
|
1288
|
+
"map",
|
|
1289
|
+
"set",
|
|
1290
|
+
"bytes",
|
|
1291
|
+
"func",
|
|
1292
|
+
"regex",
|
|
1293
|
+
]);
|
|
1087
1294
|
export function lowerStmt(lowerer, stmt) {
|
|
1295
|
+
if (ownPrototypeResetStatement(lowerer, stmt))
|
|
1296
|
+
return { kind: "block", body: [], loc: locOf(stmt) };
|
|
1088
1297
|
if (ts.isClassDeclaration(stmt)) {
|
|
1089
1298
|
if (!stmt.name)
|
|
1090
1299
|
lowerer.unsupported("SC1090", stmt, "anonymous local class declarations");
|
|
@@ -1097,7 +1306,7 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1097
1306
|
if (ts.isVariableStatement(stmt)) {
|
|
1098
1307
|
// `declare const` — ambient: no storage, no init (collectGlobals
|
|
1099
1308
|
// skipped it; reads throw Node's ReferenceError at the access).
|
|
1100
|
-
const first = stmt.declarationList.declarations[0];
|
|
1309
|
+
const first = stmt.declarationList.declarations.nodes[0];
|
|
1101
1310
|
if (first && ts.getCombinedModifierFlags(first) & ts.ModifierFlags.Ambient)
|
|
1102
1311
|
return null;
|
|
1103
1312
|
return lowerer.lowerVarStatement(stmt);
|
|
@@ -1111,6 +1320,20 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1111
1320
|
}
|
|
1112
1321
|
if (ts.isIfStatement(stmt)) {
|
|
1113
1322
|
const cond = lowerer.lowerCondition(stmt.expression);
|
|
1323
|
+
// A global-detection condition (static-typeof.ts) folds; its untaken
|
|
1324
|
+
// arm is code Node never runs and does not lower, unless it declares a
|
|
1325
|
+
// hoisted binding.
|
|
1326
|
+
const decided = staticCondition(lowerer, stmt.expression);
|
|
1327
|
+
if (decided !== null) {
|
|
1328
|
+
const taken = decided ? stmt.thenStatement : stmt.elseStatement;
|
|
1329
|
+
const untaken = decided ? stmt.elseStatement : stmt.thenStatement;
|
|
1330
|
+
if (untaken === undefined || !declaresHoistedBinding(untaken)) {
|
|
1331
|
+
const arm = taken === undefined ? [] : lowerer.lowerScopedBlock(taken);
|
|
1332
|
+
return decided
|
|
1333
|
+
? { kind: "if", cond, then: arm, else_: null, loc: locOf(stmt) }
|
|
1334
|
+
: { kind: "if", cond, then: [], else_: arm, loc: locOf(stmt) };
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1114
1337
|
// Aliased-typeof narrows (ms's `var type = typeof val` guard): the
|
|
1115
1338
|
// then-branch lowers under what a TRUE condition proves, the
|
|
1116
1339
|
// else-branch under a FALSE one — the var/let alias narrowing the
|
|
@@ -1176,6 +1399,12 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1176
1399
|
// incompatible boundary keeps the ordinary per-statement refusal.
|
|
1177
1400
|
let value = null;
|
|
1178
1401
|
if (stmt.expression) {
|
|
1402
|
+
// A constructor's returned object replaces the constructed `this`.
|
|
1403
|
+
if (lowerer.currentClass?.ctor) {
|
|
1404
|
+
const constructorReturn = lowerConstructorReturn(lowerer, stmt);
|
|
1405
|
+
if (constructorReturn !== null)
|
|
1406
|
+
return constructorReturn;
|
|
1407
|
+
}
|
|
1179
1408
|
return lowerer.lowerReturnStmt(stmt.expression, locOf(stmt));
|
|
1180
1409
|
}
|
|
1181
1410
|
else if (lowerer.ctx.returnType.kind === "union") {
|
|
@@ -1240,6 +1469,13 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1240
1469
|
else if (value.type.kind === "record" && lowerer.dynConvertible(value.type)) {
|
|
1241
1470
|
value = { kind: "dynFrom", value, liveRef: true, type: DYN, loc: locOf(stmt.expression) };
|
|
1242
1471
|
}
|
|
1472
|
+
else if (THROWN_AS_DYN.has(value.type.kind) && lowerer.dynConvertible(value.type)) {
|
|
1473
|
+
// Arrays, Maps, Sets, typed arrays, Buffers, functions, regexes and
|
|
1474
|
+
// unions over them keep their identity and contents the same way:
|
|
1475
|
+
// the catch binding, `typeof`, `instanceof`, `Array.isArray`,
|
|
1476
|
+
// inspection and typed views read the thrown object.
|
|
1477
|
+
value = lowerer.coerceInto(stmt.expression, value, DYN);
|
|
1478
|
+
}
|
|
1243
1479
|
if (value.type.kind === "date") {
|
|
1244
1480
|
lowerer.unsupported("SC1090", stmt.expression, "throwing Date values (catch bindings cannot preserve Date's object kind; throw an Error or primitive instead)");
|
|
1245
1481
|
}
|
|
@@ -1313,77 +1549,131 @@ export function lowerVarStatement(lowerer, stmt) {
|
|
|
1313
1549
|
}
|
|
1314
1550
|
const isConst = (list.flags & ts.NodeFlags.Const) !== 0;
|
|
1315
1551
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
1316
|
-
return list.declarations.flatMap((decl) => {
|
|
1317
|
-
|
|
1318
|
-
//
|
|
1319
|
-
//
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1552
|
+
return list.declarations.nodes.flatMap((decl) => {
|
|
1553
|
+
const lowered = lowerVarDeclarator(lowerer, stmt, decl, isConst, isLet);
|
|
1554
|
+
// A require binding earlier code can read is initialized from here on
|
|
1555
|
+
// (require-initialization.ts).
|
|
1556
|
+
const initialized = requireInitFlagStmt(lowerer, decl);
|
|
1557
|
+
return initialized ? [...lowered, initialized] : lowered;
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
function lowerVarDeclarator(lowerer, stmt, decl, isConst, isLet) {
|
|
1561
|
+
// The canonical ESM bridge to a compiled program module. Like a
|
|
1562
|
+
// top-level CommonJS require declaration, the binding is alias
|
|
1563
|
+
// plumbing while the dependency evaluates at this statement's
|
|
1564
|
+
// exact position through its run-once initializer.
|
|
1565
|
+
if (isConst && createRequireProgramModuleDecl(lowerer, decl.name, decl.initializer)) {
|
|
1566
|
+
if (!ts.isSourceFile(stmt.parent)) {
|
|
1567
|
+
lowerer.unsupported("SC1090", decl, "createRequire program-module bindings outside the module's top level (move the binding to the top of the file; side-effect-only requires may remain nested)");
|
|
1568
|
+
}
|
|
1569
|
+
const target = createRequireProgramModuleOf(lowerer, decl.initializer);
|
|
1570
|
+
const init = lowerer.requireInitStmt(target.spec, decl);
|
|
1571
|
+
return init ? [init] : [];
|
|
1572
|
+
}
|
|
1573
|
+
// tsc's interop bindings (`const x_1 = __importDefault(require("./m"))`)
|
|
1574
|
+
// are require bindings (cjs-tsc-interop.ts): the module's %init here.
|
|
1575
|
+
if (ts.isSourceFile(stmt.parent)) {
|
|
1576
|
+
const interop = tscInteropBindingOfDecl(lowerer, decl);
|
|
1577
|
+
if (interop !== null) {
|
|
1578
|
+
const init = lowerer.requireInitStmt(interop.spec, decl);
|
|
1327
1579
|
return init ? [init] : [];
|
|
1328
1580
|
}
|
|
1329
|
-
|
|
1330
|
-
// level the BINDINGS are alias plumbing (no storage;
|
|
1331
|
-
// resolveValueSymbol routes the reads), but the require itself is
|
|
1332
|
-
// Node's inline module evaluation — a relative require lowers to the
|
|
1333
|
-
// required module's guarded %init call at exactly this position
|
|
1334
|
-
// (first require runs the body, later ones are cache hits; builtins
|
|
1335
|
-
// load nothing). Binding requires anywhere else would need lazily-
|
|
1336
|
-
// initialized alias storage this model doesn't represent; named
|
|
1337
|
-
// fence.
|
|
1338
|
-
if (decl.initializer !== undefined &&
|
|
1339
|
-
requireSpecOf(decl.initializer) !== null &&
|
|
1340
|
-
!isNativeFfiRequire(lowerer, decl.initializer) &&
|
|
1341
|
-
isJsSourceFile(decl.getSourceFile())) {
|
|
1342
|
-
const spec = requireSpecOf(decl.initializer);
|
|
1343
|
-
if (lowerer.externalTypes.has(spec))
|
|
1344
|
-
lowerer.externalHostFence(spec, decl, false);
|
|
1345
|
-
if (ts.isSourceFile(stmt.parent)) {
|
|
1346
|
-
const init = lowerer.requireInitStmt(spec, decl);
|
|
1347
|
-
return init ? [init] : [];
|
|
1348
|
-
}
|
|
1349
|
-
// A nested BUILTIN require (`get inFreeBSDJail() { const { execSync }
|
|
1350
|
-
// = require('child_process'); ... }` — test/common's lazy-getter
|
|
1351
|
-
// idiom): builtins load nothing, so the statement is PURE alias
|
|
1352
|
-
// plumbing wherever it sits — the bindings resolve through the
|
|
1353
|
-
// same routing top-level requires use, and no statement remains.
|
|
1354
|
-
// Relative requires keep the fence: their module-init-at-position
|
|
1355
|
-
// semantics needs storage this model doesn't represent.
|
|
1356
|
-
if (canonicalBuiltinModule(spec) !== null) {
|
|
1357
|
-
return [];
|
|
1358
|
-
}
|
|
1359
|
-
lowerer.unsupported("SC1090", decl, "require() with bindings outside the module's top level (move it to the top of the file)");
|
|
1360
|
-
}
|
|
1361
|
-
// `const { NGHTTP2_CANCEL } = http2.constants` — a destructure over
|
|
1362
|
-
// the baked constants table: alias plumbing, no storage (uses read
|
|
1363
|
-
// their literals via builtinConstantBindingOf; collectGlobals skipped
|
|
1364
|
-
// the globals by the same test).
|
|
1365
|
-
if (lowerer.builtinConstantsDestructureDecl(decl.name, decl.initializer))
|
|
1581
|
+
if (isDeadTscHelperDecl(lowerer, stmt))
|
|
1366
1582
|
return [];
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1583
|
+
}
|
|
1584
|
+
// CommonJS require declarations (JS files): at the module's top
|
|
1585
|
+
// level the BINDINGS are alias plumbing (no storage;
|
|
1586
|
+
// resolveValueSymbol routes the reads), but the require itself is
|
|
1587
|
+
// Node's inline module evaluation — a relative require lowers to the
|
|
1588
|
+
// required module's guarded %init call at exactly this position
|
|
1589
|
+
// (first require runs the body, later ones are cache hits; builtins
|
|
1590
|
+
// load nothing). Binding requires anywhere else would need lazily-
|
|
1591
|
+
// initialized alias storage this model doesn't represent; named
|
|
1592
|
+
// fence.
|
|
1593
|
+
if (decl.initializer !== undefined &&
|
|
1594
|
+
requireSpecOf(decl.initializer) !== null &&
|
|
1595
|
+
!isNativeFfiRequire(lowerer, decl.initializer) &&
|
|
1596
|
+
!isJsonRequireDecl(lowerer, decl) &&
|
|
1597
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
1598
|
+
const spec = requireSpecOf(decl.initializer);
|
|
1599
|
+
if (lowerer.externalTypes.has(spec))
|
|
1600
|
+
lowerer.externalHostFence(spec, decl, false);
|
|
1601
|
+
if (ts.isSourceFile(stmt.parent)) {
|
|
1602
|
+
const init = lowerer.requireInitStmt(spec, decl);
|
|
1603
|
+
const out = init ? [init] : [];
|
|
1604
|
+
// Nested patterns destructure the named export's value right after
|
|
1605
|
+
// the module evaluated (`const { codes: { ERR_X } } = require(...)`).
|
|
1606
|
+
for (const element of requireNestedPatternsOf(decl)) {
|
|
1607
|
+
const key = element.propertyName;
|
|
1608
|
+
const value = lowerer.lowerExpr(key);
|
|
1609
|
+
lowerer.lowerBindingPattern(element.name, () => lowerer.lowerExpr(key), value.type, isLet, out);
|
|
1610
|
+
}
|
|
1611
|
+
return out;
|
|
1612
|
+
}
|
|
1613
|
+
// A nested BUILTIN require (`get inFreeBSDJail() { const { execSync }
|
|
1614
|
+
// = require('child_process'); ... }` — test/common's lazy-getter
|
|
1615
|
+
// idiom): builtins load nothing, so the statement is PURE alias
|
|
1616
|
+
// plumbing wherever it sits — the bindings resolve through the
|
|
1617
|
+
// same routing top-level requires use, and no statement remains.
|
|
1618
|
+
// Relative requires keep the fence: their module-init-at-position
|
|
1619
|
+
// semantics needs storage this model doesn't represent.
|
|
1620
|
+
if (canonicalBuiltinModule(spec) !== null) {
|
|
1621
|
+
return canonicalBuiltinModule(spec) === "punycode"
|
|
1622
|
+
? [lowerer.punycodeRequireWarning(decl)]
|
|
1623
|
+
: [];
|
|
1624
|
+
}
|
|
1625
|
+
lowerer.unsupported("SC1090", decl, "require() with bindings outside the module's top level (move it to the top of the file)");
|
|
1626
|
+
}
|
|
1627
|
+
// `const { NGHTTP2_CANCEL } = http2.constants` — a destructure over
|
|
1628
|
+
// the baked constants table: alias plumbing, no storage (uses read
|
|
1629
|
+
// their literals via builtinConstantBindingOf; collectGlobals skipped
|
|
1630
|
+
// the globals by the same test).
|
|
1631
|
+
if (lowerer.builtinConstantsDestructureDecl(decl.name, decl.initializer))
|
|
1632
|
+
return [];
|
|
1633
|
+
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
1634
|
+
// `const { createSign } = crypto` over a builtin NAMESPACE binding:
|
|
1635
|
+
// alias plumbing (builtinImportOf routes the reads) — no statement.
|
|
1636
|
+
if (builtinNamespaceDestructureModuleOf(lowerer, decl) !== null)
|
|
1637
|
+
return [];
|
|
1638
|
+
// `const { A, B } = ns` over a CommonJS module binding: each name
|
|
1639
|
+
// snapshots the named export's value here (cjs-inline-require.ts).
|
|
1640
|
+
{
|
|
1641
|
+
const nsDestructure = cjsNamespaceDestructureOf(lowerer, decl);
|
|
1642
|
+
if (nsDestructure !== null) {
|
|
1643
|
+
const out = [];
|
|
1644
|
+
for (const element of nsDestructure.elements) {
|
|
1645
|
+
const target = lowerer.globalOf(element.name);
|
|
1646
|
+
const value = cjsExportValueByName(lowerer, nsDestructure.dep, element.key, element.name);
|
|
1647
|
+
if (target === null || value === null) {
|
|
1648
|
+
lowerer.unsupported("SC1090", element.name, `destructuring the export '${element.key}' of a CommonJS module binding (it has no static value)`);
|
|
1649
|
+
}
|
|
1650
|
+
out.push({
|
|
1651
|
+
kind: "assign",
|
|
1652
|
+
localId: target.id,
|
|
1653
|
+
value: typeEquals(value.type, target.type)
|
|
1654
|
+
? value
|
|
1655
|
+
: lowerer.coerceInto(element.name, value, target.type),
|
|
1656
|
+
loc: locOf(element.name),
|
|
1657
|
+
...("tdz" in target && target.tdz ? { initializes: true } : {}),
|
|
1658
|
+
});
|
|
1659
|
+
}
|
|
1660
|
+
return out;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
return lowerer.lowerDestructuringDecl(decl, isLet);
|
|
1664
|
+
}
|
|
1665
|
+
// STORED protocol values with statically closed representations:
|
|
1666
|
+
// numeric value iterators retain source/cursor/done hidden locals; a
|
|
1667
|
+
// matchAll drain retains its companion index array so a later
|
|
1668
|
+
// for-of can serve `m.index`. Both are const-only interceptions.
|
|
1669
|
+
const numericIterator = lowerNumericIteratorDecl(lowerer, decl, isConst);
|
|
1670
|
+
if (numericIterator)
|
|
1671
|
+
return numericIterator;
|
|
1672
|
+
const drained = lowerMatchAllDrainDecl(lowerer, decl, isConst);
|
|
1673
|
+
if (drained)
|
|
1674
|
+
return drained;
|
|
1675
|
+
const lowered = lowerer.lowerVarDecl(decl, isLet);
|
|
1676
|
+
return lowered ? [lowered] : [];
|
|
1387
1677
|
}
|
|
1388
1678
|
/** The numeric indexed source of a built-in value-iterator expression:
|
|
1389
1679
|
* `numbers.values()` or the equivalent
|
|
@@ -1398,7 +1688,7 @@ export function numericIteratorSourceOf(lowerer, expr) {
|
|
|
1398
1688
|
let init = expr;
|
|
1399
1689
|
while (ts.isParenthesizedExpression(init))
|
|
1400
1690
|
init = init.expression;
|
|
1401
|
-
if (!ts.isCallExpression(init) || init.questionDotToken || init.arguments.length !== 0)
|
|
1691
|
+
if (!ts.isCallExpression(init) || init.questionDotToken || init.arguments.nodes.length !== 0)
|
|
1402
1692
|
return null;
|
|
1403
1693
|
let receiver = null;
|
|
1404
1694
|
if (ts.isPropertyAccessExpression(init.expression) &&
|
|
@@ -1494,7 +1784,7 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1494
1784
|
const loc = locOf(decl);
|
|
1495
1785
|
const access = call.expression;
|
|
1496
1786
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
1497
|
-
const re = lowerer.lowerExpr(call.arguments[0]);
|
|
1787
|
+
const re = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
1498
1788
|
const idxsT = arrayOf(F64);
|
|
1499
1789
|
const idxs = lowerer.declareHiddenLocal("%midxs", idxsT);
|
|
1500
1790
|
const local = lowerer.declareLocal(decl.name, decl.name.text, rowsT, false);
|
|
@@ -1511,7 +1801,9 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1511
1801
|
localId: local.id,
|
|
1512
1802
|
init: {
|
|
1513
1803
|
kind: "regexIntrinsic",
|
|
1514
|
-
method:
|
|
1804
|
+
method: storedMatchAllRowsReadByElements(lowerer, decl)
|
|
1805
|
+
? "matchAllCapturesInto"
|
|
1806
|
+
: "matchAllInto",
|
|
1515
1807
|
receiver,
|
|
1516
1808
|
args: [re, { kind: "varRef", localId: idxs.id, type: idxsT, loc }],
|
|
1517
1809
|
type: rowsT,
|
|
@@ -1527,7 +1819,7 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1527
1819
|
export function isParseArgsDynCheckerType(lowerer, type) {
|
|
1528
1820
|
const widened = lowerer.checker.getBaseTypeOfLiteralType(type);
|
|
1529
1821
|
const declarationBelongs = (d) => {
|
|
1530
|
-
if (!lowerer.isStdlibFile(
|
|
1822
|
+
if (!lowerer.isStdlibFile(ts.getSourceFileOfNode(d)))
|
|
1531
1823
|
return false;
|
|
1532
1824
|
let inParseArgsType = false;
|
|
1533
1825
|
for (let node = d.parent; node; node = node.parent) {
|
|
@@ -1543,8 +1835,8 @@ export function isParseArgsDynCheckerType(lowerer, type) {
|
|
|
1543
1835
|
};
|
|
1544
1836
|
const sym = widened.getAliasSymbol() ?? widened.getSymbol();
|
|
1545
1837
|
if (sym &&
|
|
1546
|
-
isParseArgsDynTypeName(sym
|
|
1547
|
-
|
|
1838
|
+
isParseArgsDynTypeName(ts.symbolName(sym)) &&
|
|
1839
|
+
sym.declarations.some(declarationBelongs)) {
|
|
1548
1840
|
return true;
|
|
1549
1841
|
}
|
|
1550
1842
|
// A discriminant check erases the token alias and leaves one anonymous
|
|
@@ -1552,7 +1844,7 @@ export function isParseArgsDynCheckerType(lowerer, type) {
|
|
|
1552
1844
|
// is the same stable signal the dotted-member bridge uses.
|
|
1553
1845
|
return lowerer.checker
|
|
1554
1846
|
.getPropertiesOfType(widened)
|
|
1555
|
-
.some((p) =>
|
|
1847
|
+
.some((p) => p.declarations.some(declarationBelongs));
|
|
1556
1848
|
}
|
|
1557
1849
|
/** Destructuring declarations, desugared as sugar over indexed/field
|
|
1558
1850
|
* reads: the initializer evaluates ONCE into a hidden temp, then each
|
|
@@ -1587,12 +1879,17 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1587
1879
|
lowerer.lowerExpr(decl.initializer);
|
|
1588
1880
|
const parseArgsDynObject = init.type.kind === "dyn" &&
|
|
1589
1881
|
isParseArgsDynCheckerType(lowerer, lowerer.typeOf(decl.initializer));
|
|
1590
|
-
// An `any`-origin source
|
|
1591
|
-
//
|
|
1882
|
+
// An `any`-origin source destructures through a represented record or
|
|
1883
|
+
// array shape, or through the checked-dynamic value it lowered to: the
|
|
1884
|
+
// pattern reads members (or iterates) the dyn value exactly as a
|
|
1885
|
+
// JavaScript file's pattern does, with the same per-site runtime fences
|
|
1886
|
+
// (null/undefined sources throw Node's TypeError). Primitive and unit
|
|
1887
|
+
// sources keep their own fences below; other carriers keep this one.
|
|
1592
1888
|
if (lowerer.anyOrigin(decl.initializer) &&
|
|
1593
|
-
!isJsSourceFile(
|
|
1889
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1594
1890
|
init.type.kind !== "record" &&
|
|
1595
|
-
init.type.kind !== "array"
|
|
1891
|
+
init.type.kind !== "array" &&
|
|
1892
|
+
init.type.kind !== "dyn") {
|
|
1596
1893
|
lowerer.anyOpFence("destructuring", decl);
|
|
1597
1894
|
}
|
|
1598
1895
|
// An IR-string source the CHECKER does not type as a string is a
|
|
@@ -1603,7 +1900,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1603
1900
|
// points), numbers and characters Node never sees. The fence names
|
|
1604
1901
|
// the checker's own type instead of the carrier.
|
|
1605
1902
|
if (init.type.kind === "string" &&
|
|
1606
|
-
isJsSourceFile(
|
|
1903
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1607
1904
|
!checkerStringSource(lowerer, decl.initializer)) {
|
|
1608
1905
|
lowerer.unsupported("SC1031", decl.name, ts.isArrayBindingPattern(decl.name)
|
|
1609
1906
|
? `array destructuring of non-array values (the source is '${lowerer.checker.typeToString(lowerer.typeOf(decl.initializer))}'-typed)`
|
|
@@ -1615,7 +1912,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1615
1912
|
init.type.kind === "bool" ||
|
|
1616
1913
|
init.type.kind === "string" ||
|
|
1617
1914
|
isUnitType(init.type)) &&
|
|
1618
|
-
!isJsSourceFile(
|
|
1915
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1619
1916
|
!(init.type.kind === "string" &&
|
|
1620
1917
|
staticStringPattern(lowerer, decl.name))) {
|
|
1621
1918
|
{
|
|
@@ -1631,7 +1928,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1631
1928
|
// (the message is the fence's — a unit value here is the failure
|
|
1632
1929
|
// path either way). TypeScript keeps the fence: narrowing first is
|
|
1633
1930
|
// the annotated fix.
|
|
1634
|
-
if (isJsSourceFile(
|
|
1931
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) && init.type.kind === "union") {
|
|
1635
1932
|
const def = lowerer.unions.get(init.type.unionId);
|
|
1636
1933
|
const dataArms = (def?.arms ?? []).filter((a) => !isUnitType(a));
|
|
1637
1934
|
const arm = dataArms[0];
|
|
@@ -1669,41 +1966,55 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1669
1966
|
init = { kind: "unionNarrow", unionId: init.type.unionId, tag, value: uref, type: arm, loc };
|
|
1670
1967
|
}
|
|
1671
1968
|
}
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
// own, so the groups projection (lowerGroupsProjection — the same
|
|
1676
|
-
// record `m.groups` reads produce) wraps one level in a synthesized
|
|
1677
|
-
// `{ groups: ... }` record and the ordinary record destructure below
|
|
1678
|
-
// serves the pattern — aliases and nested patterns included. Only
|
|
1679
|
-
// named-group regexes take the wrap: a group-less regex destructures
|
|
1680
|
-
// `groups: undefined` in Node (a nested pattern then throws), which
|
|
1681
|
-
// the fence reports honestly instead.
|
|
1682
|
-
if (ts.isObjectBindingPattern(decl.name) &&
|
|
1683
|
-
decl.name.elements.length > 0 &&
|
|
1684
|
-
isMatchSliceType(lowerer, init.type) &&
|
|
1685
|
-
decl.name.elements.every((el) => {
|
|
1686
|
-
if (el.dotDotDotToken !== undefined || el.name === undefined)
|
|
1687
|
-
return false;
|
|
1688
|
-
const prop = el.propertyName;
|
|
1689
|
-
if (prop === undefined)
|
|
1690
|
-
return ts.isIdentifier(el.name) && el.name.text === "groups";
|
|
1691
|
-
return (ts.isIdentifier(prop) || ts.isStringLiteral(prop)) && prop.text === "groups";
|
|
1692
|
-
})) {
|
|
1693
|
-
const groups = matchResultNamedGroupsOf(lowerer, decl.initializer);
|
|
1694
|
-
if (groups !== null && groups.length > 0) {
|
|
1695
|
-
const proj = lowerGroupsProjection(lowerer, init, groups, loc);
|
|
1696
|
-
const outerShape = lowerer.shapes.intern([{ name: "groups", type: proj.type }], false, undefined, ["groups"]);
|
|
1697
|
-
init = {
|
|
1698
|
-
kind: "recordLit",
|
|
1699
|
-
fields: [{ name: "groups", value: proj }],
|
|
1700
|
-
type: { kind: "record", shapeId: outerShape },
|
|
1701
|
-
loc,
|
|
1702
|
-
};
|
|
1703
|
-
}
|
|
1704
|
-
}
|
|
1969
|
+
const groupsSource = matchGroupsPatternSource(lowerer, decl.name, init, () => matchResultNamedGroupsOf(lowerer, decl.initializer), loc);
|
|
1970
|
+
if (groupsSource !== null)
|
|
1971
|
+
init = groupsSource;
|
|
1705
1972
|
const tmp = lowerer.declareHiddenLocal("%destr", init.type);
|
|
1706
1973
|
out.push({ kind: "varDecl", localId: tmp.id, init, loc });
|
|
1974
|
+
// A TypeScript `any` source destructured through its checked-dynamic
|
|
1975
|
+
// value: RequireObjectCoercible with V8's own TypeError ("Cannot
|
|
1976
|
+
// destructure property 'a' of 'f(...)' as it is null.") for the source
|
|
1977
|
+
// spellings the assignment form reproduces; other sources are refused,
|
|
1978
|
+
// as in the assignment form. JavaScript files keep their existing
|
|
1979
|
+
// per-read errors, except that a runtime computed first key checks the
|
|
1980
|
+
// source first: Node throws before it evaluates any key, and V8's bare
|
|
1981
|
+
// message names the source.
|
|
1982
|
+
const jsRuntimeKeyCheck = init.type.kind === "dyn" &&
|
|
1983
|
+
ts.isObjectBindingPattern(decl.name) &&
|
|
1984
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1985
|
+
startsWithRuntimeKey(lowerer, decl.name) &&
|
|
1986
|
+
destrSpellingOf(decl.initializer) !== null;
|
|
1987
|
+
if (jsRuntimeKeyCheck ||
|
|
1988
|
+
(init.type.kind === "dyn" &&
|
|
1989
|
+
ts.isObjectBindingPattern(decl.name) &&
|
|
1990
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1991
|
+
lowerer.anyOrigin(decl.initializer))) {
|
|
1992
|
+
const spelling = destrSpellingOf(decl.initializer);
|
|
1993
|
+
if (spelling === null) {
|
|
1994
|
+
lowerer.unsupported("SC1031", decl.initializer, "destructuring declaration from an `any` source whose expression spelling is unsupported (use a variable, ordinary property chain, or ordinary call)");
|
|
1995
|
+
}
|
|
1996
|
+
const first = decl.name.elements.nodes[0];
|
|
1997
|
+
const firstKey = first === undefined || first.dotDotDotToken !== undefined
|
|
1998
|
+
? undefined
|
|
1999
|
+
: (first.propertyName ?? first.name);
|
|
2000
|
+
// V8 names the first property when its key is an identifier, a string
|
|
2001
|
+
// or a number; a computed first key takes the bare (source-only) form.
|
|
2002
|
+
const firstProp = firstKey === undefined || ts.isComputedPropertyName(firstKey)
|
|
2003
|
+
? undefined
|
|
2004
|
+
: (patternKeyNameOf(lowerer, firstKey) ?? undefined);
|
|
2005
|
+
out.push({
|
|
2006
|
+
kind: "exprStmt",
|
|
2007
|
+
expr: {
|
|
2008
|
+
kind: "dynDestrCheck",
|
|
2009
|
+
value: { kind: "varRef", localId: tmp.id, type: init.type, loc },
|
|
2010
|
+
spelling,
|
|
2011
|
+
...(firstProp !== undefined ? { firstProp } : {}),
|
|
2012
|
+
type: init.type,
|
|
2013
|
+
loc,
|
|
2014
|
+
},
|
|
2015
|
+
loc,
|
|
2016
|
+
});
|
|
2017
|
+
}
|
|
1707
2018
|
// V8's destructuring TypeError spells STATIC sources: an identifier
|
|
1708
2019
|
// source reads "<name> is not iterable", an identifier-callee call
|
|
1709
2020
|
// "<name> is not a function or its return value is not iterable";
|
|
@@ -1719,6 +2030,44 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1719
2030
|
lowerer.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: init.type, loc }), init.type, isLet, out, dynSpell, parseArgsDynObject);
|
|
1720
2031
|
return out;
|
|
1721
2032
|
}
|
|
2033
|
+
/** `const { groups } = re.exec(s)!` / `const { groups: { year } } = m`
|
|
2034
|
+
* — every pattern element binds `groups` off a match row whose regex is
|
|
2035
|
+
* statically known. The slice (or a JavaScript callback's dynamic row)
|
|
2036
|
+
* has no record shape of its own, so the groups projection
|
|
2037
|
+
* (lowerGroupsProjection — the same record `m.groups` reads produce)
|
|
2038
|
+
* wraps one level in a synthesized `{ groups: ... }` record and the
|
|
2039
|
+
* ordinary record destructure serves the pattern — aliases and nested
|
|
2040
|
+
* patterns included. Only named-group regexes take the wrap: a
|
|
2041
|
+
* group-less regex destructures `groups: undefined` in Node (a nested
|
|
2042
|
+
* pattern then throws), which the fence reports honestly instead. Null
|
|
2043
|
+
* when the pattern or the row does not qualify. */
|
|
2044
|
+
export function matchGroupsPatternSource(lowerer, pattern, row, groupsOf, loc) {
|
|
2045
|
+
if (!ts.isObjectBindingPattern(pattern) ||
|
|
2046
|
+
pattern.elements.nodes.length === 0 ||
|
|
2047
|
+
!(row.type.kind === "dyn"
|
|
2048
|
+
? isJsSourceFile(ts.getSourceFileOfNode(pattern))
|
|
2049
|
+
: isMatchSliceType(lowerer, row.type)) ||
|
|
2050
|
+
!pattern.elements.nodes.every((el) => {
|
|
2051
|
+
if (el.dotDotDotToken !== undefined || el.name === undefined)
|
|
2052
|
+
return false;
|
|
2053
|
+
const prop = el.propertyName;
|
|
2054
|
+
if (prop === undefined)
|
|
2055
|
+
return ts.isIdentifier(el.name) && el.name.text === "groups";
|
|
2056
|
+
return (ts.isIdentifier(prop) || ts.isStringLiteral(prop)) && prop.text === "groups";
|
|
2057
|
+
}))
|
|
2058
|
+
return null;
|
|
2059
|
+
const groups = groupsOf();
|
|
2060
|
+
if (groups === null || groups.length === 0)
|
|
2061
|
+
return null;
|
|
2062
|
+
const proj = lowerGroupsProjection(lowerer, row, groups, loc);
|
|
2063
|
+
const outerShape = lowerer.shapes.intern([{ name: "groups", type: proj.type }], false, undefined, ["groups"]);
|
|
2064
|
+
return {
|
|
2065
|
+
kind: "recordLit",
|
|
2066
|
+
fields: [{ name: "groups", value: proj }],
|
|
2067
|
+
type: { kind: "record", shapeId: outerShape },
|
|
2068
|
+
loc,
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
1722
2071
|
/** One pattern level: emits a declaration (or global assignment) per
|
|
1723
2072
|
* bound name, recursing through hidden temps for nested patterns. */
|
|
1724
2073
|
export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, out, dynSpell, allowDynObject = false) {
|
|
@@ -1726,7 +2075,9 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1726
2075
|
const patternType = lowerer.typeOf(pattern);
|
|
1727
2076
|
const patternSymbol = patternType.getSymbol();
|
|
1728
2077
|
allowDynObject ||=
|
|
1729
|
-
patternSymbol
|
|
2078
|
+
patternSymbol !== undefined &&
|
|
2079
|
+
ts.symbolName(patternSymbol) === "SegmentData" &&
|
|
2080
|
+
lowerer.isStdlibSymbol(patternSymbol);
|
|
1730
2081
|
allowDynObject ||=
|
|
1731
2082
|
(patternType.flags & ts.TypeFlags.Object) !== 0 &&
|
|
1732
2083
|
lowerer.mapTypeOf(patternType)?.kind === "dyn";
|
|
@@ -1740,17 +2091,22 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1740
2091
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
1741
2092
|
lowerer.fenceStaticHeadersIteration(pattern);
|
|
1742
2093
|
if (srcType.kind === "union" &&
|
|
1743
|
-
lowerer.unions
|
|
1744
|
-
|
|
1745
|
-
|
|
2094
|
+
lowerer.unions
|
|
2095
|
+
.get(srcType.unionId)
|
|
2096
|
+
?.arms.every((arm) => arm.kind === "array" ||
|
|
2097
|
+
arm.kind === "string" ||
|
|
2098
|
+
(arm.kind === "record" && lowerer.shapes.get(arm.shapeId)?.tuple === true)) &&
|
|
2099
|
+
lowerer.unions.get(srcType.unionId).arms.some((arm) => arm.kind !== "string")) {
|
|
2100
|
+
for (let i = 0; i < pattern.elements.nodes.length; i++) {
|
|
2101
|
+
const el = pattern.elements.nodes[i];
|
|
1746
2102
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1747
2103
|
continue;
|
|
1748
2104
|
if (el.dotDotDotToken)
|
|
1749
|
-
lowerer.unsupported("SC1031", el, "rest elements over a union of array layouts");
|
|
2105
|
+
lowerer.unsupported("SC1031", el, "rest elements over a union of array or tuple layouts");
|
|
1750
2106
|
const loc = locOf(el);
|
|
1751
|
-
let value = unionArrayValueRead(lowerer, srcRef(), numLit(i, loc), loc);
|
|
2107
|
+
let value = unionArrayValueRead(lowerer, srcRef(), numLit(i, loc), loc, (text) => strCharsCall(lowerer, text, loc));
|
|
1752
2108
|
if (!value)
|
|
1753
|
-
lowerer.unsupported("SC1031", el, "array union elements without a common native representation");
|
|
2109
|
+
lowerer.unsupported("SC1031", el, "array or tuple union elements without a common native representation");
|
|
1754
2110
|
if (el.initializer)
|
|
1755
2111
|
value = applyBindingDefault(lowerer, el, value);
|
|
1756
2112
|
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
@@ -1761,7 +2117,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1761
2117
|
// shape — the positional twin of object destructuring below.
|
|
1762
2118
|
const tupleShape = srcType.kind === "record" ? lowerer.shapes.get(srcType.shapeId) : undefined;
|
|
1763
2119
|
if (srcType.kind === "record" && tupleShape?.tuple) {
|
|
1764
|
-
pattern.elements.forEach((el, i) => {
|
|
2120
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1765
2121
|
// Holes: OmittedExpression in 5.9.3, a nameless BindingElement in
|
|
1766
2122
|
// 7 (parity finding 2) — either way the position is skipped.
|
|
1767
2123
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
@@ -1828,7 +2184,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1828
2184
|
loc,
|
|
1829
2185
|
});
|
|
1830
2186
|
const itRef = () => ({ kind: "varRef", localId: it.id, type: citPat.iterT, loc });
|
|
1831
|
-
for (const el of pattern.elements) {
|
|
2187
|
+
for (const el of pattern.elements.nodes) {
|
|
1832
2188
|
const stepLoc = locOf(el);
|
|
1833
2189
|
const step = lowerer.classIteratorNextCall(citPat, itRef(), stepLoc);
|
|
1834
2190
|
if (ts.isOmittedExpression(el) || el.name === undefined) {
|
|
@@ -1902,10 +2258,10 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1902
2258
|
out.push({
|
|
1903
2259
|
kind: "varDecl",
|
|
1904
2260
|
localId: pack.id,
|
|
1905
|
-
init: pattern.elements.some((element) => ts.isBindingElement(element) && element.dotDotDotToken)
|
|
2261
|
+
init: pattern.elements.nodes.some((element) => ts.isBindingElement(element) && element.dotDotDotToken)
|
|
1906
2262
|
? {
|
|
1907
2263
|
kind: "libCall",
|
|
1908
|
-
fn: "dyn.
|
|
2264
|
+
fn: "dyn.destructureRest",
|
|
1909
2265
|
args: [srcRef(), { kind: "strLit", value: dynSpell ?? "", type: STRING, loc }],
|
|
1910
2266
|
type: DYN,
|
|
1911
2267
|
loc,
|
|
@@ -1913,14 +2269,14 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1913
2269
|
: {
|
|
1914
2270
|
kind: "dynIterN",
|
|
1915
2271
|
value: srcRef(),
|
|
1916
|
-
count: pattern.elements.length,
|
|
2272
|
+
count: pattern.elements.nodes.length,
|
|
1917
2273
|
...(dynSpell ? { notIterableMessage: dynSpell } : {}),
|
|
1918
2274
|
type: DYN,
|
|
1919
2275
|
loc,
|
|
1920
2276
|
},
|
|
1921
2277
|
loc,
|
|
1922
2278
|
});
|
|
1923
|
-
pattern.elements.forEach((el, i) => {
|
|
2279
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1924
2280
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1925
2281
|
return; // hole: the position skips
|
|
1926
2282
|
const elLoc = locOf(el);
|
|
@@ -1976,7 +2332,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1976
2332
|
// fresh number[] (never another typed array), exactly the iterator
|
|
1977
2333
|
// protocol's Array accumulation.
|
|
1978
2334
|
if (srcType.kind === "bytes") {
|
|
1979
|
-
pattern.elements.forEach((el, i) => {
|
|
2335
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1980
2336
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1981
2337
|
return;
|
|
1982
2338
|
const loc = locOf(el);
|
|
@@ -2018,10 +2374,30 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2018
2374
|
});
|
|
2019
2375
|
return;
|
|
2020
2376
|
}
|
|
2377
|
+
// Map and Set sources (`const [[k, v], ...rest] = map`): the iterator
|
|
2378
|
+
// yields the collection's entries (Map pairs) or values in order, so
|
|
2379
|
+
// the source snapshots ONCE into that array — the spread's own
|
|
2380
|
+
// machinery — and the pattern lowers as an array pattern over it,
|
|
2381
|
+
// like the string case above. Element defaults keep a fence: they
|
|
2382
|
+
// run between iterator steps and could mutate the live collection.
|
|
2383
|
+
if (srcType.kind === "map" || srcType.kind === "set") {
|
|
2384
|
+
const defaulted = pattern.elements.nodes.find((el) => ts.isBindingElement(el) && el.initializer !== undefined && !el.dotDotDotToken);
|
|
2385
|
+
if (defaulted)
|
|
2386
|
+
lowerer.unsupported("SC1031", defaulted, "binding defaults over Map/Set sources");
|
|
2387
|
+
const snapshot = lowerCollectionSpread(lowerer, srcRef(), pattern);
|
|
2388
|
+
if (snapshot && snapshot.type.kind === "array") {
|
|
2389
|
+
const loc = locOf(pattern);
|
|
2390
|
+
const snapshotT = snapshot.type;
|
|
2391
|
+
const entries = lowerer.declareHiddenLocal("%dentries", snapshotT);
|
|
2392
|
+
out.push({ kind: "varDecl", localId: entries.id, init: snapshot, loc });
|
|
2393
|
+
lowerer.lowerBindingPattern(pattern, () => ({ kind: "varRef", localId: entries.id, type: snapshotT, loc }), snapshotT, isLet, out);
|
|
2394
|
+
return;
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2021
2397
|
if (srcType.kind !== "array") {
|
|
2022
2398
|
lowerer.unsupported("SC1031", pattern, `array destructuring of non-array values (the source is ${srcType.kind}-typed)`);
|
|
2023
2399
|
}
|
|
2024
|
-
pattern.elements.forEach((el, i) => {
|
|
2400
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
2025
2401
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
2026
2402
|
return; // hole: position skipped, like JS over an array
|
|
2027
2403
|
const loc = locOf(el);
|
|
@@ -2054,7 +2430,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2054
2430
|
});
|
|
2055
2431
|
return;
|
|
2056
2432
|
}
|
|
2057
|
-
if (pattern.elements.length === 0) {
|
|
2433
|
+
if (pattern.elements.nodes.length === 0) {
|
|
2058
2434
|
// `var {} = e`, `for (const {} of ns)`: RequireObjectCoercible and
|
|
2059
2435
|
// nothing else — a pure no-op past the source's own evaluation for
|
|
2060
2436
|
// every statically non-nullish kind, record or not (the assignment
|
|
@@ -2079,19 +2455,40 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2079
2455
|
// deliberately carried by the checked-dynamic tree, so their ordinary
|
|
2080
2456
|
// object patterns use the same exact keyed-read desugar.
|
|
2081
2457
|
if (srcType.kind === "union" &&
|
|
2082
|
-
isJsSourceFile(
|
|
2458
|
+
isJsSourceFile(ts.getSourceFileOfNode(pattern)) &&
|
|
2083
2459
|
lowerer.dynConvertible(srcType)) {
|
|
2084
2460
|
lowerer.lowerBindingPattern(pattern, () => lowerer.coerceToExpected(srcRef(), DYN), DYN, isLet, out, dynSpell, allowDynObject);
|
|
2085
2461
|
return;
|
|
2086
2462
|
}
|
|
2087
2463
|
if (srcType.kind === "dyn") {
|
|
2088
|
-
|
|
2464
|
+
// A runtime computed first key evaluates after RequireObjectCoercible:
|
|
2465
|
+
// a nullish source throws before the key's side effects run. Later
|
|
2466
|
+
// keys follow a read that already threw.
|
|
2467
|
+
if (ts.isObjectBindingPattern(pattern) && startsWithRuntimeKey(lowerer, pattern)) {
|
|
2468
|
+
const loc = locOf(pattern);
|
|
2469
|
+
for (const unit of ["null", "undefined"]) {
|
|
2470
|
+
out.push({
|
|
2471
|
+
kind: "if",
|
|
2472
|
+
cond: { kind: "dynTest", test: unit, value: srcRef(), type: BOOL, loc },
|
|
2473
|
+
then: [
|
|
2474
|
+
{
|
|
2475
|
+
kind: "exprStmt",
|
|
2476
|
+
expr: nodeThrowExpr(1, "", `Cannot read properties of ${unit}`, VOID, loc),
|
|
2477
|
+
loc,
|
|
2478
|
+
},
|
|
2479
|
+
],
|
|
2480
|
+
else_: null,
|
|
2481
|
+
loc,
|
|
2482
|
+
});
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
for (const el of pattern.elements.nodes) {
|
|
2089
2486
|
if (el.name === undefined)
|
|
2090
2487
|
continue;
|
|
2091
2488
|
const loc = locOf(el);
|
|
2092
2489
|
if (el.dotDotDotToken) {
|
|
2093
2490
|
const keys = [];
|
|
2094
|
-
for (const sibling of pattern.elements) {
|
|
2491
|
+
for (const sibling of pattern.elements.nodes) {
|
|
2095
2492
|
if (sibling === el || sibling.dotDotDotToken)
|
|
2096
2493
|
continue;
|
|
2097
2494
|
const key = sibling.propertyName ?? sibling.name;
|
|
@@ -2126,10 +2523,14 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2126
2523
|
ts.isNumericLiteral(prop)
|
|
2127
2524
|
? patternKeyNameOf(lowerer, prop)
|
|
2128
2525
|
: null;
|
|
2129
|
-
|
|
2526
|
+
// A runtime computed key (`{ [name]: v }`) reads the live property.
|
|
2527
|
+
const runtimeRead = propName === null && ts.isComputedPropertyName(prop)
|
|
2528
|
+
? runtimeKeyPatternRead(lowerer, prop.expression, srcRef(), out, loc)
|
|
2529
|
+
: null;
|
|
2530
|
+
if (propName === null && runtimeRead === null) {
|
|
2130
2531
|
lowerer.unsupported("SC1031", el, "destructuring with computed keys that do not fold to one property name");
|
|
2131
2532
|
}
|
|
2132
|
-
let value = {
|
|
2533
|
+
let value = runtimeRead ?? {
|
|
2133
2534
|
kind: "dynKeyGet",
|
|
2134
2535
|
key: { kind: "strLit", value: propName, type: STRING, loc },
|
|
2135
2536
|
value: srcRef(),
|
|
@@ -2169,7 +2570,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2169
2570
|
if (!info)
|
|
2170
2571
|
lowerer.flushDeferredClass(srcType.className);
|
|
2171
2572
|
if (info) {
|
|
2172
|
-
for (const el of pattern.elements) {
|
|
2573
|
+
for (const el of pattern.elements.nodes) {
|
|
2173
2574
|
if (el.name === undefined)
|
|
2174
2575
|
continue;
|
|
2175
2576
|
const loc = locOf(el);
|
|
@@ -2179,7 +2580,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2179
2580
|
// CopyDataProperties copies own enumerable properties, which
|
|
2180
2581
|
// for a class instance are exactly the fields).
|
|
2181
2582
|
const consumed = new Set();
|
|
2182
|
-
for (const sib of pattern.elements) {
|
|
2583
|
+
for (const sib of pattern.elements.nodes) {
|
|
2183
2584
|
if (sib === el || sib.name === undefined || sib.dotDotDotToken)
|
|
2184
2585
|
continue;
|
|
2185
2586
|
const keyNode = sib.propertyName ?? (ts.isIdentifier(sib.name) ? sib.name : null);
|
|
@@ -2258,7 +2659,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2258
2659
|
// naming that. Callers vetted the source as a checker-typed string —
|
|
2259
2660
|
// builtin identity tokens fence before reaching here.
|
|
2260
2661
|
if (srcType.kind === "string") {
|
|
2261
|
-
for (const el of pattern.elements) {
|
|
2662
|
+
for (const el of pattern.elements.nodes) {
|
|
2262
2663
|
if (el.name === undefined)
|
|
2263
2664
|
continue;
|
|
2264
2665
|
const loc = locOf(el);
|
|
@@ -2294,6 +2695,21 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2294
2695
|
}
|
|
2295
2696
|
return;
|
|
2296
2697
|
}
|
|
2698
|
+
if (srcType.kind === "array" &&
|
|
2699
|
+
isMatchSliceType(lowerer, srcType) &&
|
|
2700
|
+
isRegexMatchResultPattern(lowerer, pattern)) {
|
|
2701
|
+
lowerMatchResultObjectPattern(lowerer, pattern, srcRef, srcType, isLet, out);
|
|
2702
|
+
return;
|
|
2703
|
+
}
|
|
2704
|
+
if (srcType.kind === "array" && isArrayPositionPattern(lowerer, pattern)) {
|
|
2705
|
+
lowerArrayPositionObjectPattern(lowerer, pattern, srcRef, srcType, isLet, out);
|
|
2706
|
+
return;
|
|
2707
|
+
}
|
|
2708
|
+
const nsSource = lowerer.sourceFileOfModuleNamespace(srcType);
|
|
2709
|
+
if (nsSource !== null) {
|
|
2710
|
+
lowerModuleNamespacePattern(lowerer, pattern, nsSource, isLet, out);
|
|
2711
|
+
return;
|
|
2712
|
+
}
|
|
2297
2713
|
if (srcType.kind !== "record") {
|
|
2298
2714
|
lowerer.unsupported("SC1031", pattern, srcType.kind === "object"
|
|
2299
2715
|
? "object destructuring of class instances (read the fields directly — accessors make the desugar observable)"
|
|
@@ -2302,7 +2718,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2302
2718
|
const shape = lowerer.shapes.get(srcType.shapeId);
|
|
2303
2719
|
if (!shape)
|
|
2304
2720
|
throw new InternalCompilerError(`lowerer bug: destructuring unknown shape ${srcType.shapeId}`);
|
|
2305
|
-
for (const el of pattern.elements) {
|
|
2721
|
+
for (const el of pattern.elements.nodes) {
|
|
2306
2722
|
if (el.name === undefined)
|
|
2307
2723
|
continue; // 7 spells elisions as nameless elements
|
|
2308
2724
|
// `{ a, ...rest }`: the rest binds a FRESH record of the unconsumed
|
|
@@ -2325,7 +2741,18 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2325
2741
|
? patternKeyNameOf(lowerer, prop)
|
|
2326
2742
|
: null;
|
|
2327
2743
|
if (propName === null) {
|
|
2328
|
-
|
|
2744
|
+
// A runtime computed key (`{ [name]: v }`): the keyed read of an
|
|
2745
|
+
// index-signature entry, of the declared field a literal-union key
|
|
2746
|
+
// names, or of a JavaScript record's live property.
|
|
2747
|
+
const runtimeRead = ts.isComputedPropertyName(prop)
|
|
2748
|
+
? runtimeKeyPatternRead(lowerer, prop.expression, srcRef(), out, locOf(el))
|
|
2749
|
+
: null;
|
|
2750
|
+
if (runtimeRead === null) {
|
|
2751
|
+
lowerer.unsupported("SC1031", el, "destructuring with computed keys that do not fold to one property name");
|
|
2752
|
+
}
|
|
2753
|
+
const value = el.initializer ? applyBindingDefault(lowerer, el, runtimeRead) : runtimeRead;
|
|
2754
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
2755
|
+
continue;
|
|
2329
2756
|
}
|
|
2330
2757
|
// An ACCESSOR property (%get:/%set: closure slots): the element's
|
|
2331
2758
|
// read IS a getter call — once, at the element's pattern position
|
|
@@ -2376,18 +2803,19 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2376
2803
|
// An UNDECLARED key of an INDEX-SIGNATURE shape (`const { m, n, p }
|
|
2377
2804
|
// = ....groups` over `{ [key: string]: string }` — the groups
|
|
2378
2805
|
// record, `Record<string, T>` tables generally): the overflow-map
|
|
2379
|
-
// read, exactly the dot access's recordKeyGet — a missing key
|
|
2380
|
-
//
|
|
2381
|
-
// claimed V), or binds the undefined arm (where a default applies
|
|
2382
|
-
// like any field's).
|
|
2806
|
+
// read, exactly the dot access's recordKeyGet — a missing key binds
|
|
2807
|
+
// the undefined arm (where a default applies like any field's).
|
|
2383
2808
|
const loc = locOf(el);
|
|
2809
|
+
const readType = shape.indexValue.kind === "dyn"
|
|
2810
|
+
? shape.indexValue
|
|
2811
|
+
: (lowerer.withUndefinedArmOf(shape.indexValue) ?? shape.indexValue);
|
|
2384
2812
|
let value = {
|
|
2385
2813
|
kind: "recordKeyGet",
|
|
2386
2814
|
obj: srcRef(),
|
|
2387
2815
|
shapeId: srcType.shapeId,
|
|
2388
2816
|
key: { kind: "strLit", value: propName, type: STRING, loc },
|
|
2389
2817
|
overflowOnly: true,
|
|
2390
|
-
type:
|
|
2818
|
+
type: readType,
|
|
2391
2819
|
loc,
|
|
2392
2820
|
};
|
|
2393
2821
|
if (el.initializer)
|
|
@@ -2395,7 +2823,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2395
2823
|
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
2396
2824
|
continue;
|
|
2397
2825
|
}
|
|
2398
|
-
if (!fieldType && isJsSourceFile(
|
|
2826
|
+
if (!fieldType && isJsSourceFile(ts.getSourceFileOfNode(el))) {
|
|
2399
2827
|
// Inferred JavaScript shapes can omit optional own properties and
|
|
2400
2828
|
// inherit values from their prototype. Read the live checked view.
|
|
2401
2829
|
const loc = locOf(el);
|
|
@@ -2512,7 +2940,58 @@ function patternSourceValue(lowerer, value, arrayPattern, out, loc, spelling) {
|
|
|
2512
2940
|
function patternBindingType(lowerer, name) {
|
|
2513
2941
|
const type = lowerer.typeOf(name);
|
|
2514
2942
|
return (lowerer.mapTypeOf(type) ??
|
|
2515
|
-
(isJsSourceFile(
|
|
2943
|
+
(isJsSourceFile(ts.getSourceFileOfNode(name)) ? dynFallbackType(lowerer, name, type) : null));
|
|
2944
|
+
}
|
|
2945
|
+
/** `const { a, b: c } = ns` / `const { f } = await import("./m")` over
|
|
2946
|
+
* a program module's namespace: each element reads the export exactly
|
|
2947
|
+
* like `ns.a` does — the member resolves to the exporter's own binding
|
|
2948
|
+
* (nsMemberIdentOf's rule), read once at the pattern's position, so the
|
|
2949
|
+
* bound name holds the export's value at that moment (destructuring
|
|
2950
|
+
* copies; it does not alias the live binding). The namespace value
|
|
2951
|
+
* itself was already evaluated into the pattern's temp, so its side
|
|
2952
|
+
* effects (the dynamic import) keep their order. Rest elements would
|
|
2953
|
+
* materialize the namespace object and keep their fence. The exports
|
|
2954
|
+
* come from the source's module, not from the pattern's type: an
|
|
2955
|
+
* annotation can name another module with a compatible shape. */
|
|
2956
|
+
function lowerModuleNamespacePattern(lowerer, pattern, source, isLet, out) {
|
|
2957
|
+
const moduleSym = lowerer.checker.getSymbolAtLocation(source);
|
|
2958
|
+
if (moduleSym === undefined) {
|
|
2959
|
+
lowerer.unsupported("SC1031", pattern, "destructuring a module namespace without a module symbol");
|
|
2960
|
+
}
|
|
2961
|
+
const nsType = lowerer.checker.getTypeOfSymbol(moduleSym);
|
|
2962
|
+
for (const el of pattern.elements.nodes) {
|
|
2963
|
+
if (el.name === undefined)
|
|
2964
|
+
continue;
|
|
2965
|
+
if (el.dotDotDotToken) {
|
|
2966
|
+
lowerer.unsupported("SC1031", el, "rest bindings over module namespaces (the namespace object is not materialized — bind the exports you need by name)");
|
|
2967
|
+
}
|
|
2968
|
+
const prop = el.propertyName ?? el.name;
|
|
2969
|
+
const propName = ts.isIdentifier(prop) ||
|
|
2970
|
+
ts.isComputedPropertyName(prop) ||
|
|
2971
|
+
ts.isStringLiteralLike(prop) ||
|
|
2972
|
+
ts.isNumericLiteral(prop)
|
|
2973
|
+
? patternKeyNameOf(lowerer, prop)
|
|
2974
|
+
: null;
|
|
2975
|
+
let exported = propName === null ? undefined : lowerer.checker.getPropertyOfType(nsType, propName);
|
|
2976
|
+
if (exported !== undefined && exported.flags & ts.SymbolFlags.Alias) {
|
|
2977
|
+
exported = lowerer.checker.getAliasedSymbol(exported);
|
|
2978
|
+
}
|
|
2979
|
+
const declared = exported?.valueDeclaration?.name;
|
|
2980
|
+
if (declared === undefined || !ts.isIdentifier(declared)) {
|
|
2981
|
+
lowerer.unsupported("SC1031", el, "destructuring module namespace members that are not named value exports");
|
|
2982
|
+
}
|
|
2983
|
+
let value = lowerer.lowerExpr(declared);
|
|
2984
|
+
if (el.initializer)
|
|
2985
|
+
value = applyBindingDefault(lowerer, el, value);
|
|
2986
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
/** Whether a pattern's first element has a computed key that does not
|
|
2990
|
+
* fold to one property name, so the key evaluates at run time. */
|
|
2991
|
+
function startsWithRuntimeKey(lowerer, pattern) {
|
|
2992
|
+
const first = pattern.elements.nodes[0];
|
|
2993
|
+
const key = first?.dotDotDotToken === undefined ? first?.propertyName : undefined;
|
|
2994
|
+
return (key !== undefined && ts.isComputedPropertyName(key) && patternKeyNameOf(lowerer, key) === null);
|
|
2516
2995
|
}
|
|
2517
2996
|
function patternKeyNameOf(lowerer, prop) {
|
|
2518
2997
|
if (ts.isIdentifier(prop) || ts.isPrivateIdentifier(prop))
|
|
@@ -2529,6 +3008,140 @@ function patternKeyNameOf(lowerer, prop) {
|
|
|
2529
3008
|
}
|
|
2530
3009
|
return null;
|
|
2531
3010
|
}
|
|
3011
|
+
/** True when an object pattern destructures a regex match result: the
|
|
3012
|
+
* checker types its source as the standard library's RegExpExecArray or
|
|
3013
|
+
* RegExpMatchArray. */
|
|
3014
|
+
function isRegexMatchResultPattern(lowerer, pattern) {
|
|
3015
|
+
const parent = pattern.parent;
|
|
3016
|
+
const source = ts.isVariableDeclaration(parent) && parent.initializer !== undefined
|
|
3017
|
+
? lowerer.typeOf(parent.initializer)
|
|
3018
|
+
: lowerer.typeOf(pattern);
|
|
3019
|
+
const type = lowerer.checker.getNonNullableType(source);
|
|
3020
|
+
const symbol = type.getAliasSymbol() ?? type.getSymbol();
|
|
3021
|
+
return (symbol !== undefined &&
|
|
3022
|
+
(ts.symbolName(symbol) === "RegExpExecArray" || ts.symbolName(symbol) === "RegExpMatchArray") &&
|
|
3023
|
+
lowerer.isStdlibSymbol(symbol));
|
|
3024
|
+
}
|
|
3025
|
+
/** `const { 0: whole, 1: first, index, input, groups } = re.exec(s)!`: an
|
|
3026
|
+
* object pattern over a regex match result. The result is an honest
|
|
3027
|
+
* string[] slice whose `index` and `input` are the special-form reads that
|
|
3028
|
+
* `m.index` and `m.input` lower to; numeric keys are the positional reads
|
|
3029
|
+
* of the equivalent array pattern, and `groups` is the projection `m.groups`
|
|
3030
|
+
* builds when the regex is statically known. Rest elements, defaults on
|
|
3031
|
+
* the special properties, and every other key keep a named fence. */
|
|
3032
|
+
function lowerMatchResultObjectPattern(lowerer, pattern, srcRef, srcType, isLet, out) {
|
|
3033
|
+
let groups;
|
|
3034
|
+
for (const el of pattern.elements.nodes) {
|
|
3035
|
+
if (el.name === undefined)
|
|
3036
|
+
continue;
|
|
3037
|
+
const loc = locOf(el);
|
|
3038
|
+
if (el.dotDotDotToken) {
|
|
3039
|
+
lowerer.unsupported("SC1031", el, "rest bindings over regex match results (the rest copies the positions and the index, input and groups properties — destructure them by name)");
|
|
3040
|
+
}
|
|
3041
|
+
const prop = el.propertyName ?? el.name;
|
|
3042
|
+
const propName = ts.isIdentifier(prop) ||
|
|
3043
|
+
ts.isComputedPropertyName(prop) ||
|
|
3044
|
+
ts.isStringLiteralLike(prop) ||
|
|
3045
|
+
ts.isNumericLiteral(prop)
|
|
3046
|
+
? patternKeyNameOf(lowerer, prop)
|
|
3047
|
+
: null;
|
|
3048
|
+
if (propName === null) {
|
|
3049
|
+
lowerer.unsupported("SC1031", el, "destructuring with computed keys that do not fold to one property name");
|
|
3050
|
+
}
|
|
3051
|
+
let value;
|
|
3052
|
+
if (ARRAY_POSITION_KEY.test(propName)) {
|
|
3053
|
+
value = arrayPositionBinding(lowerer, el, srcRef, srcType, Number(propName), out);
|
|
3054
|
+
}
|
|
3055
|
+
else if (propName === "index" || propName === "input") {
|
|
3056
|
+
if (el.initializer) {
|
|
3057
|
+
lowerer.unsupported("SC1031", el, `binding defaults on the '${propName}' of a regex match result`);
|
|
3058
|
+
}
|
|
3059
|
+
value = lowerer.maybeNarrow({
|
|
3060
|
+
kind: "dynKeyGet",
|
|
3061
|
+
value: lowerer.coerceToExpected(srcRef(), DYN),
|
|
3062
|
+
key: { kind: "strLit", value: propName, type: STRING, loc },
|
|
3063
|
+
type: DYN,
|
|
3064
|
+
loc,
|
|
3065
|
+
}, el.name);
|
|
3066
|
+
}
|
|
3067
|
+
else if (propName === "groups") {
|
|
3068
|
+
if (groups === undefined) {
|
|
3069
|
+
const parent = pattern.parent;
|
|
3070
|
+
groups =
|
|
3071
|
+
ts.isVariableDeclaration(parent) && parent.initializer !== undefined
|
|
3072
|
+
? matchResultNamedGroupsOf(lowerer, parent.initializer)
|
|
3073
|
+
: null;
|
|
3074
|
+
}
|
|
3075
|
+
if (groups === null || groups.length === 0 || el.initializer) {
|
|
3076
|
+
lowerer.unsupported("SC1031", el, "destructuring 'groups' from this regex match result (it lowers when the regex is statically known and has named groups, without a default)");
|
|
3077
|
+
}
|
|
3078
|
+
value = lowerGroupsProjection(lowerer, srcRef(), groups, loc);
|
|
3079
|
+
}
|
|
3080
|
+
else {
|
|
3081
|
+
lowerer.unsupported("SC1031", el, `destructuring the property '${propName}' of a regex match result (numeric positions, index, input and groups compile)`);
|
|
3082
|
+
}
|
|
3083
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
/** A canonical array index key (the numeric positions an object pattern
|
|
3087
|
+
* reads off an array). */
|
|
3088
|
+
const ARRAY_POSITION_KEY = /^(?:0|[1-9]\d{0,8})$/;
|
|
3089
|
+
/** The positional read `{ <index>: x }` takes off an array: the element,
|
|
3090
|
+
* undefined past the end, with the binding default applied. */
|
|
3091
|
+
function arrayPositionBinding(lowerer, el, srcRef, srcType, index, out) {
|
|
3092
|
+
const loc = locOf(el);
|
|
3093
|
+
const position = { kind: "numLit", value: index, type: F64, loc };
|
|
3094
|
+
const value = lowerSafeIndexRead(lowerer, srcRef(), position, loc) ?? {
|
|
3095
|
+
kind: "arrayGet",
|
|
3096
|
+
arr: srcRef(),
|
|
3097
|
+
index: position,
|
|
3098
|
+
type: srcType.elem,
|
|
3099
|
+
loc,
|
|
3100
|
+
};
|
|
3101
|
+
return el.initializer
|
|
3102
|
+
? arrayPositionDefault(lowerer, el, value, srcRef, index, srcType.elem, out)
|
|
3103
|
+
: value;
|
|
3104
|
+
}
|
|
3105
|
+
/** Whether every element of an object pattern over an array names a
|
|
3106
|
+
* numeric position or `length` (`const { 0: a, 1: b, length } =
|
|
3107
|
+
* s.split(".")`), with no rest element. */
|
|
3108
|
+
function isArrayPositionPattern(lowerer, pattern) {
|
|
3109
|
+
return pattern.elements.nodes.every((el) => {
|
|
3110
|
+
if (el.name === undefined)
|
|
3111
|
+
return true;
|
|
3112
|
+
if (el.dotDotDotToken)
|
|
3113
|
+
return false;
|
|
3114
|
+
const prop = el.propertyName ?? el.name;
|
|
3115
|
+
if (!ts.isIdentifier(prop) &&
|
|
3116
|
+
!ts.isComputedPropertyName(prop) &&
|
|
3117
|
+
!ts.isStringLiteralLike(prop) &&
|
|
3118
|
+
!ts.isNumericLiteral(prop))
|
|
3119
|
+
return false;
|
|
3120
|
+
const name = patternKeyNameOf(lowerer, prop);
|
|
3121
|
+
return name !== null && (name === "length" || ARRAY_POSITION_KEY.test(name));
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
/** An object pattern of positions and `length` over an array: each
|
|
3125
|
+
* position is the read the equivalent array pattern makes, and `length`
|
|
3126
|
+
* the array's length (always present, so its default never runs). */
|
|
3127
|
+
function lowerArrayPositionObjectPattern(lowerer, pattern, srcRef, srcType, isLet, out) {
|
|
3128
|
+
for (const el of pattern.elements.nodes) {
|
|
3129
|
+
if (el.name === undefined)
|
|
3130
|
+
continue;
|
|
3131
|
+
const name = patternKeyNameOf(lowerer, (el.propertyName ?? el.name));
|
|
3132
|
+
const value = name === "length"
|
|
3133
|
+
? {
|
|
3134
|
+
kind: "arrIntrinsic",
|
|
3135
|
+
method: "length",
|
|
3136
|
+
receiver: srcRef(),
|
|
3137
|
+
args: [],
|
|
3138
|
+
type: F64,
|
|
3139
|
+
loc: locOf(el),
|
|
3140
|
+
}
|
|
3141
|
+
: arrayPositionBinding(lowerer, el, srcRef, srcType, Number(name), out);
|
|
3142
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
2532
3145
|
/** Decode one non-rest object-assignment property into its static source
|
|
2533
3146
|
* field, destination expression, and optional default initializer. */
|
|
2534
3147
|
function destructuringPropertyOf(lowerer, prop) {
|
|
@@ -2572,7 +3185,7 @@ function checkerStringSource(lowerer, e) {
|
|
|
2572
3185
|
}
|
|
2573
3186
|
function staticStringPattern(lowerer, pattern) {
|
|
2574
3187
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
2575
|
-
return pattern.elements.every((el) => {
|
|
3188
|
+
return pattern.elements.nodes.every((el) => {
|
|
2576
3189
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
2577
3190
|
return true;
|
|
2578
3191
|
if (el.dotDotDotToken) {
|
|
@@ -2586,7 +3199,7 @@ function staticStringPattern(lowerer, pattern) {
|
|
|
2586
3199
|
return staticStringPattern(lowerer, el.name);
|
|
2587
3200
|
});
|
|
2588
3201
|
}
|
|
2589
|
-
return pattern.elements.every((el) => {
|
|
3202
|
+
return pattern.elements.nodes.every((el) => {
|
|
2590
3203
|
if (el.name === undefined)
|
|
2591
3204
|
return true;
|
|
2592
3205
|
if (el.dotDotDotToken || !ts.isIdentifier(el.name))
|
|
@@ -2652,7 +3265,7 @@ const CONSOLE_CALL_MEMBERS = new Set([
|
|
|
2652
3265
|
* when the source is not a stdlib global at all, or in TypeScript
|
|
2653
3266
|
* files (the identifier chokepoint fences the global there first). */
|
|
2654
3267
|
function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
2655
|
-
if (decl.initializer === undefined || !isJsSourceFile(
|
|
3268
|
+
if (decl.initializer === undefined || !isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
2656
3269
|
return null;
|
|
2657
3270
|
const globalName = stdlibGlobalNameOf(lowerer, decl.initializer);
|
|
2658
3271
|
if (globalName === null)
|
|
@@ -2665,7 +3278,7 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2665
3278
|
}
|
|
2666
3279
|
const srcT = lowerer.typeOf(decl.initializer);
|
|
2667
3280
|
const binds = [];
|
|
2668
|
-
for (const el of decl.name.elements) {
|
|
3281
|
+
for (const el of decl.name.elements.nodes) {
|
|
2669
3282
|
if (el.name === undefined)
|
|
2670
3283
|
continue;
|
|
2671
3284
|
if (el.dotDotDotToken) {
|
|
@@ -2687,8 +3300,9 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2687
3300
|
if (propName === null) {
|
|
2688
3301
|
lowerer.unsupported("SC1031", el, "destructuring with computed keys that do not fold to one property name");
|
|
2689
3302
|
}
|
|
2690
|
-
let token;
|
|
3303
|
+
let token = "";
|
|
2691
3304
|
let alias = null;
|
|
3305
|
+
let value = null;
|
|
2692
3306
|
if (globalName === "globalThis") {
|
|
2693
3307
|
// The member must BE a stdlib global (user script vars are
|
|
2694
3308
|
// properties of `typeof globalThis` too — their values are real
|
|
@@ -2697,9 +3311,12 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2697
3311
|
if (member === undefined || !lowerer.isStdlibSymbol(member)) {
|
|
2698
3312
|
lowerer.unsupported("SC1031", el, `destructuring the non-builtin member '${propName}' of 'globalThis'`);
|
|
2699
3313
|
}
|
|
2700
|
-
const canonical = member
|
|
3314
|
+
const canonical = ts.symbolName(member) === "global" ? "globalThis" : ts.symbolName(member);
|
|
2701
3315
|
token = `[builtin ${canonical}]`;
|
|
2702
3316
|
alias = canonical;
|
|
3317
|
+
// Builtin constructors read as their interned function values, the
|
|
3318
|
+
// same values the bare and `globalThis.X` spellings read.
|
|
3319
|
+
value = builtinGlobalValue(canonical, locOf(el), true);
|
|
2703
3320
|
}
|
|
2704
3321
|
else if (globalName === "console" && !CONSOLE_CALL_MEMBERS.has(propName)) {
|
|
2705
3322
|
token = `[builtin console.${propName}]`;
|
|
@@ -2707,6 +3324,12 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2707
3324
|
else if (TOKEN_OPAQUE_GLOBALS.has(globalName)) {
|
|
2708
3325
|
token = `[builtin ${globalName}.${propName}]`;
|
|
2709
3326
|
}
|
|
3327
|
+
else if (globalName === "process" &&
|
|
3328
|
+
ts.isIdentifier(el.name) &&
|
|
3329
|
+
(value = processDataMemberValue(lowerer, propName, el.name, locOf(el))) !== null) {
|
|
3330
|
+
// A data member reads its value once, exactly like the spelled
|
|
3331
|
+
// `process.<member>` read the destructuring performs.
|
|
3332
|
+
}
|
|
2710
3333
|
else {
|
|
2711
3334
|
lowerer.unsupported("SC1031", el, `destructuring the member '${propName}' of the builtin global '${globalName}' (a detached member loses its receiver-keyed lowering — call it through the global)`);
|
|
2712
3335
|
}
|
|
@@ -2715,6 +3338,10 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2715
3338
|
lowerer.unsupported("SC1031", el, `bindings with predeclared slots over the builtin global '${globalName}'`);
|
|
2716
3339
|
}
|
|
2717
3340
|
const g = lowerer.globalsBySymbol.get(symbol);
|
|
3341
|
+
if (value !== null) {
|
|
3342
|
+
binds.push({ name: el.name, token, alias, g, value });
|
|
3343
|
+
continue;
|
|
3344
|
+
}
|
|
2718
3345
|
if (g !== undefined && g.type.kind !== "string" && g.type.kind !== "dyn") {
|
|
2719
3346
|
lowerer.unsupported("SC1031", el, `bindings with '${lowerer.fmt(g.type)}' storage over the builtin global '${globalName}'`);
|
|
2720
3347
|
}
|
|
@@ -2723,6 +3350,27 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2723
3350
|
const out = [];
|
|
2724
3351
|
for (const b of binds) {
|
|
2725
3352
|
const loc = locOf(b.name);
|
|
3353
|
+
if (b.value !== undefined && b.alias !== null) {
|
|
3354
|
+
const symbol = lowerer.checker.getSymbolAtLocation(b.name);
|
|
3355
|
+
if (symbol)
|
|
3356
|
+
lowerer.stdlibGlobalAliases.set(symbol, b.alias);
|
|
3357
|
+
}
|
|
3358
|
+
if (b.value !== undefined) {
|
|
3359
|
+
if (b.g !== undefined) {
|
|
3360
|
+
out.push({
|
|
3361
|
+
kind: "assign",
|
|
3362
|
+
localId: b.g.id,
|
|
3363
|
+
value: lowerer.coerceInto(b.name, b.value, b.g.type),
|
|
3364
|
+
...(b.g.tdz ? { initializes: true } : {}),
|
|
3365
|
+
loc,
|
|
3366
|
+
});
|
|
3367
|
+
}
|
|
3368
|
+
else {
|
|
3369
|
+
const local = lowerer.declareLocal(b.name, b.name.text, b.value.type, isLet);
|
|
3370
|
+
out.push({ kind: "varDecl", localId: local.id, init: b.value, loc });
|
|
3371
|
+
}
|
|
3372
|
+
continue;
|
|
3373
|
+
}
|
|
2726
3374
|
const token = { kind: "strLit", value: b.token, type: STRING, loc };
|
|
2727
3375
|
if (b.alias !== null) {
|
|
2728
3376
|
const symbol = lowerer.checker.getSymbolAtLocation(b.name);
|
|
@@ -3004,7 +3652,7 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
|
|
|
3004
3652
|
const consumed = new Set();
|
|
3005
3653
|
let computedSibling = false;
|
|
3006
3654
|
if (ts.isObjectBindingPattern(pattern)) {
|
|
3007
|
-
for (const sib of pattern.elements) {
|
|
3655
|
+
for (const sib of pattern.elements.nodes) {
|
|
3008
3656
|
if (sib === el || sib.dotDotDotToken)
|
|
3009
3657
|
continue;
|
|
3010
3658
|
const key = sib.propertyName ?? sib.name;
|
|
@@ -3071,7 +3719,7 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
|
|
|
3071
3719
|
value: lowerer.presenceKeepingCopy(srcRef(), srcType.shapeId, srcField.name, lowerer.coerceInto(el, read, f.type), loc),
|
|
3072
3720
|
};
|
|
3073
3721
|
});
|
|
3074
|
-
return { kind: "recordLit", fields, type: restT, loc };
|
|
3722
|
+
return lowerer.keyOrder.copy({ kind: "recordLit", fields, type: restT, loc }, srcType.shapeId);
|
|
3075
3723
|
}
|
|
3076
3724
|
/** The fresh record for `{ a, ...rest }` over a CLASS-INSTANCE source:
|
|
3077
3725
|
* JS's CopyDataProperties copies the OWN ENUMERABLE properties — the
|
|
@@ -3125,7 +3773,7 @@ function classInstanceRestValue(lowerer, blame, srcRef, srcType, info, consumed,
|
|
|
3125
3773
|
const orderMatches = (order) => order.length === remaining.length && order.every((n, i) => n === remaining[i].name);
|
|
3126
3774
|
const deferOrderCheck = lowerer.instantiationContext !== null &&
|
|
3127
3775
|
lowerer.onEdge !== null &&
|
|
3128
|
-
!isJsSourceFile(
|
|
3776
|
+
!isJsSourceFile(ts.getSourceFileOfNode(blame));
|
|
3129
3777
|
if (!deferOrderCheck) {
|
|
3130
3778
|
if (!orderMatches(emitOrder)) {
|
|
3131
3779
|
lowerer.unsupported("SC1031", blame, "rest bindings over class instances whose packed key order cannot match Node's (Object.keys/JSON.stringify would enumerate the copied fields in a different order)");
|
|
@@ -3140,7 +3788,7 @@ function classInstanceRestValue(lowerer, blame, srcRef, srcType, info, consumed,
|
|
|
3140
3788
|
// matters.
|
|
3141
3789
|
const context = lowerer.instantiationContext;
|
|
3142
3790
|
const countFailure = !lowerer.suppressStats;
|
|
3143
|
-
const sf =
|
|
3791
|
+
const sf = ts.getSourceFileOfNode(blame);
|
|
3144
3792
|
lowerer.shapeOrderMetadataFinalizers.push(() => {
|
|
3145
3793
|
const current = lowerer.shapes.get(restT.shapeId) ?? restShape;
|
|
3146
3794
|
const currentOrder = current.declaredOrder ?? current.fields.map((f) => f.name);
|
|
@@ -3188,6 +3836,8 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3188
3836
|
const symbol = lowerer.checker.getSymbolAtLocation(name);
|
|
3189
3837
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
3190
3838
|
if (g) {
|
|
3839
|
+
if (value.type.kind === "dyn" && jsBindingKeepsCheckedObject(lowerer, name, g.type))
|
|
3840
|
+
g.type = DYN;
|
|
3191
3841
|
out.push({
|
|
3192
3842
|
kind: "assign",
|
|
3193
3843
|
localId: g.id,
|
|
@@ -3204,7 +3854,7 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3204
3854
|
// here by declareParams) carry no block-scope flag either, but their
|
|
3205
3855
|
// bindings are the parameters' own.
|
|
3206
3856
|
if (symbol && hostVariableDeclarationOf(name) !== null && isVarDeclared(name)) {
|
|
3207
|
-
const hoisted = hoistVarBinding(lowerer, symbol, name);
|
|
3857
|
+
const hoisted = hoistVarBinding(lowerer, symbol, name, value.type);
|
|
3208
3858
|
out.push({
|
|
3209
3859
|
kind: "assign",
|
|
3210
3860
|
localId: hoisted.id,
|
|
@@ -3218,7 +3868,7 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3218
3868
|
const dynStays = value.type.kind === "dyn" &&
|
|
3219
3869
|
(() => {
|
|
3220
3870
|
const mapped = lowerer.mapTypeOf(lowerer.typeOf(name));
|
|
3221
|
-
return mapped === null;
|
|
3871
|
+
return mapped === null || jsBindingKeepsCheckedObject(lowerer, name, mapped);
|
|
3222
3872
|
})();
|
|
3223
3873
|
let type = dynStays
|
|
3224
3874
|
? DYN
|
|
@@ -3269,7 +3919,7 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3269
3919
|
const isConst = (list.flags & ts.NodeFlags.Const) !== 0;
|
|
3270
3920
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0;
|
|
3271
3921
|
if (!isConst && !isLet) {
|
|
3272
|
-
const out = list.declarations.flatMap((decl) => {
|
|
3922
|
+
const out = list.declarations.nodes.flatMap((decl) => {
|
|
3273
3923
|
// `for (var {} = {}, [a] = xs; ...)`: pattern declarators ride the
|
|
3274
3924
|
// declaration desugar (var names assign their hoisted slots).
|
|
3275
3925
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
@@ -3285,7 +3935,7 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3285
3935
|
return { kind: "block", body: out, loc: locOf(list) };
|
|
3286
3936
|
}
|
|
3287
3937
|
const out = [];
|
|
3288
|
-
for (const decl of list.declarations) {
|
|
3938
|
+
for (const decl of list.declarations.nodes) {
|
|
3289
3939
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
3290
3940
|
// Destructuring produces nested initialization blocks; copying
|
|
3291
3941
|
// their captured bindings still needs a distinct head-scope plan.
|
|
@@ -3298,6 +3948,69 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3298
3948
|
}
|
|
3299
3949
|
return out.length === 1 ? out[0] : { kind: "block", body: out, loc: locOf(list) };
|
|
3300
3950
|
}
|
|
3951
|
+
/** The type of an unannotated TypeScript binding initialized with `[]`
|
|
3952
|
+
* whose element type evolves: the checker types the declaration as
|
|
3953
|
+
* `never[]` or `any[]` and each later read by the elements written before
|
|
3954
|
+
* it, and reads inside closures as the unsettled array. When every read
|
|
3955
|
+
* with a settled element type maps to the same array type, the binding has
|
|
3956
|
+
* that type. When reads disagree or the binding is reassigned, it is
|
|
3957
|
+
* checked-dynamic, as the same binding is at module scope. Null for other
|
|
3958
|
+
* bindings. */
|
|
3959
|
+
function evolvingArrayType(lowerer, decl) {
|
|
3960
|
+
if (!ts.isIdentifier(decl.name) || decl.initializer === undefined)
|
|
3961
|
+
return null;
|
|
3962
|
+
let initializer = decl.initializer;
|
|
3963
|
+
while (ts.isParenthesizedExpression(initializer))
|
|
3964
|
+
initializer = initializer.expression;
|
|
3965
|
+
if (!ts.isArrayLiteralExpression(initializer) || initializer.elements.nodes.length !== 0)
|
|
3966
|
+
return null;
|
|
3967
|
+
const unsettled = (t) => {
|
|
3968
|
+
if (!lowerer.checker.isArrayType(t))
|
|
3969
|
+
return false;
|
|
3970
|
+
const elem = lowerer.checker.getTypeArguments(t)[0];
|
|
3971
|
+
return elem !== undefined && (elem.flags & (ts.TypeFlags.Never | ts.TypeFlags.Any)) !== 0;
|
|
3972
|
+
};
|
|
3973
|
+
if (!unsettled(lowerer.typeOf(decl.name)))
|
|
3974
|
+
return null;
|
|
3975
|
+
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
3976
|
+
if (symbol === undefined)
|
|
3977
|
+
return null;
|
|
3978
|
+
const owner = (node) => {
|
|
3979
|
+
let n = node.parent;
|
|
3980
|
+
while (n !== undefined && !ts.isFunctionLike(n) && !ts.isSourceFile(n))
|
|
3981
|
+
n = n.parent;
|
|
3982
|
+
return n ?? ts.getSourceFileOfNode(node);
|
|
3983
|
+
};
|
|
3984
|
+
const scope = owner(decl);
|
|
3985
|
+
let result = null;
|
|
3986
|
+
// The file's identifiers are indexed by name once (identifiersNamed), so
|
|
3987
|
+
// each binding resolves only the uses spelled like it.
|
|
3988
|
+
for (const node of identifiersNamed(lowerer, ts.getSourceFileOfNode(decl), decl.name.text)) {
|
|
3989
|
+
if (node === decl.name ||
|
|
3990
|
+
node.pos < scope.pos ||
|
|
3991
|
+
node.end > scope.end ||
|
|
3992
|
+
lowerer.checker.getSymbolAtLocation(node) !== symbol)
|
|
3993
|
+
continue;
|
|
3994
|
+
let target = node;
|
|
3995
|
+
while (ts.isParenthesizedExpression(target.parent))
|
|
3996
|
+
target = target.parent;
|
|
3997
|
+
const parent = target.parent;
|
|
3998
|
+
const reassigned = ts.isBinaryExpression(parent) &&
|
|
3999
|
+
parent.left === target &&
|
|
4000
|
+
parent.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
4001
|
+
parent.operatorToken.kind <= ts.SyntaxKind.LastAssignment;
|
|
4002
|
+
if (reassigned)
|
|
4003
|
+
return DYN;
|
|
4004
|
+
const t = lowerer.typeOf(node);
|
|
4005
|
+
if (unsettled(t))
|
|
4006
|
+
continue;
|
|
4007
|
+
const mapped = lowerer.mapTypeOf(t);
|
|
4008
|
+
if (!mapped || mapped.kind !== "array" || (result !== null && !typeEquals(result, mapped)))
|
|
4009
|
+
return DYN;
|
|
4010
|
+
result = mapped;
|
|
4011
|
+
}
|
|
4012
|
+
return result ?? DYN;
|
|
4013
|
+
}
|
|
3301
4014
|
/** A single static type for an initializer-less JavaScript `let` whose
|
|
3302
4015
|
* later plain writes all agree. An evolving JS local reads as `undefined`
|
|
3303
4016
|
* until control flow proves a write, so a scalar slot is sound only when
|
|
@@ -3355,7 +4068,7 @@ function inferredEvolvingLetType(lowerer, decl) {
|
|
|
3355
4068
|
}
|
|
3356
4069
|
if (ts.isCallExpression(node.right) &&
|
|
3357
4070
|
(implicitMethodCallInfersReturn(lowerer, node.right) ||
|
|
3358
|
-
isJsSourceFile(node.right
|
|
4071
|
+
isJsSourceFile(ts.getSourceFileOfNode(node.right)))) {
|
|
3359
4072
|
invalid = true;
|
|
3360
4073
|
return "stop";
|
|
3361
4074
|
}
|
|
@@ -3426,6 +4139,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3426
4139
|
}
|
|
3427
4140
|
if (!ts.isIdentifier(decl.name))
|
|
3428
4141
|
lowerer.unsupported("SC1031", decl.name);
|
|
4142
|
+
{
|
|
4143
|
+
const alias = lowerTupleAliasDecl(lowerer, decl);
|
|
4144
|
+
if (alias)
|
|
4145
|
+
return alias;
|
|
4146
|
+
}
|
|
3429
4147
|
// A NULLISH generic binding (`const i: I<A & B> = null as any` — the
|
|
3430
4148
|
// declared type has no mapping, the value is provably null/undefined
|
|
3431
4149
|
// forever): no storage exists; reads know the value (member reads and
|
|
@@ -3456,10 +4174,10 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3456
4174
|
(decl.name.text === "module" || decl.name.text === "exports") &&
|
|
3457
4175
|
ts.isVariableStatement(decl.parent?.parent) &&
|
|
3458
4176
|
ts.isSourceFile(decl.parent?.parent?.parent) &&
|
|
3459
|
-
!isJsSourceFile(
|
|
3460
|
-
!
|
|
3461
|
-
.
|
|
3462
|
-
.statements.some((s) => ts.isImportDeclaration(s) ||
|
|
4177
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
4178
|
+
!ts
|
|
4179
|
+
.getSourceFileOfNode(decl)
|
|
4180
|
+
.statements.nodes.some((s) => ts.isImportDeclaration(s) ||
|
|
3463
4181
|
ts.isExportDeclaration(s) ||
|
|
3464
4182
|
ts.isExportAssignment(s) ||
|
|
3465
4183
|
(ts.canHaveModifiers(s) &&
|
|
@@ -3508,6 +4226,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3508
4226
|
// `const process = globalThis.process` — a stdlib-global snapshot:
|
|
3509
4227
|
// alias plumbing (see stdlibGlobalAliasDecl), no storage, no code.
|
|
3510
4228
|
const stableStdlibAlias = !isLet ||
|
|
4229
|
+
stdlibBufferVarAlias(lowerer, decl) ||
|
|
3511
4230
|
(ts.isVariableDeclarationList(decl.parent) &&
|
|
3512
4231
|
(decl.parent.flags & ts.NodeFlags.Let) !== 0 &&
|
|
3513
4232
|
ts.isIdentifier(decl.name) &&
|
|
@@ -3547,6 +4266,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3547
4266
|
return null;
|
|
3548
4267
|
if (!isLet && registerBuiltinCallableAlias(lowerer, decl.name, decl.initializer))
|
|
3549
4268
|
return null;
|
|
4269
|
+
if (registerBuiltinClassAlias(lowerer, decl.name, decl.initializer))
|
|
4270
|
+
return null;
|
|
3550
4271
|
// `const knownBy = (cmd) => ...` — an IMPLICIT-ANY function-value
|
|
3551
4272
|
// binding in npm-static JS (function-scope bindings register here, in
|
|
3552
4273
|
// source order before any use can lower; file-scope ones registered at
|
|
@@ -3631,17 +4352,25 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3631
4352
|
return { kind: "assign", localId: g.id, value: wrapped, loc: locOf(decl) };
|
|
3632
4353
|
return null;
|
|
3633
4354
|
}
|
|
3634
|
-
const
|
|
3635
|
-
(
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
4355
|
+
const guardedRead = isGuardedRecordRead(lowerer, decl)
|
|
4356
|
+
? lowerAbsenceProbe(lowerer, decl.initializer)
|
|
4357
|
+
: null;
|
|
4358
|
+
const raw = guardedRead ??
|
|
4359
|
+
lowerVariableInitializer(lowerer, decl.initializer, g.type.kind === "dyn" &&
|
|
4360
|
+
(isNativeBuiltinValueInitializer(lowerer, decl.initializer) ||
|
|
4361
|
+
ts.isArrayLiteralExpression(decl.initializer) ||
|
|
4362
|
+
ts.isObjectLiteralExpression(decl.initializer))
|
|
4363
|
+
? DYN
|
|
4364
|
+
: undefined);
|
|
4365
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3641
4366
|
!decl.type &&
|
|
3642
4367
|
!hasJsTypeAnnotation(decl) &&
|
|
3643
4368
|
raw.type.kind === "dyn" &&
|
|
3644
|
-
(g.type.kind === "record" ||
|
|
4369
|
+
(g.type.kind === "record" ||
|
|
4370
|
+
g.type.kind === "object" ||
|
|
4371
|
+
(ts.isIdentifier(decl.name) &&
|
|
4372
|
+
jsBindingKeepsCheckedObject(lowerer, decl.name, g.type) &&
|
|
4373
|
+
(existingValueForm(decl.initializer) || jsHoldsDynObject(lowerer, decl.initializer)))))
|
|
3645
4374
|
g.type = DYN;
|
|
3646
4375
|
g.type = inferredOptionalRecordType(lowerer, decl, g.type, raw.type);
|
|
3647
4376
|
const arithmetic = raw.type.kind === "union" ? lowerer.unions.get(raw.type.unionId)?.arms : undefined;
|
|
@@ -3682,6 +4411,9 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3682
4411
|
// types already hold the interned undefined arm), and a declaration
|
|
3683
4412
|
// re-run in a loop must not reset the persisting value.
|
|
3684
4413
|
if (isVarDeclared(decl) && declSymbol) {
|
|
4414
|
+
const fromExisting = lowerJsVarFromExisting(lowerer, decl, declSymbol);
|
|
4415
|
+
if (fromExisting)
|
|
4416
|
+
return fromExisting;
|
|
3685
4417
|
const local = hoistVarBinding(lowerer, declSymbol, decl.name);
|
|
3686
4418
|
if (!decl.initializer)
|
|
3687
4419
|
return null;
|
|
@@ -3697,7 +4429,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3697
4429
|
// immediately (the type covers the unassigned state), so they
|
|
3698
4430
|
// initialize to the interned undefined arm like an omitted optional.
|
|
3699
4431
|
let type = lowerer.irTypeOf(decl.name);
|
|
3700
|
-
if (type.kind === "dyn" && isLet && isJsSourceFile(
|
|
4432
|
+
if (type.kind === "dyn" && isLet && isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3701
4433
|
type = inferredEvolvingLetType(lowerer, decl) ?? type;
|
|
3702
4434
|
}
|
|
3703
4435
|
// `var v: void;` / `let x: undefined;` — a unit-only binding rides
|
|
@@ -3721,7 +4453,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3721
4453
|
// function (with its hint), not the unmappable declared type. If it
|
|
3722
4454
|
// poisons, still declare the local when its type is representable, so
|
|
3723
4455
|
// later references to this name don't produce cascading errors.
|
|
3724
|
-
const inferredObjectType = isJsSourceFile(
|
|
4456
|
+
const inferredObjectType = isJsSourceFile(ts.getSourceFileOfNode(decl))
|
|
3725
4457
|
? lowerer.mapTypeOf(lowerer.typeOf(decl.name))
|
|
3726
4458
|
: null;
|
|
3727
4459
|
const inferredObjectArms = inferredObjectType?.kind === "union"
|
|
@@ -3734,11 +4466,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3734
4466
|
inferredObjectType !== null &&
|
|
3735
4467
|
jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn") ||
|
|
3736
4468
|
inferredObjectArms.some((arm) => arm.kind === "record" && jsObjectBindingExpands(lowerer, decl, arm)) ||
|
|
3737
|
-
(isJsSourceFile(
|
|
4469
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3738
4470
|
!decl.type &&
|
|
3739
4471
|
!hasJsTypeAnnotation(decl) &&
|
|
3740
4472
|
ts.isObjectLiteralExpression(decl.initializer) &&
|
|
3741
|
-
decl.initializer.properties.some((property) => ts.isMethodDeclaration(property) ||
|
|
4473
|
+
decl.initializer.properties.nodes.some((property) => ts.isMethodDeclaration(property) ||
|
|
3742
4474
|
ts.isAccessor(property) ||
|
|
3743
4475
|
(ts.isPropertyAssignment(property) &&
|
|
3744
4476
|
(ts.isFunctionExpression(property.initializer) ||
|
|
@@ -3747,7 +4479,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3747
4479
|
try {
|
|
3748
4480
|
init =
|
|
3749
4481
|
expandsObject ||
|
|
3750
|
-
(isJsSourceFile(
|
|
4482
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3751
4483
|
!decl.type &&
|
|
3752
4484
|
isNativeBuiltinValueInitializer(lowerer, decl.initializer))
|
|
3753
4485
|
? lowerer.lowerExprExpecting(decl.initializer, DYN)
|
|
@@ -3779,11 +4511,22 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3779
4511
|
staticImportNamespaceType(lowerer, decl.initializer) ??
|
|
3780
4512
|
(init.type.kind === "moduleNs" ? init.type : null) ??
|
|
3781
4513
|
(init.type.kind === "dyn" ? DYN : null);
|
|
3782
|
-
if (isJsSourceFile(
|
|
4514
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3783
4515
|
!decl.type &&
|
|
3784
4516
|
!hasJsTypeAnnotation(decl) &&
|
|
3785
4517
|
init.type.kind === "func")
|
|
3786
4518
|
type = init.type;
|
|
4519
|
+
// Promise.prototype is an ordinary object the checker types Promise<any>.
|
|
4520
|
+
if (!decl.type && !hasJsTypeAnnotation(decl) && isPromisePrototypeRead(lowerer, decl.initializer))
|
|
4521
|
+
type = DYN;
|
|
4522
|
+
// A typed-arguments function expression (typed-arguments.ts): the
|
|
4523
|
+
// checker types the binding variadic, but its value has the fixed
|
|
4524
|
+
// signature every use asserts.
|
|
4525
|
+
if (!decl.type &&
|
|
4526
|
+
init.type.kind === "func" &&
|
|
4527
|
+
(lowerer.typedArgumentsLambdas.has(stripTypeWrappers(decl.initializer)) ||
|
|
4528
|
+
lowerer.nullishFuncResults.has(stripTypeWrappers(decl.initializer))))
|
|
4529
|
+
type = init.type;
|
|
3787
4530
|
// A TypeScript lambda whose closure returns the runtime result (a missing
|
|
3788
4531
|
// read, a `??` default of another type) instead of the checker's bare
|
|
3789
4532
|
// return type: the binding keeps the checker's parameters and takes the
|
|
@@ -3796,24 +4539,24 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3796
4539
|
type = { ...type, ret: init.type.ret };
|
|
3797
4540
|
if (lowerer.implicitParamTypes !== null &&
|
|
3798
4541
|
init.type.kind === "dyn" &&
|
|
3799
|
-
isJsSourceFile(
|
|
3800
|
-
npmStaticPackageOfPath(
|
|
4542
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
4543
|
+
npmStaticPackageOfPath(ts.getSourceFileOfNode(decl).fileName) !== null) {
|
|
3801
4544
|
type = DYN;
|
|
3802
4545
|
}
|
|
3803
4546
|
const preservesObjectIdentity = init.type.kind === "dyn" &&
|
|
3804
4547
|
(inferredObjectType?.kind === "record" ||
|
|
3805
4548
|
inferredObjectType?.kind === "array" ||
|
|
3806
|
-
(isJsSourceFile(
|
|
4549
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3807
4550
|
inferredObjectArms.some((arm) => arm.kind === "record") &&
|
|
3808
4551
|
inferredObjectArms.every((arm) => isUnitType(arm) || arm.kind === "record")) ||
|
|
3809
|
-
(isJsSourceFile(
|
|
4552
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3810
4553
|
inferredObjectType !== null &&
|
|
3811
4554
|
(inferredObjectType.kind === "date" ||
|
|
3812
4555
|
inferredObjectType.kind === "func" ||
|
|
3813
4556
|
inferredObjectType.kind === "object" ||
|
|
3814
4557
|
jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind ===
|
|
3815
4558
|
"dyn")) ||
|
|
3816
|
-
(isJsSourceFile(
|
|
4559
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3817
4560
|
inferredObjectType !== null &&
|
|
3818
4561
|
(inferredObjectType.kind === "void" ||
|
|
3819
4562
|
isUnitType(inferredObjectType) ||
|
|
@@ -3821,14 +4564,20 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3821
4564
|
lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType))))) &&
|
|
3822
4565
|
!decl.type &&
|
|
3823
4566
|
!hasJsTypeAnnotation(decl);
|
|
4567
|
+
// The binding of an assertion of the global object holds that object,
|
|
4568
|
+
// whatever its asserted type (assertion-identity.ts).
|
|
4569
|
+
const keepsAssertedObject = init.type.kind === "dyn" &&
|
|
4570
|
+
!decl.type &&
|
|
4571
|
+
keptIdentityAssertion(lowerer, decl.initializer) !== undefined;
|
|
3824
4572
|
if (expandsObject ||
|
|
3825
4573
|
preservesObjectIdentity ||
|
|
3826
|
-
|
|
4574
|
+
keepsAssertedObject ||
|
|
4575
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3827
4576
|
!decl.type &&
|
|
3828
4577
|
isNativeBuiltinValueInitializer(lowerer, decl.initializer))) {
|
|
3829
4578
|
type = DYN;
|
|
3830
4579
|
}
|
|
3831
|
-
if (isJsSourceFile(
|
|
4580
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3832
4581
|
!decl.type &&
|
|
3833
4582
|
init.type.kind === "array" &&
|
|
3834
4583
|
init.type.elem.kind === "dyn" &&
|
|
@@ -3843,14 +4592,14 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3843
4592
|
// cannot hold the binding's future. The binding is checked-dynamic
|
|
3844
4593
|
// instead (irTypeOf's JS story): writes dynFrom, typed exits dynCheck.
|
|
3845
4594
|
// Const keeps the static empty record — no reassignment exists.
|
|
3846
|
-
if (isLet && type?.kind === "record" && isJsSourceFile(
|
|
4595
|
+
if (isLet && type?.kind === "record" && isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3847
4596
|
const shape = lowerer.shapes.get(type.shapeId);
|
|
3848
4597
|
if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
|
|
3849
4598
|
type = DYN;
|
|
3850
4599
|
}
|
|
3851
4600
|
if (isLet &&
|
|
3852
4601
|
type !== null &&
|
|
3853
|
-
isJsSourceFile(
|
|
4602
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3854
4603
|
!decl.type &&
|
|
3855
4604
|
!hasJsTypeAnnotation(decl) &&
|
|
3856
4605
|
(type.kind === "object" || type.kind === "symbol" || jsBindingHasOpenWrites(lowerer, decl))) {
|
|
@@ -3872,11 +4621,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3872
4621
|
// exits dynCheck.
|
|
3873
4622
|
if (returnedEmptyArrayType === null &&
|
|
3874
4623
|
(type === null || type.kind === "array") &&
|
|
3875
|
-
isJsSourceFile(
|
|
4624
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3876
4625
|
let initExpr = decl.initializer;
|
|
3877
4626
|
while (ts.isParenthesizedExpression(initExpr))
|
|
3878
4627
|
initExpr = initExpr.expression;
|
|
3879
|
-
if (ts.isArrayLiteralExpression(initExpr) && initExpr.elements.length === 0) {
|
|
4628
|
+
if (ts.isArrayLiteralExpression(initExpr) && initExpr.elements.nodes.length === 0) {
|
|
3880
4629
|
const t = lowerer.typeOf(decl.name);
|
|
3881
4630
|
if (lowerer.checker.isArrayType(t)) {
|
|
3882
4631
|
const elem = lowerer.checker.getTypeArguments(t)[0];
|
|
@@ -3885,6 +4634,17 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3885
4634
|
}
|
|
3886
4635
|
}
|
|
3887
4636
|
}
|
|
4637
|
+
// A TypeScript `const nodes = [];` filled by later writes: the checker
|
|
4638
|
+
// types each read by the elements written before it (evolvingArrayType).
|
|
4639
|
+
if (returnedEmptyArrayType === null &&
|
|
4640
|
+
!decl.type &&
|
|
4641
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
4642
|
+
const evolved = evolvingArrayType(lowerer, decl);
|
|
4643
|
+
if (evolved !== null) {
|
|
4644
|
+
type = evolved;
|
|
4645
|
+
init = lowerer.lowerExprExpecting(decl.initializer, evolved);
|
|
4646
|
+
}
|
|
4647
|
+
}
|
|
3888
4648
|
// An unannotated binding holding an OOB-SAFE indexed read (`elem |
|
|
3889
4649
|
// undefined`) where the checker spells the bare element: the binding
|
|
3890
4650
|
// adopts the runtime-honest union. This covers both inferred package JS
|
|
@@ -3928,14 +4688,14 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3928
4688
|
// boxed thunk's JS arity instead.
|
|
3929
4689
|
if (type?.kind === "func" &&
|
|
3930
4690
|
init.type.kind === "dyn" &&
|
|
3931
|
-
(isJsSourceFile(
|
|
4691
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
3932
4692
|
(!decl.type &&
|
|
3933
4693
|
!hasJsTypeAnnotation(decl) &&
|
|
3934
4694
|
type.rest === true &&
|
|
3935
4695
|
type.restAbi === undefined))) {
|
|
3936
4696
|
type = DYN;
|
|
3937
4697
|
}
|
|
3938
|
-
if (isJsSourceFile(
|
|
4698
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3939
4699
|
!decl.type &&
|
|
3940
4700
|
!hasJsTypeAnnotation(decl) &&
|
|
3941
4701
|
init.type.kind === "dyn" &&
|
|
@@ -3952,7 +4712,28 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3952
4712
|
// `let` may be reassigned a different shape later; genuine `any`
|
|
3953
4713
|
// only — every other unmappable keeps its own diagnostic.
|
|
3954
4714
|
const checkerAny = (lowerer.typeOf(decl.name).flags & ts.TypeFlags.Any) !== 0;
|
|
3955
|
-
|
|
4715
|
+
// An annotation the checker could not resolve (a package type alias that
|
|
4716
|
+
// reads as `any`) over an empty object literal: the binding is a
|
|
4717
|
+
// dictionary the code fills by key (`files[name] = entry`), which the
|
|
4718
|
+
// empty struct the literal would adopt cannot hold. It holds the
|
|
4719
|
+
// checked-dynamic object instead.
|
|
4720
|
+
let emptyAnyDictionary = false;
|
|
4721
|
+
if (checkerAny && decl.type && !isLet && init.type.kind === "record") {
|
|
4722
|
+
let lit = decl.initializer;
|
|
4723
|
+
while (ts.isParenthesizedExpression(lit))
|
|
4724
|
+
lit = lit.expression;
|
|
4725
|
+
const shape = lowerer.shapes.get(init.type.shapeId);
|
|
4726
|
+
if (ts.isObjectLiteralExpression(lit) &&
|
|
4727
|
+
lit.properties.nodes.length === 0 &&
|
|
4728
|
+
shape &&
|
|
4729
|
+
shape.fields.length === 0 &&
|
|
4730
|
+
!shape.indexValue) {
|
|
4731
|
+
type = DYN;
|
|
4732
|
+
emptyAnyDictionary = true;
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4735
|
+
if (!emptyAnyDictionary &&
|
|
4736
|
+
(type === null || (type.kind === "dyn" && checkerAny)) &&
|
|
3956
4737
|
!isLet &&
|
|
3957
4738
|
(checkerAny ||
|
|
3958
4739
|
(lowerer.checkerAnyArray(decl.name) && lowerer.isArrayValueType(init.type)) ||
|
|
@@ -3960,12 +4741,16 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3960
4741
|
// type (a union with a fence-folded arm — the typeof-'bigint'
|
|
3961
4742
|
// dual-mode ternary) adopts the initializer's static type, the
|
|
3962
4743
|
// same rule genuine `any` consts take.
|
|
3963
|
-
(type === null && isJsSourceFile(
|
|
4744
|
+
(type === null && isJsSourceFile(ts.getSourceFileOfNode(decl)))) &&
|
|
3964
4745
|
init.type.kind !== "void" &&
|
|
3965
4746
|
init.type.kind !== "caught" &&
|
|
3966
4747
|
!isUnitType(init.type)) {
|
|
3967
4748
|
type = init.type;
|
|
3968
4749
|
}
|
|
4750
|
+
// `const B = factory(1)` inside a generic instance: the factory's local
|
|
4751
|
+
// class for the instance the call names.
|
|
4752
|
+
if (!type && !isLet)
|
|
4753
|
+
type = genericLocalClassBinding(lowerer, decl.name);
|
|
3969
4754
|
if (!type) {
|
|
3970
4755
|
// The JS declaration fallback (irTypeOf's story): the binding holds
|
|
3971
4756
|
// the checked-dynamic kind when even the initializer's type has no
|
|
@@ -3978,7 +4763,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3978
4763
|
lowerer.badType(decl.name, lowerer.typeOf(decl.name));
|
|
3979
4764
|
let settledType = type;
|
|
3980
4765
|
if (!isLet &&
|
|
3981
|
-
isJsSourceFile(
|
|
4766
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3982
4767
|
!hasJsTypeAnnotation(decl) &&
|
|
3983
4768
|
decl.initializer &&
|
|
3984
4769
|
ts.isNewExpression(decl.initializer)) {
|
|
@@ -4013,7 +4798,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
4013
4798
|
? npmStaticOptionalSelfWriteType(lowerer, decl, settledType)
|
|
4014
4799
|
: null;
|
|
4015
4800
|
settledType =
|
|
4016
|
-
expandsObject || preservesObjectIdentity
|
|
4801
|
+
expandsObject || preservesObjectIdentity || keepsAssertedObject
|
|
4017
4802
|
? DYN
|
|
4018
4803
|
: lowerer.runtimeOptionalBindingType(decl.name, settledType);
|
|
4019
4804
|
if (optionalSelfWriteType !== null)
|
|
@@ -4076,6 +4861,21 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
4076
4861
|
settledType = init.type;
|
|
4077
4862
|
}
|
|
4078
4863
|
}
|
|
4864
|
+
// `const view = route as Route & { order: number }`: the asserted type
|
|
4865
|
+
// refines the record arms the value is stored in (the assertion keeps
|
|
4866
|
+
// that value, see hosted-narrowing.ts). The binding keeps the stored
|
|
4867
|
+
// type, so writes through it reach the asserted object. An annotation
|
|
4868
|
+
// the stored type hosts (`const view: Route & { order: number } = ...`)
|
|
4869
|
+
// keeps it too: coercing into the annotated layout would copy the
|
|
4870
|
+
// value and read members the writes have not created yet.
|
|
4871
|
+
if (!isLet &&
|
|
4872
|
+
decl.initializer &&
|
|
4873
|
+
isAssertionInitializer(decl.initializer) &&
|
|
4874
|
+
(settledType.kind === "union" || settledType.kind === "record") &&
|
|
4875
|
+
(init.type.kind === "union" || init.type.kind === "record") &&
|
|
4876
|
+
hostsAll(lowerer, init.type, settledType)) {
|
|
4877
|
+
settledType = init.type;
|
|
4878
|
+
}
|
|
4079
4879
|
// An exact class behind a generic interface keeps its native
|
|
4080
4880
|
// representation so generic calls can specialize against its body.
|
|
4081
4881
|
if ((settledType.kind === "record" || settledType.kind === "dyn") &&
|
|
@@ -4176,7 +4976,7 @@ function lowerVariableInitializer(lowerer, node, expected) {
|
|
|
4176
4976
|
if (expected?.kind === "dyn")
|
|
4177
4977
|
return lowerDynObjectLiteral(lowerer, value);
|
|
4178
4978
|
const previous = new Map();
|
|
4179
|
-
for (const property of value.properties) {
|
|
4979
|
+
for (const property of value.properties.nodes) {
|
|
4180
4980
|
if (!ts.isPropertyAssignment(property) || !ts.isComputedPropertyName(property.name))
|
|
4181
4981
|
continue;
|
|
4182
4982
|
const keyNode = property.name.expression;
|
|
@@ -4205,7 +5005,7 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4205
5005
|
if (decl.type ||
|
|
4206
5006
|
!decl.initializer ||
|
|
4207
5007
|
!ts.isIdentifier(decl.name) ||
|
|
4208
|
-
!isJsSourceFile(
|
|
5008
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
4209
5009
|
return false;
|
|
4210
5010
|
let initializer = decl.initializer;
|
|
4211
5011
|
while (ts.isParenthesizedExpression(initializer))
|
|
@@ -4282,6 +5082,18 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4282
5082
|
const name = property(node.left);
|
|
4283
5083
|
if (name === null || (name !== undefined && !names.has(name)))
|
|
4284
5084
|
expands = true;
|
|
5085
|
+
// `state = { _tag: "Done", right }` stores an object with properties
|
|
5086
|
+
// the initializer's shape lacks; later reads of them must see them.
|
|
5087
|
+
const target = unwrap(node.left);
|
|
5088
|
+
const value = unwrap(node.right);
|
|
5089
|
+
const targetSymbol = ts.isIdentifier(target) ? lowerer.resolveValueSymbol(target) : undefined;
|
|
5090
|
+
if (targetSymbol &&
|
|
5091
|
+
aliases.has(targetSymbol) &&
|
|
5092
|
+
ts.isObjectLiteralExpression(value) &&
|
|
5093
|
+
value.properties.nodes.some((field) => !(ts.isPropertyAssignment(field) || ts.isShorthandPropertyAssignment(field)) ||
|
|
5094
|
+
!(ts.isIdentifier(field.name) || ts.isStringLiteral(field.name)) ||
|
|
5095
|
+
!names.has(field.name.text)))
|
|
5096
|
+
expands = true;
|
|
4285
5097
|
}
|
|
4286
5098
|
if (ts.isDeleteExpression(node) && property(node.expression) !== undefined)
|
|
4287
5099
|
expands = true;
|
|
@@ -4289,7 +5101,7 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4289
5101
|
ts.isPropertyAccessExpression(node.expression) &&
|
|
4290
5102
|
node.expression.name.text === "setPrototypeOf" &&
|
|
4291
5103
|
lowerer.isStdlibGlobal(node.expression.expression, "Object")) {
|
|
4292
|
-
const target = node.arguments[0];
|
|
5104
|
+
const target = node.arguments.nodes[0];
|
|
4293
5105
|
const sym = target && ts.isIdentifier(target) ? lowerer.resolveValueSymbol(target) : undefined;
|
|
4294
5106
|
if (sym && aliases.has(sym))
|
|
4295
5107
|
expands = true;
|
|
@@ -4301,12 +5113,13 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4301
5113
|
}
|
|
4302
5114
|
export function hasJsTypeAnnotation(decl) {
|
|
4303
5115
|
const statement = decl.parent?.parent;
|
|
4304
|
-
return (!!statement &&
|
|
5116
|
+
return (!!statement &&
|
|
5117
|
+
/@type\b/.test(ts.getSourceFileOfNode(decl).text.slice(statement.pos, ts.tokenStartOfNode(decl))));
|
|
4305
5118
|
}
|
|
4306
5119
|
/** Inferred JS scalar initializers do not constrain later writes through
|
|
4307
5120
|
* an any-valued callback. Keep those bindings open, including captured writes. */
|
|
4308
5121
|
export function jsBindingHasOpenWrites(lowerer, decl) {
|
|
4309
|
-
if (!isJsSourceFile(
|
|
5122
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
4310
5123
|
decl.type ||
|
|
4311
5124
|
hasJsTypeAnnotation(decl) ||
|
|
4312
5125
|
!ts.isIdentifier(decl.name))
|
|
@@ -4335,41 +5148,147 @@ export function jsBindingHasOpenWrites(lowerer, decl) {
|
|
|
4335
5148
|
writes = indexed;
|
|
4336
5149
|
lowerer.jsBindingWritesByOwner.set(owner, writes);
|
|
4337
5150
|
}
|
|
4338
|
-
|
|
4339
|
-
|
|
5151
|
+
const candidates = (writes.get(decl.name.text) ?? []).filter((node) => lowerer.resolveValueSymbol(node.left) === symbol);
|
|
5152
|
+
if (candidates.some((node) => (lowerer.typeOf(node.right).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0))
|
|
5153
|
+
return true;
|
|
5154
|
+
// A plain JavaScript write of a value the declared type cannot hold (the
|
|
5155
|
+
// checker does not report it): buffer-crc32 replaces its number[] table
|
|
5156
|
+
// with `new Int32Array(table)`. Only a different representation counts;
|
|
5157
|
+
// writes that coerce into the declared type keep it.
|
|
5158
|
+
// A write whose checker type is the declaration's own maps to the same
|
|
5159
|
+
// representation; the declared type is mapped only for the others.
|
|
5160
|
+
const declaredType = lowerer.typeOf(decl.name);
|
|
5161
|
+
const differing = candidates.filter((node) => node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
5162
|
+
lowerer.typeOf(node.right) !== declaredType);
|
|
5163
|
+
if (differing.length === 0)
|
|
5164
|
+
return false;
|
|
5165
|
+
const declared = lowerer.mapTypeOf(declaredType);
|
|
5166
|
+
if (declared === null || declared.kind === "dyn" || declared.kind === "union")
|
|
5167
|
+
return false;
|
|
5168
|
+
return differing.some((node) => {
|
|
5169
|
+
const written = lowerer.mapTypeOf(lowerer.typeOf(node.right));
|
|
5170
|
+
return (written !== null &&
|
|
5171
|
+
written.kind !== "dyn" &&
|
|
5172
|
+
written.kind !== "union" &&
|
|
5173
|
+
!isUnitType(written) &&
|
|
5174
|
+
lowerer.dynConvertible(written) &&
|
|
5175
|
+
lowerer.dynConvertible(declared) &&
|
|
5176
|
+
!typeEquals(written, declared) &&
|
|
5177
|
+
(written.kind !== declared.kind || written.kind === "bytes"));
|
|
5178
|
+
});
|
|
4340
5179
|
}
|
|
4341
5180
|
function immediatelyGuardedAbsenceProbe(lowerer, decl) {
|
|
4342
|
-
|
|
5181
|
+
const guard = immediateAbsenceGuard(lowerer, decl);
|
|
5182
|
+
// `if (!x)`: the falsy test sees a missing value.
|
|
5183
|
+
if (guard === "falsy")
|
|
5184
|
+
return true;
|
|
5185
|
+
// `if (x === undefined)` and its spellings compare the binding with the
|
|
5186
|
+
// missing value itself, so the read must be able to produce it. Only
|
|
5187
|
+
// index-signature record reads take this form: array reads already
|
|
5188
|
+
// carry their undefined arm, and their ordinary lowering keeps its
|
|
5189
|
+
// bounds proofs.
|
|
5190
|
+
return guard === "compare" && isIndexSignatureRecordRead(lowerer, decl);
|
|
5191
|
+
}
|
|
5192
|
+
/** A file-scope or block-scope `let e = map[k]` over an index-signature
|
|
5193
|
+
* record whose next statement guards `e` for absence (`if (e ===
|
|
5194
|
+
* undefined)`, `if (!e)`, ...): the get-or-create idiom. Its read keeps the
|
|
5195
|
+
* missing key as undefined even without noUncheckedIndexedAccess. */
|
|
5196
|
+
export function isGuardedRecordRead(lowerer, decl) {
|
|
5197
|
+
return immediateAbsenceGuard(lowerer, decl) !== null && isIndexSignatureRecordRead(lowerer, decl);
|
|
5198
|
+
}
|
|
5199
|
+
function isIndexSignatureRecordRead(lowerer, decl) {
|
|
5200
|
+
if (!decl.initializer)
|
|
4343
5201
|
return false;
|
|
5202
|
+
let init = decl.initializer;
|
|
5203
|
+
while (ts.isParenthesizedExpression(init))
|
|
5204
|
+
init = init.expression;
|
|
5205
|
+
if (!ts.isElementAccessExpression(init))
|
|
5206
|
+
return false;
|
|
5207
|
+
// Under noUncheckedIndexedAccess the checker already spells the missing
|
|
5208
|
+
// arm, and the ordinary read carries it.
|
|
5209
|
+
const read = lowerer.typeOf(init);
|
|
5210
|
+
if ((read.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0 ||
|
|
5211
|
+
(read.isUnionType() &&
|
|
5212
|
+
ts.constituentTypes(read).some((t) => (t.flags & ts.TypeFlags.Undefined) !== 0)))
|
|
5213
|
+
return false;
|
|
5214
|
+
const receiver = lowerer.mapTypeOf(lowerer.typeOf(init.expression));
|
|
5215
|
+
const shape = receiver?.kind === "record" ? lowerer.shapes.get(receiver.shapeId) : undefined;
|
|
5216
|
+
return !!shape && !shape.tuple && !!shape.indexValue && shape.indexValue.kind !== "dyn";
|
|
5217
|
+
}
|
|
5218
|
+
/** How the statement right after an unannotated declaration tests the
|
|
5219
|
+
* declared binding for absence: `if (!x)` ("falsy"), or a comparison with
|
|
5220
|
+
* the missing value — `x === undefined`, `x == null`, `x !== void 0`,
|
|
5221
|
+
* `typeof x === "undefined"` and their mirrored and negated spellings
|
|
5222
|
+
* ("compare"). Null for anything else. */
|
|
5223
|
+
function immediateAbsenceGuard(lowerer, decl) {
|
|
5224
|
+
if (decl.type || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
5225
|
+
return null;
|
|
4344
5226
|
const statement = decl.parent?.parent;
|
|
4345
5227
|
if (!statement || !ts.isVariableStatement(statement))
|
|
4346
|
-
return
|
|
5228
|
+
return null;
|
|
4347
5229
|
const container = statement.parent;
|
|
4348
|
-
const statements = ts.isBlock(container) || ts.isSourceFile(container) ? container.statements : null;
|
|
5230
|
+
const statements = ts.isBlock(container) || ts.isSourceFile(container) ? container.statements.nodes : null;
|
|
4349
5231
|
if (!statements)
|
|
4350
|
-
return
|
|
5232
|
+
return null;
|
|
4351
5233
|
const index = statements.indexOf(statement);
|
|
4352
5234
|
const next = index >= 0 ? statements[index + 1] : undefined;
|
|
4353
5235
|
if (!next || !ts.isIfStatement(next))
|
|
4354
|
-
return
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
operand
|
|
4364
|
-
|
|
4365
|
-
|
|
5236
|
+
return null;
|
|
5237
|
+
const binding = lowerer.resolveValueSymbol(decl.name);
|
|
5238
|
+
const peel = (node) => {
|
|
5239
|
+
while (ts.isParenthesizedExpression(node))
|
|
5240
|
+
node = node.expression;
|
|
5241
|
+
return node;
|
|
5242
|
+
};
|
|
5243
|
+
const isBinding = (node) => {
|
|
5244
|
+
const operand = peel(node);
|
|
5245
|
+
return ts.isIdentifier(operand) && lowerer.resolveValueSymbol(operand) === binding;
|
|
5246
|
+
};
|
|
5247
|
+
const condition = peel(next.expression);
|
|
5248
|
+
if (ts.isPrefixUnaryExpression(condition))
|
|
5249
|
+
return condition.operator === ts.SyntaxKind.ExclamationToken && isBinding(condition.operand)
|
|
5250
|
+
? "falsy"
|
|
5251
|
+
: null;
|
|
5252
|
+
if (!ts.isBinaryExpression(condition))
|
|
5253
|
+
return null;
|
|
5254
|
+
const op = condition.operatorToken.kind;
|
|
5255
|
+
const strict = op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
|
|
5256
|
+
op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
|
|
5257
|
+
const loose = op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken;
|
|
5258
|
+
if (!strict && !loose)
|
|
5259
|
+
return null;
|
|
5260
|
+
const isUndefined = (node) => {
|
|
5261
|
+
const operand = peel(node);
|
|
5262
|
+
if (ts.isVoidExpression(operand))
|
|
5263
|
+
return true;
|
|
5264
|
+
return (ts.isIdentifier(operand) &&
|
|
5265
|
+
operand.text === "undefined" &&
|
|
5266
|
+
(lowerer.typeOf(operand).flags & ts.TypeFlags.Undefined) !== 0);
|
|
5267
|
+
};
|
|
5268
|
+
const isNull = (node) => peel(node).kind === ts.SyntaxKind.NullKeyword;
|
|
5269
|
+
const missing = (node) => isUndefined(node) || (loose && isNull(node));
|
|
5270
|
+
const isTypeofBinding = (node) => {
|
|
5271
|
+
const operand = peel(node);
|
|
5272
|
+
return ts.isTypeOfExpression(operand) && isBinding(operand.expression);
|
|
5273
|
+
};
|
|
5274
|
+
const isUndefinedTag = (node) => {
|
|
5275
|
+
const operand = peel(node);
|
|
5276
|
+
return ts.isStringLiteralLike(operand) && operand.text === "undefined";
|
|
5277
|
+
};
|
|
5278
|
+
const { left, right } = condition;
|
|
5279
|
+
return (isBinding(left) && missing(right)) ||
|
|
5280
|
+
(missing(left) && isBinding(right)) ||
|
|
5281
|
+
(isTypeofBinding(left) && isUndefinedTag(right)) ||
|
|
5282
|
+
(isUndefinedTag(left) && isTypeofBinding(right))
|
|
5283
|
+
? "compare"
|
|
5284
|
+
: null;
|
|
4366
5285
|
}
|
|
4367
5286
|
function falsyExitRuntimeOptionalLocals(lowerer, stmt) {
|
|
4368
5287
|
if (stmt.elseStatement)
|
|
4369
5288
|
return [];
|
|
4370
5289
|
let tail = stmt.thenStatement;
|
|
4371
5290
|
while (ts.isBlock(tail)) {
|
|
4372
|
-
const last = tail.statements[tail.statements.length - 1];
|
|
5291
|
+
const last = tail.statements.nodes[tail.statements.nodes.length - 1];
|
|
4373
5292
|
if (!last)
|
|
4374
5293
|
return [];
|
|
4375
5294
|
tail = last;
|
|
@@ -4395,15 +5314,16 @@ export function lowerSwitch(lowerer, stmt) {
|
|
|
4395
5314
|
return lowerDynSwitch(lowerer, stmt, disc, labels);
|
|
4396
5315
|
if (dk === "union")
|
|
4397
5316
|
return lowerUnionSwitch(lowerer, stmt, disc, labels);
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
5317
|
+
// Objects, arrays, functions and other references match their cases
|
|
5318
|
+
// with ===, which compares them by identity.
|
|
5319
|
+
if (dk !== "f64" && dk !== "string" && dk !== "bool")
|
|
5320
|
+
return lowerBranchSwitch(lowerer, stmt, disc, labels, (stableDisc, test, expression) => lowerStrictEquality(lowerer, expression, stmt.expression, expression, stableDisc, test, false, locOf(expression)));
|
|
4401
5321
|
// The whole case-body sequence is ONE lexical scope in JS: a bare `let`
|
|
4402
5322
|
// in one case is visible in later cases.
|
|
4403
5323
|
lowerer.scopes.push(new Map());
|
|
4404
5324
|
try {
|
|
4405
5325
|
const cases = [];
|
|
4406
|
-
for (const clause of stmt.caseBlock.clauses) {
|
|
5326
|
+
for (const clause of stmt.caseBlock.clauses.nodes) {
|
|
4407
5327
|
let test = null;
|
|
4408
5328
|
if (ts.isCaseClause(clause)) {
|
|
4409
5329
|
test = lowerer.lowerExpr(clause.expression);
|
|
@@ -4413,7 +5333,7 @@ export function lowerSwitch(lowerer, stmt) {
|
|
|
4413
5333
|
}
|
|
4414
5334
|
cases.push({
|
|
4415
5335
|
test,
|
|
4416
|
-
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels),
|
|
5336
|
+
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements.nodes)), labels),
|
|
4417
5337
|
});
|
|
4418
5338
|
}
|
|
4419
5339
|
return { kind: "switch", disc, cases, ...(labels && { labels }), loc: locOf(stmt) };
|
|
@@ -4463,7 +5383,7 @@ function lowerDynSwitch(lowerer, stmt, disc, labels) {
|
|
|
4463
5383
|
loc: locOf(expression),
|
|
4464
5384
|
};
|
|
4465
5385
|
}
|
|
4466
|
-
if (!lowerer.dynConvertible(test.type)) {
|
|
5386
|
+
if (test.type.kind === "date" || !lowerer.dynConvertible(test.type)) {
|
|
4467
5387
|
lowerer.unsupported("SC1100", expression, "switch case values that cannot compare strictly with 'unknown'");
|
|
4468
5388
|
}
|
|
4469
5389
|
return {
|
|
@@ -4484,7 +5404,7 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4484
5404
|
// Calls/assignments in a case test may mutate a captured discriminant
|
|
4485
5405
|
// binding. The checker still narrows that binding as if it were the
|
|
4486
5406
|
// snapshot. Keep the original tagged value in those case bodies.
|
|
4487
|
-
const effectful = stmt.caseBlock.clauses.some((clause) => ts.isCaseClause(clause) &&
|
|
5407
|
+
const effectful = stmt.caseBlock.clauses.nodes.some((clause) => ts.isCaseClause(clause) &&
|
|
4488
5408
|
!ts.isStringLiteral(clause.expression) &&
|
|
4489
5409
|
!ts.isNumericLiteral(clause.expression) &&
|
|
4490
5410
|
!ts.isIdentifier(clause.expression) &&
|
|
@@ -4500,11 +5420,11 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4500
5420
|
lowerer.unstableSwitchBindings.add(symbol);
|
|
4501
5421
|
lowerer.scopes.push(new Map());
|
|
4502
5422
|
try {
|
|
4503
|
-
const cases = stmt.caseBlock.clauses.map((clause) => ({
|
|
5423
|
+
const cases = stmt.caseBlock.clauses.nodes.map((clause) => ({
|
|
4504
5424
|
test: ts.isCaseClause(clause)
|
|
4505
5425
|
? compare(stableDisc, lowerer.lowerExpr(clause.expression), clause.expression)
|
|
4506
5426
|
: null,
|
|
4507
|
-
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels),
|
|
5427
|
+
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements.nodes)), labels),
|
|
4508
5428
|
}));
|
|
4509
5429
|
return {
|
|
4510
5430
|
kind: "block",
|
|
@@ -4533,7 +5453,7 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4533
5453
|
* cell, deliberately narrower than dyn: the supported uses are the
|
|
4534
5454
|
* narrowing tests (`e instanceof C` over hierarchy classes, `typeof e
|
|
4535
5455
|
* === "string"/"number"/"boolean"`), reads under a proven narrow
|
|
4536
|
-
* (caughtRead bridges them with caughtNarrow,
|
|
5456
|
+
* (caughtRead bridges them with caughtNarrow, verified at run time like
|
|
4537
5457
|
* unionNarrow), and rethrow (`throw e`). Unsupported raw uses and
|
|
4538
5458
|
* assignments are fenced (SC1063 and friends); destructuring patterns
|
|
4539
5459
|
* are SC1062. Captures retain the snapshot beyond the catch scope.
|
|
@@ -4579,31 +5499,6 @@ export function lowerTry(lowerer, stmt) {
|
|
|
4579
5499
|
loc: locOf(stmt),
|
|
4580
5500
|
};
|
|
4581
5501
|
}
|
|
4582
|
-
function hasUseStrictDirective(statements) {
|
|
4583
|
-
for (const statement of statements) {
|
|
4584
|
-
if (!ts.isExpressionStatement(statement) || !ts.isStringLiteral(statement.expression))
|
|
4585
|
-
return false;
|
|
4586
|
-
if (statement.expression.text === "use strict")
|
|
4587
|
-
return true;
|
|
4588
|
-
}
|
|
4589
|
-
return false;
|
|
4590
|
-
}
|
|
4591
|
-
function isStrictDelete(node) {
|
|
4592
|
-
for (let parent = node.parent; parent; parent = parent.parent) {
|
|
4593
|
-
if (ts.isClassDeclaration(parent) || ts.isClassExpression(parent))
|
|
4594
|
-
return true;
|
|
4595
|
-
if (ts.isFunctionLike(parent) &&
|
|
4596
|
-
parent.body &&
|
|
4597
|
-
ts.isBlock(parent.body) &&
|
|
4598
|
-
hasUseStrictDirective(parent.body.statements))
|
|
4599
|
-
return true;
|
|
4600
|
-
if (ts.isSourceFile(parent)) {
|
|
4601
|
-
return (hasUseStrictDirective(parent.statements) ||
|
|
4602
|
-
(!isCjsJsFile(parent) && (isNodeEsmFile(parent) || ts.isExternalModule(parent))));
|
|
4603
|
-
}
|
|
4604
|
-
}
|
|
4605
|
-
return false;
|
|
4606
|
-
}
|
|
4607
5502
|
/** Statement-position `delete`: process.env keys → process.envUnset
|
|
4608
5503
|
* (unsetenv), pure `Record<string, T>` keys → recordKeyDelete (the
|
|
4609
5504
|
* overflow Map delete), declared OPTIONAL fields → the field's ABSENT
|
|
@@ -4666,7 +5561,29 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4666
5561
|
};
|
|
4667
5562
|
}
|
|
4668
5563
|
let obj = lowerer.lowerExpr(target.expression);
|
|
4669
|
-
|
|
5564
|
+
// `delete this.stack` in an Error subclass that declares a `stack`
|
|
5565
|
+
// accessor (quickjs-wasi's JSException): V8 gives each error an own
|
|
5566
|
+
// `stack` that shadows the accessor, and the delete removes it so reads
|
|
5567
|
+
// reach the accessor. Compiled errors keep the trace internally and
|
|
5568
|
+
// class dispatch already reads the accessor, so only the receiver's
|
|
5569
|
+
// evaluation remains.
|
|
5570
|
+
if (obj.type.kind === "object" &&
|
|
5571
|
+
ts.isPropertyAccessExpression(target) &&
|
|
5572
|
+
target.name.text === "stack") {
|
|
5573
|
+
let accessor = false;
|
|
5574
|
+
let errorBase = false;
|
|
5575
|
+
for (let c = lowerer.classes.get(obj.type.className); c; c = c.base ?? undefined) {
|
|
5576
|
+
if (c.builtinError) {
|
|
5577
|
+
errorBase = true;
|
|
5578
|
+
break;
|
|
5579
|
+
}
|
|
5580
|
+
if (c.methods.has("get:stack"))
|
|
5581
|
+
accessor = true;
|
|
5582
|
+
}
|
|
5583
|
+
if (accessor && errorBase)
|
|
5584
|
+
return { kind: "exprStmt", expr: obj, loc };
|
|
5585
|
+
}
|
|
5586
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) && obj.type.kind === "object") {
|
|
4670
5587
|
const info = lowerer.classes.get(obj.type.className);
|
|
4671
5588
|
const keyType = ts.isElementAccessExpression(target)
|
|
4672
5589
|
? lowerer.typeOf(target.argumentExpression)
|
|
@@ -4686,13 +5603,13 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4686
5603
|
};
|
|
4687
5604
|
}
|
|
4688
5605
|
}
|
|
4689
|
-
if (isJsSourceFile(
|
|
5606
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
4690
5607
|
obj.type.kind === "func" &&
|
|
4691
5608
|
lowerer.dynConvertible(obj.type)) {
|
|
4692
5609
|
obj = lowerer.coerceToExpected(obj, DYN);
|
|
4693
5610
|
}
|
|
4694
5611
|
if (obj.type.kind === "dyn") {
|
|
4695
|
-
const strict = { kind: "boolLit", value:
|
|
5612
|
+
const strict = { kind: "boolLit", value: isStrictCode(expr), type: BOOL, loc };
|
|
4696
5613
|
if (ts.isElementAccessExpression(target)) {
|
|
4697
5614
|
const key = lowerer.lowerExprExpecting(target.argumentExpression, DYN);
|
|
4698
5615
|
return {
|
|
@@ -4779,7 +5696,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4779
5696
|
const assignExport = (nameNode, value, root) => {
|
|
4780
5697
|
const symbol = lowerer.checker.getSymbolAtLocation(nameNode) ??
|
|
4781
5698
|
(ts.isIdentifier(nameNode) || ts.isPrivateIdentifier(nameNode)
|
|
4782
|
-
? lowerer.cjsModuleExportSymbol(cjs.expr
|
|
5699
|
+
? lowerer.cjsModuleExportSymbol(ts.getSourceFileOfNode(cjs.expr), nameNode.text)
|
|
4783
5700
|
: undefined);
|
|
4784
5701
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
4785
5702
|
if (!g) {
|
|
@@ -4838,7 +5755,10 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4838
5755
|
// storage — collectGlobals skipped it; importers re-resolve through
|
|
4839
5756
|
// cjsMemberExportClassSymbol): the statement lowers to nothing.
|
|
4840
5757
|
if (lowerer.cjsMemberExportClassSymbol(cjs.expr) !== null) {
|
|
4841
|
-
|
|
5758
|
+
// An inline require still evaluates its module here.
|
|
5759
|
+
const req = inlineProgramRequireOf(lowerer, cjs.value);
|
|
5760
|
+
const init = req !== null ? lowerer.requireInitStmt(req.spec, req.call) : null;
|
|
5761
|
+
return init ?? { kind: "block", body: [], loc };
|
|
4842
5762
|
}
|
|
4843
5763
|
// The tsc VOID-INIT PREAMBLE (`exports.leaf = void 0;` with the real
|
|
4844
5764
|
// `exports.leaf = leaf;` further down — every tsc-emitted dist file
|
|
@@ -4850,54 +5770,58 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4850
5770
|
// the real assignment's position already orders. Preambles with no
|
|
4851
5771
|
// later real assignment keep the ordinary path (the export IS
|
|
4852
5772
|
// undefined then).
|
|
4853
|
-
if (
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
((ts.isIdentifier(e.expression) && e.expression.text === "exports") ||
|
|
4857
|
-
(ts.isPropertyAccessExpression(e.expression) &&
|
|
4858
|
-
ts.isIdentifier(e.expression.expression) &&
|
|
4859
|
-
e.expression.expression.text === "module" &&
|
|
4860
|
-
ts.isIdentifier(e.expression.name) &&
|
|
4861
|
-
e.expression.name.text === "exports"));
|
|
4862
|
-
const isVoid = (e) => {
|
|
4863
|
-
while (ts.isParenthesizedExpression(e))
|
|
4864
|
-
e = e.expression;
|
|
4865
|
-
return (e.kind === ts.SyntaxKind.VoidExpression || (ts.isIdentifier(e) && e.text === "undefined"));
|
|
4866
|
-
};
|
|
4867
|
-
// chains: `exports.a = exports.b = void 0;` collects every name
|
|
4868
|
-
const names = [cjs.name.text];
|
|
4869
|
-
let tail = cjs.value;
|
|
4870
|
-
while (ts.isBinaryExpression(tail) &&
|
|
4871
|
-
tail.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
4872
|
-
isExportsMember(tail.left)) {
|
|
4873
|
-
names.push(tail.left.name.text);
|
|
4874
|
-
tail = tail.right;
|
|
4875
|
-
}
|
|
4876
|
-
if (isVoid(tail)) {
|
|
4877
|
-
const sfHere = cjs.expr.getSourceFile();
|
|
4878
|
-
const myPos = cjs.expr.getStart(sfHere);
|
|
4879
|
-
const laterRealOf = (name) => sfHere.statements.some((s) => {
|
|
4880
|
-
const other = cjsExportAssignmentOf(s);
|
|
4881
|
-
if (other?.kind !== "member" || !ts.isIdentifier(other.name))
|
|
4882
|
-
return false;
|
|
4883
|
-
if (other.name.text !== name)
|
|
4884
|
-
return false;
|
|
4885
|
-
if (other.expr.getStart(sfHere) <= myPos)
|
|
4886
|
-
return false;
|
|
4887
|
-
return !isVoid(other.value);
|
|
4888
|
-
});
|
|
4889
|
-
if (names.every(laterRealOf))
|
|
4890
|
-
return { kind: "block", body: [], loc };
|
|
4891
|
-
}
|
|
4892
|
-
}
|
|
4893
|
-
const sf = cjs.expr.getSourceFile();
|
|
5773
|
+
if (cjsVoidInitPreambleReals(cjs) !== null)
|
|
5774
|
+
return { kind: "block", body: [], loc };
|
|
5775
|
+
const sf = ts.getSourceFileOfNode(cjs.expr);
|
|
4894
5776
|
let root;
|
|
4895
|
-
for (const stmt of sf.statements) {
|
|
5777
|
+
for (const stmt of sf.statements.nodes) {
|
|
4896
5778
|
const whole = cjsExportAssignmentOf(stmt);
|
|
4897
5779
|
if (whole?.kind !== "table" || cjsExportDiscardReason(stmt) !== null)
|
|
4898
5780
|
continue;
|
|
4899
5781
|
root = lowerer.globalsByDeclNode.get(whole.expr);
|
|
4900
5782
|
}
|
|
5783
|
+
// A CHAIN `exports.a = exports.b = value`: Node evaluates the value
|
|
5784
|
+
// once, assigns the innermost member first, and every member holds
|
|
5785
|
+
// the same value. Each member is its own export global
|
|
5786
|
+
// (collectGlobals registers the inner ones too).
|
|
5787
|
+
{
|
|
5788
|
+
const chain = cjsExportChainOf(cjs.expr);
|
|
5789
|
+
if (chain !== null && root?.type.kind !== "dyn") {
|
|
5790
|
+
const globalOfName = (nameNode) => {
|
|
5791
|
+
const symbol = lowerer.checker.getSymbolAtLocation(nameNode) ??
|
|
5792
|
+
lowerer.cjsModuleExportSymbol(sf, nameNode.text);
|
|
5793
|
+
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
5794
|
+
if (!g) {
|
|
5795
|
+
lowerer.lowerExpr(chain.value);
|
|
5796
|
+
lowerer.badType(chain.value, lowerer.typeOf(chain.value));
|
|
5797
|
+
}
|
|
5798
|
+
return g;
|
|
5799
|
+
};
|
|
5800
|
+
const inner = chain.names[chain.names.length - 1];
|
|
5801
|
+
const innerG = globalOfName(inner);
|
|
5802
|
+
const body = [
|
|
5803
|
+
{
|
|
5804
|
+
kind: "assign",
|
|
5805
|
+
localId: innerG.id,
|
|
5806
|
+
value: lowerer.lowerExprExpecting(chain.value, innerG.type),
|
|
5807
|
+
loc: locOf(chain.value),
|
|
5808
|
+
},
|
|
5809
|
+
];
|
|
5810
|
+
for (let i = chain.names.length - 2; i >= 0; i--) {
|
|
5811
|
+
const g = globalOfName(chain.names[i]);
|
|
5812
|
+
const read = { kind: "varRef", localId: innerG.id, type: innerG.type, loc };
|
|
5813
|
+
body.push({
|
|
5814
|
+
kind: "assign",
|
|
5815
|
+
localId: g.id,
|
|
5816
|
+
value: typeEquals(g.type, innerG.type)
|
|
5817
|
+
? read
|
|
5818
|
+
: lowerer.coerceInto(chain.value, read, g.type),
|
|
5819
|
+
loc,
|
|
5820
|
+
});
|
|
5821
|
+
}
|
|
5822
|
+
return { kind: "block", body, loc };
|
|
5823
|
+
}
|
|
5824
|
+
}
|
|
4901
5825
|
return assignExport(cjs.name, cjs.value, root);
|
|
4902
5826
|
}
|
|
4903
5827
|
let tableObj = cjs.obj;
|
|
@@ -4911,7 +5835,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4911
5835
|
// were already evaluated by the const's own declaration, so this
|
|
4912
5836
|
// statement may not RE-evaluate anything: expression-valued entries
|
|
4913
5837
|
// (which the direct-table lowering assigns here) keep a fence.
|
|
4914
|
-
tableObj = cjsExportTargetLiteral(cjs.expr.right, cjs.expr
|
|
5838
|
+
tableObj = cjsExportTargetLiteral(cjs.expr.right, ts.getSourceFileOfNode(cjs.expr));
|
|
4915
5839
|
resolvedTarget = tableObj !== null;
|
|
4916
5840
|
if (!tableObj) {
|
|
4917
5841
|
const single = lowerCjsSingleValueExport(lowerer, cjs.expr, loc);
|
|
@@ -4934,7 +5858,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4934
5858
|
lowerer.unsupported("SC1090", nameNode, `exporting the mutable 'let' binding '${nameNode.text}' by reference (Node copies its VALUE at this statement — declare it const, or export a function that reads it)`);
|
|
4935
5859
|
}
|
|
4936
5860
|
};
|
|
4937
|
-
for (const prop of table.properties) {
|
|
5861
|
+
for (const prop of table.properties.nodes) {
|
|
4938
5862
|
if (ts.isShorthandPropertyAssignment(prop)) {
|
|
4939
5863
|
fenceMutable(prop.name);
|
|
4940
5864
|
continue; // alias plumbing
|
|
@@ -4952,6 +5876,29 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4952
5876
|
body.push(assignExport(prop.name, prop.initializer));
|
|
4953
5877
|
continue;
|
|
4954
5878
|
}
|
|
5879
|
+
// METHOD entries: the export global holds the method's function,
|
|
5880
|
+
// created at this statement like a function-expression entry. Node
|
|
5881
|
+
// calls it with `this` bound to the table, which the static export
|
|
5882
|
+
// table cannot represent, so a body that uses `this` keeps a fence.
|
|
5883
|
+
{
|
|
5884
|
+
const method = cjsTableMethodEntry(prop);
|
|
5885
|
+
if (method !== null && !resolvedTarget) {
|
|
5886
|
+
lowerer.rejectThisInObjectMethod(method.body);
|
|
5887
|
+
const symbol = lowerer.checker.getSymbolAtLocation(method.name) ??
|
|
5888
|
+
lowerer.cjsModuleExportSymbol(ts.getSourceFileOfNode(cjs.expr), method.name.text);
|
|
5889
|
+
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
5890
|
+
if (g) {
|
|
5891
|
+
const fn = lowerer.lowerLambda(method);
|
|
5892
|
+
body.push({
|
|
5893
|
+
kind: "assign",
|
|
5894
|
+
localId: g.id,
|
|
5895
|
+
value: typeEquals(fn.type, g.type) ? fn : lowerer.coerceInto(method, fn, g.type),
|
|
5896
|
+
loc: locOf(method),
|
|
5897
|
+
});
|
|
5898
|
+
continue;
|
|
5899
|
+
}
|
|
5900
|
+
}
|
|
5901
|
+
}
|
|
4955
5902
|
// ACCESSOR entries: no storage and no code here — reads lift the
|
|
4956
5903
|
// getter as a module-level function and call it per read
|
|
4957
5904
|
// (cjsExportAccessorRead); writes through the setter keep their
|
|
@@ -4969,8 +5916,16 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4969
5916
|
let inner = prop.expression;
|
|
4970
5917
|
while (ts.isParenthesizedExpression(inner))
|
|
4971
5918
|
inner = inner.expression;
|
|
4972
|
-
if (requireSpecOf(inner) !== null)
|
|
5919
|
+
if (requireSpecOf(inner) !== null) {
|
|
5920
|
+
// The spread still EVALUATES the module, at its place among the
|
|
5921
|
+
// table's entries (a program module joins the graph through this
|
|
5922
|
+
// inline require; cjs-inline-require.ts).
|
|
5923
|
+
const req = inlineProgramRequireOf(lowerer, inner);
|
|
5924
|
+
const init = req !== null ? lowerer.requireInitStmt(req.spec, req.call) : null;
|
|
5925
|
+
if (init !== null && !resolvedTarget)
|
|
5926
|
+
body.push(init);
|
|
4973
5927
|
continue;
|
|
5928
|
+
}
|
|
4974
5929
|
}
|
|
4975
5930
|
lowerer.unsupported("SC1090", prop, "module.exports table entries beyond plain 'name: value' properties (methods, accessors, spreads, computed names)");
|
|
4976
5931
|
}
|
|
@@ -4995,6 +5950,16 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
|
|
|
4995
5950
|
let rhs = expr.right;
|
|
4996
5951
|
while (ts.isParenthesizedExpression(rhs))
|
|
4997
5952
|
rhs = rhs.expression;
|
|
5953
|
+
// `module.exports = require("./x")`: the module re-exports x's exports.
|
|
5954
|
+
// Requirers resolve through the checker's alias to x's own export
|
|
5955
|
+
// machinery; this statement is x's evaluation at this position.
|
|
5956
|
+
{
|
|
5957
|
+
const req = inlineProgramRequireOf(lowerer, rhs);
|
|
5958
|
+
// With later member exports (`module.exports.extra = …`) the module
|
|
5959
|
+
// extends that object, so it keeps the factory root registration.
|
|
5960
|
+
if (req !== null && !lowerer.globalsByDeclNode.has(expr))
|
|
5961
|
+
return lowerer.requireInitStmt(req.spec, req.call) ?? { kind: "block", body: [], loc };
|
|
5962
|
+
}
|
|
4998
5963
|
if (ts.isIdentifier(rhs)) {
|
|
4999
5964
|
const sym = lowerer.resolveValueSymbol(rhs);
|
|
5000
5965
|
if (!sym)
|
|
@@ -5004,6 +5969,14 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
|
|
|
5004
5969
|
lowerer.genericFnsBySymbol.has(sym)) {
|
|
5005
5970
|
return { kind: "block", body: [], loc };
|
|
5006
5971
|
}
|
|
5972
|
+
// A require binding (`const x = require("./x"); module.exports = x`)
|
|
5973
|
+
// re-exports that module exactly like the inline form (the binding's
|
|
5974
|
+
// own statement already evaluated it), and a builtin global
|
|
5975
|
+
// (`module.exports = TypeError`) is the global itself: requirer
|
|
5976
|
+
// bindings alias straight through to it, so nothing is stored.
|
|
5977
|
+
if (sym.declarations.some((d) => ts.isSourceFile(d)) || lowerer.isStdlibSymbol(sym)) {
|
|
5978
|
+
return { kind: "block", body: [], loc };
|
|
5979
|
+
}
|
|
5007
5980
|
const g = lowerer.globalsBySymbol.get(sym);
|
|
5008
5981
|
if (g) {
|
|
5009
5982
|
if (g.mutable) {
|
|
@@ -5108,8 +6081,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5108
6081
|
// positions keep the first-class-namespace fences.
|
|
5109
6082
|
if (ts.isIdentifier(expr)) {
|
|
5110
6083
|
const sym = lowerer.checker.getSymbolAtLocation(expr);
|
|
5111
|
-
if (sym !== undefined &&
|
|
5112
|
-
lowerer.checker.declarationsOf(sym).some((d) => ts.isNamespaceImport(d))) {
|
|
6084
|
+
if (sym !== undefined && sym.declarations.some((d) => ts.isNamespaceImport(d))) {
|
|
5113
6085
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5114
6086
|
}
|
|
5115
6087
|
}
|
|
@@ -5142,16 +6114,22 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5142
6114
|
return (lowerer.requireInitStmt(created.spec, expr) ?? { kind: "block", body: [], loc: locOf(expr) });
|
|
5143
6115
|
}
|
|
5144
6116
|
// syncBuiltinESMExports() is the other compiler-only statement: the
|
|
5145
|
-
// call validates its zero-argument shape, then
|
|
5146
|
-
//
|
|
6117
|
+
// call validates its zero-argument shape, then refreshes the events
|
|
6118
|
+
// module's ES module namespace copy of defaultMaxListeners, the one
|
|
6119
|
+
// builtin export a program can change.
|
|
5147
6120
|
const bi = ts.isIdentifier(expr.expression)
|
|
5148
6121
|
? lowerer.builtinImportOf(expr.expression)
|
|
5149
6122
|
: ts.isPropertyAccessExpression(expr.expression)
|
|
5150
6123
|
? lowerer.builtinMemberOf(expr.expression)
|
|
5151
6124
|
: null;
|
|
5152
6125
|
if (bi?.module === "module" && bi.member === "syncBuiltinESMExports") {
|
|
5153
|
-
|
|
5154
|
-
|
|
6126
|
+
const loc = locOf(expr);
|
|
6127
|
+
lowerNodeModuleCall(lowerer, expr, bi, loc);
|
|
6128
|
+
return {
|
|
6129
|
+
kind: "exprStmt",
|
|
6130
|
+
expr: { kind: "libCall", fn: "emitter.esmSync", args: [], type: VOID, loc },
|
|
6131
|
+
loc,
|
|
6132
|
+
};
|
|
5155
6133
|
}
|
|
5156
6134
|
}
|
|
5157
6135
|
if (requireSpecOf(expr) !== null &&
|
|
@@ -5160,7 +6138,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5160
6138
|
// A binding NAMED require made by createRequire is not the CJS
|
|
5161
6139
|
// global — the expression path owns it (lowerCreateRequireCall).
|
|
5162
6140
|
createRequireCalleeFileOf(lowerer, expr.expression) === null) {
|
|
5163
|
-
const sf =
|
|
6141
|
+
const sf = ts.getSourceFileOfNode(expr);
|
|
5164
6142
|
const spec = requireSpecOf(expr);
|
|
5165
6143
|
if (lowerer.externalTypes.has(spec))
|
|
5166
6144
|
lowerer.externalHostFence(spec, expr, false);
|
|
@@ -5174,16 +6152,12 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5174
6152
|
if (!isRelativeSpecifier(spec) && canonicalBuiltinModule(spec) === null) {
|
|
5175
6153
|
const refusal = probeNodeRequireRefusal(sf.fileName, spec);
|
|
5176
6154
|
if (refusal !== null) {
|
|
6155
|
+
// The same throw as the expression form (cjs-inline-require):
|
|
6156
|
+
// an Error carrying Node's MODULE_NOT_FOUND code.
|
|
5177
6157
|
const loc = locOf(expr);
|
|
5178
6158
|
return {
|
|
5179
|
-
kind: "
|
|
5180
|
-
|
|
5181
|
-
kind: "libCall",
|
|
5182
|
-
fn: "error.new",
|
|
5183
|
-
args: [{ kind: "strLit", value: refusal.message, type: STRING, loc }],
|
|
5184
|
-
type: { kind: "object", className: "%Error" },
|
|
5185
|
-
loc,
|
|
5186
|
-
},
|
|
6159
|
+
kind: "exprStmt",
|
|
6160
|
+
expr: nodeThrowExpr(0, "MODULE_NOT_FOUND", refusal.message, VOID, loc),
|
|
5187
6161
|
loc,
|
|
5188
6162
|
};
|
|
5189
6163
|
}
|
|
@@ -5199,7 +6173,30 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5199
6173
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5200
6174
|
lowerer.unsupported("SC1090", expr, "require() outside the module's top level (move it to the top of the file)");
|
|
5201
6175
|
}
|
|
6176
|
+
// Replacing the export object (or rebinding `exports`) anywhere but a
|
|
6177
|
+
// top-level statement makes the module's exports depend on which path
|
|
6178
|
+
// ran (`cond ? module.exports = a : module.exports = b`, an
|
|
6179
|
+
// environment-dependent branch); the static export table has one shape.
|
|
6180
|
+
if (!topLevelJs &&
|
|
6181
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
6182
|
+
ts.isBinaryExpression(expr) &&
|
|
6183
|
+
expr.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
6184
|
+
(isCjsModuleExports(lowerer, expr.left) || isCjsExportsIdentifier(lowerer, expr.left))) {
|
|
6185
|
+
lowerer.unsupported("SC1090", expr.left, isCjsModuleExports(lowerer, expr.left)
|
|
6186
|
+
? "replacing module.exports outside a top-level statement (a conditional or environment-dependent export object)"
|
|
6187
|
+
: "rebinding 'exports' outside a top-level statement (a conditional or environment-dependent export object)");
|
|
6188
|
+
}
|
|
5202
6189
|
if (topLevelJs && ts.isExpressionStatement(stmtNode)) {
|
|
6190
|
+
if (isFreshExportsReset(lowerer, stmtNode))
|
|
6191
|
+
return { kind: "block", body: [], loc: locOf(expr) };
|
|
6192
|
+
// Any other `exports = …` rebinds the wrapper's exports binding: the
|
|
6193
|
+
// members later attached through it belong to the new value.
|
|
6194
|
+
if (ts.isBinaryExpression(expr) &&
|
|
6195
|
+
expr.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
6196
|
+
isCjsExportsIdentifier(lowerer, expr.left) &&
|
|
6197
|
+
cjsExportAssignmentOf(stmtNode)?.kind !== "table") {
|
|
6198
|
+
lowerer.unsupported("SC1090", expr.left, "rebinding 'exports' without module.exports (exports = value): members attached through 'exports' afterwards are properties of that value, which module.exports does not hold — write exports = module.exports = value");
|
|
6199
|
+
}
|
|
5203
6200
|
const cjs = cjsExportAssignmentOf(stmtNode);
|
|
5204
6201
|
if (cjs)
|
|
5205
6202
|
return lowerCjsExportStatement(lowerer, cjs);
|
|
@@ -5399,7 +6396,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5399
6396
|
}
|
|
5400
6397
|
else {
|
|
5401
6398
|
const recvT = lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression));
|
|
5402
|
-
|
|
6399
|
+
// A runtime-provided class (`Error.stackTraceLimit = 0`) keeps
|
|
6400
|
+
// its static lowering below.
|
|
6401
|
+
if (recvT?.kind === "classval" && !lowerer.classes.get(recvT.className)?.def.runtime) {
|
|
5403
6402
|
// A static write through a class VALUE: sound exactly when
|
|
5404
6403
|
// the value can only BE the declaring class — a LEAF class
|
|
5405
6404
|
// (no strict descendants can flow into the slot, so JS's
|
|
@@ -5499,9 +6498,12 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5499
6498
|
lowerer.stdlibGlobalMember(expr.left, "process") === "exitCode") {
|
|
5500
6499
|
const loc = locOf(expr);
|
|
5501
6500
|
const value = lowerer.lowerExprExpecting(expr.right, F64);
|
|
6501
|
+
const fn = programReadsExitCode(lowerer)
|
|
6502
|
+
? "process.setExitCodeTracked"
|
|
6503
|
+
: "process.setExitCode";
|
|
5502
6504
|
return {
|
|
5503
6505
|
kind: "exprStmt",
|
|
5504
|
-
expr: { kind: "libCall", fn
|
|
6506
|
+
expr: { kind: "libCall", fn, args: [value], type: VOID, loc },
|
|
5505
6507
|
loc,
|
|
5506
6508
|
};
|
|
5507
6509
|
}
|
|
@@ -5522,6 +6524,30 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5522
6524
|
loc,
|
|
5523
6525
|
};
|
|
5524
6526
|
}
|
|
6527
|
+
// process.emitWarning = fn: an ordinary writable property. Later
|
|
6528
|
+
// process.emitWarning(...) calls, and the warnings Node's own
|
|
6529
|
+
// modules emit through process.emitWarning, call the replacement
|
|
6530
|
+
// instead (silencing them when it does nothing).
|
|
6531
|
+
if (flag === "emitWarning") {
|
|
6532
|
+
const loc = locOf(expr);
|
|
6533
|
+
let rhs = expr.right;
|
|
6534
|
+
while (ts.isParenthesizedExpression(rhs) ||
|
|
6535
|
+
ts.isAsExpression(rhs) ||
|
|
6536
|
+
ts.isSatisfiesExpression(rhs))
|
|
6537
|
+
rhs = rhs.expression;
|
|
6538
|
+
const value = lowerer.lowerExprExpecting(rhs, DYN);
|
|
6539
|
+
return {
|
|
6540
|
+
kind: "exprStmt",
|
|
6541
|
+
expr: {
|
|
6542
|
+
kind: "libCall",
|
|
6543
|
+
fn: "process.setEmitWarning",
|
|
6544
|
+
args: [value],
|
|
6545
|
+
type: VOID,
|
|
6546
|
+
loc,
|
|
6547
|
+
},
|
|
6548
|
+
loc,
|
|
6549
|
+
};
|
|
6550
|
+
}
|
|
5525
6551
|
// process.title = name: libuv's uv_set_process_title (the
|
|
5526
6552
|
// runtime truncates to the original argument area on POSIX).
|
|
5527
6553
|
if (flag === "title") {
|
|
@@ -5586,7 +6612,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5586
6612
|
const recv = tryLowerExpression(lowerer, expr.left.expression);
|
|
5587
6613
|
if (recv &&
|
|
5588
6614
|
(recv.type.kind === "dyn" ||
|
|
5589
|
-
(isJsSourceFile(
|
|
6615
|
+
(isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
5590
6616
|
recv.type.kind === "union" &&
|
|
5591
6617
|
lowerer.dynConvertible(recv.type)))) {
|
|
5592
6618
|
const loc = locOf(expr);
|
|
@@ -5606,6 +6632,34 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5606
6632
|
loc,
|
|
5607
6633
|
};
|
|
5608
6634
|
}
|
|
6635
|
+
if (recv?.type.kind === "child" && isJsSourceFile(ts.getSourceFileOfNode(expr)))
|
|
6636
|
+
return lowerChildPropertyWrite(lowerer, recv, expr.left, expr.right, locOf(expr));
|
|
6637
|
+
// `err.code = v` on an Error value (`err as Error & { code?:
|
|
6638
|
+
// string }`): typed reads come from the runtime error's code
|
|
6639
|
+
// slot, so the write lands there. A value that is not statically
|
|
6640
|
+
// a string checks at runtime: strings take the slot, anything
|
|
6641
|
+
// else clears it and stays a dynamic own property. The
|
|
6642
|
+
// system-error members (errno, syscall, path, dest) read
|
|
6643
|
+
// through the checked-dynamic node and keep the dynamic write, as
|
|
6644
|
+
// do JavaScript files, whose reads use that node too.
|
|
6645
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
6646
|
+
recv?.type.kind === "object" &&
|
|
6647
|
+
lowerer.isErrorRootedClass(recv.type.className) &&
|
|
6648
|
+
expr.left.name.text === "code") {
|
|
6649
|
+
const loc = locOf(expr);
|
|
6650
|
+
const stringValue = isStringTyped(lowerer.typeOf(expr.right));
|
|
6651
|
+
return {
|
|
6652
|
+
kind: "exprStmt",
|
|
6653
|
+
expr: {
|
|
6654
|
+
kind: "libCall",
|
|
6655
|
+
fn: stringValue ? "error.setCode" : "error.setCodeDyn",
|
|
6656
|
+
args: [recv, lowerer.lowerExprExpecting(expr.right, stringValue ? STRING : DYN)],
|
|
6657
|
+
type: VOID,
|
|
6658
|
+
loc,
|
|
6659
|
+
},
|
|
6660
|
+
loc,
|
|
6661
|
+
};
|
|
6662
|
+
}
|
|
5609
6663
|
if (recv?.type.kind === "object" && recv.type.className === "%Error") {
|
|
5610
6664
|
const loc = locOf(expr);
|
|
5611
6665
|
return {
|
|
@@ -5657,6 +6711,25 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5657
6711
|
const recvIr = lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression));
|
|
5658
6712
|
if (recvIr?.kind === "record") {
|
|
5659
6713
|
const shape = lowerer.shapes.get(recvIr.shapeId);
|
|
6714
|
+
if (shape?.indexValue &&
|
|
6715
|
+
shape.fields.length === 0 &&
|
|
6716
|
+
declaredMemberOf(lowerer, expr.left.expression, expr.left.name.text)) {
|
|
6717
|
+
// A declared member of a literal stored as a pure index-signature
|
|
6718
|
+
// record (dictSpreadLiteralShape): a keyed write of that key.
|
|
6719
|
+
const loc = locOf(expr);
|
|
6720
|
+
const obj = lowerer.lowerExpr(expr.left.expression);
|
|
6721
|
+
if (obj.type.kind === "record") {
|
|
6722
|
+
const value = lowerer.intoIndexValueSlot(lowerer.lowerExprExpecting(expr.right, shape.indexValue), shape.indexValue, expr.right);
|
|
6723
|
+
return {
|
|
6724
|
+
kind: "recordKeySet",
|
|
6725
|
+
obj,
|
|
6726
|
+
shapeId: obj.type.shapeId,
|
|
6727
|
+
key: { kind: "strLit", value: expr.left.name.text, type: STRING, loc },
|
|
6728
|
+
value,
|
|
6729
|
+
loc,
|
|
6730
|
+
};
|
|
6731
|
+
}
|
|
6732
|
+
}
|
|
5660
6733
|
if (shape?.indexValue &&
|
|
5661
6734
|
!shape.fields.some((f) => f.name === expr.left.name.text)) {
|
|
5662
6735
|
lowerer.unsupported("SC1090", expr.left, `dot writes to index-signature keys (spell it r["${expr.left.name.text}"] = v — brackets are the index-signature form)`);
|
|
@@ -5673,6 +6746,19 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5673
6746
|
const parts = lowerDestructuringAssignParts(lowerer, expr.left, expr.right, locOf(expr));
|
|
5674
6747
|
return { kind: "block", body: parts.stmts, loc: locOf(expr) };
|
|
5675
6748
|
}
|
|
6749
|
+
// `exports.x = v` inside a function updates the member's export
|
|
6750
|
+
// global (cjs-exports-object.ts).
|
|
6751
|
+
if (ts.isPropertyAccessExpression(expr.left)) {
|
|
6752
|
+
const g = cjsExportMemberWriteGlobalOf(lowerer, expr.left);
|
|
6753
|
+
if (g) {
|
|
6754
|
+
return {
|
|
6755
|
+
kind: "assign",
|
|
6756
|
+
localId: g.id,
|
|
6757
|
+
value: lowerer.lowerExprExpecting(expr.right, g.type),
|
|
6758
|
+
loc: locOf(expr),
|
|
6759
|
+
};
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
5676
6762
|
if (!ts.isIdentifier(expr.left)) {
|
|
5677
6763
|
lowerer.unsupported("SC1090", expr.left, "assignment to non-variables");
|
|
5678
6764
|
}
|
|
@@ -5768,6 +6854,13 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5768
6854
|
if (droppedPureStdlibStatement(lowerer, expr)) {
|
|
5769
6855
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5770
6856
|
}
|
|
6857
|
+
if (stmtNode !== undefined &&
|
|
6858
|
+
ts.isExpressionStatement(stmtNode) &&
|
|
6859
|
+
ts.isBinaryExpression(expr) &&
|
|
6860
|
+
(expr.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
6861
|
+
expr.operatorToken.kind === ts.SyntaxKind.BarBarToken)) {
|
|
6862
|
+
return lowerDiscardedLogical(lowerer, expr);
|
|
6863
|
+
}
|
|
5771
6864
|
const value = lowerer.lowerExpr(expr);
|
|
5772
6865
|
// A bare unit-literal statement (`undefined;`): a pure no-op in JS,
|
|
5773
6866
|
// and the IR has no bare-unit VALUE outside a union wrap — drop it
|
|
@@ -5776,6 +6869,55 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5776
6869
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5777
6870
|
return { kind: "exprStmt", expr: value, loc: locOf(expr) };
|
|
5778
6871
|
}
|
|
6872
|
+
/** A discarded `a && b` / `a || b` statement (the minifier's `if`). The
|
|
6873
|
+
* value form lowers first, exactly as before. Only when it fails on the
|
|
6874
|
+
* logical's own result type — the operands have no common representation
|
|
6875
|
+
* (jose's `(!m || m[4] && m[1]) && invalid()` joins a boolean, a string
|
|
6876
|
+
* and undefined into the checker's `string`) — does the statement lower
|
|
6877
|
+
* as the control flow it is: `if (a) b;` / `if (!a) b;`, a condition test
|
|
6878
|
+
* that needs no result value. Diagnostics outside the statement, and
|
|
6879
|
+
* internal errors, keep the original failure. */
|
|
6880
|
+
function lowerDiscardedLogical(lowerer, expr) {
|
|
6881
|
+
const diagsBefore = lowerer.diags.length;
|
|
6882
|
+
try {
|
|
6883
|
+
const value = lowerer.lowerExpr(expr);
|
|
6884
|
+
if (value.kind === "unitLit")
|
|
6885
|
+
return { kind: "block", body: [], loc: locOf(expr) };
|
|
6886
|
+
return { kind: "exprStmt", expr: value, loc: locOf(expr) };
|
|
6887
|
+
}
|
|
6888
|
+
catch (e) {
|
|
6889
|
+
// A probe (a capture buffer is active) keeps its failure: its owner
|
|
6890
|
+
// picks another lowering, exactly as before.
|
|
6891
|
+
if (!(e instanceof PoisonError) || lowerer.diagSink !== null)
|
|
6892
|
+
throw e;
|
|
6893
|
+
const added = lowerer.diags.slice(diagsBefore);
|
|
6894
|
+
const file = ts.getSourceFileOfNode(expr).fileName;
|
|
6895
|
+
const start = ts.tokenStartOfNode(expr);
|
|
6896
|
+
const local = added.length > 0 &&
|
|
6897
|
+
added.every((d) => d.code !== "SC9001" &&
|
|
6898
|
+
d.loc.file === file &&
|
|
6899
|
+
d.loc.start >= start &&
|
|
6900
|
+
d.loc.end <= expr.end);
|
|
6901
|
+
if (!local)
|
|
6902
|
+
throw e;
|
|
6903
|
+
lowerer.diags.length = diagsBefore;
|
|
6904
|
+
}
|
|
6905
|
+
const and = expr.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken;
|
|
6906
|
+
const cond = lowerer.lowerCondition(expr.left);
|
|
6907
|
+
if (cond.kind === "boolLit") {
|
|
6908
|
+
return cond.value === and
|
|
6909
|
+
? lowerExprStatement(lowerer, expr.right)
|
|
6910
|
+
: { kind: "block", body: [], loc: locOf(expr) };
|
|
6911
|
+
}
|
|
6912
|
+
const right = () => lowerer.narrowingAliases(aliasTypeofNarrows(lowerer, expr.left, and), () => and
|
|
6913
|
+
? withRuntimeOptionalNarrowed(lowerer, runtimeOptionalTrueIds(lowerer, expr.left), () => [
|
|
6914
|
+
lowerExprStatement(lowerer, expr.right),
|
|
6915
|
+
])
|
|
6916
|
+
: [lowerExprStatement(lowerer, expr.right)]);
|
|
6917
|
+
return and
|
|
6918
|
+
? { kind: "if", cond, then: right(), else_: [], loc: locOf(expr) }
|
|
6919
|
+
: { kind: "if", cond, then: [], else_: right(), loc: locOf(expr) };
|
|
6920
|
+
}
|
|
5779
6921
|
/** True for a statement-position expression whose evaluation cannot be
|
|
5780
6922
|
* observed once the value is discarded:
|
|
5781
6923
|
* - a property/element READ (`?.` included) whose receiver IS a
|
|
@@ -5809,7 +6951,7 @@ function droppedPureStdlibStatement(lowerer, expr) {
|
|
|
5809
6951
|
const root = stdlibGlobalNameOf(lowerer, strip(proto.expression));
|
|
5810
6952
|
if (root !== "Array" && root !== "String")
|
|
5811
6953
|
return false;
|
|
5812
|
-
return expr.arguments.every((a) => sideEffectFreeOptionValue(a));
|
|
6954
|
+
return expr.arguments.nodes.every((a) => sideEffectFreeOptionValue(a));
|
|
5813
6955
|
}
|
|
5814
6956
|
if (ts.isPropertyAccessExpression(expr)) {
|
|
5815
6957
|
return stdlibGlobalNameOf(lowerer, strip(expr.expression)) !== null;
|
|
@@ -5877,18 +7019,46 @@ export function lowerDestructuringAssign(lowerer, target, init, blame, loc) {
|
|
|
5877
7019
|
}
|
|
5878
7020
|
/** V8's spelling of a destructuring RHS in its TypeError message
|
|
5879
7021
|
* ("Cannot destructure 'a' as it is undefined.") — plain identifiers
|
|
5880
|
-
* spell their name (parens unwrap),
|
|
5881
|
-
*
|
|
7022
|
+
* spell their name (parens unwrap), `this`, property chains and
|
|
7023
|
+
* identifier or numeric element reads spell their source, awaited and
|
|
7024
|
+
* yielded values spell "(intermediate value)", and calls append an
|
|
7025
|
+
* ellipsis to a supported callee spelling. Other CallPrinter forms keep
|
|
7026
|
+
* a fence. */
|
|
5882
7027
|
function destrSpellingOf(rhs) {
|
|
5883
7028
|
let e = rhs;
|
|
5884
|
-
|
|
7029
|
+
// Parentheses and the type-only wrappers are not part of the emitted
|
|
7030
|
+
// JavaScript expression V8 prints.
|
|
7031
|
+
while (ts.isParenthesizedExpression(e) ||
|
|
7032
|
+
ts.isAsExpression(e) ||
|
|
7033
|
+
ts.isSatisfiesExpression(e) ||
|
|
7034
|
+
ts.isTypeAssertion(e) ||
|
|
7035
|
+
ts.isNonNullExpression(e)) {
|
|
5885
7036
|
e = e.expression;
|
|
7037
|
+
}
|
|
5886
7038
|
if (ts.isIdentifier(e))
|
|
5887
7039
|
return e.text;
|
|
7040
|
+
if (e.kind === ts.SyntaxKind.ThisKeyword)
|
|
7041
|
+
return "this";
|
|
7042
|
+
// V8 prints an awaited or yielded operand as "(intermediate value)".
|
|
7043
|
+
if (ts.isAwaitExpression(e) || ts.isYieldExpression(e))
|
|
7044
|
+
return "(intermediate value)";
|
|
5888
7045
|
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken) {
|
|
5889
7046
|
const base = destrSpellingOf(e.expression);
|
|
5890
7047
|
return base === null ? null : `${base}.${e.name.text}`;
|
|
5891
7048
|
}
|
|
7049
|
+
// `table[key]` and `list[0]`; V8 prints a numeric key in its canonical
|
|
7050
|
+
// number form (`o[1.50]` reads "o[1.5]").
|
|
7051
|
+
if (ts.isElementAccessExpression(e) && !e.questionDotToken) {
|
|
7052
|
+
const base = destrSpellingOf(e.expression);
|
|
7053
|
+
const key = e.argumentExpression;
|
|
7054
|
+
if (base === null)
|
|
7055
|
+
return null;
|
|
7056
|
+
if (ts.isIdentifier(key))
|
|
7057
|
+
return `${base}[${key.text}]`;
|
|
7058
|
+
if (ts.isNumericLiteral(key))
|
|
7059
|
+
return `${base}[${String(Number(key.text))}]`;
|
|
7060
|
+
return null;
|
|
7061
|
+
}
|
|
5892
7062
|
if (ts.isCallExpression(e) && !e.questionDotToken) {
|
|
5893
7063
|
const callee = destrSpellingOf(e.expression);
|
|
5894
7064
|
return callee === null ? null : `${callee}(...)`;
|
|
@@ -5953,9 +7123,9 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5953
7123
|
// globals and strings alike).
|
|
5954
7124
|
{
|
|
5955
7125
|
const patternEmpty = ts.isObjectLiteralExpression(target)
|
|
5956
|
-
? target.properties.length === 0
|
|
5957
|
-
: target.elements.length === 0;
|
|
5958
|
-
if (!patternEmpty && rhs !== null && isJsSourceFile(
|
|
7126
|
+
? target.properties.nodes.length === 0
|
|
7127
|
+
: target.elements.nodes.length === 0;
|
|
7128
|
+
if (!patternEmpty && rhs !== null && isJsSourceFile(ts.getSourceFileOfNode(rhs))) {
|
|
5959
7129
|
const globalName = stdlibGlobalNameOf(lowerer, rhs);
|
|
5960
7130
|
if (globalName !== null) {
|
|
5961
7131
|
lowerer.unsupported("SC1031", blame, `destructuring assignment from the builtin global '${globalName}' (bind the members with a const destructuring declaration instead)`);
|
|
@@ -5996,7 +7166,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5996
7166
|
lowerer.unsupported("SC1031", blame, "destructuring assignment from a checked-dynamic source whose expression spelling is unsupported (use a variable, ordinary property chain, or ordinary call)");
|
|
5997
7167
|
}
|
|
5998
7168
|
let firstProp;
|
|
5999
|
-
const p0 = target.properties[0];
|
|
7169
|
+
const p0 = target.properties.nodes[0];
|
|
6000
7170
|
if (p0 !== undefined) {
|
|
6001
7171
|
if (ts.isShorthandPropertyAssignment(p0))
|
|
6002
7172
|
firstProp = p0.name.text;
|
|
@@ -6020,7 +7190,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6020
7190
|
loc,
|
|
6021
7191
|
});
|
|
6022
7192
|
}
|
|
6023
|
-
for (const prop of target.properties) {
|
|
7193
|
+
for (const prop of target.properties.nodes) {
|
|
6024
7194
|
const piece = destructAssignPiece(lowerer, prop);
|
|
6025
7195
|
const read = {
|
|
6026
7196
|
kind: "dynKeyGet",
|
|
@@ -6038,7 +7208,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6038
7208
|
}
|
|
6039
7209
|
return { stmts: out, value };
|
|
6040
7210
|
}
|
|
6041
|
-
if (target.properties.length === 0) {
|
|
7211
|
+
if (target.properties.nodes.length === 0) {
|
|
6042
7212
|
// `({} = e)`: RequireObjectCoercible and nothing else. A source the
|
|
6043
7213
|
// type system already proves non-nullish is a pure no-op past the
|
|
6044
7214
|
// RHS's own evaluation; possibly-nullish unions would throw in JS
|
|
@@ -6063,14 +7233,14 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6063
7233
|
lowerer.flushDeferredClass(objT.className);
|
|
6064
7234
|
const info = lowerer.classes.get(objT.className);
|
|
6065
7235
|
if (info) {
|
|
6066
|
-
for (const prop of target.properties) {
|
|
7236
|
+
for (const prop of target.properties.nodes) {
|
|
6067
7237
|
const propLoc = locOf(prop);
|
|
6068
7238
|
if (ts.isSpreadAssignment(prop)) {
|
|
6069
7239
|
let restTo = prop.expression;
|
|
6070
7240
|
while (ts.isParenthesizedExpression(restTo))
|
|
6071
7241
|
restTo = restTo.expression;
|
|
6072
7242
|
const consumed = new Set();
|
|
6073
|
-
for (const p of target.properties) {
|
|
7243
|
+
for (const p of target.properties.nodes) {
|
|
6074
7244
|
if (ts.isShorthandPropertyAssignment(p))
|
|
6075
7245
|
consumed.add(p.name.text);
|
|
6076
7246
|
else if (ts.isPropertyAssignment(p)) {
|
|
@@ -6184,7 +7354,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6184
7354
|
// properties keep the declaration path's named fences. Callers vetted
|
|
6185
7355
|
// the source as a checker-typed string.
|
|
6186
7356
|
if (init.type.kind === "string") {
|
|
6187
|
-
for (const prop of target.properties) {
|
|
7357
|
+
for (const prop of target.properties.nodes) {
|
|
6188
7358
|
const propLoc = locOf(prop);
|
|
6189
7359
|
if (ts.isSpreadAssignment(prop)) {
|
|
6190
7360
|
lowerer.unsupported("SC1031", prop, "rest bindings over string sources (JS packs the wrapper's per-code-unit indices — split with [...s] instead)");
|
|
@@ -6246,7 +7416,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6246
7416
|
const shape = lowerer.shapes.get(srcType.shapeId);
|
|
6247
7417
|
if (!shape)
|
|
6248
7418
|
throw new InternalCompilerError(`lowerer bug: destructuring unknown shape ${srcType.shapeId}`);
|
|
6249
|
-
for (const prop of target.properties) {
|
|
7419
|
+
for (const prop of target.properties.nodes) {
|
|
6250
7420
|
// Shorthand `{ a }` assigns local a from field a; `{ a: x }` assigns
|
|
6251
7421
|
// x from field a (a PropertyAssignment whose initializer is the
|
|
6252
7422
|
// target — JS reuses the literal syntax with inverted roles).
|
|
@@ -6263,7 +7433,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6263
7433
|
lowerer.unsupported("SC1031", prop, "rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
|
|
6264
7434
|
}
|
|
6265
7435
|
const consumed = new Set();
|
|
6266
|
-
for (const p of target.properties) {
|
|
7436
|
+
for (const p of target.properties.nodes) {
|
|
6267
7437
|
if (ts.isShorthandPropertyAssignment(p))
|
|
6268
7438
|
consumed.add(p.name.text);
|
|
6269
7439
|
else if (ts.isPropertyAssignment(p)) {
|
|
@@ -6278,7 +7448,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6278
7448
|
if (restOrder !== undefined) {
|
|
6279
7449
|
lowerer.shapeOrderMetadataFinalizers.push(lowerer.shapes.declaredOrderFinalizer(restShapeId, restOrder, () => lowerer.shapes.get(srcType.shapeId)?.declaredOrder?.filter((n) => !consumed.has(n))));
|
|
6280
7450
|
}
|
|
6281
|
-
const packed = {
|
|
7451
|
+
const packed = lowerer.keyOrder.copy({
|
|
6282
7452
|
kind: "recordLit",
|
|
6283
7453
|
fields: remaining.map((f) => ({
|
|
6284
7454
|
name: f.name,
|
|
@@ -6293,7 +7463,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6293
7463
|
})),
|
|
6294
7464
|
type: { kind: "record", shapeId: restShapeId },
|
|
6295
7465
|
loc: locOf(prop),
|
|
6296
|
-
};
|
|
7466
|
+
}, srcType.shapeId);
|
|
6297
7467
|
if (!ts.isIdentifier(restTo)) {
|
|
6298
7468
|
// `({ a, ...box.rest } = src)` — the rest packs identically and
|
|
6299
7469
|
// lands through the property/element write machinery.
|
|
@@ -6439,7 +7609,7 @@ function lowerAssignTargetInto(lowerer, out, targetNode, blame, dflt, valueOf) {
|
|
|
6439
7609
|
if (arr.type.kind === "array") {
|
|
6440
7610
|
const recv = lowerer.declareHiddenLocal("%dtRecv", arr.type);
|
|
6441
7611
|
out.push({ kind: "varDecl", localId: recv.id, init: arr, loc });
|
|
6442
|
-
const index = lowerer.lowerExpr(t.argumentExpression);
|
|
7612
|
+
const index = lowerOptionalNumber(lowerer, lowerer.lowerExpr(t.argumentExpression), locOf(t.argumentExpression), t.argumentExpression);
|
|
6443
7613
|
if (index.type.kind !== "f64") {
|
|
6444
7614
|
lowerer.unsupported("SC1090", t.argumentExpression, "indexing with non-number keys");
|
|
6445
7615
|
}
|
|
@@ -6452,6 +7622,30 @@ function lowerAssignTargetInto(lowerer, out, targetNode, blame, dflt, valueOf) {
|
|
|
6452
7622
|
return;
|
|
6453
7623
|
}
|
|
6454
7624
|
}
|
|
7625
|
+
else if (recvT?.kind === "bytes") {
|
|
7626
|
+
// A typed-array element (`[a[i], b[i]] = [h, l]`): the receiver, then
|
|
7627
|
+
// the index, then the value, as the plain element write `b[i] = v`
|
|
7628
|
+
// stores it (an f64 the runtime coerces; invalid indices are ignored).
|
|
7629
|
+
const arr = lowerer.lowerExpr(t.expression);
|
|
7630
|
+
if (arr.type.kind === "bytes") {
|
|
7631
|
+
const recv = lowerer.declareHiddenLocal("%dtRecv", arr.type);
|
|
7632
|
+
out.push({ kind: "varDecl", localId: recv.id, init: arr, loc });
|
|
7633
|
+
const index = lowerer.lowerExpr(t.argumentExpression);
|
|
7634
|
+
if (index.type.kind !== "f64") {
|
|
7635
|
+
lowerer.unsupported("SC1090", t.argumentExpression, "indexing with non-number keys");
|
|
7636
|
+
}
|
|
7637
|
+
const idx = lowerer.declareHiddenLocal("%dtIdx", F64);
|
|
7638
|
+
out.push({ kind: "varDecl", localId: idx.id, init: index, loc });
|
|
7639
|
+
out.push({
|
|
7640
|
+
kind: "bytesSet",
|
|
7641
|
+
arr: varRef(recv.id, arr.type, loc),
|
|
7642
|
+
index: varRef(idx.id, F64, loc),
|
|
7643
|
+
value: lowerer.coerceInto(blame, valueOf(F64), F64),
|
|
7644
|
+
loc,
|
|
7645
|
+
});
|
|
7646
|
+
return;
|
|
7647
|
+
}
|
|
7648
|
+
}
|
|
6455
7649
|
else if (recvT?.kind === "record") {
|
|
6456
7650
|
// Tuple positions and LITERAL declared record keys are field
|
|
6457
7651
|
// writes (the element-write lowering's own rule); runtime keys
|
|
@@ -6538,7 +7732,7 @@ function lowerArrayAssignInto(lowerer, out, target, tmpRef, blame, loc) {
|
|
|
6538
7732
|
// array divergence). The EMPTY pattern skips the split — GetIterator
|
|
6539
7733
|
// + close, nothing observable — through the iterable early-return
|
|
6540
7734
|
// below. Callers vetted the source as a checker-typed string.
|
|
6541
|
-
if (srcType.kind === "string" && target.elements.length > 0) {
|
|
7735
|
+
if (srcType.kind === "string" && target.elements.nodes.length > 0) {
|
|
6542
7736
|
const charsT = arrayOf(STRING);
|
|
6543
7737
|
const chars = lowerer.declareHiddenLocal("%dchars", charsT);
|
|
6544
7738
|
out.push({
|
|
@@ -6556,11 +7750,11 @@ function lowerArrayAssignInto(lowerer, out, target, tmpRef, blame, loc) {
|
|
|
6556
7750
|
// consumes exactly the elements the inner pattern alone would, so the
|
|
6557
7751
|
// unwrap is exact. Identifier rest operands pack in the element loop
|
|
6558
7752
|
// below.
|
|
6559
|
-
let elements = target.elements;
|
|
7753
|
+
let elements = target.elements.nodes;
|
|
6560
7754
|
if (elements.length === 1 &&
|
|
6561
7755
|
ts.isSpreadElement(elements[0]) &&
|
|
6562
7756
|
ts.isArrayLiteralExpression(elements[0].expression)) {
|
|
6563
|
-
elements = elements[0].expression.elements;
|
|
7757
|
+
elements = elements[0].expression.elements.nodes;
|
|
6564
7758
|
}
|
|
6565
7759
|
// The element-read builder per source kind; null when the source
|
|
6566
7760
|
// cannot destructure.
|
|
@@ -6753,6 +7947,14 @@ function lowerArrayAssignInto(lowerer, out, target, tmpRef, blame, loc) {
|
|
|
6753
7947
|
* specific diagnostics; other iterables fail on their types. The loop
|
|
6754
7948
|
* variable is a fresh const binding per iteration (its own scope, like a
|
|
6755
7949
|
* loop body). */
|
|
7950
|
+
/** Whether a `for await` head is untyped: the checker answers any or
|
|
7951
|
+
* unknown, or a type that maps to a checked-dynamic value. */
|
|
7952
|
+
function isUntypedIterable(lowerer, node) {
|
|
7953
|
+
const type = lowerer.typeOf(node);
|
|
7954
|
+
if ((type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)
|
|
7955
|
+
return true;
|
|
7956
|
+
return lowerer.mapTypeOf(type)?.kind === "dyn";
|
|
7957
|
+
}
|
|
6756
7958
|
export function lowerForOf(lowerer, stmt) {
|
|
6757
7959
|
// Labels consume HERE (nested statements must never see them). The
|
|
6758
7960
|
// plain array/string paths carry them; the container/matchAll/stdin
|
|
@@ -6787,13 +7989,43 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6787
7989
|
}
|
|
6788
7990
|
}
|
|
6789
7991
|
}
|
|
7992
|
+
{
|
|
7993
|
+
const opened = classAsyncGeneratorIterator(lowerer, stmt.expression);
|
|
7994
|
+
if (opened)
|
|
7995
|
+
return lowerForAwaitGenerator(lowerer, stmt, opened, labels);
|
|
7996
|
+
}
|
|
6790
7997
|
if (ts.isPropertyAccessExpression(stmt.expression) &&
|
|
6791
7998
|
lowerer.stdlibGlobalMember(stmt.expression, "process") === "stdin") {
|
|
6792
7999
|
return lowerForAwaitStdin(lowerer, stmt);
|
|
6793
8000
|
}
|
|
8001
|
+
// A checked-dynamic NodeJS.ReadableStream iterates its native stream.
|
|
8002
|
+
const dynStream = lowerForAwaitDynStream(lowerer, stmt, () => lowerForAwaitBuiltin(lowerer, stmt));
|
|
8003
|
+
if (dynStream)
|
|
8004
|
+
return dynStream;
|
|
6794
8005
|
const builtin = lowerForAwaitBuiltin(lowerer, stmt);
|
|
6795
8006
|
if (builtin)
|
|
6796
8007
|
return builtin;
|
|
8008
|
+
// An untyped value (a JavaScript async generator whose recursive
|
|
8009
|
+
// return the checker types `any`): a compiled async generator steps
|
|
8010
|
+
// natively; any other value takes the checked-dynamic async protocol.
|
|
8011
|
+
// A synchronous generator, and in JavaScript any other head that
|
|
8012
|
+
// reaches here, takes the same protocol: values of a synchronous
|
|
8013
|
+
// iterator are awaited as the async-from-sync iterator awaits them, and
|
|
8014
|
+
// a value that is not iterable throws Node's TypeError.
|
|
8015
|
+
const headT = lowerer.mapTypeOf(lowerer.typeOf(stmt.expression));
|
|
8016
|
+
const syncGenerator = (headT?.kind === "generator" && headT.async !== true) || isJsSourceFile(stmt.getSourceFile());
|
|
8017
|
+
if (lowerer.ctx.isAsync && (syncGenerator || isUntypedIterable(lowerer, stmt.expression))) {
|
|
8018
|
+
const iterable = lowerer.lowerExpr(stmt.expression);
|
|
8019
|
+
if (iterable.type.kind === "generator" && iterable.type.async)
|
|
8020
|
+
return lowerForAwaitGenerator(lowerer, stmt, iterable, labels);
|
|
8021
|
+
if (iterable.type.kind === "dyn")
|
|
8022
|
+
return lowerForOfDyn(lowerer, stmt, iterable, labels, true);
|
|
8023
|
+
if ((iterable.type.kind === "generator" || isJsSourceFile(stmt.getSourceFile())) &&
|
|
8024
|
+
lowerer.dynConvertible(iterable.type))
|
|
8025
|
+
return lowerForOfDyn(lowerer, stmt, lowerer.coerceToExpected(iterable, DYN), labels, true);
|
|
8026
|
+
}
|
|
8027
|
+
// A NodeJS.ReadableStream iterates as the general Readable.
|
|
8028
|
+
requestGeneralStreamSurface(lowerer, stmt.expression);
|
|
6797
8029
|
lowerer.unsupported("SC1070", stmt, "'for await' over this value (supported: typed async generators, represented class async iterators, process.stdin, and Node/Web readable streams)");
|
|
6798
8030
|
}
|
|
6799
8031
|
if (awaitArray && !lowerer.ctx.isAsync) {
|
|
@@ -6816,6 +8048,13 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6816
8048
|
}
|
|
6817
8049
|
}
|
|
6818
8050
|
}
|
|
8051
|
+
// A head that is a chain of iterator-helper stages runs as one loop
|
|
8052
|
+
// over the chain's source.
|
|
8053
|
+
{
|
|
8054
|
+
const fused = lowerForOfHelperChain(lowerer, stmt, labels);
|
|
8055
|
+
if (fused)
|
|
8056
|
+
return fused;
|
|
8057
|
+
}
|
|
6819
8058
|
// `for (const k of m.keys())` / `.values()` / `.entries()`: the
|
|
6820
8059
|
// iterator methods consumed DIRECTLY by a for-of head ride the
|
|
6821
8060
|
// container's live walk — exactly `for..of m` with the projection
|
|
@@ -6828,7 +8067,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6828
8067
|
while (ts.isParenthesizedExpression(src))
|
|
6829
8068
|
src = src.expression;
|
|
6830
8069
|
if (ts.isCallExpression(src) &&
|
|
6831
|
-
src.arguments.length === 0 &&
|
|
8070
|
+
src.arguments.nodes.length === 0 &&
|
|
6832
8071
|
!src.questionDotToken &&
|
|
6833
8072
|
ts.isPropertyAccessExpression(src.expression) &&
|
|
6834
8073
|
!src.expression.questionDotToken &&
|
|
@@ -6886,7 +8125,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6886
8125
|
src = src.expression;
|
|
6887
8126
|
const constIdentBinding = ts.isVariableDeclarationList(stmt.initializer) &&
|
|
6888
8127
|
(stmt.initializer.flags & ts.NodeFlags.Const) !== 0 &&
|
|
6889
|
-
ts.isIdentifier(stmt.initializer.declarations[0].name);
|
|
8128
|
+
ts.isIdentifier(stmt.initializer.declarations.nodes[0].name);
|
|
6890
8129
|
if (constIdentBinding) {
|
|
6891
8130
|
const call = directMatchAllCallOf(lowerer, src);
|
|
6892
8131
|
if (call)
|
|
@@ -6918,7 +8157,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6918
8157
|
e = e.expression;
|
|
6919
8158
|
if (ts.isCallExpression(e) &&
|
|
6920
8159
|
!e.questionDotToken &&
|
|
6921
|
-
e.arguments.length === 0 &&
|
|
8160
|
+
e.arguments.nodes.length === 0 &&
|
|
6922
8161
|
ts.isPropertyAccessExpression(e.expression) &&
|
|
6923
8162
|
!e.expression.questionDotToken &&
|
|
6924
8163
|
e.expression.name.text === "values" &&
|
|
@@ -6992,6 +8231,11 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6992
8231
|
return lowerForOfGenerator(lowerer, stmt, iterable, labels);
|
|
6993
8232
|
}
|
|
6994
8233
|
if (iterable.type.kind === "object") {
|
|
8234
|
+
// A [Symbol.iterator] generator method: the loop drives the
|
|
8235
|
+
// generator it returns.
|
|
8236
|
+
const generator = classGeneratorIterable(lowerer, iterable);
|
|
8237
|
+
if (generator)
|
|
8238
|
+
return lowerForOfGenerator(lowerer, stmt, generator, labels);
|
|
6995
8239
|
// Class iterables ([Symbol.iterator]() + next() — classIteratorOf)
|
|
6996
8240
|
// drive the same protocol with ordinary method calls.
|
|
6997
8241
|
const cit = lowerer.classIteratorOf(iterable.type);
|
|
@@ -7038,9 +8282,11 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
7038
8282
|
}
|
|
7039
8283
|
// A CHECKED-DYNAMIC iterable (`unknown[]`, the collapsed
|
|
7040
8284
|
// `(string | object)[]`, JSON-parsed values): a checked IteratorRecord
|
|
7041
|
-
// binds each yielded dyn value.
|
|
8285
|
+
// binds each yielded dyn value. Under `for await` (a JavaScript array
|
|
8286
|
+
// literal mixing promises and plain values) the async-from-sync rules
|
|
8287
|
+
// await each value.
|
|
7042
8288
|
if (iterable.type.kind === "dyn") {
|
|
7043
|
-
return lowerForOfDyn(lowerer, stmt, iterable, labels);
|
|
8289
|
+
return lowerForOfDyn(lowerer, stmt, iterable, labels, stmt.awaitModifier !== undefined);
|
|
7044
8290
|
}
|
|
7045
8291
|
if (tupleSource === null) {
|
|
7046
8292
|
lowerer.badType(stmt.expression, lowerer.typeOf(stmt.expression));
|
|
@@ -7376,7 +8622,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
7376
8622
|
const list = stmt.initializer;
|
|
7377
8623
|
const resourceLoop = (list.flags & ts.NodeFlags.Using) !== 0;
|
|
7378
8624
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
7379
|
-
const decl = list.declarations[0]; // the grammar allows exactly one
|
|
8625
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
7380
8626
|
// `for (const [k, v] of pairs)` — a destructuring loop variable: the
|
|
7381
8627
|
// element binds to a hidden per-iteration local and the pattern
|
|
7382
8628
|
// desugars to reads of it at the top of the body, exactly the
|
|
@@ -7406,7 +8652,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
7406
8652
|
// local and the body opens by ASSIGNING it into the one hoisted
|
|
7407
8653
|
// binding — closures capture the shared slot, and the value persists
|
|
7408
8654
|
// after the loop (both Node-exact for var).
|
|
7409
|
-
const varTarget = forOfVarTarget(lowerer, decl);
|
|
8655
|
+
const varTarget = forOfVarTarget(lowerer, decl, elemValueT);
|
|
7410
8656
|
if (varTarget) {
|
|
7411
8657
|
const elemType = elemValueT;
|
|
7412
8658
|
const loc = locOf(decl.name);
|
|
@@ -7523,7 +8769,7 @@ function lowerForOfStoredNumericIterator(lowerer, stmt, state, labels) {
|
|
|
7523
8769
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
7524
8770
|
}
|
|
7525
8771
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
7526
|
-
const decl = list ? list.declarations[0] : null;
|
|
8772
|
+
const decl = list ? list.declarations.nodes[0] : null;
|
|
7527
8773
|
if (decl && !ts.isIdentifier(decl.name))
|
|
7528
8774
|
lowerer.unsupported("SC1031", decl.name);
|
|
7529
8775
|
const loc = locOf(stmt);
|
|
@@ -7651,13 +8897,13 @@ function directMatchAllCallOf(lowerer, e) {
|
|
|
7651
8897
|
src = src.expression;
|
|
7652
8898
|
if (ts.isCallExpression(src) &&
|
|
7653
8899
|
!src.questionDotToken &&
|
|
7654
|
-
src.arguments.length === 1 &&
|
|
8900
|
+
src.arguments.nodes.length === 1 &&
|
|
7655
8901
|
ts.isPropertyAccessExpression(src.expression) &&
|
|
7656
8902
|
!src.expression.questionDotToken &&
|
|
7657
8903
|
src.expression.name.text === "matchAll" &&
|
|
7658
8904
|
lowerer.isStdlibMember(src.expression) &&
|
|
7659
8905
|
lowerer.mapTypeOf(lowerer.typeOf(src.expression.expression))?.kind === "string" &&
|
|
7660
|
-
lowerer.mapTypeOf(lowerer.typeOf(src.arguments[0]))?.kind === "regex") {
|
|
8906
|
+
lowerer.mapTypeOf(lowerer.typeOf(src.arguments.nodes[0]))?.kind === "regex") {
|
|
7661
8907
|
return src;
|
|
7662
8908
|
}
|
|
7663
8909
|
return null;
|
|
@@ -7682,7 +8928,7 @@ function directMatchAllCallOf(lowerer, e) {
|
|
|
7682
8928
|
*/
|
|
7683
8929
|
function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
7684
8930
|
const list = stmt.initializer;
|
|
7685
|
-
const decl = list.declarations[0];
|
|
8931
|
+
const decl = list.declarations.nodes[0];
|
|
7686
8932
|
const name = decl.name;
|
|
7687
8933
|
const loc = locOf(stmt);
|
|
7688
8934
|
const rowT = arrayOf(STRING);
|
|
@@ -7696,7 +8942,7 @@ function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
|
7696
8942
|
if (call !== null) {
|
|
7697
8943
|
const access = call.expression;
|
|
7698
8944
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
7699
|
-
const re = lowerer.lowerExpr(call.arguments[0]);
|
|
8945
|
+
const re = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
7700
8946
|
const idxs = lowerer.declareHiddenLocal("%midxs", idxsT);
|
|
7701
8947
|
idxsLocalId = idxs.id;
|
|
7702
8948
|
prelude.push({
|
|
@@ -7707,7 +8953,9 @@ function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
|
7707
8953
|
});
|
|
7708
8954
|
rowsInit = {
|
|
7709
8955
|
kind: "regexIntrinsic",
|
|
7710
|
-
method:
|
|
8956
|
+
method: matchAllRowsReadByElements(lowerer, call, true)
|
|
8957
|
+
? "matchAllCapturesInto"
|
|
8958
|
+
: "matchAllInto",
|
|
7711
8959
|
receiver,
|
|
7712
8960
|
args: [re, { kind: "varRef", localId: idxs.id, type: idxsT, loc }],
|
|
7713
8961
|
type: rowsT,
|
|
@@ -7846,7 +9094,7 @@ function lowerForOfClassIterator(lowerer, stmt, iterable, cit, labels) {
|
|
|
7846
9094
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
7847
9095
|
}
|
|
7848
9096
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
7849
|
-
const decl = list ? list.declarations[0] : null;
|
|
9097
|
+
const decl = list ? list.declarations.nodes[0] : null;
|
|
7850
9098
|
if (decl && !ts.isIdentifier(decl.name))
|
|
7851
9099
|
lowerer.unsupported("SC1031", decl.name);
|
|
7852
9100
|
const loc = locOf(stmt);
|
|
@@ -7942,24 +9190,9 @@ function lowerForOfClassIterator(lowerer, stmt, iterable, cit, labels) {
|
|
|
7942
9190
|
/** A checked IteratorRecord stays live throughout the loop. Cache next once,
|
|
7943
9191
|
* read done before value, and close only after a yielded value has arrived.
|
|
7944
9192
|
* Abrupt body throws retain precedence over errors raised by return(). */
|
|
7945
|
-
function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
9193
|
+
function lowerForOfDyn(lowerer, stmt, iterable, labels, asyncLoop = false) {
|
|
7946
9194
|
const loc = locOf(stmt);
|
|
7947
|
-
const
|
|
7948
|
-
if (ts.isIdentifier(e))
|
|
7949
|
-
return e.text;
|
|
7950
|
-
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken && ts.isIdentifier(e.name)) {
|
|
7951
|
-
const base = headText(e.expression);
|
|
7952
|
-
return base === null ? null : `${base}.${e.name.text}`;
|
|
7953
|
-
}
|
|
7954
|
-
return null;
|
|
7955
|
-
};
|
|
7956
|
-
const name = headText(stmt.expression);
|
|
7957
|
-
const callee = ts.isCallExpression(stmt.expression) ? headText(stmt.expression.expression) : null;
|
|
7958
|
-
const spell = name !== null
|
|
7959
|
-
? `${name} is not iterable`
|
|
7960
|
-
: callee !== null
|
|
7961
|
-
? `${callee} is not a function or its return value is not iterable`
|
|
7962
|
-
: "";
|
|
9195
|
+
const spell = notIterableSpelling(stmt.expression, asyncLoop ? "async iterable" : "iterable");
|
|
7963
9196
|
const iterator = lowerer.declareHiddenLocal("%dofIterator", DYN);
|
|
7964
9197
|
const next = lowerer.declareHiddenLocal("%dofNext", DYN);
|
|
7965
9198
|
const fast = lowerer.declareHiddenLocal("%dofNative", BOOL);
|
|
@@ -7970,6 +9203,14 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
7970
9203
|
const needsClose = lowerer.declareHiddenLocal("%dofNeedsClose", BOOL);
|
|
7971
9204
|
needsClose.mutable = true;
|
|
7972
9205
|
const error = lowerer.declareHiddenLocal("%dofError", CAUGHT);
|
|
9206
|
+
const syncIterator = asyncLoop ? lowerer.declareHiddenLocal("%dofSync", BOOL) : null;
|
|
9207
|
+
const awaitDyn = (value) => ({
|
|
9208
|
+
kind: "libCall",
|
|
9209
|
+
fn: "async.awaitDyn",
|
|
9210
|
+
args: [value],
|
|
9211
|
+
type: DYN,
|
|
9212
|
+
loc,
|
|
9213
|
+
});
|
|
7973
9214
|
const get = (source, key) => ({
|
|
7974
9215
|
kind: "dynKeyGet",
|
|
7975
9216
|
value: source,
|
|
@@ -8021,7 +9262,24 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
8021
9262
|
type: BOOL,
|
|
8022
9263
|
loc,
|
|
8023
9264
|
},
|
|
8024
|
-
then: [
|
|
9265
|
+
then: [
|
|
9266
|
+
{
|
|
9267
|
+
kind: "exprStmt",
|
|
9268
|
+
// return()'s (awaited) result must be an object, as for next().
|
|
9269
|
+
expr: asyncLoop
|
|
9270
|
+
? check(awaitDyn({
|
|
9271
|
+
kind: "dynCall",
|
|
9272
|
+
callee: varRef(returned.id, DYN, loc),
|
|
9273
|
+
receiver: varRef(iterator.id, DYN, loc),
|
|
9274
|
+
calleeName: "iterator method",
|
|
9275
|
+
args: [],
|
|
9276
|
+
type: DYN,
|
|
9277
|
+
loc,
|
|
9278
|
+
}))
|
|
9279
|
+
: call(varRef(returned.id, DYN, loc)),
|
|
9280
|
+
loc,
|
|
9281
|
+
},
|
|
9282
|
+
],
|
|
8025
9283
|
else_: null,
|
|
8026
9284
|
loc,
|
|
8027
9285
|
},
|
|
@@ -8063,14 +9321,14 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
8063
9321
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
8064
9322
|
}
|
|
8065
9323
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
8066
|
-
const decl = list.declarations[0];
|
|
9324
|
+
const decl = list.declarations.nodes[0];
|
|
8067
9325
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
8068
9326
|
const tmp = lowerer.declareHiddenLocal("%destr", DYN);
|
|
8069
9327
|
binds.push({ kind: "varDecl", localId: tmp.id, init: elemInit(), loc });
|
|
8070
9328
|
lowerer.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: DYN, loc }), DYN, isLet, binds);
|
|
8071
9329
|
}
|
|
8072
9330
|
else if (ts.isIdentifier(decl.name)) {
|
|
8073
|
-
const varTarget = forOfVarTarget(lowerer, decl);
|
|
9331
|
+
const varTarget = forOfVarTarget(lowerer, decl, DYN);
|
|
8074
9332
|
if (varTarget) {
|
|
8075
9333
|
// `for (var x of d)`: the element mechanics stay on a hidden
|
|
8076
9334
|
// per-iteration local; the body opens by assigning the ONE
|
|
@@ -8102,7 +9360,9 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
8102
9360
|
{
|
|
8103
9361
|
kind: "varDecl",
|
|
8104
9362
|
localId: value.id,
|
|
8105
|
-
init:
|
|
9363
|
+
init: syncIterator
|
|
9364
|
+
? asyncIteratorValue(lowerer, varRef(iterator.id, DYN, loc), varRef(next.id, DYN, loc), varRef(syncIterator.id, BOOL, loc), done, loc)
|
|
9365
|
+
: iteratorValue(lowerer, varRef(iterator.id, DYN, loc), varRef(next.id, DYN, loc), varRef(fast.id, BOOL, loc), done, loc, "iterator method"),
|
|
8106
9366
|
loc,
|
|
8107
9367
|
},
|
|
8108
9368
|
{
|
|
@@ -8127,13 +9387,29 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
8127
9387
|
localId: iterator.id,
|
|
8128
9388
|
init: check({
|
|
8129
9389
|
kind: "libCall",
|
|
8130
|
-
fn: "dyn.iterator",
|
|
9390
|
+
fn: asyncLoop ? "dyn.asyncIteratorOpen" : "dyn.iterator",
|
|
8131
9391
|
args: [iterable, { kind: "strLit", value: spell, type: STRING, loc }],
|
|
8132
9392
|
type: DYN,
|
|
8133
9393
|
loc,
|
|
8134
9394
|
}),
|
|
8135
9395
|
loc,
|
|
8136
9396
|
},
|
|
9397
|
+
...(syncIterator
|
|
9398
|
+
? [
|
|
9399
|
+
{
|
|
9400
|
+
kind: "varDecl",
|
|
9401
|
+
localId: syncIterator.id,
|
|
9402
|
+
init: {
|
|
9403
|
+
kind: "libCall",
|
|
9404
|
+
fn: "dyn.asyncIteratorWasSync",
|
|
9405
|
+
args: [],
|
|
9406
|
+
type: BOOL,
|
|
9407
|
+
loc,
|
|
9408
|
+
},
|
|
9409
|
+
loc,
|
|
9410
|
+
},
|
|
9411
|
+
]
|
|
9412
|
+
: []),
|
|
8137
9413
|
{
|
|
8138
9414
|
kind: "varDecl",
|
|
8139
9415
|
localId: next.id,
|
|
@@ -8143,7 +9419,9 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
8143
9419
|
{
|
|
8144
9420
|
kind: "varDecl",
|
|
8145
9421
|
localId: fast.id,
|
|
8146
|
-
init:
|
|
9422
|
+
init: asyncLoop
|
|
9423
|
+
? { kind: "boolLit", value: false, type: BOOL, loc }
|
|
9424
|
+
: iteratorCanStep(varRef(iterator.id, DYN, loc), varRef(next.id, DYN, loc), loc),
|
|
8147
9425
|
loc,
|
|
8148
9426
|
},
|
|
8149
9427
|
{
|
|
@@ -8195,6 +9473,91 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
8195
9473
|
lowerer.scopes.pop();
|
|
8196
9474
|
}
|
|
8197
9475
|
}
|
|
9476
|
+
/** One step of `for await` over a checked-dynamic iterator: await next()'s
|
|
9477
|
+
* result, read done before value, and await each value of a synchronous
|
|
9478
|
+
* iterator, including its final one, as the async-from-sync iterator does. */
|
|
9479
|
+
function asyncIteratorValue(lowerer, iterator, next, sync, done, loc) {
|
|
9480
|
+
const result = lowerer.declareHiddenLocal("%asyncIteratorResult", DYN);
|
|
9481
|
+
const get = (key) => ({
|
|
9482
|
+
kind: "dynKeyGet",
|
|
9483
|
+
value: varRef(result.id, DYN, loc),
|
|
9484
|
+
key: { kind: "strLit", value: key, type: STRING, loc },
|
|
9485
|
+
type: DYN,
|
|
9486
|
+
loc,
|
|
9487
|
+
});
|
|
9488
|
+
const awaitDyn = (value) => ({
|
|
9489
|
+
kind: "libCall",
|
|
9490
|
+
fn: "async.awaitDyn",
|
|
9491
|
+
args: [value],
|
|
9492
|
+
type: DYN,
|
|
9493
|
+
loc,
|
|
9494
|
+
});
|
|
9495
|
+
return {
|
|
9496
|
+
kind: "seqExpr",
|
|
9497
|
+
type: DYN,
|
|
9498
|
+
loc,
|
|
9499
|
+
stmts: [
|
|
9500
|
+
{
|
|
9501
|
+
kind: "varDecl",
|
|
9502
|
+
localId: result.id,
|
|
9503
|
+
init: {
|
|
9504
|
+
kind: "libCall",
|
|
9505
|
+
fn: "dyn.iteratorResult",
|
|
9506
|
+
args: [
|
|
9507
|
+
awaitDyn({
|
|
9508
|
+
kind: "dynCall",
|
|
9509
|
+
callee: next,
|
|
9510
|
+
receiver: iterator,
|
|
9511
|
+
calleeName: "iterator method",
|
|
9512
|
+
args: [],
|
|
9513
|
+
type: DYN,
|
|
9514
|
+
loc,
|
|
9515
|
+
}),
|
|
9516
|
+
],
|
|
9517
|
+
type: DYN,
|
|
9518
|
+
loc,
|
|
9519
|
+
},
|
|
9520
|
+
loc,
|
|
9521
|
+
},
|
|
9522
|
+
{
|
|
9523
|
+
kind: "assign",
|
|
9524
|
+
localId: done.id,
|
|
9525
|
+
value: { kind: "dynTest", test: "truthy", value: get("done"), type: BOOL, loc },
|
|
9526
|
+
loc,
|
|
9527
|
+
},
|
|
9528
|
+
],
|
|
9529
|
+
// A synchronous iterator's final value is still read and awaited, so a
|
|
9530
|
+
// throwing getter or a rejected promise there rejects the loop.
|
|
9531
|
+
result: {
|
|
9532
|
+
kind: "ternary",
|
|
9533
|
+
cond: sync,
|
|
9534
|
+
then: {
|
|
9535
|
+
kind: "ternary",
|
|
9536
|
+
cond: varRef(done.id, BOOL, loc),
|
|
9537
|
+
then: {
|
|
9538
|
+
kind: "seqExpr",
|
|
9539
|
+
stmts: [{ kind: "exprStmt", expr: awaitDyn(get("value")), loc }],
|
|
9540
|
+
result: dynUndefinedExpr(loc),
|
|
9541
|
+
type: DYN,
|
|
9542
|
+
loc,
|
|
9543
|
+
},
|
|
9544
|
+
else_: awaitDyn(get("value")),
|
|
9545
|
+
type: DYN,
|
|
9546
|
+
loc,
|
|
9547
|
+
},
|
|
9548
|
+
else_: {
|
|
9549
|
+
kind: "ternary",
|
|
9550
|
+
cond: varRef(done.id, BOOL, loc),
|
|
9551
|
+
then: dynUndefinedExpr(loc),
|
|
9552
|
+
else_: get("value"),
|
|
9553
|
+
type: DYN,
|
|
9554
|
+
loc,
|
|
9555
|
+
},
|
|
9556
|
+
type: DYN,
|
|
9557
|
+
loc,
|
|
9558
|
+
},
|
|
9559
|
+
};
|
|
9560
|
+
}
|
|
8198
9561
|
function lowerForOfString(lowerer, stmt, iterable, labels) {
|
|
8199
9562
|
let exprTarget = null;
|
|
8200
9563
|
let exprTargetNode = null;
|
|
@@ -8224,7 +9587,7 @@ function lowerForOfString(lowerer, stmt, iterable, labels) {
|
|
|
8224
9587
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
8225
9588
|
}
|
|
8226
9589
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
8227
|
-
const decl = list ? list.declarations[0] : null; // the grammar allows exactly one
|
|
9590
|
+
const decl = list ? list.declarations.nodes[0] : null; // the grammar allows exactly one
|
|
8228
9591
|
const loc = locOf(stmt);
|
|
8229
9592
|
lowerer.scopes.push(new Map());
|
|
8230
9593
|
try {
|
|
@@ -8383,7 +9746,7 @@ function lowerForIn(lowerer, stmt) {
|
|
|
8383
9746
|
while (root?.base)
|
|
8384
9747
|
root = root.base;
|
|
8385
9748
|
if (info?.decl &&
|
|
8386
|
-
isJsSourceFile(info.decl
|
|
9749
|
+
isJsSourceFile(ts.getSourceFileOfNode(info.decl)) &&
|
|
8387
9750
|
!info.def.runtime &&
|
|
8388
9751
|
!root?.def.runtime &&
|
|
8389
9752
|
!info.builtinError &&
|
|
@@ -8536,7 +9899,7 @@ function lowerForInOverKeys(lowerer, stmt, keys, labels, guard) {
|
|
|
8536
9899
|
lowerer.unsupported("SC1090", stmt.initializer, "for-in over this assignment target (declare the key in the head — for (const k in obj) — or assign a plain declared variable)");
|
|
8537
9900
|
}
|
|
8538
9901
|
const list = stmt.initializer;
|
|
8539
|
-
const decl = list.declarations[0]; // the grammar allows exactly one
|
|
9902
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
8540
9903
|
if (!ts.isIdentifier(decl.name))
|
|
8541
9904
|
lowerer.unsupported("SC1031", decl.name);
|
|
8542
9905
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
@@ -8633,7 +9996,7 @@ function lowerForInArray(lowerer, stmt, labels, arrExpr) {
|
|
|
8633
9996
|
];
|
|
8634
9997
|
}
|
|
8635
9998
|
else {
|
|
8636
|
-
const decl = stmt.initializer.declarations[0];
|
|
9999
|
+
const decl = stmt.initializer.declarations.nodes[0];
|
|
8637
10000
|
if (!ts.isIdentifier(decl.name))
|
|
8638
10001
|
lowerer.unsupported("SC1031", decl.name);
|
|
8639
10002
|
const isLet = (stmt.initializer.flags & ts.NodeFlags.Let) !== 0 ||
|
|
@@ -8736,7 +10099,7 @@ function lowerForAwaitStdin(lowerer, stmt) {
|
|
|
8736
10099
|
// threading it through a shared hoisted slot has no user yet.
|
|
8737
10100
|
if (!isConst && !isLet)
|
|
8738
10101
|
lowerer.unsupported("SC1030", list, "'var' loop bindings in 'for await' (use const)");
|
|
8739
|
-
const decl = list.declarations[0]; // the grammar allows exactly one
|
|
10102
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
8740
10103
|
if (!ts.isIdentifier(decl.name))
|
|
8741
10104
|
lowerer.unsupported("SC1031", decl.name);
|
|
8742
10105
|
const loc = locOf(stmt);
|
|
@@ -8822,4 +10185,158 @@ export function lowerForStatement(lowerer, stmt) {
|
|
|
8822
10185
|
lowerer.scopes.pop();
|
|
8823
10186
|
}
|
|
8824
10187
|
}
|
|
10188
|
+
/** safe-buffer's `var Buffer = buffer.Buffer` (or `var pna = process`, the
|
|
10189
|
+
* process-nextick-args binding once it compiles as process) at file scope:
|
|
10190
|
+
* a `var` alias of a surfaced global other than the global object itself
|
|
10191
|
+
* is the same alias plumbing as the const spelling when nothing reassigns
|
|
10192
|
+
* it and no code that runs before the declaration can read it (the
|
|
10193
|
+
* require-binding early-reference analysis), so the hoisted undefined is
|
|
10194
|
+
* unobservable. */
|
|
10195
|
+
export function stdlibBufferVarAlias(lowerer, decl) {
|
|
10196
|
+
if (!ts.isIdentifier(decl.name) ||
|
|
10197
|
+
!ts.isVariableDeclarationList(decl.parent) ||
|
|
10198
|
+
(decl.parent.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0 ||
|
|
10199
|
+
decl.initializer === undefined ||
|
|
10200
|
+
!(bufferNamespaceMember(lowerer, decl.initializer) ||
|
|
10201
|
+
(stdlibGlobalAliasNameOf(lowerer, decl.initializer) ?? "globalThis") !== "globalThis"))
|
|
10202
|
+
return false;
|
|
10203
|
+
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
10204
|
+
return (symbol !== undefined &&
|
|
10205
|
+
bindingNeverReassigned(lowerer, symbol, decl) &&
|
|
10206
|
+
requireEarlyReference(lowerer.program, decl) === null);
|
|
10207
|
+
}
|
|
10208
|
+
/** A checker type that is a string or string literal (or a union of them). */
|
|
10209
|
+
function isStringTyped(t) {
|
|
10210
|
+
if (t.isUnionType())
|
|
10211
|
+
return ts.constituentTypes(t).every(isStringTyped);
|
|
10212
|
+
return (t.flags & (ts.TypeFlags.String | ts.TypeFlags.StringLiteral)) !== 0;
|
|
10213
|
+
}
|
|
10214
|
+
/** The Error-subclass prototype reset of transpiled code, inside a class
|
|
10215
|
+
* constructor:
|
|
10216
|
+
*
|
|
10217
|
+
* const proto = new.target.prototype;
|
|
10218
|
+
* if (Object.setPrototypeOf) Object.setPrototypeOf(this, proto);
|
|
10219
|
+
* else this.__proto__ = proto;
|
|
10220
|
+
*
|
|
10221
|
+
* (also `Object.setPrototypeOf(this, new.target.prototype)` and
|
|
10222
|
+
* `Object.setPrototypeOf(this, C.prototype)` in C's own constructor when no
|
|
10223
|
+
* class extends C). A compiled instance already has exactly that prototype,
|
|
10224
|
+
* so each statement is a no-op. True for those statements. */
|
|
10225
|
+
function ownPrototypeResetStatement(lowerer, stmt) {
|
|
10226
|
+
if (ts.isVariableStatement(stmt)) {
|
|
10227
|
+
const decls = stmt.declarationList.declarations.nodes;
|
|
10228
|
+
if (decls.length !== 1 || (stmt.declarationList.flags & ts.NodeFlags.Const) === 0)
|
|
10229
|
+
return false;
|
|
10230
|
+
const decl = decls[0];
|
|
10231
|
+
if (!ts.isIdentifier(decl.name) || !decl.initializer)
|
|
10232
|
+
return false;
|
|
10233
|
+
const ctor = enclosingConstructor(decl);
|
|
10234
|
+
if (!ctor || !ownPrototypeRef(lowerer, decl.initializer, ctor))
|
|
10235
|
+
return false;
|
|
10236
|
+
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
10237
|
+
if (!symbol)
|
|
10238
|
+
return false;
|
|
10239
|
+
// Every other use of the binding must be one of the reset statements.
|
|
10240
|
+
let onlyResets = true;
|
|
10241
|
+
ts.walkPreorder(ctor, (n) => {
|
|
10242
|
+
if (!onlyResets)
|
|
10243
|
+
return "stop";
|
|
10244
|
+
if (!ts.isIdentifier(n) || n === decl.name)
|
|
10245
|
+
return undefined;
|
|
10246
|
+
if (lowerer.checker.getSymbolAtLocation(n) !== symbol)
|
|
10247
|
+
return undefined;
|
|
10248
|
+
const statement = n.parent?.parent;
|
|
10249
|
+
if (!statement ||
|
|
10250
|
+
!ts.isExpressionStatement(statement) ||
|
|
10251
|
+
resetTarget(lowerer, statement.expression) !== n)
|
|
10252
|
+
onlyResets = false;
|
|
10253
|
+
return undefined;
|
|
10254
|
+
});
|
|
10255
|
+
return onlyResets;
|
|
10256
|
+
}
|
|
10257
|
+
if (!ts.isExpressionStatement(stmt))
|
|
10258
|
+
return false;
|
|
10259
|
+
const ctor = enclosingConstructor(stmt);
|
|
10260
|
+
if (!ctor)
|
|
10261
|
+
return false;
|
|
10262
|
+
const target = resetTarget(lowerer, stmt.expression);
|
|
10263
|
+
return target !== null && ownPrototypeRef(lowerer, target, ctor);
|
|
10264
|
+
}
|
|
10265
|
+
/** The prototype operand of `Object.setPrototypeOf(this, P)` or
|
|
10266
|
+
* `this.__proto__ = P`, or null. */
|
|
10267
|
+
function resetTarget(lowerer, expr) {
|
|
10268
|
+
if (ts.isCallExpression(expr) &&
|
|
10269
|
+
expr.arguments.nodes.length === 2 &&
|
|
10270
|
+
expr.arguments.nodes[0].kind === ts.SyntaxKind.ThisKeyword &&
|
|
10271
|
+
ts.isPropertyAccessExpression(expr.expression) &&
|
|
10272
|
+
expr.expression.name.text === "setPrototypeOf" &&
|
|
10273
|
+
lowerer.isStdlibGlobal(expr.expression.expression, "Object"))
|
|
10274
|
+
return expr.arguments.nodes[1];
|
|
10275
|
+
if (ts.isBinaryExpression(expr) &&
|
|
10276
|
+
expr.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
10277
|
+
ts.isPropertyAccessExpression(expr.left) &&
|
|
10278
|
+
expr.left.expression.kind === ts.SyntaxKind.ThisKeyword &&
|
|
10279
|
+
expr.left.name.text === "__proto__")
|
|
10280
|
+
return expr.right;
|
|
10281
|
+
return null;
|
|
10282
|
+
}
|
|
10283
|
+
/** The class constructor whose body holds `node`, crossing only statements
|
|
10284
|
+
* and blocks (any nested function rebinds `this`). */
|
|
10285
|
+
function enclosingConstructor(node) {
|
|
10286
|
+
for (let cur = node.parent; cur !== undefined; cur = cur.parent) {
|
|
10287
|
+
if (ts.isConstructorDeclaration(cur))
|
|
10288
|
+
return cur;
|
|
10289
|
+
if (ts.isFunctionLike(cur) ||
|
|
10290
|
+
ts.isClassDeclaration(cur) ||
|
|
10291
|
+
ts.isClassExpression(cur) ||
|
|
10292
|
+
ts.isSourceFile(cur))
|
|
10293
|
+
return null;
|
|
10294
|
+
}
|
|
10295
|
+
return null;
|
|
10296
|
+
}
|
|
10297
|
+
/** Whether `node` denotes the prototype of the object `ctor` constructs:
|
|
10298
|
+
* `new.target.prototype`, a const holding it, or the class's own
|
|
10299
|
+
* `C.prototype` when no class extends C. */
|
|
10300
|
+
function ownPrototypeRef(lowerer, node, ctor) {
|
|
10301
|
+
while (ts.isParenthesizedExpression(node))
|
|
10302
|
+
node = node.expression;
|
|
10303
|
+
if (ts.isPropertyAccessExpression(node) && node.name.text === "prototype") {
|
|
10304
|
+
const base = node.expression;
|
|
10305
|
+
if (ts.isMetaProperty(base) &&
|
|
10306
|
+
base.keywordToken === ts.SyntaxKind.NewKeyword &&
|
|
10307
|
+
base.name.text === "target")
|
|
10308
|
+
return true;
|
|
10309
|
+
const cls = ctor.parent;
|
|
10310
|
+
if (!ts.isIdentifier(base) || !(ts.isClassDeclaration(cls) || ts.isClassExpression(cls)))
|
|
10311
|
+
return false;
|
|
10312
|
+
const symbol = lowerer.resolveValueSymbol(base);
|
|
10313
|
+
const info = symbol ? lowerer.classBySymbol.get(symbol) : undefined;
|
|
10314
|
+
if (!info || symbol.valueDeclaration !== cls)
|
|
10315
|
+
return false;
|
|
10316
|
+
for (const other of lowerer.classes.values()) {
|
|
10317
|
+
if (other !== info && lowerer.isSubclassOf(other.def.name, info.def.name))
|
|
10318
|
+
return false;
|
|
10319
|
+
}
|
|
10320
|
+
return true;
|
|
10321
|
+
}
|
|
10322
|
+
if (ts.isIdentifier(node)) {
|
|
10323
|
+
const symbol = lowerer.resolveValueSymbol(node);
|
|
10324
|
+
const decl = symbol?.valueDeclaration;
|
|
10325
|
+
return (decl !== undefined &&
|
|
10326
|
+
ts.isVariableDeclaration(decl) &&
|
|
10327
|
+
decl.initializer !== undefined &&
|
|
10328
|
+
ts.isVariableDeclarationList(decl.parent) &&
|
|
10329
|
+
(decl.parent.flags & ts.NodeFlags.Const) !== 0 &&
|
|
10330
|
+
enclosingConstructor(decl) === ctor &&
|
|
10331
|
+
!ts.isIdentifier(decl.initializer) &&
|
|
10332
|
+
ownPrototypeRef(lowerer, decl.initializer, ctor));
|
|
10333
|
+
}
|
|
10334
|
+
return false;
|
|
10335
|
+
}
|
|
10336
|
+
function isAssertionInitializer(node) {
|
|
10337
|
+
let e = node;
|
|
10338
|
+
while (ts.isParenthesizedExpression(e))
|
|
10339
|
+
e = e.expression;
|
|
10340
|
+
return ts.isAsExpression(e) || ts.isTypeAssertion(e);
|
|
10341
|
+
}
|
|
8825
10342
|
//# sourceMappingURL=lower-stmts.js.map
|