@scriptc/compiler 0.3.5 → 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 +960 -82
- 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 +324 -179
- 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 +576 -268
- package/dist/backend/llvm/emitter.js +801 -4447
- 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-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +92 -63
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +132 -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 +217 -24
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +102 -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 +77 -25
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +100 -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 +229 -5
- 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 +57 -8
- 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 +70 -9
- package/dist/backend/llvm/nullable-unions.js +105 -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 +13 -2
- package/dist/backend/llvm/record-results.js +66 -6
- 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 +143 -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 +69 -43
- package/dist/backend/llvm/shapes.js +285 -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/speculative-integers.d.ts +74 -0
- package/dist/backend/llvm/speculative-integers.js +571 -0
- package/dist/backend/llvm/speculative-integers.js.map +1 -0
- package/dist/backend/llvm/speculative-integers.test.d.ts +1 -0
- package/dist/backend/llvm/speculative-integers.test.js +148 -0
- package/dist/backend/llvm/speculative-integers.test.js.map +1 -0
- 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 +6 -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 -134
- 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 +2 -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.d.ts +7 -3
- package/dist/backend/runtime-pack.js +12 -6
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +20 -6
- 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 +25 -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 +19 -6
- 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 +11 -7
- package/dist/diagnostics/diagnostic.js +35 -23
- 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 +72 -4
- 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 +45 -6
- 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 +18 -0
- package/dist/frontend/lowering/builtins/compression.js +230 -52
- 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 +223 -38
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/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 +174 -6
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +4 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +136 -113
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.d.ts +8 -0
- package/dist/frontend/lowering/builtins/filesystem.js +213 -76
- 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/hash-stream.d.ts +12 -0
- package/dist/frontend/lowering/builtins/hash-stream.js +80 -0
- package/dist/frontend/lowering/builtins/hash-stream.js.map +1 -0
- 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 +67 -46
- 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 +468 -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 +55 -13
- package/dist/frontend/lowering/builtins/readline.js +931 -69
- 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 +16 -0
- package/dist/frontend/lowering/builtins/workers.js +246 -3
- 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.d.ts +55 -0
- package/dist/frontend/lowering/class-protocols.js +738 -22
- 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 +19 -0
- package/dist/frontend/lowering/containers/array-from-async.js +427 -0
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -0
- 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 +219 -27
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +81 -48
- 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 +238 -128
- 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 +1298 -452
- 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 +1499 -456
- 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 +268 -71
- 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 +1493 -12407
- 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 +354 -99
- 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 +19 -2
- package/dist/frontend/lowering/lower-mock.js +557 -74
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +268 -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 +638 -105
- 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 +1589 -398
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +4 -3
- package/dist/frontend/lowering/lower-stream.js +714 -75
- 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 +574 -100
- 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 +409 -26
- package/dist/frontend/lowering/lowerer.js +1918 -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/null-prototype.d.ts +13 -0
- package/dist/frontend/lowering/null-prototype.js +33 -0
- package/dist/frontend/lowering/null-prototype.js.map +1 -0
- 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 +15 -6
- package/dist/frontend/lowering/surfaces.js +278 -45
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/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.d.ts +5 -0
- package/dist/frontend/mock-shapes.js +39 -7
- 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 -254
- 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 +2612 -695
- 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 +47 -10
- 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 +139 -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 +655 -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 +10 -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 +119 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +29 -1
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loop-facts.d.ts +16 -6
- package/dist/ir/integer-loop-facts.js +143 -38
- 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 +4 -6
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +142 -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 +234 -58
- package/dist/ir/ir.js +123 -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 +150 -33
- package/dist/ir/runtime-features.js +672 -339
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +62 -0
- package/dist/ir/runtime-features.test.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 +107 -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 +220 -71
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +64 -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 +18 -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 +332 -36
|
@@ -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
|
}
|
|
@@ -246,10 +266,46 @@ function cleanupCall(lowerer, node, value, awaited) {
|
|
|
246
266
|
}
|
|
247
267
|
return null;
|
|
248
268
|
}
|
|
249
|
-
|
|
269
|
+
/** The statements that dispose `value` at scope exit. `setup` receives
|
|
270
|
+
* the statements that run at the declaration, after the value is bound. */
|
|
271
|
+
function cleanupForValue(lowerer, node, value, awaited, setup) {
|
|
250
272
|
const loc = locOf(node);
|
|
251
273
|
if (isUnitType(value.type))
|
|
252
274
|
return [];
|
|
275
|
+
if (value.type.kind === "dyn") {
|
|
276
|
+
// A dyn value (an object literal, a Disposable-typed result): the
|
|
277
|
+
// declaration reads and checks its dispose method, and scope exit
|
|
278
|
+
// calls it with the value as `this`.
|
|
279
|
+
const method = lowerer.declareHiddenLocal("%dispose", DYN);
|
|
280
|
+
setup.push({
|
|
281
|
+
kind: "varDecl",
|
|
282
|
+
localId: method.id,
|
|
283
|
+
init: {
|
|
284
|
+
kind: "libCall",
|
|
285
|
+
fn: "dyn.usingMethod",
|
|
286
|
+
args: [value, { kind: "boolLit", value: awaited, type: BOOL, loc }],
|
|
287
|
+
type: DYN,
|
|
288
|
+
loc,
|
|
289
|
+
},
|
|
290
|
+
loc,
|
|
291
|
+
});
|
|
292
|
+
const call = {
|
|
293
|
+
kind: "libCall",
|
|
294
|
+
fn: "dyn.usingDispose",
|
|
295
|
+
args: [{ kind: "varRef", localId: method.id, type: DYN, loc }, value],
|
|
296
|
+
type: DYN,
|
|
297
|
+
loc,
|
|
298
|
+
};
|
|
299
|
+
return [
|
|
300
|
+
{
|
|
301
|
+
kind: "exprStmt",
|
|
302
|
+
expr: awaited
|
|
303
|
+
? { kind: "libCall", fn: "async.awaitDyn", args: [call], type: DYN, loc }
|
|
304
|
+
: call,
|
|
305
|
+
loc,
|
|
306
|
+
},
|
|
307
|
+
];
|
|
308
|
+
}
|
|
253
309
|
if (value.type.kind === "union") {
|
|
254
310
|
const def = lowerer.unions.get(value.type.unionId);
|
|
255
311
|
if (!def)
|
|
@@ -267,7 +323,9 @@ function cleanupForValue(lowerer, node, value, awaited) {
|
|
|
267
323
|
type: arm,
|
|
268
324
|
loc,
|
|
269
325
|
};
|
|
270
|
-
|
|
326
|
+
if (arm.kind === "dyn")
|
|
327
|
+
lowerer.unsupported("SC1090", node, "disposing a union with an 'unknown' arm");
|
|
328
|
+
const body = cleanupForValue(lowerer, node, narrowed, awaited, setup);
|
|
271
329
|
out.push({
|
|
272
330
|
kind: "if",
|
|
273
331
|
cond: {
|
|
@@ -318,7 +376,7 @@ function lowerUsingStatement(lowerer, stmt) {
|
|
|
318
376
|
lowerer.unsupported("SC1090", stmt, "'await using' outside an async function or top-level-await module");
|
|
319
377
|
}
|
|
320
378
|
const registrations = [];
|
|
321
|
-
for (const decl of stmt.declarationList.declarations) {
|
|
379
|
+
for (const decl of stmt.declarationList.declarations.nodes) {
|
|
322
380
|
if (!ts.isIdentifier(decl.name))
|
|
323
381
|
lowerer.unsupported("SC1031", decl.name);
|
|
324
382
|
if (decl.initializer === undefined)
|
|
@@ -333,8 +391,9 @@ function lowerUsingStatement(lowerer, stmt) {
|
|
|
333
391
|
if (!binding)
|
|
334
392
|
throw new InternalCompilerError("lowerer bug: using declaration has no runtime binding");
|
|
335
393
|
const value = varRef(binding.id, binding.type, locOf(decl.name));
|
|
336
|
-
const
|
|
337
|
-
|
|
394
|
+
const setup = [];
|
|
395
|
+
const cleanup = cleanupForValue(lowerer, decl.name, value, awaited, setup);
|
|
396
|
+
registrations.push({ acquire: [acquire, ...setup], cleanup, loc: locOf(decl) });
|
|
338
397
|
}
|
|
339
398
|
return registrations;
|
|
340
399
|
}
|
|
@@ -347,14 +406,14 @@ function pureAnnotatedDeadConst(stmt, sf) {
|
|
|
347
406
|
return false;
|
|
348
407
|
if ((stmt.declarationList.flags & ts.NodeFlags.Const) === 0)
|
|
349
408
|
return false;
|
|
350
|
-
const decls = stmt.declarationList.declarations;
|
|
409
|
+
const decls = stmt.declarationList.declarations.nodes;
|
|
351
410
|
if (decls.length === 0)
|
|
352
411
|
return false;
|
|
353
412
|
return decls.every((d) => {
|
|
354
413
|
let init = d.initializer;
|
|
355
414
|
if (init === undefined)
|
|
356
415
|
return false;
|
|
357
|
-
const trivia = sf.text.slice(init.pos,
|
|
416
|
+
const trivia = sf.text.slice(init.pos, ts.tokenStartOfNode(init));
|
|
358
417
|
if (!trivia.includes("@__PURE__") && !trivia.includes("#__PURE__"))
|
|
359
418
|
return false;
|
|
360
419
|
// `as` casts are type-world wrappers (`(() => {...})() as unknown as
|
|
@@ -382,7 +441,7 @@ function pureAnnotatedDeadConst(stmt, sf) {
|
|
|
382
441
|
* probes that would otherwise claim (and diagnose) the call-initializer
|
|
383
442
|
* shape. */
|
|
384
443
|
export function provenanceElidedConstDecl(lowerer, decl) {
|
|
385
|
-
const sf =
|
|
444
|
+
const sf = ts.getSourceFileOfNode(decl);
|
|
386
445
|
if (!isProvenanceSourceFile(sf.fileName))
|
|
387
446
|
return false;
|
|
388
447
|
const stmt = decl.parent?.parent;
|
|
@@ -429,7 +488,7 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
429
488
|
// runtimeFence — a catchable, SC-coded throw at the statement's
|
|
430
489
|
// position — instead of failing the whole build). TypeScript keeps
|
|
431
490
|
// compile fences. ICEs (SC9001) always stay compile errors.
|
|
432
|
-
const sf = stmts[0]
|
|
491
|
+
const sf = stmts.length === 0 ? undefined : ts.getSourceFileOfNode(stmts[0]);
|
|
433
492
|
const deferFences = sf !== undefined && isJsSourceFile(sf);
|
|
434
493
|
// Register this list as open for the forward-capture machinery: a
|
|
435
494
|
// nested function lowering mid-list may pre-declare a LATER const of
|
|
@@ -443,16 +502,20 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
443
502
|
out,
|
|
444
503
|
};
|
|
445
504
|
lowerer.activeStmtLists.push(entry);
|
|
505
|
+
const inFunction = stmts.length > 0 && enclosedByFunction(stmts[0]);
|
|
506
|
+
let unreachable = false;
|
|
446
507
|
try {
|
|
447
508
|
for (let i = 0; i < stmts.length; i++) {
|
|
448
509
|
const stmt = stmts[i];
|
|
449
510
|
entry.index = i;
|
|
450
|
-
if (
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
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);
|
|
455
517
|
const diagsBefore = lowerer.diags.length;
|
|
518
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
456
519
|
try {
|
|
457
520
|
let lowered;
|
|
458
521
|
let appended = false;
|
|
@@ -461,8 +524,8 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
461
524
|
const registrations = lowerUsingStatement(lowerer, stmt);
|
|
462
525
|
const accounting = [];
|
|
463
526
|
for (const registration of registrations) {
|
|
464
|
-
out.push(registration.acquire);
|
|
465
|
-
accounting.push(registration.acquire, ...registration.cleanup);
|
|
527
|
+
out.push(...registration.acquire);
|
|
528
|
+
accounting.push(...registration.acquire, ...registration.cleanup);
|
|
466
529
|
if (registration.cleanup.length > 0) {
|
|
467
530
|
usingMarkers.push({
|
|
468
531
|
start: out.length,
|
|
@@ -519,11 +582,8 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
519
582
|
else if (!(e instanceof PoisonError)) {
|
|
520
583
|
throw e;
|
|
521
584
|
}
|
|
522
|
-
if (!lowerer.suppressStats)
|
|
523
|
-
lowerer.
|
|
524
|
-
if (sf !== undefined)
|
|
525
|
-
lowerer.bumpFileStat(sf.fileName, "failed");
|
|
526
|
-
}
|
|
585
|
+
if (!lowerer.suppressStats)
|
|
586
|
+
lowerer.countStatementFailed(stmt, sf?.fileName);
|
|
527
587
|
lowerer.noteBlockedBindings(stmt);
|
|
528
588
|
// The runtime-fence conversion (JS sources, direct diagnostics
|
|
529
589
|
// only — a capture wrapper in force means collection owns the
|
|
@@ -544,6 +604,13 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
544
604
|
if (fence)
|
|
545
605
|
out.push(fence);
|
|
546
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
|
+
}
|
|
547
614
|
}
|
|
548
615
|
}
|
|
549
616
|
// Each acquisition protects the remainder of its lexical statement
|
|
@@ -569,6 +636,48 @@ export function lowerStmts(lowerer, stmts) {
|
|
|
569
636
|
}
|
|
570
637
|
return out;
|
|
571
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
|
+
}
|
|
572
681
|
const TDZ_KINDS = new Set([
|
|
573
682
|
"func",
|
|
574
683
|
"string",
|
|
@@ -622,7 +731,7 @@ const TDZ_KINDS = new Set([
|
|
|
622
731
|
* is empty. Mutable bindings also guard writes; only the declaration's
|
|
623
732
|
* initializing assignment may leave the temporal dead zone. */
|
|
624
733
|
export function predeclareForwardCapture(lowerer, symbol) {
|
|
625
|
-
const decl =
|
|
734
|
+
const decl = symbol.valueDeclaration;
|
|
626
735
|
if (!decl ||
|
|
627
736
|
!ts.isVariableDeclaration(decl) ||
|
|
628
737
|
decl.name === undefined ||
|
|
@@ -633,6 +742,10 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
633
742
|
const flags = ts.getCombinedNodeFlags(decl);
|
|
634
743
|
if ((flags & ts.NodeFlags.BlockScoped) === 0 || (flags & ts.NodeFlags.Using) !== 0)
|
|
635
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;
|
|
636
749
|
// MODULE-scope bindings are pre-registered globals (collectGlobals):
|
|
637
750
|
// references resolve through globalOf after the local search fails, so
|
|
638
751
|
// a TDZ box here would SHADOW the global and never fill (the top-level
|
|
@@ -658,7 +771,7 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
658
771
|
if (idx < entry.index || entry.ctx === lowerer.ctx || entry.ctx.tdzPredeclared.has(symbol))
|
|
659
772
|
return false;
|
|
660
773
|
let type = lowerer.irTypeOf(decl.name);
|
|
661
|
-
if (isJsSourceFile(
|
|
774
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
662
775
|
!decl.type &&
|
|
663
776
|
!hasJsTypeAnnotation(decl) &&
|
|
664
777
|
(ts.isObjectLiteralExpression(decl.initializer) ||
|
|
@@ -700,8 +813,8 @@ export function predeclareForwardCapture(lowerer, symbol) {
|
|
|
700
813
|
* lower the declaration under the owning statement list's context, then
|
|
701
814
|
* resume the caller and thread its captures normally. */
|
|
702
815
|
export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
703
|
-
const decl =
|
|
704
|
-
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)
|
|
705
818
|
return false;
|
|
706
819
|
for (let i = lowerer.activeStmtLists.length - 1; i >= 0; i--) {
|
|
707
820
|
const entry = lowerer.activeStmtLists[i];
|
|
@@ -726,14 +839,26 @@ export function predeclareForwardFnDecl(lowerer, symbol) {
|
|
|
726
839
|
entry.ctx.hoistedFnDecls.add(decl);
|
|
727
840
|
const fnTail = lowerer.fnStack.splice(depth + 1);
|
|
728
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;
|
|
729
851
|
try {
|
|
730
852
|
entry.out.push(lowerer.lowerNestedFunctionDecl(decl));
|
|
731
853
|
}
|
|
732
854
|
catch (e) {
|
|
733
855
|
entry.ctx.hoistedFnDecls.delete(decl);
|
|
856
|
+
if (previousSink !== null)
|
|
857
|
+
previousSink.push(...lowerer.diags.splice(diagsBefore));
|
|
734
858
|
throw e;
|
|
735
859
|
}
|
|
736
860
|
finally {
|
|
861
|
+
lowerer.diagSink = previousSink;
|
|
737
862
|
entry.ctx.scopes.push(...scopeTail);
|
|
738
863
|
lowerer.fnStack.push(...fnTail);
|
|
739
864
|
}
|
|
@@ -765,16 +890,108 @@ function hostVariableDeclarationOf(name) {
|
|
|
765
890
|
* iteration), and it persists after the loop. Returns the write target
|
|
766
891
|
* (a module global for top-level loops, the hoisted function slot
|
|
767
892
|
* otherwise); null when the binding isn't a `var` identifier. */
|
|
768
|
-
export function forOfVarTarget(lowerer, decl) {
|
|
893
|
+
export function forOfVarTarget(lowerer, decl, valueType) {
|
|
769
894
|
if (!ts.isIdentifier(decl.name) || !isVarDeclared(decl))
|
|
770
895
|
return null;
|
|
771
896
|
const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
|
|
772
897
|
if (!symbol)
|
|
773
898
|
return null;
|
|
774
899
|
const g = lowerer.globalsBySymbol.get(symbol);
|
|
775
|
-
if (g)
|
|
900
|
+
if (g) {
|
|
901
|
+
if (valueType?.kind === "dyn" && jsBindingKeepsCheckedObject(lowerer, decl.name, g.type))
|
|
902
|
+
g.type = DYN;
|
|
776
903
|
return g;
|
|
777
|
-
|
|
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
|
+
};
|
|
778
995
|
}
|
|
779
996
|
/** The `var` symbol's function-scoped binding TYPE — the declared type at
|
|
780
997
|
* the binding name, with the JS-source fallbacks every mutable binding
|
|
@@ -786,12 +1003,12 @@ function varBindingType(lowerer, nameNode) {
|
|
|
786
1003
|
if (ts.isVariableDeclaration(nameNode.parent) &&
|
|
787
1004
|
isNativeProxyInitializer(lowerer, nameNode.parent.initializer))
|
|
788
1005
|
return DYN;
|
|
789
|
-
if (isJsSourceFile(
|
|
1006
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(nameNode)) &&
|
|
790
1007
|
ts.isVariableDeclaration(nameNode.parent) &&
|
|
791
1008
|
isNativeBuiltinValueInitializer(lowerer, nameNode.parent.initializer))
|
|
792
1009
|
return DYN;
|
|
793
1010
|
let type = lowerer.mapTypeOf(lowerer.typeOf(nameNode));
|
|
794
|
-
if (type?.kind === "record" && isJsSourceFile(
|
|
1011
|
+
if (type?.kind === "record" && isJsSourceFile(ts.getSourceFileOfNode(nameNode))) {
|
|
795
1012
|
const shape = lowerer.shapes.get(type.shapeId);
|
|
796
1013
|
if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
|
|
797
1014
|
type = DYN;
|
|
@@ -827,7 +1044,7 @@ function varBindingType(lowerer, nameNode) {
|
|
|
827
1044
|
* a loop re-ASSIGNS the one binding per pass and never resets it — the
|
|
828
1045
|
* classic capture semantics fall out: closures made in a loop share the
|
|
829
1046
|
* single boxed binding, where `let` gets a fresh box per iteration. */
|
|
830
|
-
function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
1047
|
+
function hoistVarBinding(lowerer, symbol, nameNode, valueType) {
|
|
831
1048
|
const existing = lowerer.ctx.hoistedVars.get(symbol);
|
|
832
1049
|
if (existing)
|
|
833
1050
|
return existing;
|
|
@@ -837,7 +1054,15 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
837
1054
|
lowerer.ctx.hoistedVars.set(symbol, bound);
|
|
838
1055
|
return bound;
|
|
839
1056
|
}
|
|
840
|
-
|
|
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;
|
|
841
1066
|
if (!type)
|
|
842
1067
|
lowerer.badType(nameNode, lowerer.typeOf(nameNode));
|
|
843
1068
|
const root = lowerer.activeStmtLists.find((e) => e.ctx === lowerer.ctx);
|
|
@@ -855,7 +1080,8 @@ function hoistVarBinding(lowerer, symbol, nameNode) {
|
|
|
855
1080
|
};
|
|
856
1081
|
lowerer.ctx.locals.push(local);
|
|
857
1082
|
lowerer.ctx.scopes[0].set(symbol, local);
|
|
858
|
-
|
|
1083
|
+
if (!keepsChecked)
|
|
1084
|
+
noteEarlyReadVar(lowerer, symbol, local);
|
|
859
1085
|
// A checked-dynamic slot holds the dyn undefined (a NULL dyn is a
|
|
860
1086
|
// trap); everything else rides unassignedSlotInit (interned union arm,
|
|
861
1087
|
const wrapped = type.kind === "dyn"
|
|
@@ -882,7 +1108,7 @@ export function predeclareForwardVar(lowerer, symbol) {
|
|
|
882
1108
|
// Module-scope vars already have their global storage.
|
|
883
1109
|
if (lowerer.globalsBySymbol.has(symbol))
|
|
884
1110
|
return false;
|
|
885
|
-
const decl =
|
|
1111
|
+
const decl = symbol.valueDeclaration;
|
|
886
1112
|
if (!decl || !ts.isVariableDeclaration(decl) || !isVarDeclared(decl))
|
|
887
1113
|
return false;
|
|
888
1114
|
const nameNode = ts.isIdentifier(decl.name) ? decl.name : null;
|
|
@@ -962,7 +1188,7 @@ export function noteBlockedBindings(lowerer, stmt) {
|
|
|
962
1188
|
}
|
|
963
1189
|
if (!list)
|
|
964
1190
|
return;
|
|
965
|
-
for (const decl of list.declarations) {
|
|
1191
|
+
for (const decl of list.declarations.nodes) {
|
|
966
1192
|
for (const nameNode of boundIdentifiersOf(decl.name)) {
|
|
967
1193
|
const symbol = lowerer.checker.getSymbolAtLocation(nameNode);
|
|
968
1194
|
if (symbol)
|
|
@@ -987,7 +1213,7 @@ export function isBlockedBinding(lowerer, symbol) {
|
|
|
987
1213
|
export function lowerScopedBlock(lowerer, stmt) {
|
|
988
1214
|
lowerer.scopes.push(new Map());
|
|
989
1215
|
try {
|
|
990
|
-
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]));
|
|
991
1217
|
}
|
|
992
1218
|
finally {
|
|
993
1219
|
lowerer.scopes.pop();
|
|
@@ -1045,7 +1271,20 @@ function lowerLabeled(lowerer, stmt) {
|
|
|
1045
1271
|
const body = lowerer.inCtl("block", () => lowerer.lowerScopedBlock(inner), labels);
|
|
1046
1272
|
return { kind: "block", body, labels, loc: locOf(stmt) };
|
|
1047
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
|
+
]);
|
|
1048
1285
|
export function lowerStmt(lowerer, stmt) {
|
|
1286
|
+
if (ownPrototypeResetStatement(lowerer, stmt))
|
|
1287
|
+
return { kind: "block", body: [], loc: locOf(stmt) };
|
|
1049
1288
|
if (ts.isClassDeclaration(stmt)) {
|
|
1050
1289
|
if (!stmt.name)
|
|
1051
1290
|
lowerer.unsupported("SC1090", stmt, "anonymous local class declarations");
|
|
@@ -1058,7 +1297,7 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1058
1297
|
if (ts.isVariableStatement(stmt)) {
|
|
1059
1298
|
// `declare const` — ambient: no storage, no init (collectGlobals
|
|
1060
1299
|
// skipped it; reads throw Node's ReferenceError at the access).
|
|
1061
|
-
const first = stmt.declarationList.declarations[0];
|
|
1300
|
+
const first = stmt.declarationList.declarations.nodes[0];
|
|
1062
1301
|
if (first && ts.getCombinedModifierFlags(first) & ts.ModifierFlags.Ambient)
|
|
1063
1302
|
return null;
|
|
1064
1303
|
return lowerer.lowerVarStatement(stmt);
|
|
@@ -1137,6 +1376,12 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1137
1376
|
// incompatible boundary keeps the ordinary per-statement refusal.
|
|
1138
1377
|
let value = null;
|
|
1139
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
|
+
}
|
|
1140
1385
|
return lowerer.lowerReturnStmt(stmt.expression, locOf(stmt));
|
|
1141
1386
|
}
|
|
1142
1387
|
else if (lowerer.ctx.returnType.kind === "union") {
|
|
@@ -1201,6 +1446,13 @@ export function lowerStmt(lowerer, stmt) {
|
|
|
1201
1446
|
else if (value.type.kind === "record" && lowerer.dynConvertible(value.type)) {
|
|
1202
1447
|
value = { kind: "dynFrom", value, liveRef: true, type: DYN, loc: locOf(stmt.expression) };
|
|
1203
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
|
+
}
|
|
1204
1456
|
if (value.type.kind === "date") {
|
|
1205
1457
|
lowerer.unsupported("SC1090", stmt.expression, "throwing Date values (catch bindings cannot preserve Date's object kind; throw an Error or primitive instead)");
|
|
1206
1458
|
}
|
|
@@ -1274,77 +1526,131 @@ export function lowerVarStatement(lowerer, stmt) {
|
|
|
1274
1526
|
}
|
|
1275
1527
|
const isConst = (list.flags & ts.NodeFlags.Const) !== 0;
|
|
1276
1528
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
1277
|
-
return list.declarations.flatMap((decl) => {
|
|
1278
|
-
|
|
1279
|
-
//
|
|
1280
|
-
//
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
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);
|
|
1288
1556
|
return init ? [init] : [];
|
|
1289
1557
|
}
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
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);
|
|
1309
1587
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
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;
|
|
1319
1638
|
}
|
|
1320
|
-
lowerer.unsupported("SC1090", decl, "require() with bindings outside the module's top level (move it to the top of the file)");
|
|
1321
1639
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
// numeric value iterators retain source/cursor/done hidden locals; a
|
|
1337
|
-
// matchAll drain retains its companion index array so a later
|
|
1338
|
-
// for-of can serve `m.index`. Both are const-only interceptions.
|
|
1339
|
-
const numericIterator = lowerNumericIteratorDecl(lowerer, decl, isConst);
|
|
1340
|
-
if (numericIterator)
|
|
1341
|
-
return numericIterator;
|
|
1342
|
-
const drained = lowerMatchAllDrainDecl(lowerer, decl, isConst);
|
|
1343
|
-
if (drained)
|
|
1344
|
-
return drained;
|
|
1345
|
-
const lowered = lowerer.lowerVarDecl(decl, isLet);
|
|
1346
|
-
return lowered ? [lowered] : [];
|
|
1347
|
-
});
|
|
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] : [];
|
|
1348
1654
|
}
|
|
1349
1655
|
/** The numeric indexed source of a built-in value-iterator expression:
|
|
1350
1656
|
* `numbers.values()` or the equivalent
|
|
@@ -1359,7 +1665,7 @@ export function numericIteratorSourceOf(lowerer, expr) {
|
|
|
1359
1665
|
let init = expr;
|
|
1360
1666
|
while (ts.isParenthesizedExpression(init))
|
|
1361
1667
|
init = init.expression;
|
|
1362
|
-
if (!ts.isCallExpression(init) || init.questionDotToken || init.arguments.length !== 0)
|
|
1668
|
+
if (!ts.isCallExpression(init) || init.questionDotToken || init.arguments.nodes.length !== 0)
|
|
1363
1669
|
return null;
|
|
1364
1670
|
let receiver = null;
|
|
1365
1671
|
if (ts.isPropertyAccessExpression(init.expression) &&
|
|
@@ -1455,7 +1761,7 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1455
1761
|
const loc = locOf(decl);
|
|
1456
1762
|
const access = call.expression;
|
|
1457
1763
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
1458
|
-
const re = lowerer.lowerExpr(call.arguments[0]);
|
|
1764
|
+
const re = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
1459
1765
|
const idxsT = arrayOf(F64);
|
|
1460
1766
|
const idxs = lowerer.declareHiddenLocal("%midxs", idxsT);
|
|
1461
1767
|
const local = lowerer.declareLocal(decl.name, decl.name.text, rowsT, false);
|
|
@@ -1472,7 +1778,9 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1472
1778
|
localId: local.id,
|
|
1473
1779
|
init: {
|
|
1474
1780
|
kind: "regexIntrinsic",
|
|
1475
|
-
method:
|
|
1781
|
+
method: storedMatchAllRowsReadByElements(lowerer, decl)
|
|
1782
|
+
? "matchAllCapturesInto"
|
|
1783
|
+
: "matchAllInto",
|
|
1476
1784
|
receiver,
|
|
1477
1785
|
args: [re, { kind: "varRef", localId: idxs.id, type: idxsT, loc }],
|
|
1478
1786
|
type: rowsT,
|
|
@@ -1488,7 +1796,7 @@ function lowerMatchAllDrainDecl(lowerer, decl, isConst) {
|
|
|
1488
1796
|
export function isParseArgsDynCheckerType(lowerer, type) {
|
|
1489
1797
|
const widened = lowerer.checker.getBaseTypeOfLiteralType(type);
|
|
1490
1798
|
const declarationBelongs = (d) => {
|
|
1491
|
-
if (!lowerer.isStdlibFile(
|
|
1799
|
+
if (!lowerer.isStdlibFile(ts.getSourceFileOfNode(d)))
|
|
1492
1800
|
return false;
|
|
1493
1801
|
let inParseArgsType = false;
|
|
1494
1802
|
for (let node = d.parent; node; node = node.parent) {
|
|
@@ -1504,8 +1812,8 @@ export function isParseArgsDynCheckerType(lowerer, type) {
|
|
|
1504
1812
|
};
|
|
1505
1813
|
const sym = widened.getAliasSymbol() ?? widened.getSymbol();
|
|
1506
1814
|
if (sym &&
|
|
1507
|
-
isParseArgsDynTypeName(sym
|
|
1508
|
-
|
|
1815
|
+
isParseArgsDynTypeName(ts.symbolName(sym)) &&
|
|
1816
|
+
sym.declarations.some(declarationBelongs)) {
|
|
1509
1817
|
return true;
|
|
1510
1818
|
}
|
|
1511
1819
|
// A discriminant check erases the token alias and leaves one anonymous
|
|
@@ -1513,7 +1821,7 @@ export function isParseArgsDynCheckerType(lowerer, type) {
|
|
|
1513
1821
|
// is the same stable signal the dotted-member bridge uses.
|
|
1514
1822
|
return lowerer.checker
|
|
1515
1823
|
.getPropertiesOfType(widened)
|
|
1516
|
-
.some((p) =>
|
|
1824
|
+
.some((p) => p.declarations.some(declarationBelongs));
|
|
1517
1825
|
}
|
|
1518
1826
|
/** Destructuring declarations, desugared as sugar over indexed/field
|
|
1519
1827
|
* reads: the initializer evaluates ONCE into a hidden temp, then each
|
|
@@ -1548,12 +1856,17 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1548
1856
|
lowerer.lowerExpr(decl.initializer);
|
|
1549
1857
|
const parseArgsDynObject = init.type.kind === "dyn" &&
|
|
1550
1858
|
isParseArgsDynCheckerType(lowerer, lowerer.typeOf(decl.initializer));
|
|
1551
|
-
// An `any`-origin source
|
|
1552
|
-
//
|
|
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.
|
|
1553
1865
|
if (lowerer.anyOrigin(decl.initializer) &&
|
|
1554
|
-
!isJsSourceFile(
|
|
1866
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1555
1867
|
init.type.kind !== "record" &&
|
|
1556
|
-
init.type.kind !== "array"
|
|
1868
|
+
init.type.kind !== "array" &&
|
|
1869
|
+
init.type.kind !== "dyn") {
|
|
1557
1870
|
lowerer.anyOpFence("destructuring", decl);
|
|
1558
1871
|
}
|
|
1559
1872
|
// An IR-string source the CHECKER does not type as a string is a
|
|
@@ -1564,7 +1877,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1564
1877
|
// points), numbers and characters Node never sees. The fence names
|
|
1565
1878
|
// the checker's own type instead of the carrier.
|
|
1566
1879
|
if (init.type.kind === "string" &&
|
|
1567
|
-
isJsSourceFile(
|
|
1880
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1568
1881
|
!checkerStringSource(lowerer, decl.initializer)) {
|
|
1569
1882
|
lowerer.unsupported("SC1031", decl.name, ts.isArrayBindingPattern(decl.name)
|
|
1570
1883
|
? `array destructuring of non-array values (the source is '${lowerer.checker.typeToString(lowerer.typeOf(decl.initializer))}'-typed)`
|
|
@@ -1576,7 +1889,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1576
1889
|
init.type.kind === "bool" ||
|
|
1577
1890
|
init.type.kind === "string" ||
|
|
1578
1891
|
isUnitType(init.type)) &&
|
|
1579
|
-
!isJsSourceFile(
|
|
1892
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1580
1893
|
!(init.type.kind === "string" &&
|
|
1581
1894
|
staticStringPattern(lowerer, decl.name))) {
|
|
1582
1895
|
{
|
|
@@ -1592,7 +1905,7 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1592
1905
|
// (the message is the fence's — a unit value here is the failure
|
|
1593
1906
|
// path either way). TypeScript keeps the fence: narrowing first is
|
|
1594
1907
|
// the annotated fix.
|
|
1595
|
-
if (isJsSourceFile(
|
|
1908
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) && init.type.kind === "union") {
|
|
1596
1909
|
const def = lowerer.unions.get(init.type.unionId);
|
|
1597
1910
|
const dataArms = (def?.arms ?? []).filter((a) => !isUnitType(a));
|
|
1598
1911
|
const arm = dataArms[0];
|
|
@@ -1630,41 +1943,47 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1630
1943
|
init = { kind: "unionNarrow", unionId: init.type.unionId, tag, value: uref, type: arm, loc };
|
|
1631
1944
|
}
|
|
1632
1945
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
// own, so the groups projection (lowerGroupsProjection — the same
|
|
1637
|
-
// record `m.groups` reads produce) wraps one level in a synthesized
|
|
1638
|
-
// `{ groups: ... }` record and the ordinary record destructure below
|
|
1639
|
-
// serves the pattern — aliases and nested patterns included. Only
|
|
1640
|
-
// named-group regexes take the wrap: a group-less regex destructures
|
|
1641
|
-
// `groups: undefined` in Node (a nested pattern then throws), which
|
|
1642
|
-
// the fence reports honestly instead.
|
|
1643
|
-
if (ts.isObjectBindingPattern(decl.name) &&
|
|
1644
|
-
decl.name.elements.length > 0 &&
|
|
1645
|
-
isMatchSliceType(lowerer, init.type) &&
|
|
1646
|
-
decl.name.elements.every((el) => {
|
|
1647
|
-
if (el.dotDotDotToken !== undefined || el.name === undefined)
|
|
1648
|
-
return false;
|
|
1649
|
-
const prop = el.propertyName;
|
|
1650
|
-
if (prop === undefined)
|
|
1651
|
-
return ts.isIdentifier(el.name) && el.name.text === "groups";
|
|
1652
|
-
return (ts.isIdentifier(prop) || ts.isStringLiteral(prop)) && prop.text === "groups";
|
|
1653
|
-
})) {
|
|
1654
|
-
const groups = matchResultNamedGroupsOf(lowerer, decl.initializer);
|
|
1655
|
-
if (groups !== null && groups.length > 0) {
|
|
1656
|
-
const proj = lowerGroupsProjection(lowerer, init, groups, loc);
|
|
1657
|
-
const outerShape = lowerer.shapes.intern([{ name: "groups", type: proj.type }], false, undefined, ["groups"]);
|
|
1658
|
-
init = {
|
|
1659
|
-
kind: "recordLit",
|
|
1660
|
-
fields: [{ name: "groups", value: proj }],
|
|
1661
|
-
type: { kind: "record", shapeId: outerShape },
|
|
1662
|
-
loc,
|
|
1663
|
-
};
|
|
1664
|
-
}
|
|
1665
|
-
}
|
|
1946
|
+
const groupsSource = matchGroupsPatternSource(lowerer, decl.name, init, () => matchResultNamedGroupsOf(lowerer, decl.initializer), loc);
|
|
1947
|
+
if (groupsSource !== null)
|
|
1948
|
+
init = groupsSource;
|
|
1666
1949
|
const tmp = lowerer.declareHiddenLocal("%destr", init.type);
|
|
1667
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
|
+
}
|
|
1668
1987
|
// V8's destructuring TypeError spells STATIC sources: an identifier
|
|
1669
1988
|
// source reads "<name> is not iterable", an identifier-callee call
|
|
1670
1989
|
// "<name> is not a function or its return value is not iterable";
|
|
@@ -1680,6 +1999,44 @@ export function lowerDestructuringDecl(lowerer, decl, isLet) {
|
|
|
1680
1999
|
lowerer.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: init.type, loc }), init.type, isLet, out, dynSpell, parseArgsDynObject);
|
|
1681
2000
|
return out;
|
|
1682
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
|
+
}
|
|
1683
2040
|
/** One pattern level: emits a declaration (or global assignment) per
|
|
1684
2041
|
* bound name, recursing through hidden temps for nested patterns. */
|
|
1685
2042
|
export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, out, dynSpell, allowDynObject = false) {
|
|
@@ -1687,7 +2044,9 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1687
2044
|
const patternType = lowerer.typeOf(pattern);
|
|
1688
2045
|
const patternSymbol = patternType.getSymbol();
|
|
1689
2046
|
allowDynObject ||=
|
|
1690
|
-
patternSymbol
|
|
2047
|
+
patternSymbol !== undefined &&
|
|
2048
|
+
ts.symbolName(patternSymbol) === "SegmentData" &&
|
|
2049
|
+
lowerer.isStdlibSymbol(patternSymbol);
|
|
1691
2050
|
allowDynObject ||=
|
|
1692
2051
|
(patternType.flags & ts.TypeFlags.Object) !== 0 &&
|
|
1693
2052
|
lowerer.mapTypeOf(patternType)?.kind === "dyn";
|
|
@@ -1701,17 +2060,22 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1701
2060
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
1702
2061
|
lowerer.fenceStaticHeadersIteration(pattern);
|
|
1703
2062
|
if (srcType.kind === "union" &&
|
|
1704
|
-
lowerer.unions
|
|
1705
|
-
|
|
1706
|
-
|
|
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];
|
|
1707
2071
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1708
2072
|
continue;
|
|
1709
2073
|
if (el.dotDotDotToken)
|
|
1710
|
-
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");
|
|
1711
2075
|
const loc = locOf(el);
|
|
1712
|
-
let value = unionArrayValueRead(lowerer, srcRef(), numLit(i, loc), loc);
|
|
2076
|
+
let value = unionArrayValueRead(lowerer, srcRef(), numLit(i, loc), loc, (text) => strCharsCall(lowerer, text, loc));
|
|
1713
2077
|
if (!value)
|
|
1714
|
-
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");
|
|
1715
2079
|
if (el.initializer)
|
|
1716
2080
|
value = applyBindingDefault(lowerer, el, value);
|
|
1717
2081
|
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
@@ -1722,7 +2086,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1722
2086
|
// shape — the positional twin of object destructuring below.
|
|
1723
2087
|
const tupleShape = srcType.kind === "record" ? lowerer.shapes.get(srcType.shapeId) : undefined;
|
|
1724
2088
|
if (srcType.kind === "record" && tupleShape?.tuple) {
|
|
1725
|
-
pattern.elements.forEach((el, i) => {
|
|
2089
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1726
2090
|
// Holes: OmittedExpression in 5.9.3, a nameless BindingElement in
|
|
1727
2091
|
// 7 (parity finding 2) — either way the position is skipped.
|
|
1728
2092
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
@@ -1789,7 +2153,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1789
2153
|
loc,
|
|
1790
2154
|
});
|
|
1791
2155
|
const itRef = () => ({ kind: "varRef", localId: it.id, type: citPat.iterT, loc });
|
|
1792
|
-
for (const el of pattern.elements) {
|
|
2156
|
+
for (const el of pattern.elements.nodes) {
|
|
1793
2157
|
const stepLoc = locOf(el);
|
|
1794
2158
|
const step = lowerer.classIteratorNextCall(citPat, itRef(), stepLoc);
|
|
1795
2159
|
if (ts.isOmittedExpression(el) || el.name === undefined) {
|
|
@@ -1863,10 +2227,10 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1863
2227
|
out.push({
|
|
1864
2228
|
kind: "varDecl",
|
|
1865
2229
|
localId: pack.id,
|
|
1866
|
-
init: pattern.elements.some((element) => ts.isBindingElement(element) && element.dotDotDotToken)
|
|
2230
|
+
init: pattern.elements.nodes.some((element) => ts.isBindingElement(element) && element.dotDotDotToken)
|
|
1867
2231
|
? {
|
|
1868
2232
|
kind: "libCall",
|
|
1869
|
-
fn: "dyn.
|
|
2233
|
+
fn: "dyn.destructureRest",
|
|
1870
2234
|
args: [srcRef(), { kind: "strLit", value: dynSpell ?? "", type: STRING, loc }],
|
|
1871
2235
|
type: DYN,
|
|
1872
2236
|
loc,
|
|
@@ -1874,14 +2238,14 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1874
2238
|
: {
|
|
1875
2239
|
kind: "dynIterN",
|
|
1876
2240
|
value: srcRef(),
|
|
1877
|
-
count: pattern.elements.length,
|
|
2241
|
+
count: pattern.elements.nodes.length,
|
|
1878
2242
|
...(dynSpell ? { notIterableMessage: dynSpell } : {}),
|
|
1879
2243
|
type: DYN,
|
|
1880
2244
|
loc,
|
|
1881
2245
|
},
|
|
1882
2246
|
loc,
|
|
1883
2247
|
});
|
|
1884
|
-
pattern.elements.forEach((el, i) => {
|
|
2248
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1885
2249
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1886
2250
|
return; // hole: the position skips
|
|
1887
2251
|
const elLoc = locOf(el);
|
|
@@ -1937,7 +2301,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1937
2301
|
// fresh number[] (never another typed array), exactly the iterator
|
|
1938
2302
|
// protocol's Array accumulation.
|
|
1939
2303
|
if (srcType.kind === "bytes") {
|
|
1940
|
-
pattern.elements.forEach((el, i) => {
|
|
2304
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1941
2305
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1942
2306
|
return;
|
|
1943
2307
|
const loc = locOf(el);
|
|
@@ -1979,10 +2343,30 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
1979
2343
|
});
|
|
1980
2344
|
return;
|
|
1981
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
|
+
}
|
|
1982
2366
|
if (srcType.kind !== "array") {
|
|
1983
2367
|
lowerer.unsupported("SC1031", pattern, `array destructuring of non-array values (the source is ${srcType.kind}-typed)`);
|
|
1984
2368
|
}
|
|
1985
|
-
pattern.elements.forEach((el, i) => {
|
|
2369
|
+
pattern.elements.nodes.forEach((el, i) => {
|
|
1986
2370
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
1987
2371
|
return; // hole: position skipped, like JS over an array
|
|
1988
2372
|
const loc = locOf(el);
|
|
@@ -2015,7 +2399,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2015
2399
|
});
|
|
2016
2400
|
return;
|
|
2017
2401
|
}
|
|
2018
|
-
if (pattern.elements.length === 0) {
|
|
2402
|
+
if (pattern.elements.nodes.length === 0) {
|
|
2019
2403
|
// `var {} = e`, `for (const {} of ns)`: RequireObjectCoercible and
|
|
2020
2404
|
// nothing else — a pure no-op past the source's own evaluation for
|
|
2021
2405
|
// every statically non-nullish kind, record or not (the assignment
|
|
@@ -2040,19 +2424,19 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2040
2424
|
// deliberately carried by the checked-dynamic tree, so their ordinary
|
|
2041
2425
|
// object patterns use the same exact keyed-read desugar.
|
|
2042
2426
|
if (srcType.kind === "union" &&
|
|
2043
|
-
isJsSourceFile(
|
|
2427
|
+
isJsSourceFile(ts.getSourceFileOfNode(pattern)) &&
|
|
2044
2428
|
lowerer.dynConvertible(srcType)) {
|
|
2045
2429
|
lowerer.lowerBindingPattern(pattern, () => lowerer.coerceToExpected(srcRef(), DYN), DYN, isLet, out, dynSpell, allowDynObject);
|
|
2046
2430
|
return;
|
|
2047
2431
|
}
|
|
2048
2432
|
if (srcType.kind === "dyn") {
|
|
2049
|
-
for (const el of pattern.elements) {
|
|
2433
|
+
for (const el of pattern.elements.nodes) {
|
|
2050
2434
|
if (el.name === undefined)
|
|
2051
2435
|
continue;
|
|
2052
2436
|
const loc = locOf(el);
|
|
2053
2437
|
if (el.dotDotDotToken) {
|
|
2054
2438
|
const keys = [];
|
|
2055
|
-
for (const sibling of pattern.elements) {
|
|
2439
|
+
for (const sibling of pattern.elements.nodes) {
|
|
2056
2440
|
if (sibling === el || sibling.dotDotDotToken)
|
|
2057
2441
|
continue;
|
|
2058
2442
|
const key = sibling.propertyName ?? sibling.name;
|
|
@@ -2130,7 +2514,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2130
2514
|
if (!info)
|
|
2131
2515
|
lowerer.flushDeferredClass(srcType.className);
|
|
2132
2516
|
if (info) {
|
|
2133
|
-
for (const el of pattern.elements) {
|
|
2517
|
+
for (const el of pattern.elements.nodes) {
|
|
2134
2518
|
if (el.name === undefined)
|
|
2135
2519
|
continue;
|
|
2136
2520
|
const loc = locOf(el);
|
|
@@ -2140,7 +2524,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2140
2524
|
// CopyDataProperties copies own enumerable properties, which
|
|
2141
2525
|
// for a class instance are exactly the fields).
|
|
2142
2526
|
const consumed = new Set();
|
|
2143
|
-
for (const sib of pattern.elements) {
|
|
2527
|
+
for (const sib of pattern.elements.nodes) {
|
|
2144
2528
|
if (sib === el || sib.name === undefined || sib.dotDotDotToken)
|
|
2145
2529
|
continue;
|
|
2146
2530
|
const keyNode = sib.propertyName ?? (ts.isIdentifier(sib.name) ? sib.name : null);
|
|
@@ -2219,7 +2603,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2219
2603
|
// naming that. Callers vetted the source as a checker-typed string —
|
|
2220
2604
|
// builtin identity tokens fence before reaching here.
|
|
2221
2605
|
if (srcType.kind === "string") {
|
|
2222
|
-
for (const el of pattern.elements) {
|
|
2606
|
+
for (const el of pattern.elements.nodes) {
|
|
2223
2607
|
if (el.name === undefined)
|
|
2224
2608
|
continue;
|
|
2225
2609
|
const loc = locOf(el);
|
|
@@ -2255,6 +2639,21 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2255
2639
|
}
|
|
2256
2640
|
return;
|
|
2257
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
|
+
}
|
|
2258
2657
|
if (srcType.kind !== "record") {
|
|
2259
2658
|
lowerer.unsupported("SC1031", pattern, srcType.kind === "object"
|
|
2260
2659
|
? "object destructuring of class instances (read the fields directly — accessors make the desugar observable)"
|
|
@@ -2263,7 +2662,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2263
2662
|
const shape = lowerer.shapes.get(srcType.shapeId);
|
|
2264
2663
|
if (!shape)
|
|
2265
2664
|
throw new InternalCompilerError(`lowerer bug: destructuring unknown shape ${srcType.shapeId}`);
|
|
2266
|
-
for (const el of pattern.elements) {
|
|
2665
|
+
for (const el of pattern.elements.nodes) {
|
|
2267
2666
|
if (el.name === undefined)
|
|
2268
2667
|
continue; // 7 spells elisions as nameless elements
|
|
2269
2668
|
// `{ a, ...rest }`: the rest binds a FRESH record of the unconsumed
|
|
@@ -2337,18 +2736,19 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2337
2736
|
// An UNDECLARED key of an INDEX-SIGNATURE shape (`const { m, n, p }
|
|
2338
2737
|
// = ....groups` over `{ [key: string]: string }` — the groups
|
|
2339
2738
|
// record, `Record<string, T>` tables generally): the overflow-map
|
|
2340
|
-
// read, exactly the dot access's recordKeyGet — a missing key
|
|
2341
|
-
//
|
|
2342
|
-
// claimed V), or binds the undefined arm (where a default applies
|
|
2343
|
-
// 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).
|
|
2344
2741
|
const loc = locOf(el);
|
|
2742
|
+
const readType = shape.indexValue.kind === "dyn"
|
|
2743
|
+
? shape.indexValue
|
|
2744
|
+
: (lowerer.withUndefinedArmOf(shape.indexValue) ?? shape.indexValue);
|
|
2345
2745
|
let value = {
|
|
2346
2746
|
kind: "recordKeyGet",
|
|
2347
2747
|
obj: srcRef(),
|
|
2348
2748
|
shapeId: srcType.shapeId,
|
|
2349
2749
|
key: { kind: "strLit", value: propName, type: STRING, loc },
|
|
2350
2750
|
overflowOnly: true,
|
|
2351
|
-
type:
|
|
2751
|
+
type: readType,
|
|
2352
2752
|
loc,
|
|
2353
2753
|
};
|
|
2354
2754
|
if (el.initializer)
|
|
@@ -2356,7 +2756,7 @@ export function lowerBindingPattern(lowerer, pattern, srcRef, srcType, isLet, ou
|
|
|
2356
2756
|
lowerer.bindPatternTarget(el.name, value, isLet, out);
|
|
2357
2757
|
continue;
|
|
2358
2758
|
}
|
|
2359
|
-
if (!fieldType && isJsSourceFile(
|
|
2759
|
+
if (!fieldType && isJsSourceFile(ts.getSourceFileOfNode(el))) {
|
|
2360
2760
|
// Inferred JavaScript shapes can omit optional own properties and
|
|
2361
2761
|
// inherit values from their prototype. Read the live checked view.
|
|
2362
2762
|
const loc = locOf(el);
|
|
@@ -2473,7 +2873,51 @@ function patternSourceValue(lowerer, value, arrayPattern, out, loc, spelling) {
|
|
|
2473
2873
|
function patternBindingType(lowerer, name) {
|
|
2474
2874
|
const type = lowerer.typeOf(name);
|
|
2475
2875
|
return (lowerer.mapTypeOf(type) ??
|
|
2476
|
-
(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
|
+
}
|
|
2477
2921
|
}
|
|
2478
2922
|
function patternKeyNameOf(lowerer, prop) {
|
|
2479
2923
|
if (ts.isIdentifier(prop) || ts.isPrivateIdentifier(prop))
|
|
@@ -2490,6 +2934,140 @@ function patternKeyNameOf(lowerer, prop) {
|
|
|
2490
2934
|
}
|
|
2491
2935
|
return null;
|
|
2492
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
|
+
}
|
|
2493
3071
|
/** Decode one non-rest object-assignment property into its static source
|
|
2494
3072
|
* field, destination expression, and optional default initializer. */
|
|
2495
3073
|
function destructuringPropertyOf(lowerer, prop) {
|
|
@@ -2533,7 +3111,7 @@ function checkerStringSource(lowerer, e) {
|
|
|
2533
3111
|
}
|
|
2534
3112
|
function staticStringPattern(lowerer, pattern) {
|
|
2535
3113
|
if (ts.isArrayBindingPattern(pattern)) {
|
|
2536
|
-
return pattern.elements.every((el) => {
|
|
3114
|
+
return pattern.elements.nodes.every((el) => {
|
|
2537
3115
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
2538
3116
|
return true;
|
|
2539
3117
|
if (el.dotDotDotToken) {
|
|
@@ -2547,7 +3125,7 @@ function staticStringPattern(lowerer, pattern) {
|
|
|
2547
3125
|
return staticStringPattern(lowerer, el.name);
|
|
2548
3126
|
});
|
|
2549
3127
|
}
|
|
2550
|
-
return pattern.elements.every((el) => {
|
|
3128
|
+
return pattern.elements.nodes.every((el) => {
|
|
2551
3129
|
if (el.name === undefined)
|
|
2552
3130
|
return true;
|
|
2553
3131
|
if (el.dotDotDotToken || !ts.isIdentifier(el.name))
|
|
@@ -2613,7 +3191,7 @@ const CONSOLE_CALL_MEMBERS = new Set([
|
|
|
2613
3191
|
* when the source is not a stdlib global at all, or in TypeScript
|
|
2614
3192
|
* files (the identifier chokepoint fences the global there first). */
|
|
2615
3193
|
function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
2616
|
-
if (decl.initializer === undefined || !isJsSourceFile(
|
|
3194
|
+
if (decl.initializer === undefined || !isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
2617
3195
|
return null;
|
|
2618
3196
|
const globalName = stdlibGlobalNameOf(lowerer, decl.initializer);
|
|
2619
3197
|
if (globalName === null)
|
|
@@ -2626,7 +3204,7 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2626
3204
|
}
|
|
2627
3205
|
const srcT = lowerer.typeOf(decl.initializer);
|
|
2628
3206
|
const binds = [];
|
|
2629
|
-
for (const el of decl.name.elements) {
|
|
3207
|
+
for (const el of decl.name.elements.nodes) {
|
|
2630
3208
|
if (el.name === undefined)
|
|
2631
3209
|
continue;
|
|
2632
3210
|
if (el.dotDotDotToken) {
|
|
@@ -2648,8 +3226,9 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2648
3226
|
if (propName === null) {
|
|
2649
3227
|
lowerer.unsupported("SC1031", el, "destructuring with computed keys that do not fold to one property name");
|
|
2650
3228
|
}
|
|
2651
|
-
let token;
|
|
3229
|
+
let token = "";
|
|
2652
3230
|
let alias = null;
|
|
3231
|
+
let value = null;
|
|
2653
3232
|
if (globalName === "globalThis") {
|
|
2654
3233
|
// The member must BE a stdlib global (user script vars are
|
|
2655
3234
|
// properties of `typeof globalThis` too — their values are real
|
|
@@ -2658,9 +3237,12 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2658
3237
|
if (member === undefined || !lowerer.isStdlibSymbol(member)) {
|
|
2659
3238
|
lowerer.unsupported("SC1031", el, `destructuring the non-builtin member '${propName}' of 'globalThis'`);
|
|
2660
3239
|
}
|
|
2661
|
-
const canonical = member
|
|
3240
|
+
const canonical = ts.symbolName(member) === "global" ? "globalThis" : ts.symbolName(member);
|
|
2662
3241
|
token = `[builtin ${canonical}]`;
|
|
2663
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);
|
|
2664
3246
|
}
|
|
2665
3247
|
else if (globalName === "console" && !CONSOLE_CALL_MEMBERS.has(propName)) {
|
|
2666
3248
|
token = `[builtin console.${propName}]`;
|
|
@@ -2668,6 +3250,12 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2668
3250
|
else if (TOKEN_OPAQUE_GLOBALS.has(globalName)) {
|
|
2669
3251
|
token = `[builtin ${globalName}.${propName}]`;
|
|
2670
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
|
+
}
|
|
2671
3259
|
else {
|
|
2672
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)`);
|
|
2673
3261
|
}
|
|
@@ -2676,6 +3264,10 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2676
3264
|
lowerer.unsupported("SC1031", el, `bindings with predeclared slots over the builtin global '${globalName}'`);
|
|
2677
3265
|
}
|
|
2678
3266
|
const g = lowerer.globalsBySymbol.get(symbol);
|
|
3267
|
+
if (value !== null) {
|
|
3268
|
+
binds.push({ name: el.name, token, alias, g, value });
|
|
3269
|
+
continue;
|
|
3270
|
+
}
|
|
2679
3271
|
if (g !== undefined && g.type.kind !== "string" && g.type.kind !== "dyn") {
|
|
2680
3272
|
lowerer.unsupported("SC1031", el, `bindings with '${lowerer.fmt(g.type)}' storage over the builtin global '${globalName}'`);
|
|
2681
3273
|
}
|
|
@@ -2684,6 +3276,27 @@ function stdlibGlobalTokenDestructure(lowerer, decl, isLet) {
|
|
|
2684
3276
|
const out = [];
|
|
2685
3277
|
for (const b of binds) {
|
|
2686
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
|
+
}
|
|
2687
3300
|
const token = { kind: "strLit", value: b.token, type: STRING, loc };
|
|
2688
3301
|
if (b.alias !== null) {
|
|
2689
3302
|
const symbol = lowerer.checker.getSymbolAtLocation(b.name);
|
|
@@ -2965,7 +3578,7 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
|
|
|
2965
3578
|
const consumed = new Set();
|
|
2966
3579
|
let computedSibling = false;
|
|
2967
3580
|
if (ts.isObjectBindingPattern(pattern)) {
|
|
2968
|
-
for (const sib of pattern.elements) {
|
|
3581
|
+
for (const sib of pattern.elements.nodes) {
|
|
2969
3582
|
if (sib === el || sib.dotDotDotToken)
|
|
2970
3583
|
continue;
|
|
2971
3584
|
const key = sib.propertyName ?? sib.name;
|
|
@@ -3032,7 +3645,7 @@ function objectRestValue(lowerer, el, srcRef, srcType, shape) {
|
|
|
3032
3645
|
value: lowerer.presenceKeepingCopy(srcRef(), srcType.shapeId, srcField.name, lowerer.coerceInto(el, read, f.type), loc),
|
|
3033
3646
|
};
|
|
3034
3647
|
});
|
|
3035
|
-
return { kind: "recordLit", fields, type: restT, loc };
|
|
3648
|
+
return lowerer.keyOrder.copy({ kind: "recordLit", fields, type: restT, loc }, srcType.shapeId);
|
|
3036
3649
|
}
|
|
3037
3650
|
/** The fresh record for `{ a, ...rest }` over a CLASS-INSTANCE source:
|
|
3038
3651
|
* JS's CopyDataProperties copies the OWN ENUMERABLE properties — the
|
|
@@ -3086,7 +3699,7 @@ function classInstanceRestValue(lowerer, blame, srcRef, srcType, info, consumed,
|
|
|
3086
3699
|
const orderMatches = (order) => order.length === remaining.length && order.every((n, i) => n === remaining[i].name);
|
|
3087
3700
|
const deferOrderCheck = lowerer.instantiationContext !== null &&
|
|
3088
3701
|
lowerer.onEdge !== null &&
|
|
3089
|
-
!isJsSourceFile(
|
|
3702
|
+
!isJsSourceFile(ts.getSourceFileOfNode(blame));
|
|
3090
3703
|
if (!deferOrderCheck) {
|
|
3091
3704
|
if (!orderMatches(emitOrder)) {
|
|
3092
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)");
|
|
@@ -3101,7 +3714,7 @@ function classInstanceRestValue(lowerer, blame, srcRef, srcType, info, consumed,
|
|
|
3101
3714
|
// matters.
|
|
3102
3715
|
const context = lowerer.instantiationContext;
|
|
3103
3716
|
const countFailure = !lowerer.suppressStats;
|
|
3104
|
-
const sf =
|
|
3717
|
+
const sf = ts.getSourceFileOfNode(blame);
|
|
3105
3718
|
lowerer.shapeOrderMetadataFinalizers.push(() => {
|
|
3106
3719
|
const current = lowerer.shapes.get(restT.shapeId) ?? restShape;
|
|
3107
3720
|
const currentOrder = current.declaredOrder ?? current.fields.map((f) => f.name);
|
|
@@ -3149,6 +3762,8 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3149
3762
|
const symbol = lowerer.checker.getSymbolAtLocation(name);
|
|
3150
3763
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
3151
3764
|
if (g) {
|
|
3765
|
+
if (value.type.kind === "dyn" && jsBindingKeepsCheckedObject(lowerer, name, g.type))
|
|
3766
|
+
g.type = DYN;
|
|
3152
3767
|
out.push({
|
|
3153
3768
|
kind: "assign",
|
|
3154
3769
|
localId: g.id,
|
|
@@ -3165,7 +3780,7 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3165
3780
|
// here by declareParams) carry no block-scope flag either, but their
|
|
3166
3781
|
// bindings are the parameters' own.
|
|
3167
3782
|
if (symbol && hostVariableDeclarationOf(name) !== null && isVarDeclared(name)) {
|
|
3168
|
-
const hoisted = hoistVarBinding(lowerer, symbol, name);
|
|
3783
|
+
const hoisted = hoistVarBinding(lowerer, symbol, name, value.type);
|
|
3169
3784
|
out.push({
|
|
3170
3785
|
kind: "assign",
|
|
3171
3786
|
localId: hoisted.id,
|
|
@@ -3179,7 +3794,7 @@ export function bindPatternTarget(lowerer, name, value, isLet, out, allowDynObje
|
|
|
3179
3794
|
const dynStays = value.type.kind === "dyn" &&
|
|
3180
3795
|
(() => {
|
|
3181
3796
|
const mapped = lowerer.mapTypeOf(lowerer.typeOf(name));
|
|
3182
|
-
return mapped === null;
|
|
3797
|
+
return mapped === null || jsBindingKeepsCheckedObject(lowerer, name, mapped);
|
|
3183
3798
|
})();
|
|
3184
3799
|
let type = dynStays
|
|
3185
3800
|
? DYN
|
|
@@ -3230,7 +3845,7 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3230
3845
|
const isConst = (list.flags & ts.NodeFlags.Const) !== 0;
|
|
3231
3846
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0;
|
|
3232
3847
|
if (!isConst && !isLet) {
|
|
3233
|
-
const out = list.declarations.flatMap((decl) => {
|
|
3848
|
+
const out = list.declarations.nodes.flatMap((decl) => {
|
|
3234
3849
|
// `for (var {} = {}, [a] = xs; ...)`: pattern declarators ride the
|
|
3235
3850
|
// declaration desugar (var names assign their hoisted slots).
|
|
3236
3851
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
@@ -3246,7 +3861,7 @@ export function lowerVarDeclList(lowerer, list) {
|
|
|
3246
3861
|
return { kind: "block", body: out, loc: locOf(list) };
|
|
3247
3862
|
}
|
|
3248
3863
|
const out = [];
|
|
3249
|
-
for (const decl of list.declarations) {
|
|
3864
|
+
for (const decl of list.declarations.nodes) {
|
|
3250
3865
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
3251
3866
|
// Destructuring produces nested initialization blocks; copying
|
|
3252
3867
|
// their captured bindings still needs a distinct head-scope plan.
|
|
@@ -3316,7 +3931,7 @@ function inferredEvolvingLetType(lowerer, decl) {
|
|
|
3316
3931
|
}
|
|
3317
3932
|
if (ts.isCallExpression(node.right) &&
|
|
3318
3933
|
(implicitMethodCallInfersReturn(lowerer, node.right) ||
|
|
3319
|
-
isJsSourceFile(node.right
|
|
3934
|
+
isJsSourceFile(ts.getSourceFileOfNode(node.right)))) {
|
|
3320
3935
|
invalid = true;
|
|
3321
3936
|
return "stop";
|
|
3322
3937
|
}
|
|
@@ -3387,6 +4002,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3387
4002
|
}
|
|
3388
4003
|
if (!ts.isIdentifier(decl.name))
|
|
3389
4004
|
lowerer.unsupported("SC1031", decl.name);
|
|
4005
|
+
{
|
|
4006
|
+
const alias = lowerTupleAliasDecl(lowerer, decl);
|
|
4007
|
+
if (alias)
|
|
4008
|
+
return alias;
|
|
4009
|
+
}
|
|
3390
4010
|
// A NULLISH generic binding (`const i: I<A & B> = null as any` — the
|
|
3391
4011
|
// declared type has no mapping, the value is provably null/undefined
|
|
3392
4012
|
// forever): no storage exists; reads know the value (member reads and
|
|
@@ -3417,10 +4037,10 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3417
4037
|
(decl.name.text === "module" || decl.name.text === "exports") &&
|
|
3418
4038
|
ts.isVariableStatement(decl.parent?.parent) &&
|
|
3419
4039
|
ts.isSourceFile(decl.parent?.parent?.parent) &&
|
|
3420
|
-
!isJsSourceFile(
|
|
3421
|
-
!
|
|
3422
|
-
.
|
|
3423
|
-
.statements.some((s) => ts.isImportDeclaration(s) ||
|
|
4040
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
4041
|
+
!ts
|
|
4042
|
+
.getSourceFileOfNode(decl)
|
|
4043
|
+
.statements.nodes.some((s) => ts.isImportDeclaration(s) ||
|
|
3424
4044
|
ts.isExportDeclaration(s) ||
|
|
3425
4045
|
ts.isExportAssignment(s) ||
|
|
3426
4046
|
(ts.canHaveModifiers(s) &&
|
|
@@ -3469,6 +4089,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3469
4089
|
// `const process = globalThis.process` — a stdlib-global snapshot:
|
|
3470
4090
|
// alias plumbing (see stdlibGlobalAliasDecl), no storage, no code.
|
|
3471
4091
|
const stableStdlibAlias = !isLet ||
|
|
4092
|
+
stdlibBufferVarAlias(lowerer, decl) ||
|
|
3472
4093
|
(ts.isVariableDeclarationList(decl.parent) &&
|
|
3473
4094
|
(decl.parent.flags & ts.NodeFlags.Let) !== 0 &&
|
|
3474
4095
|
ts.isIdentifier(decl.name) &&
|
|
@@ -3508,6 +4129,8 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3508
4129
|
return null;
|
|
3509
4130
|
if (!isLet && registerBuiltinCallableAlias(lowerer, decl.name, decl.initializer))
|
|
3510
4131
|
return null;
|
|
4132
|
+
if (registerBuiltinClassAlias(lowerer, decl.name, decl.initializer))
|
|
4133
|
+
return null;
|
|
3511
4134
|
// `const knownBy = (cmd) => ...` — an IMPLICIT-ANY function-value
|
|
3512
4135
|
// binding in npm-static JS (function-scope bindings register here, in
|
|
3513
4136
|
// source order before any use can lower; file-scope ones registered at
|
|
@@ -3592,17 +4215,25 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3592
4215
|
return { kind: "assign", localId: g.id, value: wrapped, loc: locOf(decl) };
|
|
3593
4216
|
return null;
|
|
3594
4217
|
}
|
|
3595
|
-
const
|
|
3596
|
-
(
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
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)) &&
|
|
3602
4229
|
!decl.type &&
|
|
3603
4230
|
!hasJsTypeAnnotation(decl) &&
|
|
3604
4231
|
raw.type.kind === "dyn" &&
|
|
3605
|
-
(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)))))
|
|
3606
4237
|
g.type = DYN;
|
|
3607
4238
|
g.type = inferredOptionalRecordType(lowerer, decl, g.type, raw.type);
|
|
3608
4239
|
const arithmetic = raw.type.kind === "union" ? lowerer.unions.get(raw.type.unionId)?.arms : undefined;
|
|
@@ -3643,6 +4274,9 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3643
4274
|
// types already hold the interned undefined arm), and a declaration
|
|
3644
4275
|
// re-run in a loop must not reset the persisting value.
|
|
3645
4276
|
if (isVarDeclared(decl) && declSymbol) {
|
|
4277
|
+
const fromExisting = lowerJsVarFromExisting(lowerer, decl, declSymbol);
|
|
4278
|
+
if (fromExisting)
|
|
4279
|
+
return fromExisting;
|
|
3646
4280
|
const local = hoistVarBinding(lowerer, declSymbol, decl.name);
|
|
3647
4281
|
if (!decl.initializer)
|
|
3648
4282
|
return null;
|
|
@@ -3658,7 +4292,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3658
4292
|
// immediately (the type covers the unassigned state), so they
|
|
3659
4293
|
// initialize to the interned undefined arm like an omitted optional.
|
|
3660
4294
|
let type = lowerer.irTypeOf(decl.name);
|
|
3661
|
-
if (type.kind === "dyn" && isLet && isJsSourceFile(
|
|
4295
|
+
if (type.kind === "dyn" && isLet && isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3662
4296
|
type = inferredEvolvingLetType(lowerer, decl) ?? type;
|
|
3663
4297
|
}
|
|
3664
4298
|
// `var v: void;` / `let x: undefined;` — a unit-only binding rides
|
|
@@ -3682,7 +4316,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3682
4316
|
// function (with its hint), not the unmappable declared type. If it
|
|
3683
4317
|
// poisons, still declare the local when its type is representable, so
|
|
3684
4318
|
// later references to this name don't produce cascading errors.
|
|
3685
|
-
const inferredObjectType = isJsSourceFile(
|
|
4319
|
+
const inferredObjectType = isJsSourceFile(ts.getSourceFileOfNode(decl))
|
|
3686
4320
|
? lowerer.mapTypeOf(lowerer.typeOf(decl.name))
|
|
3687
4321
|
: null;
|
|
3688
4322
|
const inferredObjectArms = inferredObjectType?.kind === "union"
|
|
@@ -3695,11 +4329,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3695
4329
|
inferredObjectType !== null &&
|
|
3696
4330
|
jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind === "dyn") ||
|
|
3697
4331
|
inferredObjectArms.some((arm) => arm.kind === "record" && jsObjectBindingExpands(lowerer, decl, arm)) ||
|
|
3698
|
-
(isJsSourceFile(
|
|
4332
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3699
4333
|
!decl.type &&
|
|
3700
4334
|
!hasJsTypeAnnotation(decl) &&
|
|
3701
4335
|
ts.isObjectLiteralExpression(decl.initializer) &&
|
|
3702
|
-
decl.initializer.properties.some((property) => ts.isMethodDeclaration(property) ||
|
|
4336
|
+
decl.initializer.properties.nodes.some((property) => ts.isMethodDeclaration(property) ||
|
|
3703
4337
|
ts.isAccessor(property) ||
|
|
3704
4338
|
(ts.isPropertyAssignment(property) &&
|
|
3705
4339
|
(ts.isFunctionExpression(property.initializer) ||
|
|
@@ -3708,7 +4342,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3708
4342
|
try {
|
|
3709
4343
|
init =
|
|
3710
4344
|
expandsObject ||
|
|
3711
|
-
(isJsSourceFile(
|
|
4345
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3712
4346
|
!decl.type &&
|
|
3713
4347
|
isNativeBuiltinValueInitializer(lowerer, decl.initializer))
|
|
3714
4348
|
? lowerer.lowerExprExpecting(decl.initializer, DYN)
|
|
@@ -3740,11 +4374,19 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3740
4374
|
staticImportNamespaceType(lowerer, decl.initializer) ??
|
|
3741
4375
|
(init.type.kind === "moduleNs" ? init.type : null) ??
|
|
3742
4376
|
(init.type.kind === "dyn" ? DYN : null);
|
|
3743
|
-
if (isJsSourceFile(
|
|
4377
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3744
4378
|
!decl.type &&
|
|
3745
4379
|
!hasJsTypeAnnotation(decl) &&
|
|
3746
4380
|
init.type.kind === "func")
|
|
3747
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;
|
|
3748
4390
|
// A TypeScript lambda whose closure returns the runtime result (a missing
|
|
3749
4391
|
// read, a `??` default of another type) instead of the checker's bare
|
|
3750
4392
|
// return type: the binding keeps the checker's parameters and takes the
|
|
@@ -3757,24 +4399,24 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3757
4399
|
type = { ...type, ret: init.type.ret };
|
|
3758
4400
|
if (lowerer.implicitParamTypes !== null &&
|
|
3759
4401
|
init.type.kind === "dyn" &&
|
|
3760
|
-
isJsSourceFile(
|
|
3761
|
-
npmStaticPackageOfPath(
|
|
4402
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
4403
|
+
npmStaticPackageOfPath(ts.getSourceFileOfNode(decl).fileName) !== null) {
|
|
3762
4404
|
type = DYN;
|
|
3763
4405
|
}
|
|
3764
4406
|
const preservesObjectIdentity = init.type.kind === "dyn" &&
|
|
3765
4407
|
(inferredObjectType?.kind === "record" ||
|
|
3766
4408
|
inferredObjectType?.kind === "array" ||
|
|
3767
|
-
(isJsSourceFile(
|
|
4409
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3768
4410
|
inferredObjectArms.some((arm) => arm.kind === "record") &&
|
|
3769
4411
|
inferredObjectArms.every((arm) => isUnitType(arm) || arm.kind === "record")) ||
|
|
3770
|
-
(isJsSourceFile(
|
|
4412
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3771
4413
|
inferredObjectType !== null &&
|
|
3772
4414
|
(inferredObjectType.kind === "date" ||
|
|
3773
4415
|
inferredObjectType.kind === "func" ||
|
|
3774
4416
|
inferredObjectType.kind === "object" ||
|
|
3775
4417
|
jsOpenObjectType(decl, inferredObjectType, lowerer.shapes, lowerer.unions).kind ===
|
|
3776
4418
|
"dyn")) ||
|
|
3777
|
-
(isJsSourceFile(
|
|
4419
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3778
4420
|
inferredObjectType !== null &&
|
|
3779
4421
|
(inferredObjectType.kind === "void" ||
|
|
3780
4422
|
isUnitType(inferredObjectType) ||
|
|
@@ -3782,14 +4424,20 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3782
4424
|
lowerer.unions.get(inferredObjectType.unionId)?.arms.every(isUnitType))))) &&
|
|
3783
4425
|
!decl.type &&
|
|
3784
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;
|
|
3785
4432
|
if (expandsObject ||
|
|
3786
4433
|
preservesObjectIdentity ||
|
|
3787
|
-
|
|
4434
|
+
keepsAssertedObject ||
|
|
4435
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3788
4436
|
!decl.type &&
|
|
3789
4437
|
isNativeBuiltinValueInitializer(lowerer, decl.initializer))) {
|
|
3790
4438
|
type = DYN;
|
|
3791
4439
|
}
|
|
3792
|
-
if (isJsSourceFile(
|
|
4440
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3793
4441
|
!decl.type &&
|
|
3794
4442
|
init.type.kind === "array" &&
|
|
3795
4443
|
init.type.elem.kind === "dyn" &&
|
|
@@ -3804,14 +4452,14 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3804
4452
|
// cannot hold the binding's future. The binding is checked-dynamic
|
|
3805
4453
|
// instead (irTypeOf's JS story): writes dynFrom, typed exits dynCheck.
|
|
3806
4454
|
// Const keeps the static empty record — no reassignment exists.
|
|
3807
|
-
if (isLet && type?.kind === "record" && isJsSourceFile(
|
|
4455
|
+
if (isLet && type?.kind === "record" && isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3808
4456
|
const shape = lowerer.shapes.get(type.shapeId);
|
|
3809
4457
|
if (shape && shape.fields.length === 0 && !shape.indexValue && !shape.tuple)
|
|
3810
4458
|
type = DYN;
|
|
3811
4459
|
}
|
|
3812
4460
|
if (isLet &&
|
|
3813
4461
|
type !== null &&
|
|
3814
|
-
isJsSourceFile(
|
|
4462
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3815
4463
|
!decl.type &&
|
|
3816
4464
|
!hasJsTypeAnnotation(decl) &&
|
|
3817
4465
|
(type.kind === "object" || type.kind === "symbol" || jsBindingHasOpenWrites(lowerer, decl))) {
|
|
@@ -3833,11 +4481,11 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3833
4481
|
// exits dynCheck.
|
|
3834
4482
|
if (returnedEmptyArrayType === null &&
|
|
3835
4483
|
(type === null || type.kind === "array") &&
|
|
3836
|
-
isJsSourceFile(
|
|
4484
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3837
4485
|
let initExpr = decl.initializer;
|
|
3838
4486
|
while (ts.isParenthesizedExpression(initExpr))
|
|
3839
4487
|
initExpr = initExpr.expression;
|
|
3840
|
-
if (ts.isArrayLiteralExpression(initExpr) && initExpr.elements.length === 0) {
|
|
4488
|
+
if (ts.isArrayLiteralExpression(initExpr) && initExpr.elements.nodes.length === 0) {
|
|
3841
4489
|
const t = lowerer.typeOf(decl.name);
|
|
3842
4490
|
if (lowerer.checker.isArrayType(t)) {
|
|
3843
4491
|
const elem = lowerer.checker.getTypeArguments(t)[0];
|
|
@@ -3889,14 +4537,14 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3889
4537
|
// boxed thunk's JS arity instead.
|
|
3890
4538
|
if (type?.kind === "func" &&
|
|
3891
4539
|
init.type.kind === "dyn" &&
|
|
3892
|
-
(isJsSourceFile(
|
|
4540
|
+
(isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
3893
4541
|
(!decl.type &&
|
|
3894
4542
|
!hasJsTypeAnnotation(decl) &&
|
|
3895
4543
|
type.rest === true &&
|
|
3896
4544
|
type.restAbi === undefined))) {
|
|
3897
4545
|
type = DYN;
|
|
3898
4546
|
}
|
|
3899
|
-
if (isJsSourceFile(
|
|
4547
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3900
4548
|
!decl.type &&
|
|
3901
4549
|
!hasJsTypeAnnotation(decl) &&
|
|
3902
4550
|
init.type.kind === "dyn" &&
|
|
@@ -3921,12 +4569,16 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3921
4569
|
// type (a union with a fence-folded arm — the typeof-'bigint'
|
|
3922
4570
|
// dual-mode ternary) adopts the initializer's static type, the
|
|
3923
4571
|
// same rule genuine `any` consts take.
|
|
3924
|
-
(type === null && isJsSourceFile(
|
|
4572
|
+
(type === null && isJsSourceFile(ts.getSourceFileOfNode(decl)))) &&
|
|
3925
4573
|
init.type.kind !== "void" &&
|
|
3926
4574
|
init.type.kind !== "caught" &&
|
|
3927
4575
|
!isUnitType(init.type)) {
|
|
3928
4576
|
type = init.type;
|
|
3929
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);
|
|
3930
4582
|
if (!type) {
|
|
3931
4583
|
// The JS declaration fallback (irTypeOf's story): the binding holds
|
|
3932
4584
|
// the checked-dynamic kind when even the initializer's type has no
|
|
@@ -3939,7 +4591,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3939
4591
|
lowerer.badType(decl.name, lowerer.typeOf(decl.name));
|
|
3940
4592
|
let settledType = type;
|
|
3941
4593
|
if (!isLet &&
|
|
3942
|
-
isJsSourceFile(
|
|
4594
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
3943
4595
|
!hasJsTypeAnnotation(decl) &&
|
|
3944
4596
|
decl.initializer &&
|
|
3945
4597
|
ts.isNewExpression(decl.initializer)) {
|
|
@@ -3974,7 +4626,7 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
3974
4626
|
? npmStaticOptionalSelfWriteType(lowerer, decl, settledType)
|
|
3975
4627
|
: null;
|
|
3976
4628
|
settledType =
|
|
3977
|
-
expandsObject || preservesObjectIdentity
|
|
4629
|
+
expandsObject || preservesObjectIdentity || keepsAssertedObject
|
|
3978
4630
|
? DYN
|
|
3979
4631
|
: lowerer.runtimeOptionalBindingType(decl.name, settledType);
|
|
3980
4632
|
if (optionalSelfWriteType !== null)
|
|
@@ -4037,6 +4689,21 @@ export function lowerVarDecl(lowerer, decl, isLet) {
|
|
|
4037
4689
|
settledType = init.type;
|
|
4038
4690
|
}
|
|
4039
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
|
+
}
|
|
4040
4707
|
// An exact class behind a generic interface keeps its native
|
|
4041
4708
|
// representation so generic calls can specialize against its body.
|
|
4042
4709
|
if ((settledType.kind === "record" || settledType.kind === "dyn") &&
|
|
@@ -4137,7 +4804,7 @@ function lowerVariableInitializer(lowerer, node, expected) {
|
|
|
4137
4804
|
if (expected?.kind === "dyn")
|
|
4138
4805
|
return lowerDynObjectLiteral(lowerer, value);
|
|
4139
4806
|
const previous = new Map();
|
|
4140
|
-
for (const property of value.properties) {
|
|
4807
|
+
for (const property of value.properties.nodes) {
|
|
4141
4808
|
if (!ts.isPropertyAssignment(property) || !ts.isComputedPropertyName(property.name))
|
|
4142
4809
|
continue;
|
|
4143
4810
|
const keyNode = property.name.expression;
|
|
@@ -4166,7 +4833,7 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4166
4833
|
if (decl.type ||
|
|
4167
4834
|
!decl.initializer ||
|
|
4168
4835
|
!ts.isIdentifier(decl.name) ||
|
|
4169
|
-
!isJsSourceFile(
|
|
4836
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
4170
4837
|
return false;
|
|
4171
4838
|
let initializer = decl.initializer;
|
|
4172
4839
|
while (ts.isParenthesizedExpression(initializer))
|
|
@@ -4243,6 +4910,18 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4243
4910
|
const name = property(node.left);
|
|
4244
4911
|
if (name === null || (name !== undefined && !names.has(name)))
|
|
4245
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;
|
|
4246
4925
|
}
|
|
4247
4926
|
if (ts.isDeleteExpression(node) && property(node.expression) !== undefined)
|
|
4248
4927
|
expands = true;
|
|
@@ -4250,7 +4929,7 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4250
4929
|
ts.isPropertyAccessExpression(node.expression) &&
|
|
4251
4930
|
node.expression.name.text === "setPrototypeOf" &&
|
|
4252
4931
|
lowerer.isStdlibGlobal(node.expression.expression, "Object")) {
|
|
4253
|
-
const target = node.arguments[0];
|
|
4932
|
+
const target = node.arguments.nodes[0];
|
|
4254
4933
|
const sym = target && ts.isIdentifier(target) ? lowerer.resolveValueSymbol(target) : undefined;
|
|
4255
4934
|
if (sym && aliases.has(sym))
|
|
4256
4935
|
expands = true;
|
|
@@ -4262,12 +4941,13 @@ function jsObjectBindingExpands(lowerer, decl, type) {
|
|
|
4262
4941
|
}
|
|
4263
4942
|
export function hasJsTypeAnnotation(decl) {
|
|
4264
4943
|
const statement = decl.parent?.parent;
|
|
4265
|
-
return (!!statement &&
|
|
4944
|
+
return (!!statement &&
|
|
4945
|
+
/@type\b/.test(ts.getSourceFileOfNode(decl).text.slice(statement.pos, ts.tokenStartOfNode(decl))));
|
|
4266
4946
|
}
|
|
4267
4947
|
/** Inferred JS scalar initializers do not constrain later writes through
|
|
4268
4948
|
* an any-valued callback. Keep those bindings open, including captured writes. */
|
|
4269
4949
|
export function jsBindingHasOpenWrites(lowerer, decl) {
|
|
4270
|
-
if (!isJsSourceFile(
|
|
4950
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(decl)) ||
|
|
4271
4951
|
decl.type ||
|
|
4272
4952
|
hasJsTypeAnnotation(decl) ||
|
|
4273
4953
|
!ts.isIdentifier(decl.name))
|
|
@@ -4300,37 +4980,117 @@ export function jsBindingHasOpenWrites(lowerer, decl) {
|
|
|
4300
4980
|
(lowerer.typeOf(node.right).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0);
|
|
4301
4981
|
}
|
|
4302
4982
|
function immediatelyGuardedAbsenceProbe(lowerer, decl) {
|
|
4303
|
-
|
|
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))
|
|
4304
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)))
|
|
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;
|
|
4305
5028
|
const statement = decl.parent?.parent;
|
|
4306
5029
|
if (!statement || !ts.isVariableStatement(statement))
|
|
4307
|
-
return
|
|
5030
|
+
return null;
|
|
4308
5031
|
const container = statement.parent;
|
|
4309
|
-
const statements = ts.isBlock(container) || ts.isSourceFile(container) ? container.statements : null;
|
|
5032
|
+
const statements = ts.isBlock(container) || ts.isSourceFile(container) ? container.statements.nodes : null;
|
|
4310
5033
|
if (!statements)
|
|
4311
|
-
return
|
|
5034
|
+
return null;
|
|
4312
5035
|
const index = statements.indexOf(statement);
|
|
4313
5036
|
const next = index >= 0 ? statements[index + 1] : undefined;
|
|
4314
5037
|
if (!next || !ts.isIfStatement(next))
|
|
4315
|
-
return
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
operand
|
|
4325
|
-
|
|
4326
|
-
|
|
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;
|
|
4327
5087
|
}
|
|
4328
5088
|
function falsyExitRuntimeOptionalLocals(lowerer, stmt) {
|
|
4329
5089
|
if (stmt.elseStatement)
|
|
4330
5090
|
return [];
|
|
4331
5091
|
let tail = stmt.thenStatement;
|
|
4332
5092
|
while (ts.isBlock(tail)) {
|
|
4333
|
-
const last = tail.statements[tail.statements.length - 1];
|
|
5093
|
+
const last = tail.statements.nodes[tail.statements.nodes.length - 1];
|
|
4334
5094
|
if (!last)
|
|
4335
5095
|
return [];
|
|
4336
5096
|
tail = last;
|
|
@@ -4356,15 +5116,16 @@ export function lowerSwitch(lowerer, stmt) {
|
|
|
4356
5116
|
return lowerDynSwitch(lowerer, stmt, disc, labels);
|
|
4357
5117
|
if (dk === "union")
|
|
4358
5118
|
return lowerUnionSwitch(lowerer, stmt, disc, labels);
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
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)));
|
|
4362
5123
|
// The whole case-body sequence is ONE lexical scope in JS: a bare `let`
|
|
4363
5124
|
// in one case is visible in later cases.
|
|
4364
5125
|
lowerer.scopes.push(new Map());
|
|
4365
5126
|
try {
|
|
4366
5127
|
const cases = [];
|
|
4367
|
-
for (const clause of stmt.caseBlock.clauses) {
|
|
5128
|
+
for (const clause of stmt.caseBlock.clauses.nodes) {
|
|
4368
5129
|
let test = null;
|
|
4369
5130
|
if (ts.isCaseClause(clause)) {
|
|
4370
5131
|
test = lowerer.lowerExpr(clause.expression);
|
|
@@ -4374,7 +5135,7 @@ export function lowerSwitch(lowerer, stmt) {
|
|
|
4374
5135
|
}
|
|
4375
5136
|
cases.push({
|
|
4376
5137
|
test,
|
|
4377
|
-
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels),
|
|
5138
|
+
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements.nodes)), labels),
|
|
4378
5139
|
});
|
|
4379
5140
|
}
|
|
4380
5141
|
return { kind: "switch", disc, cases, ...(labels && { labels }), loc: locOf(stmt) };
|
|
@@ -4424,7 +5185,7 @@ function lowerDynSwitch(lowerer, stmt, disc, labels) {
|
|
|
4424
5185
|
loc: locOf(expression),
|
|
4425
5186
|
};
|
|
4426
5187
|
}
|
|
4427
|
-
if (!lowerer.dynConvertible(test.type)) {
|
|
5188
|
+
if (test.type.kind === "date" || !lowerer.dynConvertible(test.type)) {
|
|
4428
5189
|
lowerer.unsupported("SC1100", expression, "switch case values that cannot compare strictly with 'unknown'");
|
|
4429
5190
|
}
|
|
4430
5191
|
return {
|
|
@@ -4445,7 +5206,7 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4445
5206
|
// Calls/assignments in a case test may mutate a captured discriminant
|
|
4446
5207
|
// binding. The checker still narrows that binding as if it were the
|
|
4447
5208
|
// snapshot. Keep the original tagged value in those case bodies.
|
|
4448
|
-
const effectful = stmt.caseBlock.clauses.some((clause) => ts.isCaseClause(clause) &&
|
|
5209
|
+
const effectful = stmt.caseBlock.clauses.nodes.some((clause) => ts.isCaseClause(clause) &&
|
|
4449
5210
|
!ts.isStringLiteral(clause.expression) &&
|
|
4450
5211
|
!ts.isNumericLiteral(clause.expression) &&
|
|
4451
5212
|
!ts.isIdentifier(clause.expression) &&
|
|
@@ -4461,11 +5222,11 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4461
5222
|
lowerer.unstableSwitchBindings.add(symbol);
|
|
4462
5223
|
lowerer.scopes.push(new Map());
|
|
4463
5224
|
try {
|
|
4464
|
-
const cases = stmt.caseBlock.clauses.map((clause) => ({
|
|
5225
|
+
const cases = stmt.caseBlock.clauses.nodes.map((clause) => ({
|
|
4465
5226
|
test: ts.isCaseClause(clause)
|
|
4466
5227
|
? compare(stableDisc, lowerer.lowerExpr(clause.expression), clause.expression)
|
|
4467
5228
|
: null,
|
|
4468
|
-
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements)), labels),
|
|
5229
|
+
body: lowerer.inCtl("switch", () => withRuntimeOptionalScope(lowerer, () => lowerer.lowerStmts(clause.statements.nodes)), labels),
|
|
4469
5230
|
}));
|
|
4470
5231
|
return {
|
|
4471
5232
|
kind: "block",
|
|
@@ -4494,7 +5255,7 @@ function lowerBranchSwitch(lowerer, stmt, disc, labels, compare) {
|
|
|
4494
5255
|
* cell, deliberately narrower than dyn: the supported uses are the
|
|
4495
5256
|
* narrowing tests (`e instanceof C` over hierarchy classes, `typeof e
|
|
4496
5257
|
* === "string"/"number"/"boolean"`), reads under a proven narrow
|
|
4497
|
-
* (caughtRead bridges them with caughtNarrow,
|
|
5258
|
+
* (caughtRead bridges them with caughtNarrow, verified at run time like
|
|
4498
5259
|
* unionNarrow), and rethrow (`throw e`). Unsupported raw uses and
|
|
4499
5260
|
* assignments are fenced (SC1063 and friends); destructuring patterns
|
|
4500
5261
|
* are SC1062. Captures retain the snapshot beyond the catch scope.
|
|
@@ -4540,31 +5301,6 @@ export function lowerTry(lowerer, stmt) {
|
|
|
4540
5301
|
loc: locOf(stmt),
|
|
4541
5302
|
};
|
|
4542
5303
|
}
|
|
4543
|
-
function hasUseStrictDirective(statements) {
|
|
4544
|
-
for (const statement of statements) {
|
|
4545
|
-
if (!ts.isExpressionStatement(statement) || !ts.isStringLiteral(statement.expression))
|
|
4546
|
-
return false;
|
|
4547
|
-
if (statement.expression.text === "use strict")
|
|
4548
|
-
return true;
|
|
4549
|
-
}
|
|
4550
|
-
return false;
|
|
4551
|
-
}
|
|
4552
|
-
function isStrictDelete(node) {
|
|
4553
|
-
for (let parent = node.parent; parent; parent = parent.parent) {
|
|
4554
|
-
if (ts.isClassDeclaration(parent) || ts.isClassExpression(parent))
|
|
4555
|
-
return true;
|
|
4556
|
-
if (ts.isFunctionLike(parent) &&
|
|
4557
|
-
parent.body &&
|
|
4558
|
-
ts.isBlock(parent.body) &&
|
|
4559
|
-
hasUseStrictDirective(parent.body.statements))
|
|
4560
|
-
return true;
|
|
4561
|
-
if (ts.isSourceFile(parent)) {
|
|
4562
|
-
return (hasUseStrictDirective(parent.statements) ||
|
|
4563
|
-
(!isCjsJsFile(parent) && (isNodeEsmFile(parent) || ts.isExternalModule(parent))));
|
|
4564
|
-
}
|
|
4565
|
-
}
|
|
4566
|
-
return false;
|
|
4567
|
-
}
|
|
4568
5304
|
/** Statement-position `delete`: process.env keys → process.envUnset
|
|
4569
5305
|
* (unsetenv), pure `Record<string, T>` keys → recordKeyDelete (the
|
|
4570
5306
|
* overflow Map delete), declared OPTIONAL fields → the field's ABSENT
|
|
@@ -4627,7 +5363,29 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4627
5363
|
};
|
|
4628
5364
|
}
|
|
4629
5365
|
let obj = lowerer.lowerExpr(target.expression);
|
|
4630
|
-
|
|
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") {
|
|
4631
5389
|
const info = lowerer.classes.get(obj.type.className);
|
|
4632
5390
|
const keyType = ts.isElementAccessExpression(target)
|
|
4633
5391
|
? lowerer.typeOf(target.argumentExpression)
|
|
@@ -4647,13 +5405,13 @@ function lowerDeleteStatement(lowerer, expr) {
|
|
|
4647
5405
|
};
|
|
4648
5406
|
}
|
|
4649
5407
|
}
|
|
4650
|
-
if (isJsSourceFile(
|
|
5408
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
4651
5409
|
obj.type.kind === "func" &&
|
|
4652
5410
|
lowerer.dynConvertible(obj.type)) {
|
|
4653
5411
|
obj = lowerer.coerceToExpected(obj, DYN);
|
|
4654
5412
|
}
|
|
4655
5413
|
if (obj.type.kind === "dyn") {
|
|
4656
|
-
const strict = { kind: "boolLit", value:
|
|
5414
|
+
const strict = { kind: "boolLit", value: isStrictCode(expr), type: BOOL, loc };
|
|
4657
5415
|
if (ts.isElementAccessExpression(target)) {
|
|
4658
5416
|
const key = lowerer.lowerExprExpecting(target.argumentExpression, DYN);
|
|
4659
5417
|
return {
|
|
@@ -4740,7 +5498,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4740
5498
|
const assignExport = (nameNode, value, root) => {
|
|
4741
5499
|
const symbol = lowerer.checker.getSymbolAtLocation(nameNode) ??
|
|
4742
5500
|
(ts.isIdentifier(nameNode) || ts.isPrivateIdentifier(nameNode)
|
|
4743
|
-
? lowerer.cjsModuleExportSymbol(cjs.expr
|
|
5501
|
+
? lowerer.cjsModuleExportSymbol(ts.getSourceFileOfNode(cjs.expr), nameNode.text)
|
|
4744
5502
|
: undefined);
|
|
4745
5503
|
const g = symbol ? lowerer.globalsBySymbol.get(symbol) : undefined;
|
|
4746
5504
|
if (!g) {
|
|
@@ -4799,7 +5557,10 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4799
5557
|
// storage — collectGlobals skipped it; importers re-resolve through
|
|
4800
5558
|
// cjsMemberExportClassSymbol): the statement lowers to nothing.
|
|
4801
5559
|
if (lowerer.cjsMemberExportClassSymbol(cjs.expr) !== null) {
|
|
4802
|
-
|
|
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 };
|
|
4803
5564
|
}
|
|
4804
5565
|
// The tsc VOID-INIT PREAMBLE (`exports.leaf = void 0;` with the real
|
|
4805
5566
|
// `exports.leaf = leaf;` further down — every tsc-emitted dist file
|
|
@@ -4811,54 +5572,58 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4811
5572
|
// the real assignment's position already orders. Preambles with no
|
|
4812
5573
|
// later real assignment keep the ordinary path (the export IS
|
|
4813
5574
|
// undefined then).
|
|
4814
|
-
if (
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
((ts.isIdentifier(e.expression) && e.expression.text === "exports") ||
|
|
4818
|
-
(ts.isPropertyAccessExpression(e.expression) &&
|
|
4819
|
-
ts.isIdentifier(e.expression.expression) &&
|
|
4820
|
-
e.expression.expression.text === "module" &&
|
|
4821
|
-
ts.isIdentifier(e.expression.name) &&
|
|
4822
|
-
e.expression.name.text === "exports"));
|
|
4823
|
-
const isVoid = (e) => {
|
|
4824
|
-
while (ts.isParenthesizedExpression(e))
|
|
4825
|
-
e = e.expression;
|
|
4826
|
-
return (e.kind === ts.SyntaxKind.VoidExpression || (ts.isIdentifier(e) && e.text === "undefined"));
|
|
4827
|
-
};
|
|
4828
|
-
// chains: `exports.a = exports.b = void 0;` collects every name
|
|
4829
|
-
const names = [cjs.name.text];
|
|
4830
|
-
let tail = cjs.value;
|
|
4831
|
-
while (ts.isBinaryExpression(tail) &&
|
|
4832
|
-
tail.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
4833
|
-
isExportsMember(tail.left)) {
|
|
4834
|
-
names.push(tail.left.name.text);
|
|
4835
|
-
tail = tail.right;
|
|
4836
|
-
}
|
|
4837
|
-
if (isVoid(tail)) {
|
|
4838
|
-
const sfHere = cjs.expr.getSourceFile();
|
|
4839
|
-
const myPos = cjs.expr.getStart(sfHere);
|
|
4840
|
-
const laterRealOf = (name) => sfHere.statements.some((s) => {
|
|
4841
|
-
const other = cjsExportAssignmentOf(s);
|
|
4842
|
-
if (other?.kind !== "member" || !ts.isIdentifier(other.name))
|
|
4843
|
-
return false;
|
|
4844
|
-
if (other.name.text !== name)
|
|
4845
|
-
return false;
|
|
4846
|
-
if (other.expr.getStart(sfHere) <= myPos)
|
|
4847
|
-
return false;
|
|
4848
|
-
return !isVoid(other.value);
|
|
4849
|
-
});
|
|
4850
|
-
if (names.every(laterRealOf))
|
|
4851
|
-
return { kind: "block", body: [], loc };
|
|
4852
|
-
}
|
|
4853
|
-
}
|
|
4854
|
-
const sf = cjs.expr.getSourceFile();
|
|
5575
|
+
if (cjsVoidInitPreambleReals(cjs) !== null)
|
|
5576
|
+
return { kind: "block", body: [], loc };
|
|
5577
|
+
const sf = ts.getSourceFileOfNode(cjs.expr);
|
|
4855
5578
|
let root;
|
|
4856
|
-
for (const stmt of sf.statements) {
|
|
5579
|
+
for (const stmt of sf.statements.nodes) {
|
|
4857
5580
|
const whole = cjsExportAssignmentOf(stmt);
|
|
4858
5581
|
if (whole?.kind !== "table" || cjsExportDiscardReason(stmt) !== null)
|
|
4859
5582
|
continue;
|
|
4860
5583
|
root = lowerer.globalsByDeclNode.get(whole.expr);
|
|
4861
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
|
+
}
|
|
4862
5627
|
return assignExport(cjs.name, cjs.value, root);
|
|
4863
5628
|
}
|
|
4864
5629
|
let tableObj = cjs.obj;
|
|
@@ -4872,7 +5637,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4872
5637
|
// were already evaluated by the const's own declaration, so this
|
|
4873
5638
|
// statement may not RE-evaluate anything: expression-valued entries
|
|
4874
5639
|
// (which the direct-table lowering assigns here) keep a fence.
|
|
4875
|
-
tableObj = cjsExportTargetLiteral(cjs.expr.right, cjs.expr
|
|
5640
|
+
tableObj = cjsExportTargetLiteral(cjs.expr.right, ts.getSourceFileOfNode(cjs.expr));
|
|
4876
5641
|
resolvedTarget = tableObj !== null;
|
|
4877
5642
|
if (!tableObj) {
|
|
4878
5643
|
const single = lowerCjsSingleValueExport(lowerer, cjs.expr, loc);
|
|
@@ -4895,7 +5660,7 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4895
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)`);
|
|
4896
5661
|
}
|
|
4897
5662
|
};
|
|
4898
|
-
for (const prop of table.properties) {
|
|
5663
|
+
for (const prop of table.properties.nodes) {
|
|
4899
5664
|
if (ts.isShorthandPropertyAssignment(prop)) {
|
|
4900
5665
|
fenceMutable(prop.name);
|
|
4901
5666
|
continue; // alias plumbing
|
|
@@ -4913,6 +5678,29 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4913
5678
|
body.push(assignExport(prop.name, prop.initializer));
|
|
4914
5679
|
continue;
|
|
4915
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
|
+
}
|
|
4916
5704
|
// ACCESSOR entries: no storage and no code here — reads lift the
|
|
4917
5705
|
// getter as a module-level function and call it per read
|
|
4918
5706
|
// (cjsExportAccessorRead); writes through the setter keep their
|
|
@@ -4930,8 +5718,16 @@ function lowerCjsExportStatement(lowerer, cjs) {
|
|
|
4930
5718
|
let inner = prop.expression;
|
|
4931
5719
|
while (ts.isParenthesizedExpression(inner))
|
|
4932
5720
|
inner = inner.expression;
|
|
4933
|
-
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);
|
|
4934
5729
|
continue;
|
|
5730
|
+
}
|
|
4935
5731
|
}
|
|
4936
5732
|
lowerer.unsupported("SC1090", prop, "module.exports table entries beyond plain 'name: value' properties (methods, accessors, spreads, computed names)");
|
|
4937
5733
|
}
|
|
@@ -4956,6 +5752,16 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
|
|
|
4956
5752
|
let rhs = expr.right;
|
|
4957
5753
|
while (ts.isParenthesizedExpression(rhs))
|
|
4958
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
|
+
}
|
|
4959
5765
|
if (ts.isIdentifier(rhs)) {
|
|
4960
5766
|
const sym = lowerer.resolveValueSymbol(rhs);
|
|
4961
5767
|
if (!sym)
|
|
@@ -4965,6 +5771,14 @@ function lowerCjsSingleValueExport(lowerer, expr, loc) {
|
|
|
4965
5771
|
lowerer.genericFnsBySymbol.has(sym)) {
|
|
4966
5772
|
return { kind: "block", body: [], loc };
|
|
4967
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
|
+
}
|
|
4968
5782
|
const g = lowerer.globalsBySymbol.get(sym);
|
|
4969
5783
|
if (g) {
|
|
4970
5784
|
if (g.mutable) {
|
|
@@ -5069,8 +5883,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5069
5883
|
// positions keep the first-class-namespace fences.
|
|
5070
5884
|
if (ts.isIdentifier(expr)) {
|
|
5071
5885
|
const sym = lowerer.checker.getSymbolAtLocation(expr);
|
|
5072
|
-
if (sym !== undefined &&
|
|
5073
|
-
lowerer.checker.declarationsOf(sym).some((d) => ts.isNamespaceImport(d))) {
|
|
5886
|
+
if (sym !== undefined && sym.declarations.some((d) => ts.isNamespaceImport(d))) {
|
|
5074
5887
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5075
5888
|
}
|
|
5076
5889
|
}
|
|
@@ -5103,16 +5916,22 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5103
5916
|
return (lowerer.requireInitStmt(created.spec, expr) ?? { kind: "block", body: [], loc: locOf(expr) });
|
|
5104
5917
|
}
|
|
5105
5918
|
// syncBuiltinESMExports() is the other compiler-only statement: the
|
|
5106
|
-
// call validates its zero-argument shape, then
|
|
5107
|
-
//
|
|
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.
|
|
5108
5922
|
const bi = ts.isIdentifier(expr.expression)
|
|
5109
5923
|
? lowerer.builtinImportOf(expr.expression)
|
|
5110
5924
|
: ts.isPropertyAccessExpression(expr.expression)
|
|
5111
5925
|
? lowerer.builtinMemberOf(expr.expression)
|
|
5112
5926
|
: null;
|
|
5113
5927
|
if (bi?.module === "module" && bi.member === "syncBuiltinESMExports") {
|
|
5114
|
-
|
|
5115
|
-
|
|
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
|
+
};
|
|
5116
5935
|
}
|
|
5117
5936
|
}
|
|
5118
5937
|
if (requireSpecOf(expr) !== null &&
|
|
@@ -5121,7 +5940,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5121
5940
|
// A binding NAMED require made by createRequire is not the CJS
|
|
5122
5941
|
// global — the expression path owns it (lowerCreateRequireCall).
|
|
5123
5942
|
createRequireCalleeFileOf(lowerer, expr.expression) === null) {
|
|
5124
|
-
const sf =
|
|
5943
|
+
const sf = ts.getSourceFileOfNode(expr);
|
|
5125
5944
|
const spec = requireSpecOf(expr);
|
|
5126
5945
|
if (lowerer.externalTypes.has(spec))
|
|
5127
5946
|
lowerer.externalHostFence(spec, expr, false);
|
|
@@ -5160,7 +5979,30 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5160
5979
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5161
5980
|
lowerer.unsupported("SC1090", expr, "require() outside the module's top level (move it to the top of the file)");
|
|
5162
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
|
+
}
|
|
5163
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
|
+
}
|
|
5164
6006
|
const cjs = cjsExportAssignmentOf(stmtNode);
|
|
5165
6007
|
if (cjs)
|
|
5166
6008
|
return lowerCjsExportStatement(lowerer, cjs);
|
|
@@ -5360,7 +6202,9 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5360
6202
|
}
|
|
5361
6203
|
else {
|
|
5362
6204
|
const recvT = lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression));
|
|
5363
|
-
|
|
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) {
|
|
5364
6208
|
// A static write through a class VALUE: sound exactly when
|
|
5365
6209
|
// the value can only BE the declaring class — a LEAF class
|
|
5366
6210
|
// (no strict descendants can flow into the slot, so JS's
|
|
@@ -5460,9 +6304,12 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5460
6304
|
lowerer.stdlibGlobalMember(expr.left, "process") === "exitCode") {
|
|
5461
6305
|
const loc = locOf(expr);
|
|
5462
6306
|
const value = lowerer.lowerExprExpecting(expr.right, F64);
|
|
6307
|
+
const fn = programReadsExitCode(lowerer)
|
|
6308
|
+
? "process.setExitCodeTracked"
|
|
6309
|
+
: "process.setExitCode";
|
|
5463
6310
|
return {
|
|
5464
6311
|
kind: "exprStmt",
|
|
5465
|
-
expr: { kind: "libCall", fn
|
|
6312
|
+
expr: { kind: "libCall", fn, args: [value], type: VOID, loc },
|
|
5466
6313
|
loc,
|
|
5467
6314
|
};
|
|
5468
6315
|
}
|
|
@@ -5483,6 +6330,30 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5483
6330
|
loc,
|
|
5484
6331
|
};
|
|
5485
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
|
+
}
|
|
5486
6357
|
// process.title = name: libuv's uv_set_process_title (the
|
|
5487
6358
|
// runtime truncates to the original argument area on POSIX).
|
|
5488
6359
|
if (flag === "title") {
|
|
@@ -5547,7 +6418,7 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5547
6418
|
const recv = tryLowerExpression(lowerer, expr.left.expression);
|
|
5548
6419
|
if (recv &&
|
|
5549
6420
|
(recv.type.kind === "dyn" ||
|
|
5550
|
-
(isJsSourceFile(
|
|
6421
|
+
(isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
5551
6422
|
recv.type.kind === "union" &&
|
|
5552
6423
|
lowerer.dynConvertible(recv.type)))) {
|
|
5553
6424
|
const loc = locOf(expr);
|
|
@@ -5567,6 +6438,32 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5567
6438
|
loc,
|
|
5568
6439
|
};
|
|
5569
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
|
+
}
|
|
5570
6467
|
if (recv?.type.kind === "object" && recv.type.className === "%Error") {
|
|
5571
6468
|
const loc = locOf(expr);
|
|
5572
6469
|
return {
|
|
@@ -5618,6 +6515,25 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5618
6515
|
const recvIr = lowerer.mapTypeOf(lowerer.typeOf(expr.left.expression));
|
|
5619
6516
|
if (recvIr?.kind === "record") {
|
|
5620
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
|
+
}
|
|
5621
6537
|
if (shape?.indexValue &&
|
|
5622
6538
|
!shape.fields.some((f) => f.name === expr.left.name.text)) {
|
|
5623
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)`);
|
|
@@ -5634,6 +6550,19 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5634
6550
|
const parts = lowerDestructuringAssignParts(lowerer, expr.left, expr.right, locOf(expr));
|
|
5635
6551
|
return { kind: "block", body: parts.stmts, loc: locOf(expr) };
|
|
5636
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
|
+
}
|
|
5637
6566
|
if (!ts.isIdentifier(expr.left)) {
|
|
5638
6567
|
lowerer.unsupported("SC1090", expr.left, "assignment to non-variables");
|
|
5639
6568
|
}
|
|
@@ -5729,6 +6658,13 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5729
6658
|
if (droppedPureStdlibStatement(lowerer, expr)) {
|
|
5730
6659
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5731
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
|
+
}
|
|
5732
6668
|
const value = lowerer.lowerExpr(expr);
|
|
5733
6669
|
// A bare unit-literal statement (`undefined;`): a pure no-op in JS,
|
|
5734
6670
|
// and the IR has no bare-unit VALUE outside a union wrap — drop it
|
|
@@ -5737,6 +6673,55 @@ export function lowerExprStatement(lowerer, expr) {
|
|
|
5737
6673
|
return { kind: "block", body: [], loc: locOf(expr) };
|
|
5738
6674
|
return { kind: "exprStmt", expr: value, loc: locOf(expr) };
|
|
5739
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
|
+
}
|
|
5740
6725
|
/** True for a statement-position expression whose evaluation cannot be
|
|
5741
6726
|
* observed once the value is discarded:
|
|
5742
6727
|
* - a property/element READ (`?.` included) whose receiver IS a
|
|
@@ -5770,7 +6755,7 @@ function droppedPureStdlibStatement(lowerer, expr) {
|
|
|
5770
6755
|
const root = stdlibGlobalNameOf(lowerer, strip(proto.expression));
|
|
5771
6756
|
if (root !== "Array" && root !== "String")
|
|
5772
6757
|
return false;
|
|
5773
|
-
return expr.arguments.every((a) => sideEffectFreeOptionValue(a));
|
|
6758
|
+
return expr.arguments.nodes.every((a) => sideEffectFreeOptionValue(a));
|
|
5774
6759
|
}
|
|
5775
6760
|
if (ts.isPropertyAccessExpression(expr)) {
|
|
5776
6761
|
return stdlibGlobalNameOf(lowerer, strip(expr.expression)) !== null;
|
|
@@ -5838,18 +6823,46 @@ export function lowerDestructuringAssign(lowerer, target, init, blame, loc) {
|
|
|
5838
6823
|
}
|
|
5839
6824
|
/** V8's spelling of a destructuring RHS in its TypeError message
|
|
5840
6825
|
* ("Cannot destructure 'a' as it is undefined.") — plain identifiers
|
|
5841
|
-
* spell their name (parens unwrap),
|
|
5842
|
-
*
|
|
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. */
|
|
5843
6831
|
function destrSpellingOf(rhs) {
|
|
5844
6832
|
let e = rhs;
|
|
5845
|
-
|
|
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)) {
|
|
5846
6840
|
e = e.expression;
|
|
6841
|
+
}
|
|
5847
6842
|
if (ts.isIdentifier(e))
|
|
5848
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)";
|
|
5849
6849
|
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken) {
|
|
5850
6850
|
const base = destrSpellingOf(e.expression);
|
|
5851
6851
|
return base === null ? null : `${base}.${e.name.text}`;
|
|
5852
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
|
+
}
|
|
5853
6866
|
if (ts.isCallExpression(e) && !e.questionDotToken) {
|
|
5854
6867
|
const callee = destrSpellingOf(e.expression);
|
|
5855
6868
|
return callee === null ? null : `${callee}(...)`;
|
|
@@ -5914,9 +6927,9 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5914
6927
|
// globals and strings alike).
|
|
5915
6928
|
{
|
|
5916
6929
|
const patternEmpty = ts.isObjectLiteralExpression(target)
|
|
5917
|
-
? target.properties.length === 0
|
|
5918
|
-
: target.elements.length === 0;
|
|
5919
|
-
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))) {
|
|
5920
6933
|
const globalName = stdlibGlobalNameOf(lowerer, rhs);
|
|
5921
6934
|
if (globalName !== null) {
|
|
5922
6935
|
lowerer.unsupported("SC1031", blame, `destructuring assignment from the builtin global '${globalName}' (bind the members with a const destructuring declaration instead)`);
|
|
@@ -5957,7 +6970,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5957
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)");
|
|
5958
6971
|
}
|
|
5959
6972
|
let firstProp;
|
|
5960
|
-
const p0 = target.properties[0];
|
|
6973
|
+
const p0 = target.properties.nodes[0];
|
|
5961
6974
|
if (p0 !== undefined) {
|
|
5962
6975
|
if (ts.isShorthandPropertyAssignment(p0))
|
|
5963
6976
|
firstProp = p0.name.text;
|
|
@@ -5981,7 +6994,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5981
6994
|
loc,
|
|
5982
6995
|
});
|
|
5983
6996
|
}
|
|
5984
|
-
for (const prop of target.properties) {
|
|
6997
|
+
for (const prop of target.properties.nodes) {
|
|
5985
6998
|
const piece = destructAssignPiece(lowerer, prop);
|
|
5986
6999
|
const read = {
|
|
5987
7000
|
kind: "dynKeyGet",
|
|
@@ -5999,7 +7012,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
5999
7012
|
}
|
|
6000
7013
|
return { stmts: out, value };
|
|
6001
7014
|
}
|
|
6002
|
-
if (target.properties.length === 0) {
|
|
7015
|
+
if (target.properties.nodes.length === 0) {
|
|
6003
7016
|
// `({} = e)`: RequireObjectCoercible and nothing else. A source the
|
|
6004
7017
|
// type system already proves non-nullish is a pure no-op past the
|
|
6005
7018
|
// RHS's own evaluation; possibly-nullish unions would throw in JS
|
|
@@ -6024,14 +7037,14 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6024
7037
|
lowerer.flushDeferredClass(objT.className);
|
|
6025
7038
|
const info = lowerer.classes.get(objT.className);
|
|
6026
7039
|
if (info) {
|
|
6027
|
-
for (const prop of target.properties) {
|
|
7040
|
+
for (const prop of target.properties.nodes) {
|
|
6028
7041
|
const propLoc = locOf(prop);
|
|
6029
7042
|
if (ts.isSpreadAssignment(prop)) {
|
|
6030
7043
|
let restTo = prop.expression;
|
|
6031
7044
|
while (ts.isParenthesizedExpression(restTo))
|
|
6032
7045
|
restTo = restTo.expression;
|
|
6033
7046
|
const consumed = new Set();
|
|
6034
|
-
for (const p of target.properties) {
|
|
7047
|
+
for (const p of target.properties.nodes) {
|
|
6035
7048
|
if (ts.isShorthandPropertyAssignment(p))
|
|
6036
7049
|
consumed.add(p.name.text);
|
|
6037
7050
|
else if (ts.isPropertyAssignment(p)) {
|
|
@@ -6145,7 +7158,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6145
7158
|
// properties keep the declaration path's named fences. Callers vetted
|
|
6146
7159
|
// the source as a checker-typed string.
|
|
6147
7160
|
if (init.type.kind === "string") {
|
|
6148
|
-
for (const prop of target.properties) {
|
|
7161
|
+
for (const prop of target.properties.nodes) {
|
|
6149
7162
|
const propLoc = locOf(prop);
|
|
6150
7163
|
if (ts.isSpreadAssignment(prop)) {
|
|
6151
7164
|
lowerer.unsupported("SC1031", prop, "rest bindings over string sources (JS packs the wrapper's per-code-unit indices — split with [...s] instead)");
|
|
@@ -6207,7 +7220,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6207
7220
|
const shape = lowerer.shapes.get(srcType.shapeId);
|
|
6208
7221
|
if (!shape)
|
|
6209
7222
|
throw new InternalCompilerError(`lowerer bug: destructuring unknown shape ${srcType.shapeId}`);
|
|
6210
|
-
for (const prop of target.properties) {
|
|
7223
|
+
for (const prop of target.properties.nodes) {
|
|
6211
7224
|
// Shorthand `{ a }` assigns local a from field a; `{ a: x }` assigns
|
|
6212
7225
|
// x from field a (a PropertyAssignment whose initializer is the
|
|
6213
7226
|
// target — JS reuses the literal syntax with inverted roles).
|
|
@@ -6224,7 +7237,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6224
7237
|
lowerer.unsupported("SC1031", prop, "rest bindings over index-signature shapes (the undeclared entries would need overflow packing)");
|
|
6225
7238
|
}
|
|
6226
7239
|
const consumed = new Set();
|
|
6227
|
-
for (const p of target.properties) {
|
|
7240
|
+
for (const p of target.properties.nodes) {
|
|
6228
7241
|
if (ts.isShorthandPropertyAssignment(p))
|
|
6229
7242
|
consumed.add(p.name.text);
|
|
6230
7243
|
else if (ts.isPropertyAssignment(p)) {
|
|
@@ -6239,7 +7252,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6239
7252
|
if (restOrder !== undefined) {
|
|
6240
7253
|
lowerer.shapeOrderMetadataFinalizers.push(lowerer.shapes.declaredOrderFinalizer(restShapeId, restOrder, () => lowerer.shapes.get(srcType.shapeId)?.declaredOrder?.filter((n) => !consumed.has(n))));
|
|
6241
7254
|
}
|
|
6242
|
-
const packed = {
|
|
7255
|
+
const packed = lowerer.keyOrder.copy({
|
|
6243
7256
|
kind: "recordLit",
|
|
6244
7257
|
fields: remaining.map((f) => ({
|
|
6245
7258
|
name: f.name,
|
|
@@ -6254,7 +7267,7 @@ function destructuringAssignInto(lowerer, target, init, rhs, blame, loc) {
|
|
|
6254
7267
|
})),
|
|
6255
7268
|
type: { kind: "record", shapeId: restShapeId },
|
|
6256
7269
|
loc: locOf(prop),
|
|
6257
|
-
};
|
|
7270
|
+
}, srcType.shapeId);
|
|
6258
7271
|
if (!ts.isIdentifier(restTo)) {
|
|
6259
7272
|
// `({ a, ...box.rest } = src)` — the rest packs identically and
|
|
6260
7273
|
// lands through the property/element write machinery.
|
|
@@ -6499,7 +7512,7 @@ function lowerArrayAssignInto(lowerer, out, target, tmpRef, blame, loc) {
|
|
|
6499
7512
|
// array divergence). The EMPTY pattern skips the split — GetIterator
|
|
6500
7513
|
// + close, nothing observable — through the iterable early-return
|
|
6501
7514
|
// below. Callers vetted the source as a checker-typed string.
|
|
6502
|
-
if (srcType.kind === "string" && target.elements.length > 0) {
|
|
7515
|
+
if (srcType.kind === "string" && target.elements.nodes.length > 0) {
|
|
6503
7516
|
const charsT = arrayOf(STRING);
|
|
6504
7517
|
const chars = lowerer.declareHiddenLocal("%dchars", charsT);
|
|
6505
7518
|
out.push({
|
|
@@ -6517,11 +7530,11 @@ function lowerArrayAssignInto(lowerer, out, target, tmpRef, blame, loc) {
|
|
|
6517
7530
|
// consumes exactly the elements the inner pattern alone would, so the
|
|
6518
7531
|
// unwrap is exact. Identifier rest operands pack in the element loop
|
|
6519
7532
|
// below.
|
|
6520
|
-
let elements = target.elements;
|
|
7533
|
+
let elements = target.elements.nodes;
|
|
6521
7534
|
if (elements.length === 1 &&
|
|
6522
7535
|
ts.isSpreadElement(elements[0]) &&
|
|
6523
7536
|
ts.isArrayLiteralExpression(elements[0].expression)) {
|
|
6524
|
-
elements = elements[0].expression.elements;
|
|
7537
|
+
elements = elements[0].expression.elements.nodes;
|
|
6525
7538
|
}
|
|
6526
7539
|
// The element-read builder per source kind; null when the source
|
|
6527
7540
|
// cannot destructure.
|
|
@@ -6748,13 +7761,24 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6748
7761
|
}
|
|
6749
7762
|
}
|
|
6750
7763
|
}
|
|
7764
|
+
{
|
|
7765
|
+
const opened = classAsyncGeneratorIterator(lowerer, stmt.expression);
|
|
7766
|
+
if (opened)
|
|
7767
|
+
return lowerForAwaitGenerator(lowerer, stmt, opened, labels);
|
|
7768
|
+
}
|
|
6751
7769
|
if (ts.isPropertyAccessExpression(stmt.expression) &&
|
|
6752
7770
|
lowerer.stdlibGlobalMember(stmt.expression, "process") === "stdin") {
|
|
6753
7771
|
return lowerForAwaitStdin(lowerer, stmt);
|
|
6754
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;
|
|
6755
7777
|
const builtin = lowerForAwaitBuiltin(lowerer, stmt);
|
|
6756
7778
|
if (builtin)
|
|
6757
7779
|
return builtin;
|
|
7780
|
+
// A NodeJS.ReadableStream iterates as the general Readable.
|
|
7781
|
+
requestGeneralStreamSurface(lowerer, stmt.expression);
|
|
6758
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)");
|
|
6759
7783
|
}
|
|
6760
7784
|
if (awaitArray && !lowerer.ctx.isAsync) {
|
|
@@ -6777,6 +7801,13 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6777
7801
|
}
|
|
6778
7802
|
}
|
|
6779
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
|
+
}
|
|
6780
7811
|
// `for (const k of m.keys())` / `.values()` / `.entries()`: the
|
|
6781
7812
|
// iterator methods consumed DIRECTLY by a for-of head ride the
|
|
6782
7813
|
// container's live walk — exactly `for..of m` with the projection
|
|
@@ -6789,7 +7820,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6789
7820
|
while (ts.isParenthesizedExpression(src))
|
|
6790
7821
|
src = src.expression;
|
|
6791
7822
|
if (ts.isCallExpression(src) &&
|
|
6792
|
-
src.arguments.length === 0 &&
|
|
7823
|
+
src.arguments.nodes.length === 0 &&
|
|
6793
7824
|
!src.questionDotToken &&
|
|
6794
7825
|
ts.isPropertyAccessExpression(src.expression) &&
|
|
6795
7826
|
!src.expression.questionDotToken &&
|
|
@@ -6847,7 +7878,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6847
7878
|
src = src.expression;
|
|
6848
7879
|
const constIdentBinding = ts.isVariableDeclarationList(stmt.initializer) &&
|
|
6849
7880
|
(stmt.initializer.flags & ts.NodeFlags.Const) !== 0 &&
|
|
6850
|
-
ts.isIdentifier(stmt.initializer.declarations[0].name);
|
|
7881
|
+
ts.isIdentifier(stmt.initializer.declarations.nodes[0].name);
|
|
6851
7882
|
if (constIdentBinding) {
|
|
6852
7883
|
const call = directMatchAllCallOf(lowerer, src);
|
|
6853
7884
|
if (call)
|
|
@@ -6879,7 +7910,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6879
7910
|
e = e.expression;
|
|
6880
7911
|
if (ts.isCallExpression(e) &&
|
|
6881
7912
|
!e.questionDotToken &&
|
|
6882
|
-
e.arguments.length === 0 &&
|
|
7913
|
+
e.arguments.nodes.length === 0 &&
|
|
6883
7914
|
ts.isPropertyAccessExpression(e.expression) &&
|
|
6884
7915
|
!e.expression.questionDotToken &&
|
|
6885
7916
|
e.expression.name.text === "values" &&
|
|
@@ -6953,6 +7984,11 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
6953
7984
|
return lowerForOfGenerator(lowerer, stmt, iterable, labels);
|
|
6954
7985
|
}
|
|
6955
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);
|
|
6956
7992
|
// Class iterables ([Symbol.iterator]() + next() — classIteratorOf)
|
|
6957
7993
|
// drive the same protocol with ordinary method calls.
|
|
6958
7994
|
const cit = lowerer.classIteratorOf(iterable.type);
|
|
@@ -7337,7 +8373,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
7337
8373
|
const list = stmt.initializer;
|
|
7338
8374
|
const resourceLoop = (list.flags & ts.NodeFlags.Using) !== 0;
|
|
7339
8375
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
7340
|
-
const decl = list.declarations[0]; // the grammar allows exactly one
|
|
8376
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
7341
8377
|
// `for (const [k, v] of pairs)` — a destructuring loop variable: the
|
|
7342
8378
|
// element binds to a hidden per-iteration local and the pattern
|
|
7343
8379
|
// desugars to reads of it at the top of the body, exactly the
|
|
@@ -7367,7 +8403,7 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
7367
8403
|
// local and the body opens by ASSIGNING it into the one hoisted
|
|
7368
8404
|
// binding — closures capture the shared slot, and the value persists
|
|
7369
8405
|
// after the loop (both Node-exact for var).
|
|
7370
|
-
const varTarget = forOfVarTarget(lowerer, decl);
|
|
8406
|
+
const varTarget = forOfVarTarget(lowerer, decl, elemValueT);
|
|
7371
8407
|
if (varTarget) {
|
|
7372
8408
|
const elemType = elemValueT;
|
|
7373
8409
|
const loc = locOf(decl.name);
|
|
@@ -7394,8 +8430,10 @@ export function lowerForOf(lowerer, stmt) {
|
|
|
7394
8430
|
if (!resourceLoop)
|
|
7395
8431
|
return forValues(local.id, body);
|
|
7396
8432
|
const resource = varRef(local.id, local.type, locOf(decl.name));
|
|
7397
|
-
const
|
|
8433
|
+
const setup = [];
|
|
8434
|
+
const cleanup = cleanupForValue(lowerer, decl.name, resource, isAwaitUsing(list), setup);
|
|
7398
8435
|
return forValues(local.id, [
|
|
8436
|
+
...setup,
|
|
7399
8437
|
{
|
|
7400
8438
|
kind: "tryCatch",
|
|
7401
8439
|
tryBody: body,
|
|
@@ -7482,7 +8520,7 @@ function lowerForOfStoredNumericIterator(lowerer, stmt, state, labels) {
|
|
|
7482
8520
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
7483
8521
|
}
|
|
7484
8522
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
7485
|
-
const decl = list ? list.declarations[0] : null;
|
|
8523
|
+
const decl = list ? list.declarations.nodes[0] : null;
|
|
7486
8524
|
if (decl && !ts.isIdentifier(decl.name))
|
|
7487
8525
|
lowerer.unsupported("SC1031", decl.name);
|
|
7488
8526
|
const loc = locOf(stmt);
|
|
@@ -7610,13 +8648,13 @@ function directMatchAllCallOf(lowerer, e) {
|
|
|
7610
8648
|
src = src.expression;
|
|
7611
8649
|
if (ts.isCallExpression(src) &&
|
|
7612
8650
|
!src.questionDotToken &&
|
|
7613
|
-
src.arguments.length === 1 &&
|
|
8651
|
+
src.arguments.nodes.length === 1 &&
|
|
7614
8652
|
ts.isPropertyAccessExpression(src.expression) &&
|
|
7615
8653
|
!src.expression.questionDotToken &&
|
|
7616
8654
|
src.expression.name.text === "matchAll" &&
|
|
7617
8655
|
lowerer.isStdlibMember(src.expression) &&
|
|
7618
8656
|
lowerer.mapTypeOf(lowerer.typeOf(src.expression.expression))?.kind === "string" &&
|
|
7619
|
-
lowerer.mapTypeOf(lowerer.typeOf(src.arguments[0]))?.kind === "regex") {
|
|
8657
|
+
lowerer.mapTypeOf(lowerer.typeOf(src.arguments.nodes[0]))?.kind === "regex") {
|
|
7620
8658
|
return src;
|
|
7621
8659
|
}
|
|
7622
8660
|
return null;
|
|
@@ -7641,7 +8679,7 @@ function directMatchAllCallOf(lowerer, e) {
|
|
|
7641
8679
|
*/
|
|
7642
8680
|
function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
7643
8681
|
const list = stmt.initializer;
|
|
7644
|
-
const decl = list.declarations[0];
|
|
8682
|
+
const decl = list.declarations.nodes[0];
|
|
7645
8683
|
const name = decl.name;
|
|
7646
8684
|
const loc = locOf(stmt);
|
|
7647
8685
|
const rowT = arrayOf(STRING);
|
|
@@ -7655,7 +8693,7 @@ function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
|
7655
8693
|
if (call !== null) {
|
|
7656
8694
|
const access = call.expression;
|
|
7657
8695
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
7658
|
-
const re = lowerer.lowerExpr(call.arguments[0]);
|
|
8696
|
+
const re = lowerer.lowerExpr(call.arguments.nodes[0]);
|
|
7659
8697
|
const idxs = lowerer.declareHiddenLocal("%midxs", idxsT);
|
|
7660
8698
|
idxsLocalId = idxs.id;
|
|
7661
8699
|
prelude.push({
|
|
@@ -7666,7 +8704,9 @@ function lowerForOfMatchAll(lowerer, stmt, call, stored) {
|
|
|
7666
8704
|
});
|
|
7667
8705
|
rowsInit = {
|
|
7668
8706
|
kind: "regexIntrinsic",
|
|
7669
|
-
method:
|
|
8707
|
+
method: matchAllRowsReadByElements(lowerer, call, true)
|
|
8708
|
+
? "matchAllCapturesInto"
|
|
8709
|
+
: "matchAllInto",
|
|
7670
8710
|
receiver,
|
|
7671
8711
|
args: [re, { kind: "varRef", localId: idxs.id, type: idxsT, loc }],
|
|
7672
8712
|
type: rowsT,
|
|
@@ -7805,7 +8845,7 @@ function lowerForOfClassIterator(lowerer, stmt, iterable, cit, labels) {
|
|
|
7805
8845
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
7806
8846
|
}
|
|
7807
8847
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
7808
|
-
const decl = list ? list.declarations[0] : null;
|
|
8848
|
+
const decl = list ? list.declarations.nodes[0] : null;
|
|
7809
8849
|
if (decl && !ts.isIdentifier(decl.name))
|
|
7810
8850
|
lowerer.unsupported("SC1031", decl.name);
|
|
7811
8851
|
const loc = locOf(stmt);
|
|
@@ -8022,14 +9062,14 @@ function lowerForOfDyn(lowerer, stmt, iterable, labels) {
|
|
|
8022
9062
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
8023
9063
|
}
|
|
8024
9064
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
8025
|
-
const decl = list.declarations[0];
|
|
9065
|
+
const decl = list.declarations.nodes[0];
|
|
8026
9066
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
8027
9067
|
const tmp = lowerer.declareHiddenLocal("%destr", DYN);
|
|
8028
9068
|
binds.push({ kind: "varDecl", localId: tmp.id, init: elemInit(), loc });
|
|
8029
9069
|
lowerer.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: DYN, loc }), DYN, isLet, binds);
|
|
8030
9070
|
}
|
|
8031
9071
|
else if (ts.isIdentifier(decl.name)) {
|
|
8032
|
-
const varTarget = forOfVarTarget(lowerer, decl);
|
|
9072
|
+
const varTarget = forOfVarTarget(lowerer, decl, DYN);
|
|
8033
9073
|
if (varTarget) {
|
|
8034
9074
|
// `for (var x of d)`: the element mechanics stay on a hidden
|
|
8035
9075
|
// per-iteration local; the body opens by assigning the ONE
|
|
@@ -8183,7 +9223,7 @@ function lowerForOfString(lowerer, stmt, iterable, labels) {
|
|
|
8183
9223
|
lowerer.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
8184
9224
|
}
|
|
8185
9225
|
const isLet = list !== null && (list.flags & ts.NodeFlags.Let) !== 0;
|
|
8186
|
-
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
|
|
8187
9227
|
const loc = locOf(stmt);
|
|
8188
9228
|
lowerer.scopes.push(new Map());
|
|
8189
9229
|
try {
|
|
@@ -8342,7 +9382,7 @@ function lowerForIn(lowerer, stmt) {
|
|
|
8342
9382
|
while (root?.base)
|
|
8343
9383
|
root = root.base;
|
|
8344
9384
|
if (info?.decl &&
|
|
8345
|
-
isJsSourceFile(info.decl
|
|
9385
|
+
isJsSourceFile(ts.getSourceFileOfNode(info.decl)) &&
|
|
8346
9386
|
!info.def.runtime &&
|
|
8347
9387
|
!root?.def.runtime &&
|
|
8348
9388
|
!info.builtinError &&
|
|
@@ -8495,7 +9535,7 @@ function lowerForInOverKeys(lowerer, stmt, keys, labels, guard) {
|
|
|
8495
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)");
|
|
8496
9536
|
}
|
|
8497
9537
|
const list = stmt.initializer;
|
|
8498
|
-
const decl = list.declarations[0]; // the grammar allows exactly one
|
|
9538
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
8499
9539
|
if (!ts.isIdentifier(decl.name))
|
|
8500
9540
|
lowerer.unsupported("SC1031", decl.name);
|
|
8501
9541
|
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
@@ -8592,7 +9632,7 @@ function lowerForInArray(lowerer, stmt, labels, arrExpr) {
|
|
|
8592
9632
|
];
|
|
8593
9633
|
}
|
|
8594
9634
|
else {
|
|
8595
|
-
const decl = stmt.initializer.declarations[0];
|
|
9635
|
+
const decl = stmt.initializer.declarations.nodes[0];
|
|
8596
9636
|
if (!ts.isIdentifier(decl.name))
|
|
8597
9637
|
lowerer.unsupported("SC1031", decl.name);
|
|
8598
9638
|
const isLet = (stmt.initializer.flags & ts.NodeFlags.Let) !== 0 ||
|
|
@@ -8695,7 +9735,7 @@ function lowerForAwaitStdin(lowerer, stmt) {
|
|
|
8695
9735
|
// threading it through a shared hoisted slot has no user yet.
|
|
8696
9736
|
if (!isConst && !isLet)
|
|
8697
9737
|
lowerer.unsupported("SC1030", list, "'var' loop bindings in 'for await' (use const)");
|
|
8698
|
-
const decl = list.declarations[0]; // the grammar allows exactly one
|
|
9738
|
+
const decl = list.declarations.nodes[0]; // the grammar allows exactly one
|
|
8699
9739
|
if (!ts.isIdentifier(decl.name))
|
|
8700
9740
|
lowerer.unsupported("SC1031", decl.name);
|
|
8701
9741
|
const loc = locOf(stmt);
|
|
@@ -8781,4 +9821,155 @@ export function lowerForStatement(lowerer, stmt) {
|
|
|
8781
9821
|
lowerer.scopes.pop();
|
|
8782
9822
|
}
|
|
8783
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
|
+
}
|
|
8784
9975
|
//# sourceMappingURL=lower-stmts.js.map
|