@scriptc/compiler 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +682 -50
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +6 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +11 -0
- package/dist/backend/llvm/classes.js +71 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +58 -8
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.js +1 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +12 -3
- package/dist/backend/llvm/dense-array-access.js +72 -14
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +59 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +28 -4
- package/dist/backend/llvm/dyn.js +293 -178
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1190 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1535 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +58 -0
- package/dist/backend/llvm/emit-statements.js +1964 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +547 -283
- package/dist/backend/llvm/emitter.js +689 -4643
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +71 -53
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +39 -15
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +67 -62
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +121 -25
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +54 -12
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +488 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +189 -23
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +42 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +56 -22
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +90 -50
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +187 -6
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +43 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js +2 -2
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +151 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +64 -6
- package/dist/backend/llvm/nullable-unions.js +103 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +4 -0
- package/dist/backend/llvm/publish.js +14 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +12 -1
- package/dist/backend/llvm/record-results.js +64 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +142 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +9 -6
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +1 -1
- package/dist/backend/llvm/shapes.d.ts +66 -43
- package/dist/backend/llvm/shapes.js +280 -21
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +110 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +7 -0
- package/dist/backend/mangle.js +11 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +4 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +37 -0
- package/dist/backend/native/executable.js +192 -137
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -1
- package/dist/backend/runtime-pack-core.js +10 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +5 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +5 -0
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +8 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +5 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +44 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +11 -1
- package/dist/cli/usage.js +20 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +13 -0
- package/dist/contracts/check.js +24 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -6
- package/dist/diagnostics/diagnostic.js +29 -21
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +17 -0
- package/dist/executable/executable-cache.js +13 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +7 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +63 -5
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +16 -5
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +107 -44
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
- package/dist/frontend/lowering/builtins/crypto.js +211 -37
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +169 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +77 -77
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +232 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +55 -44
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +32 -1
- package/dist/frontend/lowering/builtins/process.js +461 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
- package/dist/frontend/lowering/builtins/readline.js +136 -39
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +16 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +75 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
- package/dist/frontend/lowering/builtins/workers.js +193 -8
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +19 -1
- package/dist/frontend/lowering/call-signatures.js +254 -47
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +528 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +25 -44
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +80 -18
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +261 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +51 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
- package/dist/frontend/lowering/containers/array-from-async.js +159 -14
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +89 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +161 -101
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +54 -25
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
- package/dist/frontend/lowering/cycle-initialization.js +39 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +62 -125
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +703 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2483 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1797 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +253 -85
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
- package/dist/frontend/lowering/expressions/property-access.js +3544 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1679 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +538 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +39 -0
- package/dist/frontend/lowering/generic-functions.js +393 -75
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +32 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1239 -442
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +50 -3
- package/dist/frontend/lowering/lower-classes.js +1473 -468
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +179 -8
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +258 -70
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1481 -12489
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +68 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +29 -16
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +331 -96
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +8 -1
- package/dist/frontend/lowering/lower-mock.js +185 -18
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +267 -61
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +45 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +488 -100
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +151 -109
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
- package/dist/frontend/lowering/lower-stmts.js +1541 -391
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +398 -56
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +437 -62
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +80 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +399 -26
- package/dist/frontend/lowering/lowerer.js +1910 -305
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +10 -10
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +12 -3
- package/dist/frontend/lowering/surfaces.js +252 -41
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.js +13 -6
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
- package/dist/frontend/npm-static-bundled-chunks.js +810 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +768 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +17 -1
- package/dist/frontend/npm-static.js +167 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.js +164 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +92 -2
- package/dist/frontend/program.js +1557 -255
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +36 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +20 -1
- package/dist/frontend/services.js +40 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +5 -1
- package/dist/frontend/ts7/program-host.js +12 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +54 -24
- package/dist/frontend/ts7/semantic-model.js +88 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +11 -11
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2545 -719
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +30 -0
- package/dist/ir/array-length-stability.js +236 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +113 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +103 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +494 -25
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +9 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +97 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/integer-loop-facts.d.ts +2 -0
- package/dist/ir/integer-loop-facts.js +24 -3
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +3 -0
- package/dist/ir/integer-ranges.js +3 -1
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +82 -1
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +221 -58
- package/dist/ir/ir.js +119 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +365 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +148 -33
- package/dist/ir/runtime-features.js +629 -386
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +103 -94
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +175 -68
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +26 -9
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +13 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +2 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/prepare.js +7 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +12 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +21 -20
- package/surface-manifest.json +303 -19
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
import { lowerTupleAliasDecl, stripTypeWrappers } from "./typed-arguments.js";
|
|
2
|
+
import { declaredMemberOf } 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 { matchAllRowsReadByElements, storedMatchAllRowsReadByElements, } from "./containers/match-row-uses.js";
|
|
1
7
|
import { dynUndefinedExpr, numLit, varRef } from "../../ir/build.js";
|
|
8
|
+
import { lowerCollectionSpread } from "./containers/collection-methods.js";
|
|
2
9
|
import { lowerEventObjectPropertyWrite } from "./lower-event-target.js";
|
|
3
10
|
import { lowerDynObjectLiteral } from "./expressions/object-literals.js";
|
|
4
11
|
import { importMetaBindingSource } from "./import-meta.js";
|
|
@@ -10,23 +17,32 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
10
17
|
* flow (if/while/for/for-of/do, switch, try/catch, abrupt completions),
|
|
11
18
|
* explicit resource management, and blocked-binding poisoning. */
|
|
12
19
|
import * as ts from "../ts7/adapter.js";
|
|
20
|
+
import { processDataMemberValue, programReadsExitCode } from "./builtins/process.js";
|
|
21
|
+
import { requireInitFlagStmt } from "./require-initialization.js";
|
|
22
|
+
import { isJsonRequireDecl } from "./json-require.js";
|
|
13
23
|
import { bindingSource } from "../binding-source.js";
|
|
24
|
+
import { lowerConstructorReturn } from "./constructor-returns.js";
|
|
25
|
+
import { cjsExportValueByName, cjsNamespaceDestructureOf, cjsTableMethodEntry, inlineProgramRequireOf, requireNestedPatternsOf, } from "./cjs-inline-require.js";
|
|
26
|
+
import { cjsExportMemberWriteGlobalOf, isCjsExportsIdentifier, isCjsModuleExports, isFreshExportsReset, } from "./cjs-exports-object.js";
|
|
27
|
+
import { isDeadTscHelperDecl, tscInteropBindingOfDecl } from "./cjs-tsc-interop.js";
|
|
14
28
|
import { arrayValueRead, arrayValueStore, arrayValueType, unionArrayValueRead, lowerSafeIndexRead, } from "./array-values.js";
|
|
15
29
|
import { lowerForAwaitGenerator, lowerForOfGenerator, lowerYieldStarStatement, } from "./lower-generators.js";
|
|
16
|
-
import { lowerForAwaitBuiltin } from "./lower-async-iteration.js";
|
|
30
|
+
import { classAsyncGeneratorIterator, lowerForAwaitBuiltin } from "./lower-async-iteration.js";
|
|
17
31
|
import { BOOL, BYTES_U8, CAUGHT, DYN, F64, STRING, UNDEFINED_T, VOID, arrayOf, isDynTypedRefType, isUnitType, shapeHasAccessorSlots, typeEquals, } from "../../ir/ir.js";
|
|
18
32
|
import { PoisonError, boundIdentifiersOf, dynFallbackType, neverTaintedJsType, staticImportNamespaceType, } from "./lowerer.js";
|
|
19
33
|
import { enforceLibBoundary, lowerSurplusCalls } from "./lib-boundary.js";
|
|
20
|
-
import { cjsExportAssignmentOf, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile,
|
|
21
|
-
import {
|
|
34
|
+
import { cjsExportAssignmentOf, cjsExportChainOf, cjsVoidInitPreambleReals, cjsExportDiscardReason, cjsExportTargetLiteral, isCjsJsFile, isEsModuleStamp, isJsSourceFile, locOf, requireEarlyReference, requireSpecOf, } from "../program.js";
|
|
35
|
+
import { isStrictCode } from "./strict-mode.js";
|
|
36
|
+
import { COMPOUND_ASSIGN_OPS, STR_METHODS, UNSUPPORTED_STMT, isStdlibMember, sideEffectFreeOptionValue, stdlibGlobalAliasDecl, stdlibGlobalAliasNameOf, bufferNamespaceMember, stdlibGlobalNameOf, } from "./surfaces.js";
|
|
22
37
|
import { isNativeBuiltinValueInitializer } from "./lower-builtin-values.js";
|
|
23
38
|
import { isProvenanceSourceFile } from "../provenance-registry.js";
|
|
24
39
|
import { ambientUndefVarRootOf, lowerImportEquals, nsUndefRead, nsWritableTarget, trapDeclRootOf, } from "./lower-namespaces.js";
|
|
25
40
|
import { expandoWritableTarget, lowerExpandoAssignStmt } from "./lower-expando.js";
|
|
26
41
|
import { lowerForOfArrayIter, lowerForOfMap, lowerForOfSearchParams, lowerForOfSet, } from "./containers/for-of.js";
|
|
42
|
+
import { lowerForOfHelperChain } from "./containers/iterator-helpers.js";
|
|
27
43
|
import { objectIterOverIndexShape } from "./containers/indexed-objects.js";
|
|
28
44
|
import { strCharsCall } from "./containers/array-construction.js";
|
|
29
|
-
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, } from "./generic-functions.js";
|
|
45
|
+
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, implicitLocalFnInfoOf, implicitLocalFnNodeOf, implicitMethodCallInfersReturn, genericLocalClassBinding, } from "./generic-functions.js";
|
|
30
46
|
import { bindingNeverReassigned, deadUnmappableBinding, nullishExprUnitOf, nullishGenericBindingUnitOf, } from "./binding-analysis.js";
|
|
31
47
|
import { hasExplicitJsDocReturn } from "./function-returns.js";
|
|
32
48
|
import { recordKeysArrayCall } from "./lower-calls.js";
|
|
@@ -47,11 +63,13 @@ import { isTimersPromisesIntervalCall } from "./builtins/timers.js";
|
|
|
47
63
|
import { isNativeFfiRequire, builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireCalleeFileOf, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireProgramModuleOf, } from "./builtins/module-bindings.js";
|
|
48
64
|
import { lowerNodeModuleCall } from "./builtins/module-resolution.js";
|
|
49
65
|
import { registerBuiltinCallableAlias } from "./builtins/callable-aliases.js";
|
|
66
|
+
import { builtinClassAliasOwnsNoSlot, registerBuiltinClassAlias } from "./builtins/class-values.js";
|
|
50
67
|
import { lowerEnumDeclaration } from "./lower-enums.js";
|
|
51
68
|
import { abstractPropertyDeclOf, aliasTypeofNarrows, isMatchSliceType, lowerAbsenceProbe, lowerCompoundValueToTarget, lowerElementCompoundStatement, lowerIncDec, lowerIncDecTarget, lowerGroupsProjection, matchResultNamedGroupsOf, runtimeOptionalGuardIds, runtimeOptionalTrueIds, symbolFieldInfo, withRuntimeOptionalNarrowed, } from "./lower-exprs.js";
|
|
52
69
|
import { globalSymbolKey } from "./expressions/global-symbols.js";
|
|
53
70
|
import { lowerShortCircuitAssignment } from "./expressions/nullish-assignment.js";
|
|
54
|
-
import { lowerEnvironmentKey, lowerNativeFunctionAssignment } from "./lower-exprs.js";
|
|
71
|
+
import { builtinGlobalValue, jsHoldsDynObject, lowerEnvironmentKey, lowerNativeFunctionAssignment, lowerStrictEquality, } from "./lower-exprs.js";
|
|
72
|
+
import { keptIdentityAssertion } from "./assertion-identity.js";
|
|
55
73
|
import { isNativeProxyInitializer } from "./expressions/native-proxy.js";
|
|
56
74
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
57
75
|
import { lowerUnionFieldWrite } from "./expressions/union-fields.js";
|
|
@@ -64,6 +82,7 @@ import { constituentTypes } from "../ts7/checker.js";
|
|
|
64
82
|
import { npmStaticPackageOfPath } from "../npm-static.js";
|
|
65
83
|
import { fenceNodeModuleMutation } from "./lower-node-module.js";
|
|
66
84
|
import { fencePerfEntryKeyWalk } from "./builtins/performance.js";
|
|
85
|
+
import { classGeneratorIterable } from "./class-iterables.js";
|
|
67
86
|
/** An opted package's directly-returned empty array may take the function's
|
|
68
87
|
* explicit static return element type. This is the common JS accumulator
|
|
69
88
|
* shape (`const result = []; result.push(value); return result`) and is
|
|
@@ -72,9 +91,9 @@ function npmStaticReturnedEmptyArrayType(lowerer, decl) {
|
|
|
72
91
|
if (!ts.isIdentifier(decl.name) ||
|
|
73
92
|
decl.initializer === undefined ||
|
|
74
93
|
!ts.isArrayLiteralExpression(decl.initializer) ||
|
|
75
|
-
decl.initializer.elements.length !== 0 ||
|
|
76
|
-
!isJsSourceFile(
|
|
77
|
-
npmStaticPackageOfPath(
|
|
94
|
+
decl.initializer.elements.nodes.length !== 0 ||
|
|
95
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
96
|
+
npmStaticPackageOfPath(ts.getSourceFileOfNode(decl).fileName) === null ||
|
|
78
97
|
lowerer.ctx.returnType.kind !== "array") {
|
|
79
98
|
return null;
|
|
80
99
|
}
|
|
@@ -112,8 +131,8 @@ function npmStaticReturnedEmptyArrayType(lowerer, decl) {
|
|
|
112
131
|
* the assignment, narrows it. */
|
|
113
132
|
function npmStaticOptionalSelfWriteType(lowerer, decl, initial) {
|
|
114
133
|
if (!ts.isIdentifier(decl.name) ||
|
|
115
|
-
!isJsSourceFile(
|
|
116
|
-
npmStaticPackageOfPath(
|
|
134
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
135
|
+
npmStaticPackageOfPath(ts.getSourceFileOfNode(decl).fileName) === null ||
|
|
117
136
|
initial.kind === "union") {
|
|
118
137
|
return null;
|
|
119
138
|
}
|
|
@@ -173,8 +192,9 @@ function stdlibTypeNamed(lowerer, node, name) {
|
|
|
173
192
|
if (t.flags & ts.TypeFlags.Union)
|
|
174
193
|
return constituentTypes(t).some(visit);
|
|
175
194
|
const sym = t.getAliasSymbol() ?? t.getSymbol();
|
|
176
|
-
return (sym
|
|
177
|
-
|
|
195
|
+
return (sym !== undefined &&
|
|
196
|
+
ts.symbolName(sym) === name &&
|
|
197
|
+
sym.declarations.some((d) => lowerer.isStdlibFile(ts.getSourceFileOfNode(d))));
|
|
178
198
|
};
|
|
179
199
|
return visit(lowerer.typeOf(node));
|
|
180
200
|
}
|
|
@@ -356,7 +376,7 @@ function lowerUsingStatement(lowerer, stmt) {
|
|
|
356
376
|
lowerer.unsupported("SC1090", stmt, "'await using' outside an async function or top-level-await module");
|
|
357
377
|
}
|
|
358
378
|
const registrations = [];
|
|
359
|
-
for (const decl of stmt.declarationList.declarations) {
|
|
379
|
+
for (const decl of stmt.declarationList.declarations.nodes) {
|
|
360
380
|
if (!ts.isIdentifier(decl.name))
|
|
361
381
|
lowerer.unsupported("SC1031", decl.name);
|
|
362
382
|
if (decl.initializer === undefined)
|
|
@@ -386,14 +406,14 @@ function pureAnnotatedDeadConst(stmt, sf) {
|
|
|
386
406
|
return false;
|
|
387
407
|
if ((stmt.declarationList.flags & ts.NodeFlags.Const) === 0)
|
|
388
408
|
return false;
|
|
389
|
-
const decls = stmt.declarationList.declarations;
|
|
409
|
+
const decls = stmt.declarationList.declarations.nodes;
|
|
390
410
|
if (decls.length === 0)
|
|
391
411
|
return false;
|
|
392
412
|
return decls.every((d) => {
|
|
393
413
|
let init = d.initializer;
|
|
394
414
|
if (init === undefined)
|
|
395
415
|
return false;
|
|
396
|
-
const trivia = sf.text.slice(init.pos,
|
|
416
|
+
const trivia = sf.text.slice(init.pos, ts.tokenStartOfNode(init));
|
|
397
417
|
if (!trivia.includes("@__PURE__") && !trivia.includes("#__PURE__"))
|
|
398
418
|
return false;
|
|
399
419
|
// `as` casts are type-world wrappers (`(() => {...})() as unknown as
|
|
@@ -421,7 +441,7 @@ function pureAnnotatedDeadConst(stmt, sf) {
|
|
|
421
441
|
* probes that would otherwise claim (and diagnose) the call-initializer
|
|
422
442
|
* shape. */
|
|
423
443
|
export function provenanceElidedConstDecl(lowerer, decl) {
|
|
424
|
-
const sf =
|
|
444
|
+
const sf = ts.getSourceFileOfNode(decl);
|
|
425
445
|
if (!isProvenanceSourceFile(sf.fileName))
|
|
426
446
|
return false;
|
|
427
447
|
const stmt = decl.parent?.parent;
|
|
@@ -468,7 +488,7 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
468
488
|
// runtimeFence — a catchable, SC-coded throw at the statement's
|
|
469
489
|
// position — instead of failing the whole build). TypeScript keeps
|
|
470
490
|
// compile fences. ICEs (SC9001) always stay compile errors.
|
|
471
|
-
const sf = stmts[0]
|
|
491
|
+
const sf = stmts.length === 0 ? undefined : ts.getSourceFileOfNode(stmts[0]);
|
|
472
492
|
const deferFences = sf !== undefined && isJsSourceFile(sf);
|
|
473
493
|
// Register this list as open for the forward-capture machinery: a
|
|
474
494
|
// nested function lowering mid-list may pre-declare a LATER const of
|
|
@@ -482,16 +502,20 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
482
502
|
out,
|
|
483
503
|
};
|
|
484
504
|
lowerer.activeStmtLists.push(entry);
|
|
505
|
+
const inFunction = stmts.length > 0 && enclosedByFunction(stmts[0]);
|
|
506
|
+
let unreachable = false;
|
|
485
507
|
try {
|
|
486
508
|
for (let i = 0; i < stmts.length; i++) {
|
|
487
509
|
const stmt = stmts[i];
|
|
488
510
|
entry.index = i;
|
|
489
|
-
if (
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
511
|
+
if (unreachable && skipsWhenUnreachable(stmt))
|
|
512
|
+
continue;
|
|
513
|
+
if (inFunction && isAbruptStatement(stmt))
|
|
514
|
+
unreachable = true;
|
|
515
|
+
if (!lowerer.suppressStats)
|
|
516
|
+
lowerer.countStatement(stmt, sf?.fileName);
|
|
494
517
|
const diagsBefore = lowerer.diags.length;
|
|
518
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
495
519
|
try {
|
|
496
520
|
let lowered;
|
|
497
521
|
let appended = false;
|
|
@@ -558,11 +582,8 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
558
582
|
else if (!(e instanceof PoisonError)) {
|
|
559
583
|
throw e;
|
|
560
584
|
}
|
|
561
|
-
if (!lowerer.suppressStats)
|
|
562
|
-
lowerer.
|
|
563
|
-
if (sf !== undefined)
|
|
564
|
-
lowerer.bumpFileStat(sf.fileName, "failed");
|
|
565
|
-
}
|
|
585
|
+
if (!lowerer.suppressStats)
|
|
586
|
+
lowerer.countStatementFailed(stmt, sf?.fileName);
|
|
566
587
|
lowerer.noteBlockedBindings(stmt);
|
|
567
588
|
// The runtime-fence conversion (JS sources, direct diagnostics
|
|
568
589
|
// only — a capture wrapper in force means collection owns the
|
|
@@ -583,6 +604,13 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
583
604
|
if (fence)
|
|
584
605
|
out.push(fence);
|
|
585
606
|
}
|
|
607
|
+
else if (deferFences) {
|
|
608
|
+
// Inside a capture buffer the owner keeps the diagnostics, but
|
|
609
|
+
// the statement still must not vanish from a result it keeps.
|
|
610
|
+
const fence = lowerer.capturedRuntimeFence(sinkMark, stmt);
|
|
611
|
+
if (fence)
|
|
612
|
+
out.push(fence);
|
|
613
|
+
}
|
|
586
614
|
}
|
|
587
615
|
}
|
|
588
616
|
// Each acquisition protects the remainder of its lexical statement
|
|
@@ -608,6 +636,48 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
608
636
|
}
|
|
609
637
|
return out;
|
|
610
638
|
}
|
|
639
|
+
/** Whether a statement list belongs to a function body (at any block
|
|
640
|
+
* depth) rather than to a module's top level. */
|
|
641
|
+
function enclosedByFunction(stmt) {
|
|
642
|
+
let owner = stmt.parent;
|
|
643
|
+
while (owner !== undefined && !ts.isFunctionLike(owner) && !ts.isSourceFile(owner))
|
|
644
|
+
owner = owner.parent;
|
|
645
|
+
return owner !== undefined && ts.isFunctionLike(owner);
|
|
646
|
+
}
|
|
647
|
+
/** `return`, `throw`, `break` and `continue`: the rest of the enclosing
|
|
648
|
+
* statement list never runs. */
|
|
649
|
+
function isAbruptStatement(stmt) {
|
|
650
|
+
return (ts.isReturnStatement(stmt) ||
|
|
651
|
+
ts.isThrowStatement(stmt) ||
|
|
652
|
+
ts.isBreakStatement(stmt) ||
|
|
653
|
+
ts.isContinueStatement(stmt));
|
|
654
|
+
}
|
|
655
|
+
/** Statements after an abrupt statement in a function body that lowering
|
|
656
|
+
* skips: they never execute, so neither their unsupported constructs nor the
|
|
657
|
+
* functions they reference become part of the program (production builds of
|
|
658
|
+
* libraries keep development-only code behind `throw` stubs this way).
|
|
659
|
+
* Hoisting keeps its meaning: a reference above the abrupt statement to a
|
|
660
|
+
* later function declaration lowers that declaration eagerly
|
|
661
|
+
* (predeclareForwardFnDecl), and references to a later `var`, `let` or
|
|
662
|
+
* `const` binding resolve through the forward-hoisting machinery to its
|
|
663
|
+
* undefined or TDZ state, which skipping its initializer preserves. Class,
|
|
664
|
+
* enum, module and import/export declarations and generic function
|
|
665
|
+
* declarations still lower. */
|
|
666
|
+
function skipsWhenUnreachable(stmt) {
|
|
667
|
+
if (ts.isFunctionDeclaration(stmt))
|
|
668
|
+
return stmt.typeParameters === undefined;
|
|
669
|
+
if (ts.isVariableStatement(stmt))
|
|
670
|
+
return !(stmt.modifiers?.nodes ?? []).some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
671
|
+
return !(ts.isClassDeclaration(stmt) ||
|
|
672
|
+
ts.isEnumDeclaration(stmt) ||
|
|
673
|
+
ts.isModuleDeclaration(stmt) ||
|
|
674
|
+
ts.isImportDeclaration(stmt) ||
|
|
675
|
+
ts.isImportEqualsDeclaration(stmt) ||
|
|
676
|
+
ts.isExportDeclaration(stmt) ||
|
|
677
|
+
ts.isExportAssignment(stmt) ||
|
|
678
|
+
ts.isInterfaceDeclaration(stmt) ||
|
|
679
|
+
ts.isTypeAliasDeclaration(stmt));
|
|
680
|
+
}
|
|
611
681
|
const TDZ_KINDS = new Set([
|
|
612
682
|
"func",
|
|
613
683
|
"string",
|
|
@@ -661,7 +731,7 @@ const TDZ_KINDS = new Set([
|
|
|
661
731
|
* is empty. Mutable bindings also guard writes; only the declaration's
|
|
662
732
|
* initializing assignment may leave the temporal dead zone. */
|
|
663
733
|
export function predeclareForwardCapture(lowerer, symbol) {
|
|
664
|
-
const decl =
|
|
734
|
+
const decl = symbol.valueDeclaration;
|
|
665
735
|
if (!decl ||
|
|
666
736
|
!ts.isVariableDeclaration(decl) ||
|
|
667
737
|
decl.name === undefined ||
|
|
@@ -672,6 +742,10 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
672
742
|
const flags = ts.getCombinedNodeFlags(decl);
|
|
673
743
|
if ((flags & ts.NodeFlags.BlockScoped) === 0 || (flags & ts.NodeFlags.Using) !== 0)
|
|
674
744
|
return false;
|
|
745
|
+
// `const E = EventEmitter` has no storage to box: uses resolve at
|
|
746
|
+
// compile time (builtinClassAliasOf).
|
|
747
|
+
if (builtinClassAliasOwnsNoSlot(lowerer, symbol))
|
|
748
|
+
return false;
|
|
675
749
|
// MODULE-scope bindings are pre-registered globals (collectGlobals):
|
|
676
750
|
// references resolve through globalOf after the local search fails, so
|
|
677
751
|
// a TDZ box here would SHADOW the global and never fill (the top-level
|
|
@@ -697,7 +771,7 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
697
771
|
if (idx < entry.index || entry.ctx === lowerer.ctx || entry.ctx.tdzPredeclared.has(symbol))
|
|
698
772
|
return false;
|
|
699
773
|
let type = lowerer.irTypeOf(decl.name);
|
|
700
|
-
if (isJsSourceFile(
|
|
774
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
701
775
|
!decl.type &&
|
|
702
776
|
!hasJsTypeAnnotation(decl) &&
|
|
703
777
|
(ts.isObjectLiteralExpression(decl.initializer) ||
|
|
@@ -739,8 +813,8 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
739
813
|
* lower the declaration under the owning statement list's context, then
|
|
740
814
|
* resume the caller and thread its captures normally. */
|
|
741
815
|
export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
742
|
-
const decl =
|
|
743
|
-
if (!decl || !ts.isFunctionDeclaration(decl) || !decl.body || decl.typeParameters)
|
|
816
|
+
const decl = symbol.valueDeclaration;
|
|
817
|
+
if (!decl || !ts.isFunctionDeclaration(decl) || !decl.body || decl.typeParameters?.nodes)
|
|
744
818
|
return false;
|
|
745
819
|
for (let i = lowerer.activeStmtLists.length - 1; i >= 0; i--) {
|
|
746
820
|
const entry = lowerer.activeStmtLists[i];
|
|
@@ -765,14 +839,26 @@ export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
|
765
839
|
entry.ctx.hoistedFnDecls.add(decl);
|
|
766
840
|
const fnTail = lowerer.fnStack.splice(depth + 1);
|
|
767
841
|
const scopeTail = entry.ctx.scopes.splice(frameIdx + 1);
|
|
842
|
+
// The hoisted function is kept even when the reference lowers inside
|
|
843
|
+
// a speculative attempt (a probe's temporary diagnostic sink): lower
|
|
844
|
+
// it without that sink, so its failing JS statements keep their
|
|
845
|
+
// runtime fences instead of vanishing from a body that is kept. A
|
|
846
|
+
// declaration that fails as a whole is not kept: its diagnostics go
|
|
847
|
+
// back to the probe.
|
|
848
|
+
const previousSink = lowerer.diagSink;
|
|
849
|
+
const diagsBefore = lowerer.diags.length;
|
|
850
|
+
lowerer.diagSink = null;
|
|
768
851
|
try {
|
|
769
852
|
entry.out.push(lowerer.lowerNestedFunctionDecl(decl));
|
|
770
853
|
}
|
|
771
854
|
catch (e) {
|
|
772
855
|
entry.ctx.hoistedFnDecls.delete(decl);
|
|
856
|
+
if (previousSink !== null)
|
|
857
|
+
previousSink.push(...lowerer.diags.splice(diagsBefore));
|
|
773
858
|
throw e;
|
|
774
859
|
}
|
|
775
860
|
finally {
|
|
861
|
+
lowerer.diagSink = previousSink;
|
|
776
862
|
entry.ctx.scopes.push(...scopeTail);
|
|
777
863
|
lowerer.fnStack.push(...fnTail);
|
|
778
864
|
}
|
|
@@ -804,16 +890,108 @@ function hostVariableDeclarationOf(name) {
|
|
|
804
890
|
* iteration), and it persists after the loop. Returns the write target
|
|
805
891
|
* (a module global for top-level loops, the hoisted function slot
|
|
806
892
|
* otherwise); null when the binding isn't a `var` identifier. */
|
|
807
|
-
export function forOfVarTarget(lowerer, decl) {
|
|
893
|
+
export function forOfVarTarget(lowerer, decl, valueType) {
|
|
808
894
|
if (!ts.isIdentifier(decl.name) || !isVarDeclared(decl))
|
|
809
895
|
return null;
|
|
810
896
|
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
811
897
|
if (!symbol)
|
|
812
898
|
return null;
|
|
813
899
|
const g = lowerer.globalsBySymbol.get(symbol);
|
|
814
|
-
if (g)
|
|
900
|
+
if (g) {
|
|
901
|
+
if (valueType?.kind === "dyn" && jsBindingKeepsCheckedObject(lowerer, decl.name, g.type))
|
|
902
|
+
g.type = DYN;
|
|
815
903
|
return g;
|
|
816
|
-
|
|
904
|
+
}
|
|
905
|
+
return hoistVarBinding(lowerer, symbol, decl.name, valueType);
|
|
906
|
+
}
|
|
907
|
+
/** JavaScript: whether an unannotated variable binding whose static type
|
|
908
|
+
* is `type` keeps a checked-dynamic value unconverted. The checker types
|
|
909
|
+
* such a binding by the object it receives (an element of an evolving
|
|
910
|
+
* `[]`, a `find` result, a member of a checked-dynamic object), but the
|
|
911
|
+
* value is an existing checked-dynamic object or array: a record- or
|
|
912
|
+
* array-typed slot would hold a converted copy, so writes through the
|
|
913
|
+
* binding would miss the object other references see, and `===` against
|
|
914
|
+
* them would fail. Block-scoped bindings with an identifier name keep such
|
|
915
|
+
* values by the same rule in lowerVarDecl (preservesObjectIdentity). */
|
|
916
|
+
function jsBindingKeepsCheckedObject(lowerer, nameNode, type) {
|
|
917
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(nameNode)))
|
|
918
|
+
return false;
|
|
919
|
+
const host = hostVariableDeclarationOf(nameNode);
|
|
920
|
+
if (!host || host.type || hasJsTypeAnnotation(host))
|
|
921
|
+
return false;
|
|
922
|
+
const arms = type.kind === "union" ? (lowerer.unions.get(type.unionId)?.arms ?? []) : [type];
|
|
923
|
+
return (arms.some((arm) => arm.kind === "record" || arm.kind === "array") &&
|
|
924
|
+
arms.every((arm) => arm.kind === "record" || arm.kind === "array" || isUnitType(arm)));
|
|
925
|
+
}
|
|
926
|
+
/** Whether `node` mentions the binding `symbol` anywhere, nested functions
|
|
927
|
+
* included. */
|
|
928
|
+
function mentionsSymbol(lowerer, node, symbol) {
|
|
929
|
+
if (ts.isIdentifier(node))
|
|
930
|
+
return lowerer.checker.getSymbolAtLocation(node) === symbol;
|
|
931
|
+
return (ts.forEachChild(node, (child) => mentionsSymbol(lowerer, child, symbol) ? true : undefined) === true);
|
|
932
|
+
}
|
|
933
|
+
/** Whether `node` evaluates to an existing value rather than constructing
|
|
934
|
+
* one whose layout a destination directs: not a literal, `new`, function
|
|
935
|
+
* or class expression, nor a conditional with such an arm (an arm that
|
|
936
|
+
* is `null` or `undefined` constructs nothing). */
|
|
937
|
+
function existingValueForm(node, armOfConditional = false) {
|
|
938
|
+
while (ts.isParenthesizedExpression(node))
|
|
939
|
+
node = node.expression;
|
|
940
|
+
if (ts.isConditionalExpression(node))
|
|
941
|
+
return existingValueForm(node.whenTrue, true) && existingValueForm(node.whenFalse, true);
|
|
942
|
+
if (armOfConditional &&
|
|
943
|
+
(node.kind === ts.SyntaxKind.NullKeyword ||
|
|
944
|
+
(ts.isIdentifier(node) && node.text === "undefined")))
|
|
945
|
+
return true;
|
|
946
|
+
return !(ts.isObjectLiteralExpression(node) ||
|
|
947
|
+
ts.isArrayLiteralExpression(node) ||
|
|
948
|
+
ts.isNewExpression(node) ||
|
|
949
|
+
ts.isFunctionExpression(node) ||
|
|
950
|
+
ts.isArrowFunction(node) ||
|
|
951
|
+
ts.isClassExpression(node) ||
|
|
952
|
+
ts.isLiteralExpression(node) ||
|
|
953
|
+
node.kind === ts.SyntaxKind.NullKeyword);
|
|
954
|
+
}
|
|
955
|
+
/** JavaScript `var x = e` whose binding could hold an existing
|
|
956
|
+
* checked-dynamic object (jsBindingKeepsCheckedObject): lowers `e` BEFORE
|
|
957
|
+
* minting the hoisted slot, as a block-scoped declaration does, so a
|
|
958
|
+
* checked-dynamic value gets a checked-dynamic slot instead of a converted
|
|
959
|
+
* copy. Other values coerce into the planned slot exactly as
|
|
960
|
+
* lowerExprExpecting would. Null when the declaration does not qualify:
|
|
961
|
+
* the slot already exists, the initializer is fresh construction whose
|
|
962
|
+
* layout the slot type directs (existingValueForm; a literal holding an
|
|
963
|
+
* existing checked-dynamic object qualifies), or it refers to the binding
|
|
964
|
+
* itself (hoist-before-init resolves that reference). */
|
|
965
|
+
function lowerJsVarFromExisting(lowerer, decl, symbol) {
|
|
966
|
+
if (!ts.isIdentifier(decl.name) || !decl.initializer)
|
|
967
|
+
return null;
|
|
968
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(decl)) || lowerer.ctx.hoistedVars.has(symbol))
|
|
969
|
+
return null;
|
|
970
|
+
if (lowerer.bindingIn(lowerer.ctx, symbol))
|
|
971
|
+
return null;
|
|
972
|
+
let node = decl.initializer;
|
|
973
|
+
while (ts.isParenthesizedExpression(node) || ts.isSatisfiesExpression(node))
|
|
974
|
+
node = node.expression;
|
|
975
|
+
// A literal holding an existing checked-dynamic object builds as a
|
|
976
|
+
// checked-dynamic literal without a destination (lowerArrayLiteral,
|
|
977
|
+
// lowerObjectLiteral): a record- or array-typed slot would copy it.
|
|
978
|
+
const holdsChecked = (ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node)) &&
|
|
979
|
+
jsHoldsDynObject(lowerer, node);
|
|
980
|
+
if (!holdsChecked && !existingValueForm(node))
|
|
981
|
+
return null;
|
|
982
|
+
const planned = varBindingType(lowerer, decl.name);
|
|
983
|
+
if (!planned || !jsBindingKeepsCheckedObject(lowerer, decl.name, planned))
|
|
984
|
+
return null;
|
|
985
|
+
if (mentionsSymbol(lowerer, node, symbol))
|
|
986
|
+
return null;
|
|
987
|
+
const value = lowerer.lowerExpr(node);
|
|
988
|
+
const local = hoistVarBinding(lowerer, symbol, decl.name, value.type.kind === "dyn" ? DYN : undefined);
|
|
989
|
+
return {
|
|
990
|
+
kind: "assign",
|
|
991
|
+
localId: local.id,
|
|
992
|
+
value: lowerer.coerceExistingInto(node, value, local.type),
|
|
993
|
+
loc: locOf(decl),
|
|
994
|
+
};
|
|
817
995
|
}
|
|
818
996
|
/** The `var` symbol's function-scoped binding TYPE — the declared type at
|
|
819
997
|
* the binding name, with the JS-source fallbacks every mutable binding
|
|
@@ -825,12 +1003,12 @@ function varBindingType(lowerer, nameNode) {
|
|
|
825
1003
|
if (ts.isVariableDeclaration(nameNode.parent) &&
|
|
826
1004
|
isNativeProxyInitializer(lowerer, nameNode.parent.initializer))
|
|
827
1005
|
return DYN;
|
|
828
|
-
if (isJsSourceFile(
|
|
1006
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(nameNode)) &&
|
|
829
1007
|
ts.isVariableDeclaration(nameNode.parent) &&
|
|
830
1008
|
isNativeBuiltinValueInitializer(lowerer, nameNode.parent.initializer))
|
|
831
1009
|
return DYN;
|
|
832
1010
|
let type = lowerer.mapTypeOf(lowerer.typeOf(nameNode));
|
|
833
|
-
if (type?.kind === "record" && isJsSourceFile(
|
|
1011
|
+
if (type?.kind === "record" && isJsSourceFile(ts.getSourceFileOfNode(nameNode))) {
|
|
834
1012
|
const shape = lowerer.shapes.get(type.shapeId);
|
|
835
1013
|
if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
|
|
836
1014
|
type = DYN;
|
|
@@ -866,7 +1044,7 @@ function varBindingType(lowerer, nameNode) {
|
|
|
866
1044
|
* a loop re-ASSIGNS the one binding per pass and never resets it — the
|
|
867
1045
|
* classic capture semantics fall out: closures made in a loop share the
|
|
868
1046
|
* single boxed binding, where `let` gets a fresh box per iteration. */
|
|
869
|
-
function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
1047
|
+
function hoistVarBinding(lowerer, symbol, nameNode, valueType) {
|
|
870
1048
|
const existing = lowerer.ctx.hoistedVars.get(symbol);
|
|
871
1049
|
if (existing)
|
|
872
1050
|
return existing;
|
|
@@ -876,7 +1054,15 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
876
1054
|
lowerer.ctx.hoistedVars.set(symbol, bound);
|
|
877
1055
|
return bound;
|
|
878
1056
|
}
|
|
879
|
-
|
|
1057
|
+
let type = varBindingType(lowerer, nameNode);
|
|
1058
|
+
// The first value stored is an existing checked-dynamic object: keep it
|
|
1059
|
+
// (jsBindingKeepsCheckedObject). A checked-dynamic slot holds undefined
|
|
1060
|
+
// natively, so no runtime-optional widening applies.
|
|
1061
|
+
const keepsChecked = valueType?.kind === "dyn" &&
|
|
1062
|
+
type !== null &&
|
|
1063
|
+
jsBindingKeepsCheckedObject(lowerer, nameNode, type);
|
|
1064
|
+
if (keepsChecked)
|
|
1065
|
+
type = DYN;
|
|
880
1066
|
if (!type)
|
|
881
1067
|
lowerer.badType(nameNode, lowerer.typeOf(nameNode));
|
|
882
1068
|
const root = lowerer.activeStmtLists.find((e) => e.ctx === lowerer.ctx);
|
|
@@ -894,7 +1080,8 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
894
1080
|
};
|
|
895
1081
|
lowerer.ctx.locals.push(local);
|
|
896
1082
|
lowerer.ctx.scopes[0].set(symbol, local);
|
|
897
|
-
|
|
1083
|
+
if (!keepsChecked)
|
|
1084
|
+
noteEarlyReadVar(lowerer, symbol, local);
|
|
898
1085
|
// A checked-dynamic slot holds the dyn undefined (a NULL dyn is a
|
|
899
1086
|
// trap); everything else rides unassignedSlotInit (interned union arm,
|
|
900
1087
|
const wrapped = type.kind === "dyn"
|
|
@@ -921,7 +1108,7 @@ export function predeclareForwardVar(lowerer, symbol) {
|
|
|
921
1108
|
// Module-scope vars already have their global storage.
|
|
922
1109
|
if (lowerer.globalsBySymbol.has(symbol))
|
|
923
1110
|
return false;
|
|
924
|
-
const decl =
|
|
1111
|
+
const decl = symbol.valueDeclaration;
|
|
925
1112
|
if (!decl || !ts.isVariableDeclaration(decl) || !isVarDeclared(decl))
|
|
926
1113
|
return false;
|
|
927
1114
|
const nameNode = ts.isIdentifier(decl.name) ? decl.name : null;
|
|
@@ -1001,7 +1188,7 @@ export function noteBlockedBindings(lowerer, stmt) {
|
|
|
1001
1188
|
}
|
|
1002
1189
|
if (!list)
|
|
1003
1190
|
return;
|
|
1004
|
-
for (const decl of list.declarations) {
|
|
1191
|
+
for (const decl of list.declarations.nodes) {
|
|
1005
1192
|
for (const nameNode of boundIdentifiersOf(decl.name)) {
|
|
1006
1193
|
const symbol = lowerer.checker.getSymbolAtLocation(nameNode);
|
|
1007
1194
|
if (symbol)
|
|
@@ -1026,7 +1213,7 @@ export function isBlockedBinding(lowerer, symbol) {
|
|
|
1026
1213
|
export function lowerScopedBlock(lowerer, stmt) {
|
|
1027
1214
|
lowerer.scopes.push(new Map());
|
|
1028
1215
|
try {
|
|
1029
|
-
return withRuntimeOptionalScope(lowerer, () => ts.isBlock(stmt) ? lowerer.lowerStmts(stmt.statements) : lowerer.lowerStmts([stmt]));
|
|
1216
|
+
return withRuntimeOptionalScope(lowerer, () => ts.isBlock(stmt) ? lowerer.lowerStmts(stmt.statements.nodes) : lowerer.lowerStmts([stmt]));
|
|
1030
1217
|
}
|
|
1031
1218
|
finally {
|
|
1032
1219
|
lowerer.scopes.pop();
|
|
@@ -1084,7 +1271,20 @@ function lowerLabeled(lowerer, stmt) {
|
|
|
1084
1271
|
const body = lowerer.inCtl("block", () => lowerer.lowerScopedBlock(inner), labels);
|
|
1085
1272
|
return { kind: "block", body, labels, loc: locOf(stmt) };
|
|
1086
1273
|
}
|
|
1274
|
+
// Value kinds a `throw` converts to a checked-dynamic value, so the catch
|
|
1275
|
+
// binding sees the thrown object rather than a type-erased reference.
|
|
1276
|
+
const THROWN_AS_DYN = new Set([
|
|
1277
|
+
"array",
|
|
1278
|
+
"union",
|
|
1279
|
+
"map",
|
|
1280
|
+
"set",
|
|
1281
|
+
"bytes",
|
|
1282
|
+
"func",
|
|
1283
|
+
"regex",
|
|
1284
|
+
]);
|
|
1087
1285
|
export function lowerStmt(lowerer, stmt) {
|
|
1286
|
+
if (ownPrototypeResetStatement(lowerer, stmt))
|
|
1287
|
+
return { kind: "block", body: [], loc: locOf(stmt) };
|
|
1088
1288
|
if (ts.isClassDeclaration(stmt)) {
|
|
1089
1289
|
if (!stmt.name)
|
|
1090
1290
|
lowerer.unsupported("SC1090", stmt, "anonymous local class declarations");
|
|
@@ -1097,7 +1297,7 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1097
1297
|
if (ts.isVariableStatement(stmt)) {
|
|
1098
1298
|
// `declare const` — ambient: no storage, no init (collectGlobals
|
|
1099
1299
|
// skipped it; reads throw Node's ReferenceError at the access).
|
|
1100
|
-
const first = stmt.declarationList.declarations[0];
|
|
1300
|
+
const first = stmt.declarationList.declarations.nodes[0];
|
|
1101
1301
|
if (first && ts.getCombinedModifierFlags(first) & ts.ModifierFlags.Ambient)
|
|
1102
1302
|
return null;
|
|
1103
1303
|
return lowerer.lowerVarStatement(stmt);
|
|
@@ -1176,6 +1376,12 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1176
1376
|
// incompatible boundary keeps the ordinary per-statement refusal.
|
|
1177
1377
|
let value = null;
|
|
1178
1378
|
if (stmt.expression) {
|
|
1379
|
+
// A constructor's returned object replaces the constructed `this`.
|
|
1380
|
+
if (lowerer.currentClass?.ctor) {
|
|
1381
|
+
const constructorReturn = lowerConstructorReturn(lowerer, stmt);
|
|
1382
|
+
if (constructorReturn !== null)
|
|
1383
|
+
return constructorReturn;
|
|
1384
|
+
}
|
|
1179
1385
|
return lowerer.lowerReturnStmt(stmt.expression, locOf(stmt));
|
|
1180
1386
|
}
|
|
1181
1387
|
else if (lowerer.ctx.returnType.kind === "union") {
|
|
@@ -1240,6 +1446,13 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1240
1446
|
else if (value.type.kind === "record" && lowerer.dynConvertible(value.type)) {
|
|
1241
1447
|
value = { kind: "dynFrom", value, liveRef: true, type: DYN, loc: locOf(stmt.expression) };
|
|
1242
1448
|
}
|
|
1449
|
+
else if (THROWN_AS_DYN.has(value.type.kind) && lowerer.dynConvertible(value.type)) {
|
|
1450
|
+
// Arrays, Maps, Sets, typed arrays, Buffers, functions, regexes and
|
|
1451
|
+
// unions over them keep their identity and contents the same way:
|
|
1452
|
+
// the catch binding, `typeof`, `instanceof`, `Array.isArray`,
|
|
1453
|
+
// inspection and typed views read the thrown object.
|
|
1454
|
+
value = lowerer.coerceInto(stmt.expression, value, DYN);
|
|
1455
|
+
}
|
|
1243
1456
|
if (value.type.kind === "date") {
|
|
1244
1457
|
lowerer.unsupported("SC1090", stmt.expression, "throwing Date values (catch bindings cannot preserve Date's object kind; throw an Error or primitive instead)");
|
|
1245
1458
|
}
|
|
@@ -1313,77 +1526,131 @@ export function lowerVarStatement(lowerer, stmt) {
|
|
|
1313
1526
|
}
|
|
1314
1527
|
const isConst = (list.flags & ts.NodeFlags.Const) !== 0;
|
|
1315
1528
|
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
|
-
|
|
1529
|
+
return list.declarations.nodes.flatMap((decl) => {
|
|
1530
|
+
const lowered = lowerVarDeclarator(lowerer, stmt, decl, isConst, isLet);
|
|
1531
|
+
// A require binding earlier code can read is initialized from here on
|
|
1532
|
+
// (require-initialization.ts).
|
|
1533
|
+
const initialized = requireInitFlagStmt(lowerer, decl);
|
|
1534
|
+
return initialized ? [...lowered, initialized] : lowered;
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
function lowerVarDeclarator(lowerer, stmt, decl, isConst, isLet) {
|
|
1538
|
+
// The canonical ESM bridge to a compiled program module. Like a
|
|
1539
|
+
// top-level CommonJS require declaration, the binding is alias
|
|
1540
|
+
// plumbing while the dependency evaluates at this statement's
|
|
1541
|
+
// exact position through its run-once initializer.
|
|
1542
|
+
if (isConst && createRequireProgramModuleDecl(lowerer, decl.name, decl.initializer)) {
|
|
1543
|
+
if (!ts.isSourceFile(stmt.parent)) {
|
|
1544
|
+
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)");
|
|
1545
|
+
}
|
|
1546
|
+
const target = createRequireProgramModuleOf(lowerer, decl.initializer);
|
|
1547
|
+
const init = lowerer.requireInitStmt(target.spec, decl);
|
|
1548
|
+
return init ? [init] : [];
|
|
1549
|
+
}
|
|
1550
|
+
// tsc's interop bindings (`const x_1 = __importDefault(require("./m"))`)
|
|
1551
|
+
// are require bindings (cjs-tsc-interop.ts): the module's %init here.
|
|
1552
|
+
if (ts.isSourceFile(stmt.parent)) {
|
|
1553
|
+
const interop = tscInteropBindingOfDecl(lowerer, decl);
|
|
1554
|
+
if (interop !== null) {
|
|
1555
|
+
const init = lowerer.requireInitStmt(interop.spec, decl);
|
|
1327
1556
|
return init ? [init] : [];
|
|
1328
1557
|
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1558
|
+
if (isDeadTscHelperDecl(lowerer, stmt))
|
|
1559
|
+
return [];
|
|
1560
|
+
}
|
|
1561
|
+
// CommonJS require declarations (JS files): at the module's top
|
|
1562
|
+
// level the BINDINGS are alias plumbing (no storage;
|
|
1563
|
+
// resolveValueSymbol routes the reads), but the require itself is
|
|
1564
|
+
// Node's inline module evaluation — a relative require lowers to the
|
|
1565
|
+
// required module's guarded %init call at exactly this position
|
|
1566
|
+
// (first require runs the body, later ones are cache hits; builtins
|
|
1567
|
+
// load nothing). Binding requires anywhere else would need lazily-
|
|
1568
|
+
// initialized alias storage this model doesn't represent; named
|
|
1569
|
+
// fence.
|
|
1570
|
+
if (decl.initializer !== undefined &&
|
|
1571
|
+
requireSpecOf(decl.initializer) !== null &&
|
|
1572
|
+
!isNativeFfiRequire(lowerer, decl.initializer) &&
|
|
1573
|
+
!isJsonRequireDecl(lowerer, decl) &&
|
|
1574
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
1575
|
+
const spec = requireSpecOf(decl.initializer);
|
|
1576
|
+
if (lowerer.externalTypes.has(spec))
|
|
1577
|
+
lowerer.externalHostFence(spec, decl, false);
|
|
1578
|
+
if (ts.isSourceFile(stmt.parent)) {
|
|
1579
|
+
const init = lowerer.requireInitStmt(spec, decl);
|
|
1580
|
+
const out = init ? [init] : [];
|
|
1581
|
+
// Nested patterns destructure the named export's value right after
|
|
1582
|
+
// the module evaluated (`const { codes: { ERR_X } } = require(...)`).
|
|
1583
|
+
for (const element of requireNestedPatternsOf(decl)) {
|
|
1584
|
+
const key = element.propertyName;
|
|
1585
|
+
const value = lowerer.lowerExpr(key);
|
|
1586
|
+
lowerer.lowerBindingPattern(element.name, () => lowerer.lowerExpr(key), value.type, isLet, out);
|
|
1348
1587
|
}
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1588
|
+
return out;
|
|
1589
|
+
}
|
|
1590
|
+
// A nested BUILTIN require (`get inFreeBSDJail() { const { execSync }
|
|
1591
|
+
// = require('child_process'); ... }` — test/common's lazy-getter
|
|
1592
|
+
// idiom): builtins load nothing, so the statement is PURE alias
|
|
1593
|
+
// plumbing wherever it sits — the bindings resolve through the
|
|
1594
|
+
// same routing top-level requires use, and no statement remains.
|
|
1595
|
+
// Relative requires keep the fence: their module-init-at-position
|
|
1596
|
+
// semantics needs storage this model doesn't represent.
|
|
1597
|
+
if (canonicalBuiltinModule(spec) !== null) {
|
|
1598
|
+
return canonicalBuiltinModule(spec) === "punycode"
|
|
1599
|
+
? [lowerer.punycodeRequireWarning(decl)]
|
|
1600
|
+
: [];
|
|
1601
|
+
}
|
|
1602
|
+
lowerer.unsupported("SC1090", decl, "require() with bindings outside the module's top level (move it to the top of the file)");
|
|
1603
|
+
}
|
|
1604
|
+
// `const { NGHTTP2_CANCEL } = http2.constants` — a destructure over
|
|
1605
|
+
// the baked constants table: alias plumbing, no storage (uses read
|
|
1606
|
+
// their literals via builtinConstantBindingOf; collectGlobals skipped
|
|
1607
|
+
// the globals by the same test).
|
|
1608
|
+
if (lowerer.builtinConstantsDestructureDecl(decl.name, decl.initializer))
|
|
1609
|
+
return [];
|
|
1610
|
+
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
1611
|
+
// `const { createSign } = crypto` over a builtin NAMESPACE binding:
|
|
1612
|
+
// alias plumbing (builtinImportOf routes the reads) — no statement.
|
|
1613
|
+
if (builtinNamespaceDestructureModuleOf(lowerer, decl) !== null)
|
|
1614
|
+
return [];
|
|
1615
|
+
// `const { A, B } = ns` over a CommonJS module binding: each name
|
|
1616
|
+
// snapshots the named export's value here (cjs-inline-require.ts).
|
|
1617
|
+
{
|
|
1618
|
+
const nsDestructure = cjsNamespaceDestructureOf(lowerer, decl);
|
|
1619
|
+
if (nsDestructure !== null) {
|
|
1620
|
+
const out = [];
|
|
1621
|
+
for (const element of nsDestructure.elements) {
|
|
1622
|
+
const target = lowerer.globalOf(element.name);
|
|
1623
|
+
const value = cjsExportValueByName(lowerer, nsDestructure.dep, element.key, element.name);
|
|
1624
|
+
if (target === null || value === null) {
|
|
1625
|
+
lowerer.unsupported("SC1090", element.name, `destructuring the export '${element.key}' of a CommonJS module binding (it has no static value)`);
|
|
1626
|
+
}
|
|
1627
|
+
out.push({
|
|
1628
|
+
kind: "assign",
|
|
1629
|
+
localId: target.id,
|
|
1630
|
+
value: typeEquals(value.type, target.type)
|
|
1631
|
+
? value
|
|
1632
|
+
: lowerer.coerceInto(element.name, value, target.type),
|
|
1633
|
+
loc: locOf(element.name),
|
|
1634
|
+
...("tdz" in target && target.tdz ? { initializes: true } : {}),
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
return out;
|
|
1358
1638
|
}
|
|
1359
|
-
lowerer.unsupported("SC1090", decl, "require() with bindings outside the module's top level (move it to the top of the file)");
|
|
1360
1639
|
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
// numeric value iterators retain source/cursor/done hidden locals; a
|
|
1376
|
-
// matchAll drain retains its companion index array so a later
|
|
1377
|
-
// for-of can serve `m.index`. Both are const-only interceptions.
|
|
1378
|
-
const numericIterator = lowerNumericIteratorDecl(lowerer, decl, isConst);
|
|
1379
|
-
if (numericIterator)
|
|
1380
|
-
return numericIterator;
|
|
1381
|
-
const drained = lowerMatchAllDrainDecl(lowerer, decl, isConst);
|
|
1382
|
-
if (drained)
|
|
1383
|
-
return drained;
|
|
1384
|
-
const lowered = lowerer.lowerVarDecl(decl, isLet);
|
|
1385
|
-
return lowered ? [lowered] : [];
|
|
1386
|
-
});
|
|
1640
|
+
return lowerer.lowerDestructuringDecl(decl, isLet);
|
|
1641
|
+
}
|
|
1642
|
+
// STORED protocol values with statically closed representations:
|
|
1643
|
+
// numeric value iterators retain source/cursor/done hidden locals; a
|
|
1644
|
+
// matchAll drain retains its companion index array so a later
|
|
1645
|
+
// for-of can serve `m.index`. Both are const-only interceptions.
|
|
1646
|
+
const numericIterator = lowerNumericIteratorDecl(lowerer, decl, isConst);
|
|
1647
|
+
if (numericIterator)
|
|
1648
|
+
return numericIterator;
|
|
1649
|
+
const drained = lowerMatchAllDrainDecl(lowerer, decl, isConst);
|
|
1650
|
+
if (drained)
|
|
1651
|
+
return drained;
|
|
1652
|
+
const lowered = lowerer.lowerVarDecl(decl, isLet);
|
|
1653
|
+
return lowered ? [lowered] : [];
|
|
1387
1654
|
}
|
|
1388
1655
|
/** The numeric indexed source of a built-in value-iterator expression:
|
|
1389
1656
|
* `numbers.values()` or the equivalent
|
|
@@ -1398,7 +1665,7 @@ export function numericIteratorSourceOf(lowerer, expr) {
|
|
|
1398
1665
|
let init = expr;
|
|
1399
1666
|
while (ts.isParenthesizedExpression(init))
|
|
1400
1667
|
init = init.expression;
|
|
1401
|
-
if (!ts.isCallExpression(init) || init.questionDotToken || init.arguments.length !== 0)
|
|
1668
|
+
if (!ts.isCallExpression(init) || init.questionDotToken || init.arguments.nodes.length !== 0)
|
|
1402
1669
|
return null;
|
|
1403
1670
|
let receiver = null;
|
|
1404
1671
|
if (ts.isPropertyAccessExpression(init.expression) &&
|
|
@@ -1494,7 +1761,7 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1494
1761
|
const loc = locOf(decl);
|
|
1495
1762
|
const access = call.expression;
|
|
1496
1763
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
1497
|
-
const re = lowerer.lowerExpr(call.arguments[0]);
|
|
1764
|
+
const re = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
1498
1765
|
const idxsT = arrayOf(F64);
|
|
1499
1766
|
const idxs = lowerer.declareHiddenLocal("%midxs", idxsT);
|
|
1500
1767
|
const local = lowerer.declareLocal(decl.name, decl.name.text, rowsT, false);
|
|
@@ -1511,7 +1778,9 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1511
1778
|
localId: local.id,
|
|
1512
1779
|
init: {
|
|
1513
1780
|
kind: "regexIntrinsic",
|
|
1514
|
-
method:
|
|
1781
|
+
method: storedMatchAllRowsReadByElements(lowerer, decl)
|
|
1782
|
+
? "matchAllCapturesInto"
|
|
1783
|
+
: "matchAllInto",
|
|
1515
1784
|
receiver,
|
|
1516
1785
|
args: [re, { kind: "varRef", localId: idxs.id, type: idxsT, loc }],
|
|
1517
1786
|
type: rowsT,
|
|
@@ -1527,7 +1796,7 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1527
1796
|
export function isParseArgsDynCheckerType(lowerer, type) {
|
|
1528
1797
|
const widened = lowerer.checker.getBaseTypeOfLiteralType(type);
|
|
1529
1798
|
const declarationBelongs = (d) => {
|
|
1530
|
-
if (!lowerer.isStdlibFile(
|
|
1799
|
+
if (!lowerer.isStdlibFile(ts.getSourceFileOfNode(d)))
|
|
1531
1800
|
return false;
|
|
1532
1801
|
let inParseArgsType = false;
|
|
1533
1802
|
for (let node = d.parent; node; node = node.parent) {
|
|
@@ -1543,8 +1812,8 @@ export function isParseArgsDynCheckerType(lowerer, type) {
|
|
|
1543
1812
|
};
|
|
1544
1813
|
const sym = widened.getAliasSymbol() ?? widened.getSymbol();
|
|
1545
1814
|
if (sym &&
|
|
1546
|
-
isParseArgsDynTypeName(sym
|
|
1547
|
-
|
|
1815
|
+
isParseArgsDynTypeName(ts.symbolName(sym)) &&
|
|
1816
|
+
sym.declarations.some(declarationBelongs)) {
|
|
1548
1817
|
return true;
|
|
1549
1818
|
}
|
|
1550
1819
|
// A discriminant check erases the token alias and leaves one anonymous
|
|
@@ -1552,7 +1821,7 @@ export function isParseArgsDynCheckerType(lowerer, type) {
|
|
|
1552
1821
|
// is the same stable signal the dotted-member bridge uses.
|
|
1553
1822
|
return lowerer.checker
|
|
1554
1823
|
.getPropertiesOfType(widened)
|
|
1555
|
-
.some((p) =>
|
|
1824
|
+
.some((p) => p.declarations.some(declarationBelongs));
|
|
1556
1825
|
}
|
|
1557
1826
|
/** Destructuring declarations, desugared as sugar over indexed/field
|
|
1558
1827
|
* reads: the initializer evaluates ONCE into a hidden temp, then each
|
|
@@ -1587,12 +1856,17 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1587
1856
|
lowerer.lowerExpr(decl.initializer);
|
|
1588
1857
|
const parseArgsDynObject = init.type.kind === "dyn" &&
|
|
1589
1858
|
isParseArgsDynCheckerType(lowerer, lowerer.typeOf(decl.initializer));
|
|
1590
|
-
// An `any`-origin source
|
|
1591
|
-
//
|
|
1859
|
+
// An `any`-origin source destructures through a represented record or
|
|
1860
|
+
// array shape, or through the checked-dynamic value it lowered to: the
|
|
1861
|
+
// pattern reads members (or iterates) the dyn value exactly as a
|
|
1862
|
+
// JavaScript file's pattern does, with the same per-site runtime fences
|
|
1863
|
+
// (null/undefined sources throw Node's TypeError). Primitive and unit
|
|
1864
|
+
// sources keep their own fences below; other carriers keep this one.
|
|
1592
1865
|
if (lowerer.anyOrigin(decl.initializer) &&
|
|
1593
|
-
!isJsSourceFile(
|
|
1866
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1594
1867
|
init.type.kind !== "record" &&
|
|
1595
|
-
init.type.kind !== "array"
|
|
1868
|
+
init.type.kind !== "array" &&
|
|
1869
|
+
init.type.kind !== "dyn") {
|
|
1596
1870
|
lowerer.anyOpFence("destructuring", decl);
|
|
1597
1871
|
}
|
|
1598
1872
|
// An IR-string source the CHECKER does not type as a string is a
|
|
@@ -1603,7 +1877,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1603
1877
|
// points), numbers and characters Node never sees. The fence names
|
|
1604
1878
|
// the checker's own type instead of the carrier.
|
|
1605
1879
|
if (init.type.kind === "string" &&
|
|
1606
|
-
isJsSourceFile(
|
|
1880
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1607
1881
|
!checkerStringSource(lowerer, decl.initializer)) {
|
|
1608
1882
|
lowerer.unsupported("SC1031", decl.name, ts.isArrayBindingPattern(decl.name)
|
|
1609
1883
|
? `array destructuring of non-array values (the source is '${lowerer.checker.typeToString(lowerer.typeOf(decl.initializer))}'-typed)`
|
|
@@ -1615,7 +1889,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1615
1889
|
init.type.kind === "bool" ||
|
|
1616
1890
|
init.type.kind === "string" ||
|
|
1617
1891
|
isUnitType(init.type)) &&
|
|
1618
|
-
!isJsSourceFile(
|
|
1892
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1619
1893
|
!(init.type.kind === "string" &&
|
|
1620
1894
|
staticStringPattern(lowerer, decl.name))) {
|
|
1621
1895
|
{
|
|
@@ -1631,7 +1905,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1631
1905
|
// (the message is the fence's — a unit value here is the failure
|
|
1632
1906
|
// path either way). TypeScript keeps the fence: narrowing first is
|
|
1633
1907
|
// the annotated fix.
|
|
1634
|
-
if (isJsSourceFile(
|
|
1908
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) && init.type.kind === "union") {
|
|
1635
1909
|
const def = lowerer.unions.get(init.type.unionId);
|
|
1636
1910
|
const dataArms = (def?.arms ?? []).filter((a) => !isUnitType(a));
|
|
1637
1911
|
const arm = dataArms[0];
|
|
@@ -1669,41 +1943,47 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1669
1943
|
init = { kind: "unionNarrow", unionId: init.type.unionId, tag, value: uref, type: arm, loc };
|
|
1670
1944
|
}
|
|
1671
1945
|
}
|
|
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
|
-
}
|
|
1946
|
+
const groupsSource = matchGroupsPatternSource(lowerer, decl.name, init, () => matchResultNamedGroupsOf(lowerer, decl.initializer), loc);
|
|
1947
|
+
if (groupsSource !== null)
|
|
1948
|
+
init = groupsSource;
|
|
1705
1949
|
const tmp = lowerer.declareHiddenLocal("%destr", init.type);
|
|
1706
1950
|
out.push({ kind: "varDecl", localId: tmp.id, init, loc });
|
|
1951
|
+
// A TypeScript `any` source destructured through its checked-dynamic
|
|
1952
|
+
// value: RequireObjectCoercible with V8's own TypeError ("Cannot
|
|
1953
|
+
// destructure property 'a' of 'f(...)' as it is null.") for the source
|
|
1954
|
+
// spellings the assignment form reproduces; other sources are refused,
|
|
1955
|
+
// as in the assignment form. JavaScript files keep their existing
|
|
1956
|
+
// per-read errors.
|
|
1957
|
+
if (init.type.kind === "dyn" &&
|
|
1958
|
+
ts.isObjectBindingPattern(decl.name) &&
|
|
1959
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1960
|
+
lowerer.anyOrigin(decl.initializer)) {
|
|
1961
|
+
const spelling = destrSpellingOf(decl.initializer);
|
|
1962
|
+
if (spelling === null) {
|
|
1963
|
+
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)");
|
|
1964
|
+
}
|
|
1965
|
+
const first = decl.name.elements.nodes[0];
|
|
1966
|
+
const firstKey = first === undefined || first.dotDotDotToken !== undefined
|
|
1967
|
+
? undefined
|
|
1968
|
+
: (first.propertyName ?? first.name);
|
|
1969
|
+
// V8 names the first property when its key is an identifier, a string
|
|
1970
|
+
// or a number; a computed first key takes the bare (source-only) form.
|
|
1971
|
+
const firstProp = firstKey === undefined || ts.isComputedPropertyName(firstKey)
|
|
1972
|
+
? undefined
|
|
1973
|
+
: (patternKeyNameOf(lowerer, firstKey) ?? undefined);
|
|
1974
|
+
out.push({
|
|
1975
|
+
kind: "exprStmt",
|
|
1976
|
+
expr: {
|
|
1977
|
+
kind: "dynDestrCheck",
|
|
1978
|
+
value: { kind: "varRef", localId: tmp.id, type: init.type, loc },
|
|
1979
|
+
spelling,
|
|
1980
|
+
...(firstProp !== undefined ? { firstProp } : {}),
|
|
1981
|
+
type: init.type,
|
|
1982
|
+
loc,
|
|
1983
|
+
},
|
|
1984
|
+
loc,
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1707
1987
|
// V8's destructuring TypeError spells STATIC sources: an identifier
|
|
1708
1988
|
// source reads "<name> is not iterable", an identifier-callee call
|
|
1709
1989
|
// "<name> is not a function or its return value is not iterable";
|
|
@@ -1719,6 +1999,44 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1719
1999
|
lowerer.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: init.type, loc }), init.type, isLet, out, dynSpell, parseArgsDynObject);
|
|
1720
2000
|
return out;
|
|
1721
2001
|
}
|
|
2002
|
+
/** `const { groups } = re.exec(s)!` / `const { groups: { year } } = m`
|
|
2003
|
+
* — every pattern element binds `groups` off a match row whose regex is
|
|
2004
|
+
* statically known. The slice (or a JavaScript callback's dynamic row)
|
|
2005
|
+
* has no record shape of its own, so the groups projection
|
|
2006
|
+
* (lowerGroupsProjection — the same record `m.groups` reads produce)
|
|
2007
|
+
* wraps one level in a synthesized `{ groups: ... }` record and the
|
|
2008
|
+
* ordinary record destructure serves the pattern — aliases and nested
|
|
2009
|
+
* patterns included. Only named-group regexes take the wrap: a
|
|
2010
|
+
* group-less regex destructures `groups: undefined` in Node (a nested
|
|
2011
|
+
* pattern then throws), which the fence reports honestly instead. Null
|
|
2012
|
+
* when the pattern or the row does not qualify. */
|
|
2013
|
+
export function matchGroupsPatternSource(lowerer, pattern, row, groupsOf, loc) {
|
|
2014
|
+
if (!ts.isObjectBindingPattern(pattern) ||
|
|
2015
|
+
pattern.elements.nodes.length === 0 ||
|
|
2016
|
+
!(row.type.kind === "dyn"
|
|
2017
|
+
? isJsSourceFile(ts.getSourceFileOfNode(pattern))
|
|
2018
|
+
: isMatchSliceType(lowerer, row.type)) ||
|
|
2019
|
+
!pattern.elements.nodes.every((el) => {
|
|
2020
|
+
if (el.dotDotDotToken !== undefined || el.name === undefined)
|
|
2021
|
+
return false;
|
|
2022
|
+
const prop = el.propertyName;
|
|
2023
|
+
if (prop === undefined)
|
|
2024
|
+
return ts.isIdentifier(el.name) && el.name.text === "groups";
|
|
2025
|
+
return (ts.isIdentifier(prop) || ts.isStringLiteral(prop)) && prop.text === "groups";
|
|
2026
|
+
}))
|
|
2027
|
+
return null;
|
|
2028
|
+
const groups = groupsOf();
|
|
2029
|
+
if (groups === null || groups.length === 0)
|
|
2030
|
+
return null;
|
|
2031
|
+
const proj = lowerGroupsProjection(lowerer, row, groups, loc);
|
|
2032
|
+
const outerShape = lowerer.shapes.intern([{ name: "groups", type: proj.type }], false, undefined, ["groups"]);
|
|
2033
|
+
return {
|
|
2034
|
+
kind: "recordLit",
|
|
2035
|
+
fields: [{ name: "groups", value: proj }],
|
|
2036
|
+
type: { kind: "record", shapeId: outerShape },
|
|
2037
|
+
loc,
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
1722
2040
|
/** One pattern level: emits a declaration (or global assignment) per
|
|
1723
2041
|
* bound name, recursing through hidden temps for nested patterns. */
|
|
1724
2042
|
export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, out, dynSpell, allowDynObject = false) {
|
|
@@ -1726,7 +2044,9 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1726
2044
|
const patternType = lowerer.typeOf(pattern);
|
|
1727
2045
|
const patternSymbol = patternType.getSymbol();
|
|
1728
2046
|
allowDynObject ||=
|
|
1729
|
-
patternSymbol
|
|
2047
|
+
patternSymbol !== undefined &&
|
|
2048
|
+
ts.symbolName(patternSymbol) === "SegmentData" &&
|
|
2049
|
+
lowerer.isStdlibSymbol(patternSymbol);
|
|
1730
2050
|
allowDynObject ||=
|
|
1731
2051
|
(patternType.flags & ts.TypeFlags.Object) !== 0 &&
|
|
1732
2052
|
lowerer.mapTypeOf(patternType)?.kind === "dyn";
|
|
@@ -1740,17 +2060,22 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1740
2060
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
1741
2061
|
lowerer.fenceStaticHeadersIteration(pattern);
|
|
1742
2062
|
if (srcType.kind === "union" &&
|
|
1743
|
-
lowerer.unions
|
|
1744
|
-
|
|
1745
|
-
|
|
2063
|
+
lowerer.unions
|
|
2064
|
+
.get(srcType.unionId)
|
|
2065
|
+
?.arms.every((arm) => arm.kind === "array" ||
|
|
2066
|
+
arm.kind === "string" ||
|
|
2067
|
+
(arm.kind === "record" && lowerer.shapes.get(arm.shapeId)?.tuple === true)) &&
|
|
2068
|
+
lowerer.unions.get(srcType.unionId).arms.some((arm) => arm.kind !== "string")) {
|
|
2069
|
+
for (let i = 0; i < pattern.elements.nodes.length; i++) {
|
|
2070
|
+
const el = pattern.elements.nodes[i];
|
|
1746
2071
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1747
2072
|
continue;
|
|
1748
2073
|
if (el.dotDotDotToken)
|
|
1749
|
-
lowerer.unsupported("SC1031", el, "rest elements over a union of array layouts");
|
|
2074
|
+
lowerer.unsupported("SC1031", el, "rest elements over a union of array or tuple layouts");
|
|
1750
2075
|
const loc = locOf(el);
|
|
1751
|
-
let value = unionArrayValueRead(lowerer, srcRef(), numLit(i, loc), loc);
|
|
2076
|
+
let value = unionArrayValueRead(lowerer, srcRef(), numLit(i, loc), loc, (text) => strCharsCall(lowerer, text, loc));
|
|
1752
2077
|
if (!value)
|
|
1753
|
-
lowerer.unsupported("SC1031", el, "array union elements without a common native representation");
|
|
2078
|
+
lowerer.unsupported("SC1031", el, "array or tuple union elements without a common native representation");
|
|
1754
2079
|
if (el.initializer)
|
|
1755
2080
|
value = applyBindingDefault(lowerer, el, value);
|
|
1756
2081
|
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
@@ -1761,7 +2086,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1761
2086
|
// shape — the positional twin of object destructuring below.
|
|
1762
2087
|
const tupleShape = srcType.kind === "record" ? lowerer.shapes.get(srcType.shapeId) : undefined;
|
|
1763
2088
|
if (srcType.kind === "record" && tupleShape?.tuple) {
|
|
1764
|
-
pattern.elements.forEach((el, i) => {
|
|
2089
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1765
2090
|
// Holes: OmittedExpression in 5.9.3, a nameless BindingElement in
|
|
1766
2091
|
// 7 (parity finding 2) — either way the position is skipped.
|
|
1767
2092
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
@@ -1828,7 +2153,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1828
2153
|
loc,
|
|
1829
2154
|
});
|
|
1830
2155
|
const itRef = () => ({ kind: "varRef", localId: it.id, type: citPat.iterT, loc });
|
|
1831
|
-
for (const el of pattern.elements) {
|
|
2156
|
+
for (const el of pattern.elements.nodes) {
|
|
1832
2157
|
const stepLoc = locOf(el);
|
|
1833
2158
|
const step = lowerer.classIteratorNextCall(citPat, itRef(), stepLoc);
|
|
1834
2159
|
if (ts.isOmittedExpression(el) || el.name === undefined) {
|
|
@@ -1902,10 +2227,10 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1902
2227
|
out.push({
|
|
1903
2228
|
kind: "varDecl",
|
|
1904
2229
|
localId: pack.id,
|
|
1905
|
-
init: pattern.elements.some((element) => ts.isBindingElement(element) && element.dotDotDotToken)
|
|
2230
|
+
init: pattern.elements.nodes.some((element) => ts.isBindingElement(element) && element.dotDotDotToken)
|
|
1906
2231
|
? {
|
|
1907
2232
|
kind: "libCall",
|
|
1908
|
-
fn: "dyn.
|
|
2233
|
+
fn: "dyn.destructureRest",
|
|
1909
2234
|
args: [srcRef(), { kind: "strLit", value: dynSpell ?? "", type: STRING, loc }],
|
|
1910
2235
|
type: DYN,
|
|
1911
2236
|
loc,
|
|
@@ -1913,14 +2238,14 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1913
2238
|
: {
|
|
1914
2239
|
kind: "dynIterN",
|
|
1915
2240
|
value: srcRef(),
|
|
1916
|
-
count: pattern.elements.length,
|
|
2241
|
+
count: pattern.elements.nodes.length,
|
|
1917
2242
|
...(dynSpell ? { notIterableMessage: dynSpell } : {}),
|
|
1918
2243
|
type: DYN,
|
|
1919
2244
|
loc,
|
|
1920
2245
|
},
|
|
1921
2246
|
loc,
|
|
1922
2247
|
});
|
|
1923
|
-
pattern.elements.forEach((el, i) => {
|
|
2248
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1924
2249
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1925
2250
|
return; // hole: the position skips
|
|
1926
2251
|
const elLoc = locOf(el);
|
|
@@ -1976,7 +2301,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1976
2301
|
// fresh number[] (never another typed array), exactly the iterator
|
|
1977
2302
|
// protocol's Array accumulation.
|
|
1978
2303
|
if (srcType.kind === "bytes") {
|
|
1979
|
-
pattern.elements.forEach((el, i) => {
|
|
2304
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1980
2305
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1981
2306
|
return;
|
|
1982
2307
|
const loc = locOf(el);
|
|
@@ -2018,10 +2343,30 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2018
2343
|
});
|
|
2019
2344
|
return;
|
|
2020
2345
|
}
|
|
2346
|
+
// Map and Set sources (`const [[k, v], ...rest] = map`): the iterator
|
|
2347
|
+
// yields the collection's entries (Map pairs) or values in order, so
|
|
2348
|
+
// the source snapshots ONCE into that array — the spread's own
|
|
2349
|
+
// machinery — and the pattern lowers as an array pattern over it,
|
|
2350
|
+
// like the string case above. Element defaults keep a fence: they
|
|
2351
|
+
// run between iterator steps and could mutate the live collection.
|
|
2352
|
+
if (srcType.kind === "map" || srcType.kind === "set") {
|
|
2353
|
+
const defaulted = pattern.elements.nodes.find((el) => ts.isBindingElement(el) && el.initializer !== undefined && !el.dotDotDotToken);
|
|
2354
|
+
if (defaulted)
|
|
2355
|
+
lowerer.unsupported("SC1031", defaulted, "binding defaults over Map/Set sources");
|
|
2356
|
+
const snapshot = lowerCollectionSpread(lowerer, srcRef(), pattern);
|
|
2357
|
+
if (snapshot && snapshot.type.kind === "array") {
|
|
2358
|
+
const loc = locOf(pattern);
|
|
2359
|
+
const snapshotT = snapshot.type;
|
|
2360
|
+
const entries = lowerer.declareHiddenLocal("%dentries", snapshotT);
|
|
2361
|
+
out.push({ kind: "varDecl", localId: entries.id, init: snapshot, loc });
|
|
2362
|
+
lowerer.lowerBindingPattern(pattern, () => ({ kind: "varRef", localId: entries.id, type: snapshotT, loc }), snapshotT, isLet, out);
|
|
2363
|
+
return;
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2021
2366
|
if (srcType.kind !== "array") {
|
|
2022
2367
|
lowerer.unsupported("SC1031", pattern, `array destructuring of non-array values (the source is ${srcType.kind}-typed)`);
|
|
2023
2368
|
}
|
|
2024
|
-
pattern.elements.forEach((el, i) => {
|
|
2369
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
2025
2370
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
2026
2371
|
return; // hole: position skipped, like JS over an array
|
|
2027
2372
|
const loc = locOf(el);
|
|
@@ -2054,7 +2399,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2054
2399
|
});
|
|
2055
2400
|
return;
|
|
2056
2401
|
}
|
|
2057
|
-
if (pattern.elements.length === 0) {
|
|
2402
|
+
if (pattern.elements.nodes.length === 0) {
|
|
2058
2403
|
// `var {} = e`, `for (const {} of ns)`: RequireObjectCoercible and
|
|
2059
2404
|
// nothing else — a pure no-op past the source's own evaluation for
|
|
2060
2405
|
// every statically non-nullish kind, record or not (the assignment
|
|
@@ -2079,19 +2424,19 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2079
2424
|
// deliberately carried by the checked-dynamic tree, so their ordinary
|
|
2080
2425
|
// object patterns use the same exact keyed-read desugar.
|
|
2081
2426
|
if (srcType.kind === "union" &&
|
|
2082
|
-
isJsSourceFile(
|
|
2427
|
+
isJsSourceFile(ts.getSourceFileOfNode(pattern)) &&
|
|
2083
2428
|
lowerer.dynConvertible(srcType)) {
|
|
2084
2429
|
lowerer.lowerBindingPattern(pattern, () => lowerer.coerceToExpected(srcRef(), DYN), DYN, isLet, out, dynSpell, allowDynObject);
|
|
2085
2430
|
return;
|
|
2086
2431
|
}
|
|
2087
2432
|
if (srcType.kind === "dyn") {
|
|
2088
|
-
for (const el of pattern.elements) {
|
|
2433
|
+
for (const el of pattern.elements.nodes) {
|
|
2089
2434
|
if (el.name === undefined)
|
|
2090
2435
|
continue;
|
|
2091
2436
|
const loc = locOf(el);
|
|
2092
2437
|
if (el.dotDotDotToken) {
|
|
2093
2438
|
const keys = [];
|
|
2094
|
-
for (const sibling of pattern.elements) {
|
|
2439
|
+
for (const sibling of pattern.elements.nodes) {
|
|
2095
2440
|
if (sibling === el || sibling.dotDotDotToken)
|
|
2096
2441
|
continue;
|
|
2097
2442
|
const key = sibling.propertyName ?? sibling.name;
|
|
@@ -2169,7 +2514,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2169
2514
|
if (!info)
|
|
2170
2515
|
lowerer.flushDeferredClass(srcType.className);
|
|
2171
2516
|
if (info) {
|
|
2172
|
-
for (const el of pattern.elements) {
|
|
2517
|
+
for (const el of pattern.elements.nodes) {
|
|
2173
2518
|
if (el.name === undefined)
|
|
2174
2519
|
continue;
|
|
2175
2520
|
const loc = locOf(el);
|
|
@@ -2179,7 +2524,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2179
2524
|
// CopyDataProperties copies own enumerable properties, which
|
|
2180
2525
|
// for a class instance are exactly the fields).
|
|
2181
2526
|
const consumed = new Set();
|
|
2182
|
-
for (const sib of pattern.elements) {
|
|
2527
|
+
for (const sib of pattern.elements.nodes) {
|
|
2183
2528
|
if (sib === el || sib.name === undefined || sib.dotDotDotToken)
|
|
2184
2529
|
continue;
|
|
2185
2530
|
const keyNode = sib.propertyName ?? (ts.isIdentifier(sib.name) ? sib.name : null);
|
|
@@ -2258,7 +2603,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2258
2603
|
// naming that. Callers vetted the source as a checker-typed string —
|
|
2259
2604
|
// builtin identity tokens fence before reaching here.
|
|
2260
2605
|
if (srcType.kind === "string") {
|
|
2261
|
-
for (const el of pattern.elements) {
|
|
2606
|
+
for (const el of pattern.elements.nodes) {
|
|
2262
2607
|
if (el.name === undefined)
|
|
2263
2608
|
continue;
|
|
2264
2609
|
const loc = locOf(el);
|
|
@@ -2294,6 +2639,21 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2294
2639
|
}
|
|
2295
2640
|
return;
|
|
2296
2641
|
}
|
|
2642
|
+
if (srcType.kind === "array" &&
|
|
2643
|
+
isMatchSliceType(lowerer, srcType) &&
|
|
2644
|
+
isRegexMatchResultPattern(lowerer, pattern)) {
|
|
2645
|
+
lowerMatchResultObjectPattern(lowerer, pattern, srcRef, srcType, isLet, out);
|
|
2646
|
+
return;
|
|
2647
|
+
}
|
|
2648
|
+
if (srcType.kind === "array" && isArrayPositionPattern(lowerer, pattern)) {
|
|
2649
|
+
lowerArrayPositionObjectPattern(lowerer, pattern, srcRef, srcType, isLet, out);
|
|
2650
|
+
return;
|
|
2651
|
+
}
|
|
2652
|
+
const nsSource = lowerer.sourceFileOfModuleNamespace(srcType);
|
|
2653
|
+
if (nsSource !== null) {
|
|
2654
|
+
lowerModuleNamespacePattern(lowerer, pattern, nsSource, isLet, out);
|
|
2655
|
+
return;
|
|
2656
|
+
}
|
|
2297
2657
|
if (srcType.kind !== "record") {
|
|
2298
2658
|
lowerer.unsupported("SC1031", pattern, srcType.kind === "object"
|
|
2299
2659
|
? "object destructuring of class instances (read the fields directly — accessors make the desugar observable)"
|
|
@@ -2302,7 +2662,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2302
2662
|
const shape = lowerer.shapes.get(srcType.shapeId);
|
|
2303
2663
|
if (!shape)
|
|
2304
2664
|
throw new InternalCompilerError(`lowerer bug: destructuring unknown shape ${srcType.shapeId}`);
|
|
2305
|
-
for (const el of pattern.elements) {
|
|
2665
|
+
for (const el of pattern.elements.nodes) {
|
|
2306
2666
|
if (el.name === undefined)
|
|
2307
2667
|
continue; // 7 spells elisions as nameless elements
|
|
2308
2668
|
// `{ a, ...rest }`: the rest binds a FRESH record of the unconsumed
|
|
@@ -2376,18 +2736,19 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2376
2736
|
// An UNDECLARED key of an INDEX-SIGNATURE shape (`const { m, n, p }
|
|
2377
2737
|
// = ....groups` over `{ [key: string]: string }` — the groups
|
|
2378
2738
|
// 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).
|
|
2739
|
+
// read, exactly the dot access's recordKeyGet — a missing key binds
|
|
2740
|
+
// the undefined arm (where a default applies like any field's).
|
|
2383
2741
|
const loc = locOf(el);
|
|
2742
|
+
const readType = shape.indexValue.kind === "dyn"
|
|
2743
|
+
? shape.indexValue
|
|
2744
|
+
: (lowerer.withUndefinedArmOf(shape.indexValue) ?? shape.indexValue);
|
|
2384
2745
|
let value = {
|
|
2385
2746
|
kind: "recordKeyGet",
|
|
2386
2747
|
obj: srcRef(),
|
|
2387
2748
|
shapeId: srcType.shapeId,
|
|
2388
2749
|
key: { kind: "strLit", value: propName, type: STRING, loc },
|
|
2389
2750
|
overflowOnly: true,
|
|
2390
|
-
type:
|
|
2751
|
+
type: readType,
|
|
2391
2752
|
loc,
|
|
2392
2753
|
};
|
|
2393
2754
|
if (el.initializer)
|
|
@@ -2395,7 +2756,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2395
2756
|
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
2396
2757
|
continue;
|
|
2397
2758
|
}
|
|
2398
|
-
if (!fieldType && isJsSourceFile(
|
|
2759
|
+
if (!fieldType && isJsSourceFile(ts.getSourceFileOfNode(el))) {
|
|
2399
2760
|
// Inferred JavaScript shapes can omit optional own properties and
|
|
2400
2761
|
// inherit values from their prototype. Read the live checked view.
|
|
2401
2762
|
const loc = locOf(el);
|
|
@@ -2512,7 +2873,51 @@ function patternSourceValue(lowerer, value, arrayPattern, out, loc, spelling) {
|
|
|
2512
2873
|
function patternBindingType(lowerer, name) {
|
|
2513
2874
|
const type = lowerer.typeOf(name);
|
|
2514
2875
|
return (lowerer.mapTypeOf(type) ??
|
|
2515
|
-
(isJsSourceFile(
|
|
2876
|
+
(isJsSourceFile(ts.getSourceFileOfNode(name)) ? dynFallbackType(lowerer, name, type) : null));
|
|
2877
|
+
}
|
|
2878
|
+
/** `const { a, b: c } = ns` / `const { f } = await import("./m")` over
|
|
2879
|
+
* a program module's namespace: each element reads the export exactly
|
|
2880
|
+
* like `ns.a` does — the member resolves to the exporter's own binding
|
|
2881
|
+
* (nsMemberIdentOf's rule), read once at the pattern's position, so the
|
|
2882
|
+
* bound name holds the export's value at that moment (destructuring
|
|
2883
|
+
* copies; it does not alias the live binding). The namespace value
|
|
2884
|
+
* itself was already evaluated into the pattern's temp, so its side
|
|
2885
|
+
* effects (the dynamic import) keep their order. Rest elements would
|
|
2886
|
+
* materialize the namespace object and keep their fence. The exports
|
|
2887
|
+
* come from the source's module, not from the pattern's type: an
|
|
2888
|
+
* annotation can name another module with a compatible shape. */
|
|
2889
|
+
function lowerModuleNamespacePattern(lowerer, pattern, source, isLet, out) {
|
|
2890
|
+
const moduleSym = lowerer.checker.getSymbolAtLocation(source);
|
|
2891
|
+
if (moduleSym === undefined) {
|
|
2892
|
+
lowerer.unsupported("SC1031", pattern, "destructuring a module namespace without a module symbol");
|
|
2893
|
+
}
|
|
2894
|
+
const nsType = lowerer.checker.getTypeOfSymbol(moduleSym);
|
|
2895
|
+
for (const el of pattern.elements.nodes) {
|
|
2896
|
+
if (el.name === undefined)
|
|
2897
|
+
continue;
|
|
2898
|
+
if (el.dotDotDotToken) {
|
|
2899
|
+
lowerer.unsupported("SC1031", el, "rest bindings over module namespaces (the namespace object is not materialized — bind the exports you need by name)");
|
|
2900
|
+
}
|
|
2901
|
+
const prop = el.propertyName ?? el.name;
|
|
2902
|
+
const propName = ts.isIdentifier(prop) ||
|
|
2903
|
+
ts.isComputedPropertyName(prop) ||
|
|
2904
|
+
ts.isStringLiteralLike(prop) ||
|
|
2905
|
+
ts.isNumericLiteral(prop)
|
|
2906
|
+
? patternKeyNameOf(lowerer, prop)
|
|
2907
|
+
: null;
|
|
2908
|
+
let exported = propName === null ? undefined : lowerer.checker.getPropertyOfType(nsType, propName);
|
|
2909
|
+
if (exported !== undefined && exported.flags & ts.SymbolFlags.Alias) {
|
|
2910
|
+
exported = lowerer.checker.getAliasedSymbol(exported);
|
|
2911
|
+
}
|
|
2912
|
+
const declared = exported?.valueDeclaration?.name;
|
|
2913
|
+
if (declared === undefined || !ts.isIdentifier(declared)) {
|
|
2914
|
+
lowerer.unsupported("SC1031", el, "destructuring module namespace members that are not named value exports");
|
|
2915
|
+
}
|
|
2916
|
+
let value = lowerer.lowerExpr(declared);
|
|
2917
|
+
if (el.initializer)
|
|
2918
|
+
value = applyBindingDefault(lowerer, el, value);
|
|
2919
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
2920
|
+
}
|
|
2516
2921
|
}
|
|
2517
2922
|
function patternKeyNameOf(lowerer, prop) {
|
|
2518
2923
|
if (ts.isIdentifier(prop) || ts.isPrivateIdentifier(prop))
|
|
@@ -2529,6 +2934,140 @@ function patternKeyNameOf(lowerer, prop) {
|
|
|
2529
2934
|
}
|
|
2530
2935
|
return null;
|
|
2531
2936
|
}
|
|
2937
|
+
/** True when an object pattern destructures a regex match result: the
|
|
2938
|
+
* checker types its source as the standard library's RegExpExecArray or
|
|
2939
|
+
* RegExpMatchArray. */
|
|
2940
|
+
function isRegexMatchResultPattern(lowerer, pattern) {
|
|
2941
|
+
const parent = pattern.parent;
|
|
2942
|
+
const source = ts.isVariableDeclaration(parent) && parent.initializer !== undefined
|
|
2943
|
+
? lowerer.typeOf(parent.initializer)
|
|
2944
|
+
: lowerer.typeOf(pattern);
|
|
2945
|
+
const type = lowerer.checker.getNonNullableType(source);
|
|
2946
|
+
const symbol = type.getAliasSymbol() ?? type.getSymbol();
|
|
2947
|
+
return (symbol !== undefined &&
|
|
2948
|
+
(ts.symbolName(symbol) === "RegExpExecArray" || ts.symbolName(symbol) === "RegExpMatchArray") &&
|
|
2949
|
+
lowerer.isStdlibSymbol(symbol));
|
|
2950
|
+
}
|
|
2951
|
+
/** `const { 0: whole, 1: first, index, input, groups } = re.exec(s)!`: an
|
|
2952
|
+
* object pattern over a regex match result. The result is an honest
|
|
2953
|
+
* string[] slice whose `index` and `input` are the special-form reads that
|
|
2954
|
+
* `m.index` and `m.input` lower to; numeric keys are the positional reads
|
|
2955
|
+
* of the equivalent array pattern, and `groups` is the projection `m.groups`
|
|
2956
|
+
* builds when the regex is statically known. Rest elements, defaults on
|
|
2957
|
+
* the special properties, and every other key keep a named fence. */
|
|
2958
|
+
function lowerMatchResultObjectPattern(lowerer, pattern, srcRef, srcType, isLet, out) {
|
|
2959
|
+
let groups;
|
|
2960
|
+
for (const el of pattern.elements.nodes) {
|
|
2961
|
+
if (el.name === undefined)
|
|
2962
|
+
continue;
|
|
2963
|
+
const loc = locOf(el);
|
|
2964
|
+
if (el.dotDotDotToken) {
|
|
2965
|
+
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)");
|
|
2966
|
+
}
|
|
2967
|
+
const prop = el.propertyName ?? el.name;
|
|
2968
|
+
const propName = ts.isIdentifier(prop) ||
|
|
2969
|
+
ts.isComputedPropertyName(prop) ||
|
|
2970
|
+
ts.isStringLiteralLike(prop) ||
|
|
2971
|
+
ts.isNumericLiteral(prop)
|
|
2972
|
+
? patternKeyNameOf(lowerer, prop)
|
|
2973
|
+
: null;
|
|
2974
|
+
if (propName === null) {
|
|
2975
|
+
lowerer.unsupported("SC1031", el, "destructuring with computed keys that do not fold to one property name");
|
|
2976
|
+
}
|
|
2977
|
+
let value;
|
|
2978
|
+
if (ARRAY_POSITION_KEY.test(propName)) {
|
|
2979
|
+
value = arrayPositionBinding(lowerer, el, srcRef, srcType, Number(propName), out);
|
|
2980
|
+
}
|
|
2981
|
+
else if (propName === "index" || propName === "input") {
|
|
2982
|
+
if (el.initializer) {
|
|
2983
|
+
lowerer.unsupported("SC1031", el, `binding defaults on the '${propName}' of a regex match result`);
|
|
2984
|
+
}
|
|
2985
|
+
value = lowerer.maybeNarrow({
|
|
2986
|
+
kind: "dynKeyGet",
|
|
2987
|
+
value: lowerer.coerceToExpected(srcRef(), DYN),
|
|
2988
|
+
key: { kind: "strLit", value: propName, type: STRING, loc },
|
|
2989
|
+
type: DYN,
|
|
2990
|
+
loc,
|
|
2991
|
+
}, el.name);
|
|
2992
|
+
}
|
|
2993
|
+
else if (propName === "groups") {
|
|
2994
|
+
if (groups === undefined) {
|
|
2995
|
+
const parent = pattern.parent;
|
|
2996
|
+
groups =
|
|
2997
|
+
ts.isVariableDeclaration(parent) && parent.initializer !== undefined
|
|
2998
|
+
? matchResultNamedGroupsOf(lowerer, parent.initializer)
|
|
2999
|
+
: null;
|
|
3000
|
+
}
|
|
3001
|
+
if (groups === null || groups.length === 0 || el.initializer) {
|
|
3002
|
+
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)");
|
|
3003
|
+
}
|
|
3004
|
+
value = lowerGroupsProjection(lowerer, srcRef(), groups, loc);
|
|
3005
|
+
}
|
|
3006
|
+
else {
|
|
3007
|
+
lowerer.unsupported("SC1031", el, `destructuring the property '${propName}' of a regex match result (numeric positions, index, input and groups compile)`);
|
|
3008
|
+
}
|
|
3009
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
/** A canonical array index key (the numeric positions an object pattern
|
|
3013
|
+
* reads off an array). */
|
|
3014
|
+
const ARRAY_POSITION_KEY = /^(?:0|[1-9]\d{0,8})$/;
|
|
3015
|
+
/** The positional read `{ <index>: x }` takes off an array: the element,
|
|
3016
|
+
* undefined past the end, with the binding default applied. */
|
|
3017
|
+
function arrayPositionBinding(lowerer, el, srcRef, srcType, index, out) {
|
|
3018
|
+
const loc = locOf(el);
|
|
3019
|
+
const position = { kind: "numLit", value: index, type: F64, loc };
|
|
3020
|
+
const value = lowerSafeIndexRead(lowerer, srcRef(), position, loc) ?? {
|
|
3021
|
+
kind: "arrayGet",
|
|
3022
|
+
arr: srcRef(),
|
|
3023
|
+
index: position,
|
|
3024
|
+
type: srcType.elem,
|
|
3025
|
+
loc,
|
|
3026
|
+
};
|
|
3027
|
+
return el.initializer
|
|
3028
|
+
? arrayPositionDefault(lowerer, el, value, srcRef, index, srcType.elem, out)
|
|
3029
|
+
: value;
|
|
3030
|
+
}
|
|
3031
|
+
/** Whether every element of an object pattern over an array names a
|
|
3032
|
+
* numeric position or `length` (`const { 0: a, 1: b, length } =
|
|
3033
|
+
* s.split(".")`), with no rest element. */
|
|
3034
|
+
function isArrayPositionPattern(lowerer, pattern) {
|
|
3035
|
+
return pattern.elements.nodes.every((el) => {
|
|
3036
|
+
if (el.name === undefined)
|
|
3037
|
+
return true;
|
|
3038
|
+
if (el.dotDotDotToken)
|
|
3039
|
+
return false;
|
|
3040
|
+
const prop = el.propertyName ?? el.name;
|
|
3041
|
+
if (!ts.isIdentifier(prop) &&
|
|
3042
|
+
!ts.isComputedPropertyName(prop) &&
|
|
3043
|
+
!ts.isStringLiteralLike(prop) &&
|
|
3044
|
+
!ts.isNumericLiteral(prop))
|
|
3045
|
+
return false;
|
|
3046
|
+
const name = patternKeyNameOf(lowerer, prop);
|
|
3047
|
+
return name !== null && (name === "length" || ARRAY_POSITION_KEY.test(name));
|
|
3048
|
+
});
|
|
3049
|
+
}
|
|
3050
|
+
/** An object pattern of positions and `length` over an array: each
|
|
3051
|
+
* position is the read the equivalent array pattern makes, and `length`
|
|
3052
|
+
* the array's length (always present, so its default never runs). */
|
|
3053
|
+
function lowerArrayPositionObjectPattern(lowerer, pattern, srcRef, srcType, isLet, out) {
|
|
3054
|
+
for (const el of pattern.elements.nodes) {
|
|
3055
|
+
if (el.name === undefined)
|
|
3056
|
+
continue;
|
|
3057
|
+
const name = patternKeyNameOf(lowerer, (el.propertyName ?? el.name));
|
|
3058
|
+
const value = name === "length"
|
|
3059
|
+
? {
|
|
3060
|
+
kind: "arrIntrinsic",
|
|
3061
|
+
method: "length",
|
|
3062
|
+
receiver: srcRef(),
|
|
3063
|
+
args: [],
|
|
3064
|
+
type: F64,
|
|
3065
|
+
loc: locOf(el),
|
|
3066
|
+
}
|
|
3067
|
+
: arrayPositionBinding(lowerer, el, srcRef, srcType, Number(name), out);
|
|
3068
|
+
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
2532
3071
|
/** Decode one non-rest object-assignment property into its static source
|
|
2533
3072
|
* field, destination expression, and optional default initializer. */
|
|
2534
3073
|
function destructuringPropertyOf(lowerer, prop) {
|
|
@@ -2572,7 +3111,7 @@ function checkerStringSource(lowerer, e) {
|
|
|
2572
3111
|
}
|
|
2573
3112
|
function staticStringPattern(lowerer, pattern) {
|
|
2574
3113
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
2575
|
-
return pattern.elements.every((el) => {
|
|
3114
|
+
return pattern.elements.nodes.every((el) => {
|
|
2576
3115
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
2577
3116
|
return true;
|
|
2578
3117
|
if (el.dotDotDotToken) {
|
|
@@ -2586,7 +3125,7 @@ function staticStringPattern(lowerer, pattern) {
|
|
|
2586
3125
|
return staticStringPattern(lowerer, el.name);
|
|
2587
3126
|
});
|
|
2588
3127
|
}
|
|
2589
|
-
return pattern.elements.every((el) => {
|
|
3128
|
+
return pattern.elements.nodes.every((el) => {
|
|
2590
3129
|
if (el.name === undefined)
|
|
2591
3130
|
return true;
|
|
2592
3131
|
if (el.dotDotDotToken || !ts.isIdentifier(el.name))
|
|
@@ -2652,7 +3191,7 @@ const CONSOLE_CALL_MEMBERS = new Set([
|
|
|
2652
3191
|
* when the source is not a stdlib global at all, or in TypeScript
|
|
2653
3192
|
* files (the identifier chokepoint fences the global there first). */
|
|
2654
3193
|
function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
2655
|
-
if (decl.initializer === undefined || !isJsSourceFile(
|
|
3194
|
+
if (decl.initializer === undefined || !isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
2656
3195
|
return null;
|
|
2657
3196
|
const globalName = stdlibGlobalNameOf(lowerer, decl.initializer);
|
|
2658
3197
|
if (globalName === null)
|
|
@@ -2665,7 +3204,7 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2665
3204
|
}
|
|
2666
3205
|
const srcT = lowerer.typeOf(decl.initializer);
|
|
2667
3206
|
const binds = [];
|
|
2668
|
-
for (const el of decl.name.elements) {
|
|
3207
|
+
for (const el of decl.name.elements.nodes) {
|
|
2669
3208
|
if (el.name === undefined)
|
|
2670
3209
|
continue;
|
|
2671
3210
|
if (el.dotDotDotToken) {
|
|
@@ -2687,8 +3226,9 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2687
3226
|
if (propName === null) {
|
|
2688
3227
|
lowerer.unsupported("SC1031", el, "destructuring with computed keys that do not fold to one property name");
|
|
2689
3228
|
}
|
|
2690
|
-
let token;
|
|
3229
|
+
let token = "";
|
|
2691
3230
|
let alias = null;
|
|
3231
|
+
let value = null;
|
|
2692
3232
|
if (globalName === "globalThis") {
|
|
2693
3233
|
// The member must BE a stdlib global (user script vars are
|
|
2694
3234
|
// properties of `typeof globalThis` too — their values are real
|
|
@@ -2697,9 +3237,12 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2697
3237
|
if (member === undefined || !lowerer.isStdlibSymbol(member)) {
|
|
2698
3238
|
lowerer.unsupported("SC1031", el, `destructuring the non-builtin member '${propName}' of 'globalThis'`);
|
|
2699
3239
|
}
|
|
2700
|
-
const canonical = member
|
|
3240
|
+
const canonical = ts.symbolName(member) === "global" ? "globalThis" : ts.symbolName(member);
|
|
2701
3241
|
token = `[builtin ${canonical}]`;
|
|
2702
3242
|
alias = canonical;
|
|
3243
|
+
// Builtin constructors read as their interned function values, the
|
|
3244
|
+
// same values the bare and `globalThis.X` spellings read.
|
|
3245
|
+
value = builtinGlobalValue(canonical, locOf(el), true);
|
|
2703
3246
|
}
|
|
2704
3247
|
else if (globalName === "console" && !CONSOLE_CALL_MEMBERS.has(propName)) {
|
|
2705
3248
|
token = `[builtin console.${propName}]`;
|
|
@@ -2707,6 +3250,12 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2707
3250
|
else if (TOKEN_OPAQUE_GLOBALS.has(globalName)) {
|
|
2708
3251
|
token = `[builtin ${globalName}.${propName}]`;
|
|
2709
3252
|
}
|
|
3253
|
+
else if (globalName === "process" &&
|
|
3254
|
+
ts.isIdentifier(el.name) &&
|
|
3255
|
+
(value = processDataMemberValue(lowerer, propName, el.name, locOf(el))) !== null) {
|
|
3256
|
+
// A data member reads its value once, exactly like the spelled
|
|
3257
|
+
// `process.<member>` read the destructuring performs.
|
|
3258
|
+
}
|
|
2710
3259
|
else {
|
|
2711
3260
|
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
3261
|
}
|
|
@@ -2715,6 +3264,10 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2715
3264
|
lowerer.unsupported("SC1031", el, `bindings with predeclared slots over the builtin global '${globalName}'`);
|
|
2716
3265
|
}
|
|
2717
3266
|
const g = lowerer.globalsBySymbol.get(symbol);
|
|
3267
|
+
if (value !== null) {
|
|
3268
|
+
binds.push({ name: el.name, token, alias, g, value });
|
|
3269
|
+
continue;
|
|
3270
|
+
}
|
|
2718
3271
|
if (g !== undefined && g.type.kind !== "string" && g.type.kind !== "dyn") {
|
|
2719
3272
|
lowerer.unsupported("SC1031", el, `bindings with '${lowerer.fmt(g.type)}' storage over the builtin global '${globalName}'`);
|
|
2720
3273
|
}
|
|
@@ -2723,6 +3276,27 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2723
3276
|
const out = [];
|
|
2724
3277
|
for (const b of binds) {
|
|
2725
3278
|
const loc = locOf(b.name);
|
|
3279
|
+
if (b.value !== undefined && b.alias !== null) {
|
|
3280
|
+
const symbol = lowerer.checker.getSymbolAtLocation(b.name);
|
|
3281
|
+
if (symbol)
|
|
3282
|
+
lowerer.stdlibGlobalAliases.set(symbol, b.alias);
|
|
3283
|
+
}
|
|
3284
|
+
if (b.value !== undefined) {
|
|
3285
|
+
if (b.g !== undefined) {
|
|
3286
|
+
out.push({
|
|
3287
|
+
kind: "assign",
|
|
3288
|
+
localId: b.g.id,
|
|
3289
|
+
value: lowerer.coerceInto(b.name, b.value, b.g.type),
|
|
3290
|
+
...(b.g.tdz ? { initializes: true } : {}),
|
|
3291
|
+
loc,
|
|
3292
|
+
});
|
|
3293
|
+
}
|
|
3294
|
+
else {
|
|
3295
|
+
const local = lowerer.declareLocal(b.name, b.name.text, b.value.type, isLet);
|
|
3296
|
+
out.push({ kind: "varDecl", localId: local.id, init: b.value, loc });
|
|
3297
|
+
}
|
|
3298
|
+
continue;
|
|
3299
|
+
}
|
|
2726
3300
|
const token = { kind: "strLit", value: b.token, type: STRING, loc };
|
|
2727
3301
|
if (b.alias !== null) {
|
|
2728
3302
|
const symbol = lowerer.checker.getSymbolAtLocation(b.name);
|
|
@@ -3004,7 +3578,7 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
|
|
|
3004
3578
|
const consumed = new Set();
|
|
3005
3579
|
let computedSibling = false;
|
|
3006
3580
|
if (ts.isObjectBindingPattern(pattern)) {
|
|
3007
|
-
for (const sib of pattern.elements) {
|
|
3581
|
+
for (const sib of pattern.elements.nodes) {
|
|
3008
3582
|
if (sib === el || sib.dotDotDotToken)
|
|
3009
3583
|
continue;
|
|
3010
3584
|
const key = sib.propertyName ?? sib.name;
|
|
@@ -3071,7 +3645,7 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
|
|
|
3071
3645
|
value: lowerer.presenceKeepingCopy(srcRef(), srcType.shapeId, srcField.name, lowerer.coerceInto(el, read, f.type), loc),
|
|
3072
3646
|
};
|
|
3073
3647
|
});
|
|
3074
|
-
return { kind: "recordLit", fields, type: restT, loc };
|
|
3648
|
+
return lowerer.keyOrder.copy({ kind: "recordLit", fields, type: restT, loc }, srcType.shapeId);
|
|
3075
3649
|
}
|
|
3076
3650
|
/** The fresh record for `{ a, ...rest }` over a CLASS-INSTANCE source:
|
|
3077
3651
|
* JS's CopyDataProperties copies the OWN ENUMERABLE properties — the
|
|
@@ -3125,7 +3699,7 @@ function classInstanceRestValue(lowerer, blame, srcRef, srcType, info, consumed,
|
|
|
3125
3699
|
const orderMatches = (order) => order.length === remaining.length && order.every((n, i) => n === remaining[i].name);
|
|
3126
3700
|
const deferOrderCheck = lowerer.instantiationContext !== null &&
|
|
3127
3701
|
lowerer.onEdge !== null &&
|
|
3128
|
-
!isJsSourceFile(
|
|
3702
|
+
!isJsSourceFile(ts.getSourceFileOfNode(blame));
|
|
3129
3703
|
if (!deferOrderCheck) {
|
|
3130
3704
|
if (!orderMatches(emitOrder)) {
|
|
3131
3705
|
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 +3714,7 @@ function classInstanceRestValue(lowerer, blame, srcRef, srcType, info, consumed,
|
|
|
3140
3714
|
// matters.
|
|
3141
3715
|
const context = lowerer.instantiationContext;
|
|
3142
3716
|
const countFailure = !lowerer.suppressStats;
|
|
3143
|
-
const sf =
|
|
3717
|
+
const sf = ts.getSourceFileOfNode(blame);
|
|
3144
3718
|
lowerer.shapeOrderMetadataFinalizers.push(() => {
|
|
3145
3719
|
const current = lowerer.shapes.get(restT.shapeId) ?? restShape;
|
|
3146
3720
|
const currentOrder = current.declaredOrder ?? current.fields.map((f) => f.name);
|
|
@@ -3188,6 +3762,8 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3188
3762
|
const symbol = lowerer.checker.getSymbolAtLocation(name);
|
|
3189
3763
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
3190
3764
|
if (g) {
|
|
3765
|
+
if (value.type.kind === "dyn" && jsBindingKeepsCheckedObject(lowerer, name, g.type))
|
|
3766
|
+
g.type = DYN;
|
|
3191
3767
|
out.push({
|
|
3192
3768
|
kind: "assign",
|
|
3193
3769
|
localId: g.id,
|
|
@@ -3204,7 +3780,7 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3204
3780
|
// here by declareParams) carry no block-scope flag either, but their
|
|
3205
3781
|
// bindings are the parameters' own.
|
|
3206
3782
|
if (symbol && hostVariableDeclarationOf(name) !== null && isVarDeclared(name)) {
|
|
3207
|
-
const hoisted = hoistVarBinding(lowerer, symbol, name);
|
|
3783
|
+
const hoisted = hoistVarBinding(lowerer, symbol, name, value.type);
|
|
3208
3784
|
out.push({
|
|
3209
3785
|
kind: "assign",
|
|
3210
3786
|
localId: hoisted.id,
|
|
@@ -3218,7 +3794,7 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3218
3794
|
const dynStays = value.type.kind === "dyn" &&
|
|
3219
3795
|
(() => {
|
|
3220
3796
|
const mapped = lowerer.mapTypeOf(lowerer.typeOf(name));
|
|
3221
|
-
return mapped === null;
|
|
3797
|
+
return mapped === null || jsBindingKeepsCheckedObject(lowerer, name, mapped);
|
|
3222
3798
|
})();
|
|
3223
3799
|
let type = dynStays
|
|
3224
3800
|
? DYN
|
|
@@ -3269,7 +3845,7 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3269
3845
|
const isConst = (list.flags & ts.NodeFlags.Const) !== 0;
|
|
3270
3846
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0;
|
|
3271
3847
|
if (!isConst && !isLet) {
|
|
3272
|
-
const out = list.declarations.flatMap((decl) => {
|
|
3848
|
+
const out = list.declarations.nodes.flatMap((decl) => {
|
|
3273
3849
|
// `for (var {} = {}, [a] = xs; ...)`: pattern declarators ride the
|
|
3274
3850
|
// declaration desugar (var names assign their hoisted slots).
|
|
3275
3851
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
@@ -3285,7 +3861,7 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3285
3861
|
return { kind: "block", body: out, loc: locOf(list) };
|
|
3286
3862
|
}
|
|
3287
3863
|
const out = [];
|
|
3288
|
-
for (const decl of list.declarations) {
|
|
3864
|
+
for (const decl of list.declarations.nodes) {
|
|
3289
3865
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
3290
3866
|
// Destructuring produces nested initialization blocks; copying
|
|
3291
3867
|
// their captured bindings still needs a distinct head-scope plan.
|
|
@@ -3355,7 +3931,7 @@ function inferredEvolvingLetType(lowerer, decl) {
|
|
|
3355
3931
|
}
|
|
3356
3932
|
if (ts.isCallExpression(node.right) &&
|
|
3357
3933
|
(implicitMethodCallInfersReturn(lowerer, node.right) ||
|
|
3358
|
-
isJsSourceFile(node.right
|
|
3934
|
+
isJsSourceFile(ts.getSourceFileOfNode(node.right)))) {
|
|
3359
3935
|
invalid = true;
|
|
3360
3936
|
return "stop";
|
|
3361
3937
|
}
|
|
@@ -3426,6 +4002,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3426
4002
|
}
|
|
3427
4003
|
if (!ts.isIdentifier(decl.name))
|
|
3428
4004
|
lowerer.unsupported("SC1031", decl.name);
|
|
4005
|
+
{
|
|
4006
|
+
const alias = lowerTupleAliasDecl(lowerer, decl);
|
|
4007
|
+
if (alias)
|
|
4008
|
+
return alias;
|
|
4009
|
+
}
|
|
3429
4010
|
// A NULLISH generic binding (`const i: I<A & B> = null as any` — the
|
|
3430
4011
|
// declared type has no mapping, the value is provably null/undefined
|
|
3431
4012
|
// forever): no storage exists; reads know the value (member reads and
|
|
@@ -3456,10 +4037,10 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3456
4037
|
(decl.name.text === "module" || decl.name.text === "exports") &&
|
|
3457
4038
|
ts.isVariableStatement(decl.parent?.parent) &&
|
|
3458
4039
|
ts.isSourceFile(decl.parent?.parent?.parent) &&
|
|
3459
|
-
!isJsSourceFile(
|
|
3460
|
-
!
|
|
3461
|
-
.
|
|
3462
|
-
.statements.some((s) => ts.isImportDeclaration(s) ||
|
|
4040
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
4041
|
+
!ts
|
|
4042
|
+
.getSourceFileOfNode(decl)
|
|
4043
|
+
.statements.nodes.some((s) => ts.isImportDeclaration(s) ||
|
|
3463
4044
|
ts.isExportDeclaration(s) ||
|
|
3464
4045
|
ts.isExportAssignment(s) ||
|
|
3465
4046
|
(ts.canHaveModifiers(s) &&
|
|
@@ -3508,6 +4089,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3508
4089
|
// `const process = globalThis.process` — a stdlib-global snapshot:
|
|
3509
4090
|
// alias plumbing (see stdlibGlobalAliasDecl), no storage, no code.
|
|
3510
4091
|
const stableStdlibAlias = !isLet ||
|
|
4092
|
+
stdlibBufferVarAlias(lowerer, decl) ||
|
|
3511
4093
|
(ts.isVariableDeclarationList(decl.parent) &&
|
|
3512
4094
|
(decl.parent.flags & ts.NodeFlags.Let) !== 0 &&
|
|
3513
4095
|
ts.isIdentifier(decl.name) &&
|
|
@@ -3547,6 +4129,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3547
4129
|
return null;
|
|
3548
4130
|
if (!isLet && registerBuiltinCallableAlias(lowerer, decl.name, decl.initializer))
|
|
3549
4131
|
return null;
|
|
4132
|
+
if (registerBuiltinClassAlias(lowerer, decl.name, decl.initializer))
|
|
4133
|
+
return null;
|
|
3550
4134
|
// `const knownBy = (cmd) => ...` — an IMPLICIT-ANY function-value
|
|
3551
4135
|
// binding in npm-static JS (function-scope bindings register here, in
|
|
3552
4136
|
// source order before any use can lower; file-scope ones registered at
|
|
@@ -3631,17 +4215,25 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3631
4215
|
return { kind: "assign", localId: g.id, value: wrapped, loc: locOf(decl) };
|
|
3632
4216
|
return null;
|
|
3633
4217
|
}
|
|
3634
|
-
const
|
|
3635
|
-
(
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
4218
|
+
const guardedRead = isGuardedRecordRead(lowerer, decl)
|
|
4219
|
+
? lowerAbsenceProbe(lowerer, decl.initializer)
|
|
4220
|
+
: null;
|
|
4221
|
+
const raw = guardedRead ??
|
|
4222
|
+
lowerVariableInitializer(lowerer, decl.initializer, g.type.kind === "dyn" &&
|
|
4223
|
+
(isNativeBuiltinValueInitializer(lowerer, decl.initializer) ||
|
|
4224
|
+
ts.isArrayLiteralExpression(decl.initializer) ||
|
|
4225
|
+
ts.isObjectLiteralExpression(decl.initializer))
|
|
4226
|
+
? DYN
|
|
4227
|
+
: undefined);
|
|
4228
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3641
4229
|
!decl.type &&
|
|
3642
4230
|
!hasJsTypeAnnotation(decl) &&
|
|
3643
4231
|
raw.type.kind === "dyn" &&
|
|
3644
|
-
(g.type.kind === "record" ||
|
|
4232
|
+
(g.type.kind === "record" ||
|
|
4233
|
+
g.type.kind === "object" ||
|
|
4234
|
+
(ts.isIdentifier(decl.name) &&
|
|
4235
|
+
jsBindingKeepsCheckedObject(lowerer, decl.name, g.type) &&
|
|
4236
|
+
(existingValueForm(decl.initializer) || jsHoldsDynObject(lowerer, decl.initializer)))))
|
|
3645
4237
|
g.type = DYN;
|
|
3646
4238
|
g.type = inferredOptionalRecordType(lowerer, decl, g.type, raw.type);
|
|
3647
4239
|
const arithmetic = raw.type.kind === "union" ? lowerer.unions.get(raw.type.unionId)?.arms : undefined;
|
|
@@ -3682,6 +4274,9 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3682
4274
|
// types already hold the interned undefined arm), and a declaration
|
|
3683
4275
|
// re-run in a loop must not reset the persisting value.
|
|
3684
4276
|
if (isVarDeclared(decl) && declSymbol) {
|
|
4277
|
+
const fromExisting = lowerJsVarFromExisting(lowerer, decl, declSymbol);
|
|
4278
|
+
if (fromExisting)
|
|
4279
|
+
return fromExisting;
|
|
3685
4280
|
const local = hoistVarBinding(lowerer, declSymbol, decl.name);
|
|
3686
4281
|
if (!decl.initializer)
|
|
3687
4282
|
return null;
|
|
@@ -3697,7 +4292,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3697
4292
|
// immediately (the type covers the unassigned state), so they
|
|
3698
4293
|
// initialize to the interned undefined arm like an omitted optional.
|
|
3699
4294
|
let type = lowerer.irTypeOf(decl.name);
|
|
3700
|
-
if (type.kind === "dyn" && isLet && isJsSourceFile(
|
|
4295
|
+
if (type.kind === "dyn" && isLet && isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3701
4296
|
type = inferredEvolvingLetType(lowerer, decl) ?? type;
|
|
3702
4297
|
}
|
|
3703
4298
|
// `var v: void;` / `let x: undefined;` — a unit-only binding rides
|
|
@@ -3721,7 +4316,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3721
4316
|
// function (with its hint), not the unmappable declared type. If it
|
|
3722
4317
|
// poisons, still declare the local when its type is representable, so
|
|
3723
4318
|
// later references to this name don't produce cascading errors.
|
|
3724
|
-
const inferredObjectType = isJsSourceFile(
|
|
4319
|
+
const inferredObjectType = isJsSourceFile(ts.getSourceFileOfNode(decl))
|
|
3725
4320
|
? lowerer.mapTypeOf(lowerer.typeOf(decl.name))
|
|
3726
4321
|
: null;
|
|
3727
4322
|
const inferredObjectArms = inferredObjectType?.kind === "union"
|
|
@@ -3734,11 +4329,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3734
4329
|
inferredObjectType !== null &&
|
|
3735
4330
|
jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn") ||
|
|
3736
4331
|
inferredObjectArms.some((arm) => arm.kind === "record" && jsObjectBindingExpands(lowerer, decl, arm)) ||
|
|
3737
|
-
(isJsSourceFile(
|
|
4332
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3738
4333
|
!decl.type &&
|
|
3739
4334
|
!hasJsTypeAnnotation(decl) &&
|
|
3740
4335
|
ts.isObjectLiteralExpression(decl.initializer) &&
|
|
3741
|
-
decl.initializer.properties.some((property) => ts.isMethodDeclaration(property) ||
|
|
4336
|
+
decl.initializer.properties.nodes.some((property) => ts.isMethodDeclaration(property) ||
|
|
3742
4337
|
ts.isAccessor(property) ||
|
|
3743
4338
|
(ts.isPropertyAssignment(property) &&
|
|
3744
4339
|
(ts.isFunctionExpression(property.initializer) ||
|
|
@@ -3747,7 +4342,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3747
4342
|
try {
|
|
3748
4343
|
init =
|
|
3749
4344
|
expandsObject ||
|
|
3750
|
-
(isJsSourceFile(
|
|
4345
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3751
4346
|
!decl.type &&
|
|
3752
4347
|
isNativeBuiltinValueInitializer(lowerer, decl.initializer))
|
|
3753
4348
|
? lowerer.lowerExprExpecting(decl.initializer, DYN)
|
|
@@ -3779,11 +4374,19 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3779
4374
|
staticImportNamespaceType(lowerer, decl.initializer) ??
|
|
3780
4375
|
(init.type.kind === "moduleNs" ? init.type : null) ??
|
|
3781
4376
|
(init.type.kind === "dyn" ? DYN : null);
|
|
3782
|
-
if (isJsSourceFile(
|
|
4377
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3783
4378
|
!decl.type &&
|
|
3784
4379
|
!hasJsTypeAnnotation(decl) &&
|
|
3785
4380
|
init.type.kind === "func")
|
|
3786
4381
|
type = init.type;
|
|
4382
|
+
// A typed-arguments function expression (typed-arguments.ts): the
|
|
4383
|
+
// checker types the binding variadic, but its value has the fixed
|
|
4384
|
+
// signature every use asserts.
|
|
4385
|
+
if (!decl.type &&
|
|
4386
|
+
init.type.kind === "func" &&
|
|
4387
|
+
(lowerer.typedArgumentsLambdas.has(stripTypeWrappers(decl.initializer)) ||
|
|
4388
|
+
lowerer.nullishFuncResults.has(stripTypeWrappers(decl.initializer))))
|
|
4389
|
+
type = init.type;
|
|
3787
4390
|
// A TypeScript lambda whose closure returns the runtime result (a missing
|
|
3788
4391
|
// read, a `??` default of another type) instead of the checker's bare
|
|
3789
4392
|
// return type: the binding keeps the checker's parameters and takes the
|
|
@@ -3796,24 +4399,24 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3796
4399
|
type = { ...type, ret: init.type.ret };
|
|
3797
4400
|
if (lowerer.implicitParamTypes !== null &&
|
|
3798
4401
|
init.type.kind === "dyn" &&
|
|
3799
|
-
isJsSourceFile(
|
|
3800
|
-
npmStaticPackageOfPath(
|
|
4402
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
4403
|
+
npmStaticPackageOfPath(ts.getSourceFileOfNode(decl).fileName) !== null) {
|
|
3801
4404
|
type = DYN;
|
|
3802
4405
|
}
|
|
3803
4406
|
const preservesObjectIdentity = init.type.kind === "dyn" &&
|
|
3804
4407
|
(inferredObjectType?.kind === "record" ||
|
|
3805
4408
|
inferredObjectType?.kind === "array" ||
|
|
3806
|
-
(isJsSourceFile(
|
|
4409
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3807
4410
|
inferredObjectArms.some((arm) => arm.kind === "record") &&
|
|
3808
4411
|
inferredObjectArms.every((arm) => isUnitType(arm) || arm.kind === "record")) ||
|
|
3809
|
-
(isJsSourceFile(
|
|
4412
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3810
4413
|
inferredObjectType !== null &&
|
|
3811
4414
|
(inferredObjectType.kind === "date" ||
|
|
3812
4415
|
inferredObjectType.kind === "func" ||
|
|
3813
4416
|
inferredObjectType.kind === "object" ||
|
|
3814
4417
|
jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind ===
|
|
3815
4418
|
"dyn")) ||
|
|
3816
|
-
(isJsSourceFile(
|
|
4419
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3817
4420
|
inferredObjectType !== null &&
|
|
3818
4421
|
(inferredObjectType.kind === "void" ||
|
|
3819
4422
|
isUnitType(inferredObjectType) ||
|
|
@@ -3821,14 +4424,20 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3821
4424
|
lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType))))) &&
|
|
3822
4425
|
!decl.type &&
|
|
3823
4426
|
!hasJsTypeAnnotation(decl);
|
|
4427
|
+
// The binding of an assertion of the global object holds that object,
|
|
4428
|
+
// whatever its asserted type (assertion-identity.ts).
|
|
4429
|
+
const keepsAssertedObject = init.type.kind === "dyn" &&
|
|
4430
|
+
!decl.type &&
|
|
4431
|
+
keptIdentityAssertion(lowerer, decl.initializer) !== undefined;
|
|
3824
4432
|
if (expandsObject ||
|
|
3825
4433
|
preservesObjectIdentity ||
|
|
3826
|
-
|
|
4434
|
+
keepsAssertedObject ||
|
|
4435
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3827
4436
|
!decl.type &&
|
|
3828
4437
|
isNativeBuiltinValueInitializer(lowerer, decl.initializer))) {
|
|
3829
4438
|
type = DYN;
|
|
3830
4439
|
}
|
|
3831
|
-
if (isJsSourceFile(
|
|
4440
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3832
4441
|
!decl.type &&
|
|
3833
4442
|
init.type.kind === "array" &&
|
|
3834
4443
|
init.type.elem.kind === "dyn" &&
|
|
@@ -3843,14 +4452,14 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3843
4452
|
// cannot hold the binding's future. The binding is checked-dynamic
|
|
3844
4453
|
// instead (irTypeOf's JS story): writes dynFrom, typed exits dynCheck.
|
|
3845
4454
|
// Const keeps the static empty record — no reassignment exists.
|
|
3846
|
-
if (isLet && type?.kind === "record" && isJsSourceFile(
|
|
4455
|
+
if (isLet && type?.kind === "record" && isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3847
4456
|
const shape = lowerer.shapes.get(type.shapeId);
|
|
3848
4457
|
if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
|
|
3849
4458
|
type = DYN;
|
|
3850
4459
|
}
|
|
3851
4460
|
if (isLet &&
|
|
3852
4461
|
type !== null &&
|
|
3853
|
-
isJsSourceFile(
|
|
4462
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3854
4463
|
!decl.type &&
|
|
3855
4464
|
!hasJsTypeAnnotation(decl) &&
|
|
3856
4465
|
(type.kind === "object" || type.kind === "symbol" || jsBindingHasOpenWrites(lowerer, decl))) {
|
|
@@ -3872,11 +4481,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3872
4481
|
// exits dynCheck.
|
|
3873
4482
|
if (returnedEmptyArrayType === null &&
|
|
3874
4483
|
(type === null || type.kind === "array") &&
|
|
3875
|
-
isJsSourceFile(
|
|
4484
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3876
4485
|
let initExpr = decl.initializer;
|
|
3877
4486
|
while (ts.isParenthesizedExpression(initExpr))
|
|
3878
4487
|
initExpr = initExpr.expression;
|
|
3879
|
-
if (ts.isArrayLiteralExpression(initExpr) && initExpr.elements.length === 0) {
|
|
4488
|
+
if (ts.isArrayLiteralExpression(initExpr) && initExpr.elements.nodes.length === 0) {
|
|
3880
4489
|
const t = lowerer.typeOf(decl.name);
|
|
3881
4490
|
if (lowerer.checker.isArrayType(t)) {
|
|
3882
4491
|
const elem = lowerer.checker.getTypeArguments(t)[0];
|
|
@@ -3928,14 +4537,14 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3928
4537
|
// boxed thunk's JS arity instead.
|
|
3929
4538
|
if (type?.kind === "func" &&
|
|
3930
4539
|
init.type.kind === "dyn" &&
|
|
3931
|
-
(isJsSourceFile(
|
|
4540
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
3932
4541
|
(!decl.type &&
|
|
3933
4542
|
!hasJsTypeAnnotation(decl) &&
|
|
3934
4543
|
type.rest === true &&
|
|
3935
4544
|
type.restAbi === undefined))) {
|
|
3936
4545
|
type = DYN;
|
|
3937
4546
|
}
|
|
3938
|
-
if (isJsSourceFile(
|
|
4547
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3939
4548
|
!decl.type &&
|
|
3940
4549
|
!hasJsTypeAnnotation(decl) &&
|
|
3941
4550
|
init.type.kind === "dyn" &&
|
|
@@ -3960,12 +4569,16 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3960
4569
|
// type (a union with a fence-folded arm — the typeof-'bigint'
|
|
3961
4570
|
// dual-mode ternary) adopts the initializer's static type, the
|
|
3962
4571
|
// same rule genuine `any` consts take.
|
|
3963
|
-
(type === null && isJsSourceFile(
|
|
4572
|
+
(type === null && isJsSourceFile(ts.getSourceFileOfNode(decl)))) &&
|
|
3964
4573
|
init.type.kind !== "void" &&
|
|
3965
4574
|
init.type.kind !== "caught" &&
|
|
3966
4575
|
!isUnitType(init.type)) {
|
|
3967
4576
|
type = init.type;
|
|
3968
4577
|
}
|
|
4578
|
+
// `const B = factory(1)` inside a generic instance: the factory's local
|
|
4579
|
+
// class for the instance the call names.
|
|
4580
|
+
if (!type && !isLet)
|
|
4581
|
+
type = genericLocalClassBinding(lowerer, decl.name);
|
|
3969
4582
|
if (!type) {
|
|
3970
4583
|
// The JS declaration fallback (irTypeOf's story): the binding holds
|
|
3971
4584
|
// the checked-dynamic kind when even the initializer's type has no
|
|
@@ -3978,7 +4591,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3978
4591
|
lowerer.badType(decl.name, lowerer.typeOf(decl.name));
|
|
3979
4592
|
let settledType = type;
|
|
3980
4593
|
if (!isLet &&
|
|
3981
|
-
isJsSourceFile(
|
|
4594
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3982
4595
|
!hasJsTypeAnnotation(decl) &&
|
|
3983
4596
|
decl.initializer &&
|
|
3984
4597
|
ts.isNewExpression(decl.initializer)) {
|
|
@@ -4013,7 +4626,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
4013
4626
|
? npmStaticOptionalSelfWriteType(lowerer, decl, settledType)
|
|
4014
4627
|
: null;
|
|
4015
4628
|
settledType =
|
|
4016
|
-
expandsObject || preservesObjectIdentity
|
|
4629
|
+
expandsObject || preservesObjectIdentity || keepsAssertedObject
|
|
4017
4630
|
? DYN
|
|
4018
4631
|
: lowerer.runtimeOptionalBindingType(decl.name, settledType);
|
|
4019
4632
|
if (optionalSelfWriteType !== null)
|
|
@@ -4076,6 +4689,21 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
4076
4689
|
settledType = init.type;
|
|
4077
4690
|
}
|
|
4078
4691
|
}
|
|
4692
|
+
// `const view = route as Route & { order: number }`: the asserted type
|
|
4693
|
+
// refines the record arms the value is stored in (the assertion keeps
|
|
4694
|
+
// that value, see hosted-narrowing.ts). The binding keeps the stored
|
|
4695
|
+
// type, so writes through it reach the asserted object. An annotation
|
|
4696
|
+
// the stored type hosts (`const view: Route & { order: number } = ...`)
|
|
4697
|
+
// keeps it too: coercing into the annotated layout would copy the
|
|
4698
|
+
// value and read members the writes have not created yet.
|
|
4699
|
+
if (!isLet &&
|
|
4700
|
+
decl.initializer &&
|
|
4701
|
+
isAssertionInitializer(decl.initializer) &&
|
|
4702
|
+
(settledType.kind === "union" || settledType.kind === "record") &&
|
|
4703
|
+
(init.type.kind === "union" || init.type.kind === "record") &&
|
|
4704
|
+
hostsAll(lowerer, init.type, settledType)) {
|
|
4705
|
+
settledType = init.type;
|
|
4706
|
+
}
|
|
4079
4707
|
// An exact class behind a generic interface keeps its native
|
|
4080
4708
|
// representation so generic calls can specialize against its body.
|
|
4081
4709
|
if ((settledType.kind === "record" || settledType.kind === "dyn") &&
|
|
@@ -4176,7 +4804,7 @@ function lowerVariableInitializer(lowerer, node, expected) {
|
|
|
4176
4804
|
if (expected?.kind === "dyn")
|
|
4177
4805
|
return lowerDynObjectLiteral(lowerer, value);
|
|
4178
4806
|
const previous = new Map();
|
|
4179
|
-
for (const property of value.properties) {
|
|
4807
|
+
for (const property of value.properties.nodes) {
|
|
4180
4808
|
if (!ts.isPropertyAssignment(property) || !ts.isComputedPropertyName(property.name))
|
|
4181
4809
|
continue;
|
|
4182
4810
|
const keyNode = property.name.expression;
|
|
@@ -4205,7 +4833,7 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4205
4833
|
if (decl.type ||
|
|
4206
4834
|
!decl.initializer ||
|
|
4207
4835
|
!ts.isIdentifier(decl.name) ||
|
|
4208
|
-
!isJsSourceFile(
|
|
4836
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
4209
4837
|
return false;
|
|
4210
4838
|
let initializer = decl.initializer;
|
|
4211
4839
|
while (ts.isParenthesizedExpression(initializer))
|
|
@@ -4282,6 +4910,18 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4282
4910
|
const name = property(node.left);
|
|
4283
4911
|
if (name === null || (name !== undefined && !names.has(name)))
|
|
4284
4912
|
expands = true;
|
|
4913
|
+
// `state = { _tag: "Done", right }` stores an object with properties
|
|
4914
|
+
// the initializer's shape lacks; later reads of them must see them.
|
|
4915
|
+
const target = unwrap(node.left);
|
|
4916
|
+
const value = unwrap(node.right);
|
|
4917
|
+
const targetSymbol = ts.isIdentifier(target) ? lowerer.resolveValueSymbol(target) : undefined;
|
|
4918
|
+
if (targetSymbol &&
|
|
4919
|
+
aliases.has(targetSymbol) &&
|
|
4920
|
+
ts.isObjectLiteralExpression(value) &&
|
|
4921
|
+
value.properties.nodes.some((field) => !(ts.isPropertyAssignment(field) || ts.isShorthandPropertyAssignment(field)) ||
|
|
4922
|
+
!(ts.isIdentifier(field.name) || ts.isStringLiteral(field.name)) ||
|
|
4923
|
+
!names.has(field.name.text)))
|
|
4924
|
+
expands = true;
|
|
4285
4925
|
}
|
|
4286
4926
|
if (ts.isDeleteExpression(node) && property(node.expression) !== undefined)
|
|
4287
4927
|
expands = true;
|
|
@@ -4289,7 +4929,7 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4289
4929
|
ts.isPropertyAccessExpression(node.expression) &&
|
|
4290
4930
|
node.expression.name.text === "setPrototypeOf" &&
|
|
4291
4931
|
lowerer.isStdlibGlobal(node.expression.expression, "Object")) {
|
|
4292
|
-
const target = node.arguments[0];
|
|
4932
|
+
const target = node.arguments.nodes[0];
|
|
4293
4933
|
const sym = target && ts.isIdentifier(target) ? lowerer.resolveValueSymbol(target) : undefined;
|
|
4294
4934
|
if (sym && aliases.has(sym))
|
|
4295
4935
|
expands = true;
|
|
@@ -4301,12 +4941,13 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4301
4941
|
}
|
|
4302
4942
|
export function hasJsTypeAnnotation(decl) {
|
|
4303
4943
|
const statement = decl.parent?.parent;
|
|
4304
|
-
return (!!statement &&
|
|
4944
|
+
return (!!statement &&
|
|
4945
|
+
/@type\b/.test(ts.getSourceFileOfNode(decl).text.slice(statement.pos, ts.tokenStartOfNode(decl))));
|
|
4305
4946
|
}
|
|
4306
4947
|
/** Inferred JS scalar initializers do not constrain later writes through
|
|
4307
4948
|
* an any-valued callback. Keep those bindings open, including captured writes. */
|
|
4308
4949
|
export function jsBindingHasOpenWrites(lowerer, decl) {
|
|
4309
|
-
if (!isJsSourceFile(
|
|
4950
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
4310
4951
|
decl.type ||
|
|
4311
4952
|
hasJsTypeAnnotation(decl) ||
|
|
4312
4953
|
!ts.isIdentifier(decl.name))
|
|
@@ -4339,37 +4980,117 @@ export function jsBindingHasOpenWrites(lowerer, decl) {
|
|
|
4339
4980
|
(lowerer.typeOf(node.right).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0);
|
|
4340
4981
|
}
|
|
4341
4982
|
function immediatelyGuardedAbsenceProbe(lowerer, decl) {
|
|
4342
|
-
|
|
4983
|
+
const guard = immediateAbsenceGuard(lowerer, decl);
|
|
4984
|
+
// `if (!x)`: the falsy test sees a missing value.
|
|
4985
|
+
if (guard === "falsy")
|
|
4986
|
+
return true;
|
|
4987
|
+
// `if (x === undefined)` and its spellings compare the binding with the
|
|
4988
|
+
// missing value itself, so the read must be able to produce it. Only
|
|
4989
|
+
// index-signature record reads take this form: array reads already
|
|
4990
|
+
// carry their undefined arm, and their ordinary lowering keeps its
|
|
4991
|
+
// bounds proofs.
|
|
4992
|
+
return guard === "compare" && isIndexSignatureRecordRead(lowerer, decl);
|
|
4993
|
+
}
|
|
4994
|
+
/** A file-scope or block-scope `let e = map[k]` over an index-signature
|
|
4995
|
+
* record whose next statement guards `e` for absence (`if (e ===
|
|
4996
|
+
* undefined)`, `if (!e)`, ...): the get-or-create idiom. Its read keeps the
|
|
4997
|
+
* missing key as undefined even without noUncheckedIndexedAccess. */
|
|
4998
|
+
export function isGuardedRecordRead(lowerer, decl) {
|
|
4999
|
+
return immediateAbsenceGuard(lowerer, decl) !== null && isIndexSignatureRecordRead(lowerer, decl);
|
|
5000
|
+
}
|
|
5001
|
+
function isIndexSignatureRecordRead(lowerer, decl) {
|
|
5002
|
+
if (!decl.initializer)
|
|
5003
|
+
return false;
|
|
5004
|
+
let init = decl.initializer;
|
|
5005
|
+
while (ts.isParenthesizedExpression(init))
|
|
5006
|
+
init = init.expression;
|
|
5007
|
+
if (!ts.isElementAccessExpression(init))
|
|
5008
|
+
return false;
|
|
5009
|
+
// Under noUncheckedIndexedAccess the checker already spells the missing
|
|
5010
|
+
// arm, and the ordinary read carries it.
|
|
5011
|
+
const read = lowerer.typeOf(init);
|
|
5012
|
+
if ((read.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0 ||
|
|
5013
|
+
(read.isUnionType() &&
|
|
5014
|
+
ts.constituentTypes(read).some((t) => (t.flags & ts.TypeFlags.Undefined) !== 0)))
|
|
4343
5015
|
return false;
|
|
5016
|
+
const receiver = lowerer.mapTypeOf(lowerer.typeOf(init.expression));
|
|
5017
|
+
const shape = receiver?.kind === "record" ? lowerer.shapes.get(receiver.shapeId) : undefined;
|
|
5018
|
+
return !!shape && !shape.tuple && !!shape.indexValue && shape.indexValue.kind !== "dyn";
|
|
5019
|
+
}
|
|
5020
|
+
/** How the statement right after an unannotated declaration tests the
|
|
5021
|
+
* declared binding for absence: `if (!x)` ("falsy"), or a comparison with
|
|
5022
|
+
* the missing value — `x === undefined`, `x == null`, `x !== void 0`,
|
|
5023
|
+
* `typeof x === "undefined"` and their mirrored and negated spellings
|
|
5024
|
+
* ("compare"). Null for anything else. */
|
|
5025
|
+
function immediateAbsenceGuard(lowerer, decl) {
|
|
5026
|
+
if (decl.type || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
5027
|
+
return null;
|
|
4344
5028
|
const statement = decl.parent?.parent;
|
|
4345
5029
|
if (!statement || !ts.isVariableStatement(statement))
|
|
4346
|
-
return
|
|
5030
|
+
return null;
|
|
4347
5031
|
const container = statement.parent;
|
|
4348
|
-
const statements = ts.isBlock(container) || ts.isSourceFile(container) ? container.statements : null;
|
|
5032
|
+
const statements = ts.isBlock(container) || ts.isSourceFile(container) ? container.statements.nodes : null;
|
|
4349
5033
|
if (!statements)
|
|
4350
|
-
return
|
|
5034
|
+
return null;
|
|
4351
5035
|
const index = statements.indexOf(statement);
|
|
4352
5036
|
const next = index >= 0 ? statements[index + 1] : undefined;
|
|
4353
5037
|
if (!next || !ts.isIfStatement(next))
|
|
4354
|
-
return
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
operand
|
|
4364
|
-
|
|
4365
|
-
|
|
5038
|
+
return null;
|
|
5039
|
+
const binding = lowerer.resolveValueSymbol(decl.name);
|
|
5040
|
+
const peel = (node) => {
|
|
5041
|
+
while (ts.isParenthesizedExpression(node))
|
|
5042
|
+
node = node.expression;
|
|
5043
|
+
return node;
|
|
5044
|
+
};
|
|
5045
|
+
const isBinding = (node) => {
|
|
5046
|
+
const operand = peel(node);
|
|
5047
|
+
return ts.isIdentifier(operand) && lowerer.resolveValueSymbol(operand) === binding;
|
|
5048
|
+
};
|
|
5049
|
+
const condition = peel(next.expression);
|
|
5050
|
+
if (ts.isPrefixUnaryExpression(condition))
|
|
5051
|
+
return condition.operator === ts.SyntaxKind.ExclamationToken && isBinding(condition.operand)
|
|
5052
|
+
? "falsy"
|
|
5053
|
+
: null;
|
|
5054
|
+
if (!ts.isBinaryExpression(condition))
|
|
5055
|
+
return null;
|
|
5056
|
+
const op = condition.operatorToken.kind;
|
|
5057
|
+
const strict = op === ts.SyntaxKind.EqualsEqualsEqualsToken ||
|
|
5058
|
+
op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
|
|
5059
|
+
const loose = op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken;
|
|
5060
|
+
if (!strict && !loose)
|
|
5061
|
+
return null;
|
|
5062
|
+
const isUndefined = (node) => {
|
|
5063
|
+
const operand = peel(node);
|
|
5064
|
+
if (ts.isVoidExpression(operand))
|
|
5065
|
+
return true;
|
|
5066
|
+
return (ts.isIdentifier(operand) &&
|
|
5067
|
+
operand.text === "undefined" &&
|
|
5068
|
+
(lowerer.typeOf(operand).flags & ts.TypeFlags.Undefined) !== 0);
|
|
5069
|
+
};
|
|
5070
|
+
const isNull = (node) => peel(node).kind === ts.SyntaxKind.NullKeyword;
|
|
5071
|
+
const missing = (node) => isUndefined(node) || (loose && isNull(node));
|
|
5072
|
+
const isTypeofBinding = (node) => {
|
|
5073
|
+
const operand = peel(node);
|
|
5074
|
+
return ts.isTypeOfExpression(operand) && isBinding(operand.expression);
|
|
5075
|
+
};
|
|
5076
|
+
const isUndefinedTag = (node) => {
|
|
5077
|
+
const operand = peel(node);
|
|
5078
|
+
return ts.isStringLiteralLike(operand) && operand.text === "undefined";
|
|
5079
|
+
};
|
|
5080
|
+
const { left, right } = condition;
|
|
5081
|
+
return (isBinding(left) && missing(right)) ||
|
|
5082
|
+
(missing(left) && isBinding(right)) ||
|
|
5083
|
+
(isTypeofBinding(left) && isUndefinedTag(right)) ||
|
|
5084
|
+
(isUndefinedTag(left) && isTypeofBinding(right))
|
|
5085
|
+
? "compare"
|
|
5086
|
+
: null;
|
|
4366
5087
|
}
|
|
4367
5088
|
function falsyExitRuntimeOptionalLocals(lowerer, stmt) {
|
|
4368
5089
|
if (stmt.elseStatement)
|
|
4369
5090
|
return [];
|
|
4370
5091
|
let tail = stmt.thenStatement;
|
|
4371
5092
|
while (ts.isBlock(tail)) {
|
|
4372
|
-
const last = tail.statements[tail.statements.length - 1];
|
|
5093
|
+
const last = tail.statements.nodes[tail.statements.nodes.length - 1];
|
|
4373
5094
|
if (!last)
|
|
4374
5095
|
return [];
|
|
4375
5096
|
tail = last;
|
|
@@ -4395,15 +5116,16 @@ export function lowerSwitch(lowerer, stmt) {
|
|
|
4395
5116
|
return lowerDynSwitch(lowerer, stmt, disc, labels);
|
|
4396
5117
|
if (dk === "union")
|
|
4397
5118
|
return lowerUnionSwitch(lowerer, stmt, disc, labels);
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
5119
|
+
// Objects, arrays, functions and other references match their cases
|
|
5120
|
+
// with ===, which compares them by identity.
|
|
5121
|
+
if (dk !== "f64" && dk !== "string" && dk !== "bool")
|
|
5122
|
+
return lowerBranchSwitch(lowerer, stmt, disc, labels, (stableDisc, test, expression) => lowerStrictEquality(lowerer, expression, stmt.expression, expression, stableDisc, test, false, locOf(expression)));
|
|
4401
5123
|
// The whole case-body sequence is ONE lexical scope in JS: a bare `let`
|
|
4402
5124
|
// in one case is visible in later cases.
|
|
4403
5125
|
lowerer.scopes.push(new Map());
|
|
4404
5126
|
try {
|
|
4405
5127
|
const cases = [];
|
|
4406
|
-
for (const clause of stmt.caseBlock.clauses) {
|
|
5128
|
+
for (const clause of stmt.caseBlock.clauses.nodes) {
|
|
4407
5129
|
let test = null;
|
|
4408
5130
|
if (ts.isCaseClause(clause)) {
|
|
4409
5131
|
test = lowerer.lowerExpr(clause.expression);
|
|
@@ -4413,7 +5135,7 @@ export function lowerSwitch(lowerer, stmt) {
|
|
|
4413
5135
|
}
|
|
4414
5136
|
cases.push({
|
|
4415
5137
|
test,
|
|
4416
|
-
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels),
|
|
5138
|
+
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements.nodes)), labels),
|
|
4417
5139
|
});
|
|
4418
5140
|
}
|
|
4419
5141
|
return { kind: "switch", disc, cases, ...(labels && { labels }), loc: locOf(stmt) };
|
|
@@ -4463,7 +5185,7 @@ function lowerDynSwitch(lowerer, stmt, disc, labels) {
|
|
|
4463
5185
|
loc: locOf(expression),
|
|
4464
5186
|
};
|
|
4465
5187
|
}
|
|
4466
|
-
if (!lowerer.dynConvertible(test.type)) {
|
|
5188
|
+
if (test.type.kind === "date" || !lowerer.dynConvertible(test.type)) {
|
|
4467
5189
|
lowerer.unsupported("SC1100", expression, "switch case values that cannot compare strictly with 'unknown'");
|
|
4468
5190
|
}
|
|
4469
5191
|
return {
|
|
@@ -4484,7 +5206,7 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4484
5206
|
// Calls/assignments in a case test may mutate a captured discriminant
|
|
4485
5207
|
// binding. The checker still narrows that binding as if it were the
|
|
4486
5208
|
// snapshot. Keep the original tagged value in those case bodies.
|
|
4487
|
-
const effectful = stmt.caseBlock.clauses.some((clause) => ts.isCaseClause(clause) &&
|
|
5209
|
+
const effectful = stmt.caseBlock.clauses.nodes.some((clause) => ts.isCaseClause(clause) &&
|
|
4488
5210
|
!ts.isStringLiteral(clause.expression) &&
|
|
4489
5211
|
!ts.isNumericLiteral(clause.expression) &&
|
|
4490
5212
|
!ts.isIdentifier(clause.expression) &&
|
|
@@ -4500,11 +5222,11 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4500
5222
|
lowerer.unstableSwitchBindings.add(symbol);
|
|
4501
5223
|
lowerer.scopes.push(new Map());
|
|
4502
5224
|
try {
|
|
4503
|
-
const cases = stmt.caseBlock.clauses.map((clause) => ({
|
|
5225
|
+
const cases = stmt.caseBlock.clauses.nodes.map((clause) => ({
|
|
4504
5226
|
test: ts.isCaseClause(clause)
|
|
4505
5227
|
? compare(stableDisc, lowerer.lowerExpr(clause.expression), clause.expression)
|
|
4506
5228
|
: null,
|
|
4507
|
-
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels),
|
|
5229
|
+
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements.nodes)), labels),
|
|
4508
5230
|
}));
|
|
4509
5231
|
return {
|
|
4510
5232
|
kind: "block",
|
|
@@ -4533,7 +5255,7 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4533
5255
|
* cell, deliberately narrower than dyn: the supported uses are the
|
|
4534
5256
|
* narrowing tests (`e instanceof C` over hierarchy classes, `typeof e
|
|
4535
5257
|
* === "string"/"number"/"boolean"`), reads under a proven narrow
|
|
4536
|
-
* (caughtRead bridges them with caughtNarrow,
|
|
5258
|
+
* (caughtRead bridges them with caughtNarrow, verified at run time like
|
|
4537
5259
|
* unionNarrow), and rethrow (`throw e`). Unsupported raw uses and
|
|
4538
5260
|
* assignments are fenced (SC1063 and friends); destructuring patterns
|
|
4539
5261
|
* are SC1062. Captures retain the snapshot beyond the catch scope.
|
|
@@ -4579,31 +5301,6 @@ export function lowerTry(lowerer, stmt) {
|
|
|
4579
5301
|
loc: locOf(stmt),
|
|
4580
5302
|
};
|
|
4581
5303
|
}
|
|
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
5304
|
/** Statement-position `delete`: process.env keys → process.envUnset
|
|
4608
5305
|
* (unsetenv), pure `Record<string, T>` keys → recordKeyDelete (the
|
|
4609
5306
|
* overflow Map delete), declared OPTIONAL fields → the field's ABSENT
|
|
@@ -4666,7 +5363,29 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4666
5363
|
};
|
|
4667
5364
|
}
|
|
4668
5365
|
let obj = lowerer.lowerExpr(target.expression);
|
|
4669
|
-
|
|
5366
|
+
// `delete this.stack` in an Error subclass that declares a `stack`
|
|
5367
|
+
// accessor (quickjs-wasi's JSException): V8 gives each error an own
|
|
5368
|
+
// `stack` that shadows the accessor, and the delete removes it so reads
|
|
5369
|
+
// reach the accessor. Compiled errors keep the trace internally and
|
|
5370
|
+
// class dispatch already reads the accessor, so only the receiver's
|
|
5371
|
+
// evaluation remains.
|
|
5372
|
+
if (obj.type.kind === "object" &&
|
|
5373
|
+
ts.isPropertyAccessExpression(target) &&
|
|
5374
|
+
target.name.text === "stack") {
|
|
5375
|
+
let accessor = false;
|
|
5376
|
+
let errorBase = false;
|
|
5377
|
+
for (let c = lowerer.classes.get(obj.type.className); c; c = c.base ?? undefined) {
|
|
5378
|
+
if (c.builtinError) {
|
|
5379
|
+
errorBase = true;
|
|
5380
|
+
break;
|
|
5381
|
+
}
|
|
5382
|
+
if (c.methods.has("get:stack"))
|
|
5383
|
+
accessor = true;
|
|
5384
|
+
}
|
|
5385
|
+
if (accessor && errorBase)
|
|
5386
|
+
return { kind: "exprStmt", expr: obj, loc };
|
|
5387
|
+
}
|
|
5388
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) && obj.type.kind === "object") {
|
|
4670
5389
|
const info = lowerer.classes.get(obj.type.className);
|
|
4671
5390
|
const keyType = ts.isElementAccessExpression(target)
|
|
4672
5391
|
? lowerer.typeOf(target.argumentExpression)
|
|
@@ -4686,13 +5405,13 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4686
5405
|
};
|
|
4687
5406
|
}
|
|
4688
5407
|
}
|
|
4689
|
-
if (isJsSourceFile(
|
|
5408
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
4690
5409
|
obj.type.kind === "func" &&
|
|
4691
5410
|
lowerer.dynConvertible(obj.type)) {
|
|
4692
5411
|
obj = lowerer.coerceToExpected(obj, DYN);
|
|
4693
5412
|
}
|
|
4694
5413
|
if (obj.type.kind === "dyn") {
|
|
4695
|
-
const strict = { kind: "boolLit", value:
|
|
5414
|
+
const strict = { kind: "boolLit", value: isStrictCode(expr), type: BOOL, loc };
|
|
4696
5415
|
if (ts.isElementAccessExpression(target)) {
|
|
4697
5416
|
const key = lowerer.lowerExprExpecting(target.argumentExpression, DYN);
|
|
4698
5417
|
return {
|
|
@@ -4779,7 +5498,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4779
5498
|
const assignExport = (nameNode, value, root) => {
|
|
4780
5499
|
const symbol = lowerer.checker.getSymbolAtLocation(nameNode) ??
|
|
4781
5500
|
(ts.isIdentifier(nameNode) || ts.isPrivateIdentifier(nameNode)
|
|
4782
|
-
? lowerer.cjsModuleExportSymbol(cjs.expr
|
|
5501
|
+
? lowerer.cjsModuleExportSymbol(ts.getSourceFileOfNode(cjs.expr), nameNode.text)
|
|
4783
5502
|
: undefined);
|
|
4784
5503
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
4785
5504
|
if (!g) {
|
|
@@ -4838,7 +5557,10 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4838
5557
|
// storage — collectGlobals skipped it; importers re-resolve through
|
|
4839
5558
|
// cjsMemberExportClassSymbol): the statement lowers to nothing.
|
|
4840
5559
|
if (lowerer.cjsMemberExportClassSymbol(cjs.expr) !== null) {
|
|
4841
|
-
|
|
5560
|
+
// An inline require still evaluates its module here.
|
|
5561
|
+
const req = inlineProgramRequireOf(lowerer, cjs.value);
|
|
5562
|
+
const init = req !== null ? lowerer.requireInitStmt(req.spec, req.call) : null;
|
|
5563
|
+
return init ?? { kind: "block", body: [], loc };
|
|
4842
5564
|
}
|
|
4843
5565
|
// The tsc VOID-INIT PREAMBLE (`exports.leaf = void 0;` with the real
|
|
4844
5566
|
// `exports.leaf = leaf;` further down — every tsc-emitted dist file
|
|
@@ -4850,54 +5572,58 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4850
5572
|
// the real assignment's position already orders. Preambles with no
|
|
4851
5573
|
// later real assignment keep the ordinary path (the export IS
|
|
4852
5574
|
// 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();
|
|
5575
|
+
if (cjsVoidInitPreambleReals(cjs) !== null)
|
|
5576
|
+
return { kind: "block", body: [], loc };
|
|
5577
|
+
const sf = ts.getSourceFileOfNode(cjs.expr);
|
|
4894
5578
|
let root;
|
|
4895
|
-
for (const stmt of sf.statements) {
|
|
5579
|
+
for (const stmt of sf.statements.nodes) {
|
|
4896
5580
|
const whole = cjsExportAssignmentOf(stmt);
|
|
4897
5581
|
if (whole?.kind !== "table" || cjsExportDiscardReason(stmt) !== null)
|
|
4898
5582
|
continue;
|
|
4899
5583
|
root = lowerer.globalsByDeclNode.get(whole.expr);
|
|
4900
5584
|
}
|
|
5585
|
+
// A CHAIN `exports.a = exports.b = value`: Node evaluates the value
|
|
5586
|
+
// once, assigns the innermost member first, and every member holds
|
|
5587
|
+
// the same value. Each member is its own export global
|
|
5588
|
+
// (collectGlobals registers the inner ones too).
|
|
5589
|
+
{
|
|
5590
|
+
const chain = cjsExportChainOf(cjs.expr);
|
|
5591
|
+
if (chain !== null && root?.type.kind !== "dyn") {
|
|
5592
|
+
const globalOfName = (nameNode) => {
|
|
5593
|
+
const symbol = lowerer.checker.getSymbolAtLocation(nameNode) ??
|
|
5594
|
+
lowerer.cjsModuleExportSymbol(sf, nameNode.text);
|
|
5595
|
+
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
5596
|
+
if (!g) {
|
|
5597
|
+
lowerer.lowerExpr(chain.value);
|
|
5598
|
+
lowerer.badType(chain.value, lowerer.typeOf(chain.value));
|
|
5599
|
+
}
|
|
5600
|
+
return g;
|
|
5601
|
+
};
|
|
5602
|
+
const inner = chain.names[chain.names.length - 1];
|
|
5603
|
+
const innerG = globalOfName(inner);
|
|
5604
|
+
const body = [
|
|
5605
|
+
{
|
|
5606
|
+
kind: "assign",
|
|
5607
|
+
localId: innerG.id,
|
|
5608
|
+
value: lowerer.lowerExprExpecting(chain.value, innerG.type),
|
|
5609
|
+
loc: locOf(chain.value),
|
|
5610
|
+
},
|
|
5611
|
+
];
|
|
5612
|
+
for (let i = chain.names.length - 2; i >= 0; i--) {
|
|
5613
|
+
const g = globalOfName(chain.names[i]);
|
|
5614
|
+
const read = { kind: "varRef", localId: innerG.id, type: innerG.type, loc };
|
|
5615
|
+
body.push({
|
|
5616
|
+
kind: "assign",
|
|
5617
|
+
localId: g.id,
|
|
5618
|
+
value: typeEquals(g.type, innerG.type)
|
|
5619
|
+
? read
|
|
5620
|
+
: lowerer.coerceInto(chain.value, read, g.type),
|
|
5621
|
+
loc,
|
|
5622
|
+
});
|
|
5623
|
+
}
|
|
5624
|
+
return { kind: "block", body, loc };
|
|
5625
|
+
}
|
|
5626
|
+
}
|
|
4901
5627
|
return assignExport(cjs.name, cjs.value, root);
|
|
4902
5628
|
}
|
|
4903
5629
|
let tableObj = cjs.obj;
|
|
@@ -4911,7 +5637,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4911
5637
|
// were already evaluated by the const's own declaration, so this
|
|
4912
5638
|
// statement may not RE-evaluate anything: expression-valued entries
|
|
4913
5639
|
// (which the direct-table lowering assigns here) keep a fence.
|
|
4914
|
-
tableObj = cjsExportTargetLiteral(cjs.expr.right, cjs.expr
|
|
5640
|
+
tableObj = cjsExportTargetLiteral(cjs.expr.right, ts.getSourceFileOfNode(cjs.expr));
|
|
4915
5641
|
resolvedTarget = tableObj !== null;
|
|
4916
5642
|
if (!tableObj) {
|
|
4917
5643
|
const single = lowerCjsSingleValueExport(lowerer, cjs.expr, loc);
|
|
@@ -4934,7 +5660,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4934
5660
|
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
5661
|
}
|
|
4936
5662
|
};
|
|
4937
|
-
for (const prop of table.properties) {
|
|
5663
|
+
for (const prop of table.properties.nodes) {
|
|
4938
5664
|
if (ts.isShorthandPropertyAssignment(prop)) {
|
|
4939
5665
|
fenceMutable(prop.name);
|
|
4940
5666
|
continue; // alias plumbing
|
|
@@ -4952,6 +5678,29 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4952
5678
|
body.push(assignExport(prop.name, prop.initializer));
|
|
4953
5679
|
continue;
|
|
4954
5680
|
}
|
|
5681
|
+
// METHOD entries: the export global holds the method's function,
|
|
5682
|
+
// created at this statement like a function-expression entry. Node
|
|
5683
|
+
// calls it with `this` bound to the table, which the static export
|
|
5684
|
+
// table cannot represent, so a body that uses `this` keeps a fence.
|
|
5685
|
+
{
|
|
5686
|
+
const method = cjsTableMethodEntry(prop);
|
|
5687
|
+
if (method !== null && !resolvedTarget) {
|
|
5688
|
+
lowerer.rejectThisInObjectMethod(method.body);
|
|
5689
|
+
const symbol = lowerer.checker.getSymbolAtLocation(method.name) ??
|
|
5690
|
+
lowerer.cjsModuleExportSymbol(ts.getSourceFileOfNode(cjs.expr), method.name.text);
|
|
5691
|
+
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
5692
|
+
if (g) {
|
|
5693
|
+
const fn = lowerer.lowerLambda(method);
|
|
5694
|
+
body.push({
|
|
5695
|
+
kind: "assign",
|
|
5696
|
+
localId: g.id,
|
|
5697
|
+
value: typeEquals(fn.type, g.type) ? fn : lowerer.coerceInto(method, fn, g.type),
|
|
5698
|
+
loc: locOf(method),
|
|
5699
|
+
});
|
|
5700
|
+
continue;
|
|
5701
|
+
}
|
|
5702
|
+
}
|
|
5703
|
+
}
|
|
4955
5704
|
// ACCESSOR entries: no storage and no code here — reads lift the
|
|
4956
5705
|
// getter as a module-level function and call it per read
|
|
4957
5706
|
// (cjsExportAccessorRead); writes through the setter keep their
|
|
@@ -4969,8 +5718,16 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4969
5718
|
let inner = prop.expression;
|
|
4970
5719
|
while (ts.isParenthesizedExpression(inner))
|
|
4971
5720
|
inner = inner.expression;
|
|
4972
|
-
if (requireSpecOf(inner) !== null)
|
|
5721
|
+
if (requireSpecOf(inner) !== null) {
|
|
5722
|
+
// The spread still EVALUATES the module, at its place among the
|
|
5723
|
+
// table's entries (a program module joins the graph through this
|
|
5724
|
+
// inline require; cjs-inline-require.ts).
|
|
5725
|
+
const req = inlineProgramRequireOf(lowerer, inner);
|
|
5726
|
+
const init = req !== null ? lowerer.requireInitStmt(req.spec, req.call) : null;
|
|
5727
|
+
if (init !== null && !resolvedTarget)
|
|
5728
|
+
body.push(init);
|
|
4973
5729
|
continue;
|
|
5730
|
+
}
|
|
4974
5731
|
}
|
|
4975
5732
|
lowerer.unsupported("SC1090", prop, "module.exports table entries beyond plain 'name: value' properties (methods, accessors, spreads, computed names)");
|
|
4976
5733
|
}
|
|
@@ -4995,6 +5752,16 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
|
|
|
4995
5752
|
let rhs = expr.right;
|
|
4996
5753
|
while (ts.isParenthesizedExpression(rhs))
|
|
4997
5754
|
rhs = rhs.expression;
|
|
5755
|
+
// `module.exports = require("./x")`: the module re-exports x's exports.
|
|
5756
|
+
// Requirers resolve through the checker's alias to x's own export
|
|
5757
|
+
// machinery; this statement is x's evaluation at this position.
|
|
5758
|
+
{
|
|
5759
|
+
const req = inlineProgramRequireOf(lowerer, rhs);
|
|
5760
|
+
// With later member exports (`module.exports.extra = …`) the module
|
|
5761
|
+
// extends that object, so it keeps the factory root registration.
|
|
5762
|
+
if (req !== null && !lowerer.globalsByDeclNode.has(expr))
|
|
5763
|
+
return lowerer.requireInitStmt(req.spec, req.call) ?? { kind: "block", body: [], loc };
|
|
5764
|
+
}
|
|
4998
5765
|
if (ts.isIdentifier(rhs)) {
|
|
4999
5766
|
const sym = lowerer.resolveValueSymbol(rhs);
|
|
5000
5767
|
if (!sym)
|
|
@@ -5004,6 +5771,14 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
|
|
|
5004
5771
|
lowerer.genericFnsBySymbol.has(sym)) {
|
|
5005
5772
|
return { kind: "block", body: [], loc };
|
|
5006
5773
|
}
|
|
5774
|
+
// A require binding (`const x = require("./x"); module.exports = x`)
|
|
5775
|
+
// re-exports that module exactly like the inline form (the binding's
|
|
5776
|
+
// own statement already evaluated it), and a builtin global
|
|
5777
|
+
// (`module.exports = TypeError`) is the global itself: requirer
|
|
5778
|
+
// bindings alias straight through to it, so nothing is stored.
|
|
5779
|
+
if (sym.declarations.some((d) => ts.isSourceFile(d)) || lowerer.isStdlibSymbol(sym)) {
|
|
5780
|
+
return { kind: "block", body: [], loc };
|
|
5781
|
+
}
|
|
5007
5782
|
const g = lowerer.globalsBySymbol.get(sym);
|
|
5008
5783
|
if (g) {
|
|
5009
5784
|
if (g.mutable) {
|
|
@@ -5108,8 +5883,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5108
5883
|
// positions keep the first-class-namespace fences.
|
|
5109
5884
|
if (ts.isIdentifier(expr)) {
|
|
5110
5885
|
const sym = lowerer.checker.getSymbolAtLocation(expr);
|
|
5111
|
-
if (sym !== undefined &&
|
|
5112
|
-
lowerer.checker.declarationsOf(sym).some((d) => ts.isNamespaceImport(d))) {
|
|
5886
|
+
if (sym !== undefined && sym.declarations.some((d) => ts.isNamespaceImport(d))) {
|
|
5113
5887
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5114
5888
|
}
|
|
5115
5889
|
}
|
|
@@ -5142,16 +5916,22 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5142
5916
|
return (lowerer.requireInitStmt(created.spec, expr) ?? { kind: "block", body: [], loc: locOf(expr) });
|
|
5143
5917
|
}
|
|
5144
5918
|
// syncBuiltinESMExports() is the other compiler-only statement: the
|
|
5145
|
-
// call validates its zero-argument shape, then
|
|
5146
|
-
//
|
|
5919
|
+
// call validates its zero-argument shape, then refreshes the events
|
|
5920
|
+
// module's ES module namespace copy of defaultMaxListeners, the one
|
|
5921
|
+
// builtin export a program can change.
|
|
5147
5922
|
const bi = ts.isIdentifier(expr.expression)
|
|
5148
5923
|
? lowerer.builtinImportOf(expr.expression)
|
|
5149
5924
|
: ts.isPropertyAccessExpression(expr.expression)
|
|
5150
5925
|
? lowerer.builtinMemberOf(expr.expression)
|
|
5151
5926
|
: null;
|
|
5152
5927
|
if (bi?.module === "module" && bi.member === "syncBuiltinESMExports") {
|
|
5153
|
-
|
|
5154
|
-
|
|
5928
|
+
const loc = locOf(expr);
|
|
5929
|
+
lowerNodeModuleCall(lowerer, expr, bi, loc);
|
|
5930
|
+
return {
|
|
5931
|
+
kind: "exprStmt",
|
|
5932
|
+
expr: { kind: "libCall", fn: "emitter.esmSync", args: [], type: VOID, loc },
|
|
5933
|
+
loc,
|
|
5934
|
+
};
|
|
5155
5935
|
}
|
|
5156
5936
|
}
|
|
5157
5937
|
if (requireSpecOf(expr) !== null &&
|
|
@@ -5160,7 +5940,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5160
5940
|
// A binding NAMED require made by createRequire is not the CJS
|
|
5161
5941
|
// global — the expression path owns it (lowerCreateRequireCall).
|
|
5162
5942
|
createRequireCalleeFileOf(lowerer, expr.expression) === null) {
|
|
5163
|
-
const sf =
|
|
5943
|
+
const sf = ts.getSourceFileOfNode(expr);
|
|
5164
5944
|
const spec = requireSpecOf(expr);
|
|
5165
5945
|
if (lowerer.externalTypes.has(spec))
|
|
5166
5946
|
lowerer.externalHostFence(spec, expr, false);
|
|
@@ -5199,7 +5979,30 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5199
5979
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5200
5980
|
lowerer.unsupported("SC1090", expr, "require() outside the module's top level (move it to the top of the file)");
|
|
5201
5981
|
}
|
|
5982
|
+
// Replacing the export object (or rebinding `exports`) anywhere but a
|
|
5983
|
+
// top-level statement makes the module's exports depend on which path
|
|
5984
|
+
// ran (`cond ? module.exports = a : module.exports = b`, an
|
|
5985
|
+
// environment-dependent branch); the static export table has one shape.
|
|
5986
|
+
if (!topLevelJs &&
|
|
5987
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
5988
|
+
ts.isBinaryExpression(expr) &&
|
|
5989
|
+
expr.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
5990
|
+
(isCjsModuleExports(lowerer, expr.left) || isCjsExportsIdentifier(lowerer, expr.left))) {
|
|
5991
|
+
lowerer.unsupported("SC1090", expr.left, isCjsModuleExports(lowerer, expr.left)
|
|
5992
|
+
? "replacing module.exports outside a top-level statement (a conditional or environment-dependent export object)"
|
|
5993
|
+
: "rebinding 'exports' outside a top-level statement (a conditional or environment-dependent export object)");
|
|
5994
|
+
}
|
|
5202
5995
|
if (topLevelJs && ts.isExpressionStatement(stmtNode)) {
|
|
5996
|
+
if (isFreshExportsReset(lowerer, stmtNode))
|
|
5997
|
+
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5998
|
+
// Any other `exports = …` rebinds the wrapper's exports binding: the
|
|
5999
|
+
// members later attached through it belong to the new value.
|
|
6000
|
+
if (ts.isBinaryExpression(expr) &&
|
|
6001
|
+
expr.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
6002
|
+
isCjsExportsIdentifier(lowerer, expr.left) &&
|
|
6003
|
+
cjsExportAssignmentOf(stmtNode)?.kind !== "table") {
|
|
6004
|
+
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");
|
|
6005
|
+
}
|
|
5203
6006
|
const cjs = cjsExportAssignmentOf(stmtNode);
|
|
5204
6007
|
if (cjs)
|
|
5205
6008
|
return lowerCjsExportStatement(lowerer, cjs);
|
|
@@ -5399,7 +6202,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5399
6202
|
}
|
|
5400
6203
|
else {
|
|
5401
6204
|
const recvT = lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression));
|
|
5402
|
-
|
|
6205
|
+
// A runtime-provided class (`Error.stackTraceLimit = 0`) keeps
|
|
6206
|
+
// its static lowering below.
|
|
6207
|
+
if (recvT?.kind === "classval" && !lowerer.classes.get(recvT.className)?.def.runtime) {
|
|
5403
6208
|
// A static write through a class VALUE: sound exactly when
|
|
5404
6209
|
// the value can only BE the declaring class — a LEAF class
|
|
5405
6210
|
// (no strict descendants can flow into the slot, so JS's
|
|
@@ -5499,9 +6304,12 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5499
6304
|
lowerer.stdlibGlobalMember(expr.left, "process") === "exitCode") {
|
|
5500
6305
|
const loc = locOf(expr);
|
|
5501
6306
|
const value = lowerer.lowerExprExpecting(expr.right, F64);
|
|
6307
|
+
const fn = programReadsExitCode(lowerer)
|
|
6308
|
+
? "process.setExitCodeTracked"
|
|
6309
|
+
: "process.setExitCode";
|
|
5502
6310
|
return {
|
|
5503
6311
|
kind: "exprStmt",
|
|
5504
|
-
expr: { kind: "libCall", fn
|
|
6312
|
+
expr: { kind: "libCall", fn, args: [value], type: VOID, loc },
|
|
5505
6313
|
loc,
|
|
5506
6314
|
};
|
|
5507
6315
|
}
|
|
@@ -5522,6 +6330,30 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5522
6330
|
loc,
|
|
5523
6331
|
};
|
|
5524
6332
|
}
|
|
6333
|
+
// process.emitWarning = fn: an ordinary writable property. Later
|
|
6334
|
+
// process.emitWarning(...) calls, and the warnings Node's own
|
|
6335
|
+
// modules emit through process.emitWarning, call the replacement
|
|
6336
|
+
// instead (silencing them when it does nothing).
|
|
6337
|
+
if (flag === "emitWarning") {
|
|
6338
|
+
const loc = locOf(expr);
|
|
6339
|
+
let rhs = expr.right;
|
|
6340
|
+
while (ts.isParenthesizedExpression(rhs) ||
|
|
6341
|
+
ts.isAsExpression(rhs) ||
|
|
6342
|
+
ts.isSatisfiesExpression(rhs))
|
|
6343
|
+
rhs = rhs.expression;
|
|
6344
|
+
const value = lowerer.lowerExprExpecting(rhs, DYN);
|
|
6345
|
+
return {
|
|
6346
|
+
kind: "exprStmt",
|
|
6347
|
+
expr: {
|
|
6348
|
+
kind: "libCall",
|
|
6349
|
+
fn: "process.setEmitWarning",
|
|
6350
|
+
args: [value],
|
|
6351
|
+
type: VOID,
|
|
6352
|
+
loc,
|
|
6353
|
+
},
|
|
6354
|
+
loc,
|
|
6355
|
+
};
|
|
6356
|
+
}
|
|
5525
6357
|
// process.title = name: libuv's uv_set_process_title (the
|
|
5526
6358
|
// runtime truncates to the original argument area on POSIX).
|
|
5527
6359
|
if (flag === "title") {
|
|
@@ -5586,7 +6418,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5586
6418
|
const recv = tryLowerExpression(lowerer, expr.left.expression);
|
|
5587
6419
|
if (recv &&
|
|
5588
6420
|
(recv.type.kind === "dyn" ||
|
|
5589
|
-
(isJsSourceFile(
|
|
6421
|
+
(isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
5590
6422
|
recv.type.kind === "union" &&
|
|
5591
6423
|
lowerer.dynConvertible(recv.type)))) {
|
|
5592
6424
|
const loc = locOf(expr);
|
|
@@ -5606,6 +6438,32 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5606
6438
|
loc,
|
|
5607
6439
|
};
|
|
5608
6440
|
}
|
|
6441
|
+
// `err.code = v` on an Error value (`err as Error & { code?:
|
|
6442
|
+
// string }`): typed reads come from the runtime error's code
|
|
6443
|
+
// slot, so the write lands there. A value that is not statically
|
|
6444
|
+
// a string checks at runtime: strings take the slot, anything
|
|
6445
|
+
// else clears it and stays a dynamic own property. The
|
|
6446
|
+
// system-error members (errno, syscall, path, dest) read
|
|
6447
|
+
// through the checked-dynamic node and keep the dynamic write, as
|
|
6448
|
+
// do JavaScript files, whose reads use that node too.
|
|
6449
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
6450
|
+
recv?.type.kind === "object" &&
|
|
6451
|
+
lowerer.isErrorRootedClass(recv.type.className) &&
|
|
6452
|
+
expr.left.name.text === "code") {
|
|
6453
|
+
const loc = locOf(expr);
|
|
6454
|
+
const stringValue = isStringTyped(lowerer.typeOf(expr.right));
|
|
6455
|
+
return {
|
|
6456
|
+
kind: "exprStmt",
|
|
6457
|
+
expr: {
|
|
6458
|
+
kind: "libCall",
|
|
6459
|
+
fn: stringValue ? "error.setCode" : "error.setCodeDyn",
|
|
6460
|
+
args: [recv, lowerer.lowerExprExpecting(expr.right, stringValue ? STRING : DYN)],
|
|
6461
|
+
type: VOID,
|
|
6462
|
+
loc,
|
|
6463
|
+
},
|
|
6464
|
+
loc,
|
|
6465
|
+
};
|
|
6466
|
+
}
|
|
5609
6467
|
if (recv?.type.kind === "object" && recv.type.className === "%Error") {
|
|
5610
6468
|
const loc = locOf(expr);
|
|
5611
6469
|
return {
|
|
@@ -5657,6 +6515,25 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5657
6515
|
const recvIr = lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression));
|
|
5658
6516
|
if (recvIr?.kind === "record") {
|
|
5659
6517
|
const shape = lowerer.shapes.get(recvIr.shapeId);
|
|
6518
|
+
if (shape?.indexValue &&
|
|
6519
|
+
shape.fields.length === 0 &&
|
|
6520
|
+
declaredMemberOf(lowerer, expr.left.expression, expr.left.name.text)) {
|
|
6521
|
+
// A declared member of a literal stored as a pure index-signature
|
|
6522
|
+
// record (dictSpreadLiteralShape): a keyed write of that key.
|
|
6523
|
+
const loc = locOf(expr);
|
|
6524
|
+
const obj = lowerer.lowerExpr(expr.left.expression);
|
|
6525
|
+
if (obj.type.kind === "record") {
|
|
6526
|
+
const value = lowerer.intoIndexValueSlot(lowerer.lowerExprExpecting(expr.right, shape.indexValue), shape.indexValue, expr.right);
|
|
6527
|
+
return {
|
|
6528
|
+
kind: "recordKeySet",
|
|
6529
|
+
obj,
|
|
6530
|
+
shapeId: obj.type.shapeId,
|
|
6531
|
+
key: { kind: "strLit", value: expr.left.name.text, type: STRING, loc },
|
|
6532
|
+
value,
|
|
6533
|
+
loc,
|
|
6534
|
+
};
|
|
6535
|
+
}
|
|
6536
|
+
}
|
|
5660
6537
|
if (shape?.indexValue &&
|
|
5661
6538
|
!shape.fields.some((f) => f.name === expr.left.name.text)) {
|
|
5662
6539
|
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 +6550,19 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5673
6550
|
const parts = lowerDestructuringAssignParts(lowerer, expr.left, expr.right, locOf(expr));
|
|
5674
6551
|
return { kind: "block", body: parts.stmts, loc: locOf(expr) };
|
|
5675
6552
|
}
|
|
6553
|
+
// `exports.x = v` inside a function updates the member's export
|
|
6554
|
+
// global (cjs-exports-object.ts).
|
|
6555
|
+
if (ts.isPropertyAccessExpression(expr.left)) {
|
|
6556
|
+
const g = cjsExportMemberWriteGlobalOf(lowerer, expr.left);
|
|
6557
|
+
if (g) {
|
|
6558
|
+
return {
|
|
6559
|
+
kind: "assign",
|
|
6560
|
+
localId: g.id,
|
|
6561
|
+
value: lowerer.lowerExprExpecting(expr.right, g.type),
|
|
6562
|
+
loc: locOf(expr),
|
|
6563
|
+
};
|
|
6564
|
+
}
|
|
6565
|
+
}
|
|
5676
6566
|
if (!ts.isIdentifier(expr.left)) {
|
|
5677
6567
|
lowerer.unsupported("SC1090", expr.left, "assignment to non-variables");
|
|
5678
6568
|
}
|
|
@@ -5768,6 +6658,13 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5768
6658
|
if (droppedPureStdlibStatement(lowerer, expr)) {
|
|
5769
6659
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5770
6660
|
}
|
|
6661
|
+
if (stmtNode !== undefined &&
|
|
6662
|
+
ts.isExpressionStatement(stmtNode) &&
|
|
6663
|
+
ts.isBinaryExpression(expr) &&
|
|
6664
|
+
(expr.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
6665
|
+
expr.operatorToken.kind === ts.SyntaxKind.BarBarToken)) {
|
|
6666
|
+
return lowerDiscardedLogical(lowerer, expr);
|
|
6667
|
+
}
|
|
5771
6668
|
const value = lowerer.lowerExpr(expr);
|
|
5772
6669
|
// A bare unit-literal statement (`undefined;`): a pure no-op in JS,
|
|
5773
6670
|
// and the IR has no bare-unit VALUE outside a union wrap — drop it
|
|
@@ -5776,6 +6673,55 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5776
6673
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5777
6674
|
return { kind: "exprStmt", expr: value, loc: locOf(expr) };
|
|
5778
6675
|
}
|
|
6676
|
+
/** A discarded `a && b` / `a || b` statement (the minifier's `if`). The
|
|
6677
|
+
* value form lowers first, exactly as before. Only when it fails on the
|
|
6678
|
+
* logical's own result type — the operands have no common representation
|
|
6679
|
+
* (jose's `(!m || m[4] && m[1]) && invalid()` joins a boolean, a string
|
|
6680
|
+
* and undefined into the checker's `string`) — does the statement lower
|
|
6681
|
+
* as the control flow it is: `if (a) b;` / `if (!a) b;`, a condition test
|
|
6682
|
+
* that needs no result value. Diagnostics outside the statement, and
|
|
6683
|
+
* internal errors, keep the original failure. */
|
|
6684
|
+
function lowerDiscardedLogical(lowerer, expr) {
|
|
6685
|
+
const diagsBefore = lowerer.diags.length;
|
|
6686
|
+
try {
|
|
6687
|
+
const value = lowerer.lowerExpr(expr);
|
|
6688
|
+
if (value.kind === "unitLit")
|
|
6689
|
+
return { kind: "block", body: [], loc: locOf(expr) };
|
|
6690
|
+
return { kind: "exprStmt", expr: value, loc: locOf(expr) };
|
|
6691
|
+
}
|
|
6692
|
+
catch (e) {
|
|
6693
|
+
// A probe (a capture buffer is active) keeps its failure: its owner
|
|
6694
|
+
// picks another lowering, exactly as before.
|
|
6695
|
+
if (!(e instanceof PoisonError) || lowerer.diagSink !== null)
|
|
6696
|
+
throw e;
|
|
6697
|
+
const added = lowerer.diags.slice(diagsBefore);
|
|
6698
|
+
const file = ts.getSourceFileOfNode(expr).fileName;
|
|
6699
|
+
const start = ts.tokenStartOfNode(expr);
|
|
6700
|
+
const local = added.length > 0 &&
|
|
6701
|
+
added.every((d) => d.code !== "SC9001" &&
|
|
6702
|
+
d.loc.file === file &&
|
|
6703
|
+
d.loc.start >= start &&
|
|
6704
|
+
d.loc.end <= expr.end);
|
|
6705
|
+
if (!local)
|
|
6706
|
+
throw e;
|
|
6707
|
+
lowerer.diags.length = diagsBefore;
|
|
6708
|
+
}
|
|
6709
|
+
const and = expr.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken;
|
|
6710
|
+
const cond = lowerer.lowerCondition(expr.left);
|
|
6711
|
+
if (cond.kind === "boolLit") {
|
|
6712
|
+
return cond.value === and
|
|
6713
|
+
? lowerExprStatement(lowerer, expr.right)
|
|
6714
|
+
: { kind: "block", body: [], loc: locOf(expr) };
|
|
6715
|
+
}
|
|
6716
|
+
const right = () => lowerer.narrowingAliases(aliasTypeofNarrows(lowerer, expr.left, and), () => and
|
|
6717
|
+
? withRuntimeOptionalNarrowed(lowerer, runtimeOptionalTrueIds(lowerer, expr.left), () => [
|
|
6718
|
+
lowerExprStatement(lowerer, expr.right),
|
|
6719
|
+
])
|
|
6720
|
+
: [lowerExprStatement(lowerer, expr.right)]);
|
|
6721
|
+
return and
|
|
6722
|
+
? { kind: "if", cond, then: right(), else_: [], loc: locOf(expr) }
|
|
6723
|
+
: { kind: "if", cond, then: [], else_: right(), loc: locOf(expr) };
|
|
6724
|
+
}
|
|
5779
6725
|
/** True for a statement-position expression whose evaluation cannot be
|
|
5780
6726
|
* observed once the value is discarded:
|
|
5781
6727
|
* - a property/element READ (`?.` included) whose receiver IS a
|
|
@@ -5809,7 +6755,7 @@ function droppedPureStdlibStatement(lowerer, expr) {
|
|
|
5809
6755
|
const root = stdlibGlobalNameOf(lowerer, strip(proto.expression));
|
|
5810
6756
|
if (root !== "Array" && root !== "String")
|
|
5811
6757
|
return false;
|
|
5812
|
-
return expr.arguments.every((a) => sideEffectFreeOptionValue(a));
|
|
6758
|
+
return expr.arguments.nodes.every((a) => sideEffectFreeOptionValue(a));
|
|
5813
6759
|
}
|
|
5814
6760
|
if (ts.isPropertyAccessExpression(expr)) {
|
|
5815
6761
|
return stdlibGlobalNameOf(lowerer, strip(expr.expression)) !== null;
|
|
@@ -5877,18 +6823,46 @@ export function lowerDestructuringAssign(lowerer, target, init, blame, loc) {
|
|
|
5877
6823
|
}
|
|
5878
6824
|
/** V8's spelling of a destructuring RHS in its TypeError message
|
|
5879
6825
|
* ("Cannot destructure 'a' as it is undefined.") — plain identifiers
|
|
5880
|
-
* spell their name (parens unwrap),
|
|
5881
|
-
*
|
|
6826
|
+
* spell their name (parens unwrap), `this`, property chains and
|
|
6827
|
+
* identifier or numeric element reads spell their source, awaited and
|
|
6828
|
+
* yielded values spell "(intermediate value)", and calls append an
|
|
6829
|
+
* ellipsis to a supported callee spelling. Other CallPrinter forms keep
|
|
6830
|
+
* a fence. */
|
|
5882
6831
|
function destrSpellingOf(rhs) {
|
|
5883
6832
|
let e = rhs;
|
|
5884
|
-
|
|
6833
|
+
// Parentheses and the type-only wrappers are not part of the emitted
|
|
6834
|
+
// JavaScript expression V8 prints.
|
|
6835
|
+
while (ts.isParenthesizedExpression(e) ||
|
|
6836
|
+
ts.isAsExpression(e) ||
|
|
6837
|
+
ts.isSatisfiesExpression(e) ||
|
|
6838
|
+
ts.isTypeAssertion(e) ||
|
|
6839
|
+
ts.isNonNullExpression(e)) {
|
|
5885
6840
|
e = e.expression;
|
|
6841
|
+
}
|
|
5886
6842
|
if (ts.isIdentifier(e))
|
|
5887
6843
|
return e.text;
|
|
6844
|
+
if (e.kind === ts.SyntaxKind.ThisKeyword)
|
|
6845
|
+
return "this";
|
|
6846
|
+
// V8 prints an awaited or yielded operand as "(intermediate value)".
|
|
6847
|
+
if (ts.isAwaitExpression(e) || ts.isYieldExpression(e))
|
|
6848
|
+
return "(intermediate value)";
|
|
5888
6849
|
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken) {
|
|
5889
6850
|
const base = destrSpellingOf(e.expression);
|
|
5890
6851
|
return base === null ? null : `${base}.${e.name.text}`;
|
|
5891
6852
|
}
|
|
6853
|
+
// `table[key]` and `list[0]`; V8 prints a numeric key in its canonical
|
|
6854
|
+
// number form (`o[1.50]` reads "o[1.5]").
|
|
6855
|
+
if (ts.isElementAccessExpression(e) && !e.questionDotToken) {
|
|
6856
|
+
const base = destrSpellingOf(e.expression);
|
|
6857
|
+
const key = e.argumentExpression;
|
|
6858
|
+
if (base === null)
|
|
6859
|
+
return null;
|
|
6860
|
+
if (ts.isIdentifier(key))
|
|
6861
|
+
return `${base}[${key.text}]`;
|
|
6862
|
+
if (ts.isNumericLiteral(key))
|
|
6863
|
+
return `${base}[${String(Number(key.text))}]`;
|
|
6864
|
+
return null;
|
|
6865
|
+
}
|
|
5892
6866
|
if (ts.isCallExpression(e) && !e.questionDotToken) {
|
|
5893
6867
|
const callee = destrSpellingOf(e.expression);
|
|
5894
6868
|
return callee === null ? null : `${callee}(...)`;
|
|
@@ -5953,9 +6927,9 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5953
6927
|
// globals and strings alike).
|
|
5954
6928
|
{
|
|
5955
6929
|
const patternEmpty = ts.isObjectLiteralExpression(target)
|
|
5956
|
-
? target.properties.length === 0
|
|
5957
|
-
: target.elements.length === 0;
|
|
5958
|
-
if (!patternEmpty && rhs !== null && isJsSourceFile(
|
|
6930
|
+
? target.properties.nodes.length === 0
|
|
6931
|
+
: target.elements.nodes.length === 0;
|
|
6932
|
+
if (!patternEmpty && rhs !== null && isJsSourceFile(ts.getSourceFileOfNode(rhs))) {
|
|
5959
6933
|
const globalName = stdlibGlobalNameOf(lowerer, rhs);
|
|
5960
6934
|
if (globalName !== null) {
|
|
5961
6935
|
lowerer.unsupported("SC1031", blame, `destructuring assignment from the builtin global '${globalName}' (bind the members with a const destructuring declaration instead)`);
|
|
@@ -5996,7 +6970,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5996
6970
|
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
6971
|
}
|
|
5998
6972
|
let firstProp;
|
|
5999
|
-
const p0 = target.properties[0];
|
|
6973
|
+
const p0 = target.properties.nodes[0];
|
|
6000
6974
|
if (p0 !== undefined) {
|
|
6001
6975
|
if (ts.isShorthandPropertyAssignment(p0))
|
|
6002
6976
|
firstProp = p0.name.text;
|
|
@@ -6020,7 +6994,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6020
6994
|
loc,
|
|
6021
6995
|
});
|
|
6022
6996
|
}
|
|
6023
|
-
for (const prop of target.properties) {
|
|
6997
|
+
for (const prop of target.properties.nodes) {
|
|
6024
6998
|
const piece = destructAssignPiece(lowerer, prop);
|
|
6025
6999
|
const read = {
|
|
6026
7000
|
kind: "dynKeyGet",
|
|
@@ -6038,7 +7012,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6038
7012
|
}
|
|
6039
7013
|
return { stmts: out, value };
|
|
6040
7014
|
}
|
|
6041
|
-
if (target.properties.length === 0) {
|
|
7015
|
+
if (target.properties.nodes.length === 0) {
|
|
6042
7016
|
// `({} = e)`: RequireObjectCoercible and nothing else. A source the
|
|
6043
7017
|
// type system already proves non-nullish is a pure no-op past the
|
|
6044
7018
|
// RHS's own evaluation; possibly-nullish unions would throw in JS
|
|
@@ -6063,14 +7037,14 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6063
7037
|
lowerer.flushDeferredClass(objT.className);
|
|
6064
7038
|
const info = lowerer.classes.get(objT.className);
|
|
6065
7039
|
if (info) {
|
|
6066
|
-
for (const prop of target.properties) {
|
|
7040
|
+
for (const prop of target.properties.nodes) {
|
|
6067
7041
|
const propLoc = locOf(prop);
|
|
6068
7042
|
if (ts.isSpreadAssignment(prop)) {
|
|
6069
7043
|
let restTo = prop.expression;
|
|
6070
7044
|
while (ts.isParenthesizedExpression(restTo))
|
|
6071
7045
|
restTo = restTo.expression;
|
|
6072
7046
|
const consumed = new Set();
|
|
6073
|
-
for (const p of target.properties) {
|
|
7047
|
+
for (const p of target.properties.nodes) {
|
|
6074
7048
|
if (ts.isShorthandPropertyAssignment(p))
|
|
6075
7049
|
consumed.add(p.name.text);
|
|
6076
7050
|
else if (ts.isPropertyAssignment(p)) {
|
|
@@ -6184,7 +7158,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6184
7158
|
// properties keep the declaration path's named fences. Callers vetted
|
|
6185
7159
|
// the source as a checker-typed string.
|
|
6186
7160
|
if (init.type.kind === "string") {
|
|
6187
|
-
for (const prop of target.properties) {
|
|
7161
|
+
for (const prop of target.properties.nodes) {
|
|
6188
7162
|
const propLoc = locOf(prop);
|
|
6189
7163
|
if (ts.isSpreadAssignment(prop)) {
|
|
6190
7164
|
lowerer.unsupported("SC1031", prop, "rest bindings over string sources (JS packs the wrapper's per-code-unit indices — split with [...s] instead)");
|
|
@@ -6246,7 +7220,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6246
7220
|
const shape = lowerer.shapes.get(srcType.shapeId);
|
|
6247
7221
|
if (!shape)
|
|
6248
7222
|
throw new InternalCompilerError(`lowerer bug: destructuring unknown shape ${srcType.shapeId}`);
|
|
6249
|
-
for (const prop of target.properties) {
|
|
7223
|
+
for (const prop of target.properties.nodes) {
|
|
6250
7224
|
// Shorthand `{ a }` assigns local a from field a; `{ a: x }` assigns
|
|
6251
7225
|
// x from field a (a PropertyAssignment whose initializer is the
|
|
6252
7226
|
// target — JS reuses the literal syntax with inverted roles).
|
|
@@ -6263,7 +7237,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6263
7237
|
lowerer.unsupported("SC1031", prop, "rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
|
|
6264
7238
|
}
|
|
6265
7239
|
const consumed = new Set();
|
|
6266
|
-
for (const p of target.properties) {
|
|
7240
|
+
for (const p of target.properties.nodes) {
|
|
6267
7241
|
if (ts.isShorthandPropertyAssignment(p))
|
|
6268
7242
|
consumed.add(p.name.text);
|
|
6269
7243
|
else if (ts.isPropertyAssignment(p)) {
|
|
@@ -6278,7 +7252,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6278
7252
|
if (restOrder !== undefined) {
|
|
6279
7253
|
lowerer.shapeOrderMetadataFinalizers.push(lowerer.shapes.declaredOrderFinalizer(restShapeId, restOrder, () => lowerer.shapes.get(srcType.shapeId)?.declaredOrder?.filter((n) => !consumed.has(n))));
|
|
6280
7254
|
}
|
|
6281
|
-
const packed = {
|
|
7255
|
+
const packed = lowerer.keyOrder.copy({
|
|
6282
7256
|
kind: "recordLit",
|
|
6283
7257
|
fields: remaining.map((f) => ({
|
|
6284
7258
|
name: f.name,
|
|
@@ -6293,7 +7267,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6293
7267
|
})),
|
|
6294
7268
|
type: { kind: "record", shapeId: restShapeId },
|
|
6295
7269
|
loc: locOf(prop),
|
|
6296
|
-
};
|
|
7270
|
+
}, srcType.shapeId);
|
|
6297
7271
|
if (!ts.isIdentifier(restTo)) {
|
|
6298
7272
|
// `({ a, ...box.rest } = src)` — the rest packs identically and
|
|
6299
7273
|
// lands through the property/element write machinery.
|
|
@@ -6538,7 +7512,7 @@ function lowerArrayAssignInto(lowerer, out, target, tmpRef, blame, loc) {
|
|
|
6538
7512
|
// array divergence). The EMPTY pattern skips the split — GetIterator
|
|
6539
7513
|
// + close, nothing observable — through the iterable early-return
|
|
6540
7514
|
// below. Callers vetted the source as a checker-typed string.
|
|
6541
|
-
if (srcType.kind === "string" && target.elements.length > 0) {
|
|
7515
|
+
if (srcType.kind === "string" && target.elements.nodes.length > 0) {
|
|
6542
7516
|
const charsT = arrayOf(STRING);
|
|
6543
7517
|
const chars = lowerer.declareHiddenLocal("%dchars", charsT);
|
|
6544
7518
|
out.push({
|
|
@@ -6556,11 +7530,11 @@ function lowerArrayAssignInto(lowerer, out, target, tmpRef, blame, loc) {
|
|
|
6556
7530
|
// consumes exactly the elements the inner pattern alone would, so the
|
|
6557
7531
|
// unwrap is exact. Identifier rest operands pack in the element loop
|
|
6558
7532
|
// below.
|
|
6559
|
-
let elements = target.elements;
|
|
7533
|
+
let elements = target.elements.nodes;
|
|
6560
7534
|
if (elements.length === 1 &&
|
|
6561
7535
|
ts.isSpreadElement(elements[0]) &&
|
|
6562
7536
|
ts.isArrayLiteralExpression(elements[0].expression)) {
|
|
6563
|
-
elements = elements[0].expression.elements;
|
|
7537
|
+
elements = elements[0].expression.elements.nodes;
|
|
6564
7538
|
}
|
|
6565
7539
|
// The element-read builder per source kind; null when the source
|
|
6566
7540
|
// cannot destructure.
|
|
@@ -6787,13 +7761,24 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6787
7761
|
}
|
|
6788
7762
|
}
|
|
6789
7763
|
}
|
|
7764
|
+
{
|
|
7765
|
+
const opened = classAsyncGeneratorIterator(lowerer, stmt.expression);
|
|
7766
|
+
if (opened)
|
|
7767
|
+
return lowerForAwaitGenerator(lowerer, stmt, opened, labels);
|
|
7768
|
+
}
|
|
6790
7769
|
if (ts.isPropertyAccessExpression(stmt.expression) &&
|
|
6791
7770
|
lowerer.stdlibGlobalMember(stmt.expression, "process") === "stdin") {
|
|
6792
7771
|
return lowerForAwaitStdin(lowerer, stmt);
|
|
6793
7772
|
}
|
|
7773
|
+
// A checked-dynamic NodeJS.ReadableStream iterates its native stream.
|
|
7774
|
+
const dynStream = lowerForAwaitDynStream(lowerer, stmt, () => lowerForAwaitBuiltin(lowerer, stmt));
|
|
7775
|
+
if (dynStream)
|
|
7776
|
+
return dynStream;
|
|
6794
7777
|
const builtin = lowerForAwaitBuiltin(lowerer, stmt);
|
|
6795
7778
|
if (builtin)
|
|
6796
7779
|
return builtin;
|
|
7780
|
+
// A NodeJS.ReadableStream iterates as the general Readable.
|
|
7781
|
+
requestGeneralStreamSurface(lowerer, stmt.expression);
|
|
6797
7782
|
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
7783
|
}
|
|
6799
7784
|
if (awaitArray && !lowerer.ctx.isAsync) {
|
|
@@ -6816,6 +7801,13 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6816
7801
|
}
|
|
6817
7802
|
}
|
|
6818
7803
|
}
|
|
7804
|
+
// A head that is a chain of iterator-helper stages runs as one loop
|
|
7805
|
+
// over the chain's source.
|
|
7806
|
+
{
|
|
7807
|
+
const fused = lowerForOfHelperChain(lowerer, stmt, labels);
|
|
7808
|
+
if (fused)
|
|
7809
|
+
return fused;
|
|
7810
|
+
}
|
|
6819
7811
|
// `for (const k of m.keys())` / `.values()` / `.entries()`: the
|
|
6820
7812
|
// iterator methods consumed DIRECTLY by a for-of head ride the
|
|
6821
7813
|
// container's live walk — exactly `for..of m` with the projection
|
|
@@ -6828,7 +7820,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6828
7820
|
while (ts.isParenthesizedExpression(src))
|
|
6829
7821
|
src = src.expression;
|
|
6830
7822
|
if (ts.isCallExpression(src) &&
|
|
6831
|
-
src.arguments.length === 0 &&
|
|
7823
|
+
src.arguments.nodes.length === 0 &&
|
|
6832
7824
|
!src.questionDotToken &&
|
|
6833
7825
|
ts.isPropertyAccessExpression(src.expression) &&
|
|
6834
7826
|
!src.expression.questionDotToken &&
|
|
@@ -6886,7 +7878,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6886
7878
|
src = src.expression;
|
|
6887
7879
|
const constIdentBinding = ts.isVariableDeclarationList(stmt.initializer) &&
|
|
6888
7880
|
(stmt.initializer.flags & ts.NodeFlags.Const) !== 0 &&
|
|
6889
|
-
ts.isIdentifier(stmt.initializer.declarations[0].name);
|
|
7881
|
+
ts.isIdentifier(stmt.initializer.declarations.nodes[0].name);
|
|
6890
7882
|
if (constIdentBinding) {
|
|
6891
7883
|
const call = directMatchAllCallOf(lowerer, src);
|
|
6892
7884
|
if (call)
|
|
@@ -6918,7 +7910,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6918
7910
|
e = e.expression;
|
|
6919
7911
|
if (ts.isCallExpression(e) &&
|
|
6920
7912
|
!e.questionDotToken &&
|
|
6921
|
-
e.arguments.length === 0 &&
|
|
7913
|
+
e.arguments.nodes.length === 0 &&
|
|
6922
7914
|
ts.isPropertyAccessExpression(e.expression) &&
|
|
6923
7915
|
!e.expression.questionDotToken &&
|
|
6924
7916
|
e.expression.name.text === "values" &&
|
|
@@ -6992,6 +7984,11 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6992
7984
|
return lowerForOfGenerator(lowerer, stmt, iterable, labels);
|
|
6993
7985
|
}
|
|
6994
7986
|
if (iterable.type.kind === "object") {
|
|
7987
|
+
// A [Symbol.iterator] generator method: the loop drives the
|
|
7988
|
+
// generator it returns.
|
|
7989
|
+
const generator = classGeneratorIterable(lowerer, iterable);
|
|
7990
|
+
if (generator)
|
|
7991
|
+
return lowerForOfGenerator(lowerer, stmt, generator, labels);
|
|
6995
7992
|
// Class iterables ([Symbol.iterator]() + next() — classIteratorOf)
|
|
6996
7993
|
// drive the same protocol with ordinary method calls.
|
|
6997
7994
|
const cit = lowerer.classIteratorOf(iterable.type);
|
|
@@ -7376,7 +8373,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
7376
8373
|
const list = stmt.initializer;
|
|
7377
8374
|
const resourceLoop = (list.flags & ts.NodeFlags.Using) !== 0;
|
|
7378
8375
|
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
|
|
8376
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
7380
8377
|
// `for (const [k, v] of pairs)` — a destructuring loop variable: the
|
|
7381
8378
|
// element binds to a hidden per-iteration local and the pattern
|
|
7382
8379
|
// desugars to reads of it at the top of the body, exactly the
|
|
@@ -7406,7 +8403,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
7406
8403
|
// local and the body opens by ASSIGNING it into the one hoisted
|
|
7407
8404
|
// binding — closures capture the shared slot, and the value persists
|
|
7408
8405
|
// after the loop (both Node-exact for var).
|
|
7409
|
-
const varTarget = forOfVarTarget(lowerer, decl);
|
|
8406
|
+
const varTarget = forOfVarTarget(lowerer, decl, elemValueT);
|
|
7410
8407
|
if (varTarget) {
|
|
7411
8408
|
const elemType = elemValueT;
|
|
7412
8409
|
const loc = locOf(decl.name);
|
|
@@ -7523,7 +8520,7 @@ function lowerForOfStoredNumericIterator(lowerer, stmt, state, labels) {
|
|
|
7523
8520
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
7524
8521
|
}
|
|
7525
8522
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
7526
|
-
const decl = list ? list.declarations[0] : null;
|
|
8523
|
+
const decl = list ? list.declarations.nodes[0] : null;
|
|
7527
8524
|
if (decl && !ts.isIdentifier(decl.name))
|
|
7528
8525
|
lowerer.unsupported("SC1031", decl.name);
|
|
7529
8526
|
const loc = locOf(stmt);
|
|
@@ -7651,13 +8648,13 @@ function directMatchAllCallOf(lowerer, e) {
|
|
|
7651
8648
|
src = src.expression;
|
|
7652
8649
|
if (ts.isCallExpression(src) &&
|
|
7653
8650
|
!src.questionDotToken &&
|
|
7654
|
-
src.arguments.length === 1 &&
|
|
8651
|
+
src.arguments.nodes.length === 1 &&
|
|
7655
8652
|
ts.isPropertyAccessExpression(src.expression) &&
|
|
7656
8653
|
!src.expression.questionDotToken &&
|
|
7657
8654
|
src.expression.name.text === "matchAll" &&
|
|
7658
8655
|
lowerer.isStdlibMember(src.expression) &&
|
|
7659
8656
|
lowerer.mapTypeOf(lowerer.typeOf(src.expression.expression))?.kind === "string" &&
|
|
7660
|
-
lowerer.mapTypeOf(lowerer.typeOf(src.arguments[0]))?.kind === "regex") {
|
|
8657
|
+
lowerer.mapTypeOf(lowerer.typeOf(src.arguments.nodes[0]))?.kind === "regex") {
|
|
7661
8658
|
return src;
|
|
7662
8659
|
}
|
|
7663
8660
|
return null;
|
|
@@ -7682,7 +8679,7 @@ function directMatchAllCallOf(lowerer, e) {
|
|
|
7682
8679
|
*/
|
|
7683
8680
|
function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
7684
8681
|
const list = stmt.initializer;
|
|
7685
|
-
const decl = list.declarations[0];
|
|
8682
|
+
const decl = list.declarations.nodes[0];
|
|
7686
8683
|
const name = decl.name;
|
|
7687
8684
|
const loc = locOf(stmt);
|
|
7688
8685
|
const rowT = arrayOf(STRING);
|
|
@@ -7696,7 +8693,7 @@ function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
|
7696
8693
|
if (call !== null) {
|
|
7697
8694
|
const access = call.expression;
|
|
7698
8695
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
7699
|
-
const re = lowerer.lowerExpr(call.arguments[0]);
|
|
8696
|
+
const re = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
7700
8697
|
const idxs = lowerer.declareHiddenLocal("%midxs", idxsT);
|
|
7701
8698
|
idxsLocalId = idxs.id;
|
|
7702
8699
|
prelude.push({
|
|
@@ -7707,7 +8704,9 @@ function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
|
7707
8704
|
});
|
|
7708
8705
|
rowsInit = {
|
|
7709
8706
|
kind: "regexIntrinsic",
|
|
7710
|
-
method:
|
|
8707
|
+
method: matchAllRowsReadByElements(lowerer, call, true)
|
|
8708
|
+
? "matchAllCapturesInto"
|
|
8709
|
+
: "matchAllInto",
|
|
7711
8710
|
receiver,
|
|
7712
8711
|
args: [re, { kind: "varRef", localId: idxs.id, type: idxsT, loc }],
|
|
7713
8712
|
type: rowsT,
|
|
@@ -7846,7 +8845,7 @@ function lowerForOfClassIterator(lowerer, stmt, iterable, cit, labels) {
|
|
|
7846
8845
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
7847
8846
|
}
|
|
7848
8847
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
7849
|
-
const decl = list ? list.declarations[0] : null;
|
|
8848
|
+
const decl = list ? list.declarations.nodes[0] : null;
|
|
7850
8849
|
if (decl && !ts.isIdentifier(decl.name))
|
|
7851
8850
|
lowerer.unsupported("SC1031", decl.name);
|
|
7852
8851
|
const loc = locOf(stmt);
|
|
@@ -8063,14 +9062,14 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
8063
9062
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
8064
9063
|
}
|
|
8065
9064
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
8066
|
-
const decl = list.declarations[0];
|
|
9065
|
+
const decl = list.declarations.nodes[0];
|
|
8067
9066
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
8068
9067
|
const tmp = lowerer.declareHiddenLocal("%destr", DYN);
|
|
8069
9068
|
binds.push({ kind: "varDecl", localId: tmp.id, init: elemInit(), loc });
|
|
8070
9069
|
lowerer.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: DYN, loc }), DYN, isLet, binds);
|
|
8071
9070
|
}
|
|
8072
9071
|
else if (ts.isIdentifier(decl.name)) {
|
|
8073
|
-
const varTarget = forOfVarTarget(lowerer, decl);
|
|
9072
|
+
const varTarget = forOfVarTarget(lowerer, decl, DYN);
|
|
8074
9073
|
if (varTarget) {
|
|
8075
9074
|
// `for (var x of d)`: the element mechanics stay on a hidden
|
|
8076
9075
|
// per-iteration local; the body opens by assigning the ONE
|
|
@@ -8224,7 +9223,7 @@ function lowerForOfString(lowerer, stmt, iterable, labels) {
|
|
|
8224
9223
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
8225
9224
|
}
|
|
8226
9225
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
8227
|
-
const decl = list ? list.declarations[0] : null; // the grammar allows exactly one
|
|
9226
|
+
const decl = list ? list.declarations.nodes[0] : null; // the grammar allows exactly one
|
|
8228
9227
|
const loc = locOf(stmt);
|
|
8229
9228
|
lowerer.scopes.push(new Map());
|
|
8230
9229
|
try {
|
|
@@ -8383,7 +9382,7 @@ function lowerForIn(lowerer, stmt) {
|
|
|
8383
9382
|
while (root?.base)
|
|
8384
9383
|
root = root.base;
|
|
8385
9384
|
if (info?.decl &&
|
|
8386
|
-
isJsSourceFile(info.decl
|
|
9385
|
+
isJsSourceFile(ts.getSourceFileOfNode(info.decl)) &&
|
|
8387
9386
|
!info.def.runtime &&
|
|
8388
9387
|
!root?.def.runtime &&
|
|
8389
9388
|
!info.builtinError &&
|
|
@@ -8536,7 +9535,7 @@ function lowerForInOverKeys(lowerer, stmt, keys, labels, guard) {
|
|
|
8536
9535
|
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
9536
|
}
|
|
8538
9537
|
const list = stmt.initializer;
|
|
8539
|
-
const decl = list.declarations[0]; // the grammar allows exactly one
|
|
9538
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
8540
9539
|
if (!ts.isIdentifier(decl.name))
|
|
8541
9540
|
lowerer.unsupported("SC1031", decl.name);
|
|
8542
9541
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
@@ -8633,7 +9632,7 @@ function lowerForInArray(lowerer, stmt, labels, arrExpr) {
|
|
|
8633
9632
|
];
|
|
8634
9633
|
}
|
|
8635
9634
|
else {
|
|
8636
|
-
const decl = stmt.initializer.declarations[0];
|
|
9635
|
+
const decl = stmt.initializer.declarations.nodes[0];
|
|
8637
9636
|
if (!ts.isIdentifier(decl.name))
|
|
8638
9637
|
lowerer.unsupported("SC1031", decl.name);
|
|
8639
9638
|
const isLet = (stmt.initializer.flags & ts.NodeFlags.Let) !== 0 ||
|
|
@@ -8736,7 +9735,7 @@ function lowerForAwaitStdin(lowerer, stmt) {
|
|
|
8736
9735
|
// threading it through a shared hoisted slot has no user yet.
|
|
8737
9736
|
if (!isConst && !isLet)
|
|
8738
9737
|
lowerer.unsupported("SC1030", list, "'var' loop bindings in 'for await' (use const)");
|
|
8739
|
-
const decl = list.declarations[0]; // the grammar allows exactly one
|
|
9738
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
8740
9739
|
if (!ts.isIdentifier(decl.name))
|
|
8741
9740
|
lowerer.unsupported("SC1031", decl.name);
|
|
8742
9741
|
const loc = locOf(stmt);
|
|
@@ -8822,4 +9821,155 @@ export function lowerForStatement(lowerer, stmt) {
|
|
|
8822
9821
|
lowerer.scopes.pop();
|
|
8823
9822
|
}
|
|
8824
9823
|
}
|
|
9824
|
+
/** safe-buffer's `var Buffer = buffer.Buffer` at file scope: a `var` alias
|
|
9825
|
+
* of the global Buffer is the same alias plumbing as the const spelling
|
|
9826
|
+
* when nothing reassigns it and no code that runs before the declaration
|
|
9827
|
+
* can read it (the require-binding early-reference analysis), so the
|
|
9828
|
+
* hoisted undefined is unobservable. */
|
|
9829
|
+
export function stdlibBufferVarAlias(lowerer, decl) {
|
|
9830
|
+
if (!ts.isIdentifier(decl.name) ||
|
|
9831
|
+
!ts.isVariableDeclarationList(decl.parent) ||
|
|
9832
|
+
(decl.parent.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0 ||
|
|
9833
|
+
decl.initializer === undefined ||
|
|
9834
|
+
!bufferNamespaceMember(lowerer, decl.initializer))
|
|
9835
|
+
return false;
|
|
9836
|
+
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
9837
|
+
return (symbol !== undefined &&
|
|
9838
|
+
bindingNeverReassigned(lowerer, symbol, decl) &&
|
|
9839
|
+
requireEarlyReference(lowerer.program, decl) === null);
|
|
9840
|
+
}
|
|
9841
|
+
/** A checker type that is a string or string literal (or a union of them). */
|
|
9842
|
+
function isStringTyped(t) {
|
|
9843
|
+
if (t.isUnionType())
|
|
9844
|
+
return ts.constituentTypes(t).every(isStringTyped);
|
|
9845
|
+
return (t.flags & (ts.TypeFlags.String | ts.TypeFlags.StringLiteral)) !== 0;
|
|
9846
|
+
}
|
|
9847
|
+
/** The Error-subclass prototype reset of transpiled code, inside a class
|
|
9848
|
+
* constructor:
|
|
9849
|
+
*
|
|
9850
|
+
* const proto = new.target.prototype;
|
|
9851
|
+
* if (Object.setPrototypeOf) Object.setPrototypeOf(this, proto);
|
|
9852
|
+
* else this.__proto__ = proto;
|
|
9853
|
+
*
|
|
9854
|
+
* (also `Object.setPrototypeOf(this, new.target.prototype)` and
|
|
9855
|
+
* `Object.setPrototypeOf(this, C.prototype)` in C's own constructor when no
|
|
9856
|
+
* class extends C). A compiled instance already has exactly that prototype,
|
|
9857
|
+
* so each statement is a no-op. True for those statements. */
|
|
9858
|
+
function ownPrototypeResetStatement(lowerer, stmt) {
|
|
9859
|
+
if (ts.isVariableStatement(stmt)) {
|
|
9860
|
+
const decls = stmt.declarationList.declarations.nodes;
|
|
9861
|
+
if (decls.length !== 1 || (stmt.declarationList.flags & ts.NodeFlags.Const) === 0)
|
|
9862
|
+
return false;
|
|
9863
|
+
const decl = decls[0];
|
|
9864
|
+
if (!ts.isIdentifier(decl.name) || !decl.initializer)
|
|
9865
|
+
return false;
|
|
9866
|
+
const ctor = enclosingConstructor(decl);
|
|
9867
|
+
if (!ctor || !ownPrototypeRef(lowerer, decl.initializer, ctor))
|
|
9868
|
+
return false;
|
|
9869
|
+
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
9870
|
+
if (!symbol)
|
|
9871
|
+
return false;
|
|
9872
|
+
// Every other use of the binding must be one of the reset statements.
|
|
9873
|
+
let onlyResets = true;
|
|
9874
|
+
ts.walkPreorder(ctor, (n) => {
|
|
9875
|
+
if (!onlyResets)
|
|
9876
|
+
return "stop";
|
|
9877
|
+
if (!ts.isIdentifier(n) || n === decl.name)
|
|
9878
|
+
return undefined;
|
|
9879
|
+
if (lowerer.checker.getSymbolAtLocation(n) !== symbol)
|
|
9880
|
+
return undefined;
|
|
9881
|
+
const statement = n.parent?.parent;
|
|
9882
|
+
if (!statement ||
|
|
9883
|
+
!ts.isExpressionStatement(statement) ||
|
|
9884
|
+
resetTarget(lowerer, statement.expression) !== n)
|
|
9885
|
+
onlyResets = false;
|
|
9886
|
+
return undefined;
|
|
9887
|
+
});
|
|
9888
|
+
return onlyResets;
|
|
9889
|
+
}
|
|
9890
|
+
if (!ts.isExpressionStatement(stmt))
|
|
9891
|
+
return false;
|
|
9892
|
+
const ctor = enclosingConstructor(stmt);
|
|
9893
|
+
if (!ctor)
|
|
9894
|
+
return false;
|
|
9895
|
+
const target = resetTarget(lowerer, stmt.expression);
|
|
9896
|
+
return target !== null && ownPrototypeRef(lowerer, target, ctor);
|
|
9897
|
+
}
|
|
9898
|
+
/** The prototype operand of `Object.setPrototypeOf(this, P)` or
|
|
9899
|
+
* `this.__proto__ = P`, or null. */
|
|
9900
|
+
function resetTarget(lowerer, expr) {
|
|
9901
|
+
if (ts.isCallExpression(expr) &&
|
|
9902
|
+
expr.arguments.nodes.length === 2 &&
|
|
9903
|
+
expr.arguments.nodes[0].kind === ts.SyntaxKind.ThisKeyword &&
|
|
9904
|
+
ts.isPropertyAccessExpression(expr.expression) &&
|
|
9905
|
+
expr.expression.name.text === "setPrototypeOf" &&
|
|
9906
|
+
lowerer.isStdlibGlobal(expr.expression.expression, "Object"))
|
|
9907
|
+
return expr.arguments.nodes[1];
|
|
9908
|
+
if (ts.isBinaryExpression(expr) &&
|
|
9909
|
+
expr.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
9910
|
+
ts.isPropertyAccessExpression(expr.left) &&
|
|
9911
|
+
expr.left.expression.kind === ts.SyntaxKind.ThisKeyword &&
|
|
9912
|
+
expr.left.name.text === "__proto__")
|
|
9913
|
+
return expr.right;
|
|
9914
|
+
return null;
|
|
9915
|
+
}
|
|
9916
|
+
/** The class constructor whose body holds `node`, crossing only statements
|
|
9917
|
+
* and blocks (any nested function rebinds `this`). */
|
|
9918
|
+
function enclosingConstructor(node) {
|
|
9919
|
+
for (let cur = node.parent; cur !== undefined; cur = cur.parent) {
|
|
9920
|
+
if (ts.isConstructorDeclaration(cur))
|
|
9921
|
+
return cur;
|
|
9922
|
+
if (ts.isFunctionLike(cur) ||
|
|
9923
|
+
ts.isClassDeclaration(cur) ||
|
|
9924
|
+
ts.isClassExpression(cur) ||
|
|
9925
|
+
ts.isSourceFile(cur))
|
|
9926
|
+
return null;
|
|
9927
|
+
}
|
|
9928
|
+
return null;
|
|
9929
|
+
}
|
|
9930
|
+
/** Whether `node` denotes the prototype of the object `ctor` constructs:
|
|
9931
|
+
* `new.target.prototype`, a const holding it, or the class's own
|
|
9932
|
+
* `C.prototype` when no class extends C. */
|
|
9933
|
+
function ownPrototypeRef(lowerer, node, ctor) {
|
|
9934
|
+
while (ts.isParenthesizedExpression(node))
|
|
9935
|
+
node = node.expression;
|
|
9936
|
+
if (ts.isPropertyAccessExpression(node) && node.name.text === "prototype") {
|
|
9937
|
+
const base = node.expression;
|
|
9938
|
+
if (ts.isMetaProperty(base) &&
|
|
9939
|
+
base.keywordToken === ts.SyntaxKind.NewKeyword &&
|
|
9940
|
+
base.name.text === "target")
|
|
9941
|
+
return true;
|
|
9942
|
+
const cls = ctor.parent;
|
|
9943
|
+
if (!ts.isIdentifier(base) || !(ts.isClassDeclaration(cls) || ts.isClassExpression(cls)))
|
|
9944
|
+
return false;
|
|
9945
|
+
const symbol = lowerer.resolveValueSymbol(base);
|
|
9946
|
+
const info = symbol ? lowerer.classBySymbol.get(symbol) : undefined;
|
|
9947
|
+
if (!info || symbol.valueDeclaration !== cls)
|
|
9948
|
+
return false;
|
|
9949
|
+
for (const other of lowerer.classes.values()) {
|
|
9950
|
+
if (other !== info && lowerer.isSubclassOf(other.def.name, info.def.name))
|
|
9951
|
+
return false;
|
|
9952
|
+
}
|
|
9953
|
+
return true;
|
|
9954
|
+
}
|
|
9955
|
+
if (ts.isIdentifier(node)) {
|
|
9956
|
+
const symbol = lowerer.resolveValueSymbol(node);
|
|
9957
|
+
const decl = symbol?.valueDeclaration;
|
|
9958
|
+
return (decl !== undefined &&
|
|
9959
|
+
ts.isVariableDeclaration(decl) &&
|
|
9960
|
+
decl.initializer !== undefined &&
|
|
9961
|
+
ts.isVariableDeclarationList(decl.parent) &&
|
|
9962
|
+
(decl.parent.flags & ts.NodeFlags.Const) !== 0 &&
|
|
9963
|
+
enclosingConstructor(decl) === ctor &&
|
|
9964
|
+
!ts.isIdentifier(decl.initializer) &&
|
|
9965
|
+
ownPrototypeRef(lowerer, decl.initializer, ctor));
|
|
9966
|
+
}
|
|
9967
|
+
return false;
|
|
9968
|
+
}
|
|
9969
|
+
function isAssertionInitializer(node) {
|
|
9970
|
+
let e = node;
|
|
9971
|
+
while (ts.isParenthesizedExpression(e))
|
|
9972
|
+
e = e.expression;
|
|
9973
|
+
return ts.isAsExpression(e) || ts.isTypeAssertion(e);
|
|
9974
|
+
}
|
|
8825
9975
|
//# sourceMappingURL=lower-stmts.js.map
|