@scriptc/compiler 0.3.6 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +717 -55
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +20 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +9 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/link-plan-core.d.ts +2 -0
- package/dist/backend/link-plan-core.js +2 -0
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan.d.ts +1 -0
- package/dist/backend/link-plan.js +1 -0
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.js +3 -1
- package/dist/backend/llvm/array-search.js.map +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +38 -1
- package/dist/backend/llvm/classes.js +185 -35
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +79 -17
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +21 -3
- package/dist/backend/llvm/common.js +51 -3
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +15 -4
- package/dist/backend/llvm/dense-array-access.js +125 -44
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +63 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +37 -4
- package/dist/backend/llvm/dyn.js +354 -183
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1193 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1557 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +59 -0
- package/dist/backend/llvm/emit-statements.js +2041 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +566 -291
- package/dist/backend/llvm/emitter.js +728 -4671
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +87 -56
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +45 -24
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +113 -66
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +124 -28
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +57 -2
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +65 -27
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.js +3 -3
- package/dist/backend/llvm/integer-clones.js.map +1 -1
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/js-ic.d.ts +18 -0
- package/dist/backend/llvm/js-ic.js +712 -0
- package/dist/backend/llvm/js-ic.js.map +1 -0
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +616 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +189 -23
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +42 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +56 -22
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +94 -53
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +209 -6
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +43 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +42 -33
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.d.ts +20 -4
- package/dist/backend/llvm/map-number-lookup.js +45 -9
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +215 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +64 -6
- package/dist/backend/llvm/nullable-unions.js +103 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +7 -0
- package/dist/backend/llvm/publish.js +50 -19
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +12 -1
- package/dist/backend/llvm/record-results.js +64 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +142 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +10 -7
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +8 -2
- package/dist/backend/llvm/regions.test.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +74 -45
- package/dist/backend/llvm/shapes.js +289 -28
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +20 -1
- package/dist/backend/llvm/speculative-integers.js +94 -6
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.test.js +55 -1
- package/dist/backend/llvm/speculative-integers.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +1 -1
- package/dist/backend/llvm/string-reads.js +4 -4
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +111 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +12 -0
- package/dist/backend/mangle.js +18 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +4 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +57 -0
- package/dist/backend/native/executable.js +211 -139
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +2 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +6 -0
- package/dist/backend/native-codegen.js +19 -0
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +27 -0
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +48 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-profile.d.ts +32 -0
- package/dist/backend/native-profile.js +39 -0
- package/dist/backend/native-profile.js.map +1 -0
- package/dist/backend/native-profile.test.d.ts +1 -0
- package/dist/backend/native-profile.test.js +58 -0
- package/dist/backend/native-profile.test.js.map +1 -0
- package/dist/backend/native-tools.d.ts +14 -0
- package/dist/backend/native-tools.js +13 -0
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +13 -1
- package/dist/backend/runtime-pack-core.js +14 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +9 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +9 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +15 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +8 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +106 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +3 -0
- package/dist/cli/output-options.d.ts +2 -0
- package/dist/cli/output-options.js +9 -0
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/usage.d.ts +21 -1
- package/dist/cli/usage.js +43 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +22 -0
- package/dist/contracts/check.js +25 -8
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -6
- package/dist/diagnostics/diagnostic.js +29 -21
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +27 -0
- package/dist/executable/executable-cache.js +19 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +12 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/arguments-usage.d.ts +8 -0
- package/dist/frontend/arguments-usage.js +98 -0
- package/dist/frontend/arguments-usage.js.map +1 -1
- package/dist/frontend/arguments-usage.test.d.ts +1 -0
- package/dist/frontend/arguments-usage.test.js +32 -0
- package/dist/frontend/arguments-usage.test.js.map +1 -0
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/builtin-package-aliases.d.ts +24 -0
- package/dist/frontend/builtin-package-aliases.js +133 -0
- package/dist/frontend/builtin-package-aliases.js.map +1 -0
- package/dist/frontend/builtin-package-aliases.test.d.ts +1 -0
- package/dist/frontend/builtin-package-aliases.test.js +48 -0
- package/dist/frontend/builtin-package-aliases.test.js.map +1 -0
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/dts-paths.d.ts +4 -0
- package/dist/frontend/dts-paths.js +9 -1
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +63 -5
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +31 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +205 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +17 -5
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +107 -44
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +22 -0
- package/dist/frontend/lowering/builtins/crypto.js +215 -38
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/ecdh.d.ts +10 -0
- package/dist/frontend/lowering/builtins/ecdh.js +208 -0
- package/dist/frontend/lowering/builtins/ecdh.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +169 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +77 -77
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +284 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +55 -44
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +41 -1
- package/dist/frontend/lowering/builtins/process.js +505 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +40 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +338 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
- package/dist/frontend/lowering/builtins/readline.js +136 -39
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +42 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +79 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/typed-array-members.d.ts +7 -0
- package/dist/frontend/lowering/builtins/typed-array-members.js +160 -0
- package/dist/frontend/lowering/builtins/typed-array-members.js.map +1 -0
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
- package/dist/frontend/lowering/builtins/workers.js +193 -8
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +23 -1
- package/dist/frontend/lowering/call-signatures.js +379 -55
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +561 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1124 -90
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +10 -0
- package/dist/frontend/lowering/class-protocols.js +76 -45
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +86 -19
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +264 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/fresh-spread.d.ts +13 -0
- package/dist/frontend/lowering/coercions/fresh-spread.js +95 -0
- package/dist/frontend/lowering/coercions/fresh-spread.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +239 -68
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +17 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +287 -118
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +58 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
- package/dist/frontend/lowering/containers/array-from-async.js +159 -14
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +94 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +9 -0
- package/dist/frontend/lowering/containers/bytes.js +649 -113
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +126 -28
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +455 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +30 -10
- package/dist/frontend/lowering/cycle-initialization.js +191 -35
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +62 -125
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +723 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2557 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1804 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +52 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +307 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1337 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +301 -86
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -2
- package/dist/frontend/lowering/expressions/optional-chains.js +103 -17
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +115 -0
- package/dist/frontend/lowering/expressions/property-access.js +3787 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1724 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +551 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-delegation.d.ts +8 -0
- package/dist/frontend/lowering/generator-delegation.js +191 -1
- package/dist/frontend/lowering/generator-delegation.js.map +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +43 -0
- package/dist/frontend/lowering/generic-functions.js +593 -118
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/handle-properties.d.ts +24 -0
- package/dist/frontend/lowering/handle-properties.js +281 -0
- package/dist/frontend/lowering/handle-properties.js.map +1 -0
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterable-spelling.d.ts +7 -0
- package/dist/frontend/lowering/iterable-spelling.js +38 -0
- package/dist/frontend/lowering/iterable-spelling.js.map +1 -0
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.d.ts +33 -15
- package/dist/frontend/lowering/lower-array-sort.js +117 -21
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.test.js +93 -14
- package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +33 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1404 -448
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +54 -3
- package/dist/frontend/lowering/lower-classes.js +1529 -472
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +241 -21
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +258 -70
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1509 -12486
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +72 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +39 -20
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +900 -107
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +8 -1
- package/dist/frontend/lowering/lower-mock.js +185 -18
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +11 -3
- package/dist/frontend/lowering/lower-modules.js +445 -94
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +65 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +514 -101
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +179 -118
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +30 -7
- package/dist/frontend/lowering/lower-stmts.js +1950 -433
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +398 -56
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +437 -62
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +96 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +424 -27
- package/dist/frontend/lowering/lowerer.js +2062 -310
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/rebindable-functions.d.ts +8 -0
- package/dist/frontend/lowering/rebindable-functions.js +54 -0
- package/dist/frontend/lowering/rebindable-functions.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/static-typeof.d.ts +26 -0
- package/dist/frontend/lowering/static-typeof.js +133 -0
- package/dist/frontend/lowering/static-typeof.js.map +1 -0
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +13 -12
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +12 -3
- package/dist/frontend/lowering/surfaces.js +282 -45
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thenables.d.ts +16 -0
- package/dist/frontend/lowering/thenables.js +124 -0
- package/dist/frontend/lowering/thenables.js.map +1 -0
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.js +13 -6
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-builtin-aliases.d.ts +8 -0
- package/dist/frontend/npm-static-builtin-aliases.js +65 -0
- package/dist/frontend/npm-static-builtin-aliases.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.d.ts +58 -0
- package/dist/frontend/npm-static-bundled-chunks.js +981 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +399 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +988 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +336 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-enum-iife.d.ts +6 -0
- package/dist/frontend/npm-static-enum-iife.js +280 -0
- package/dist/frontend/npm-static-enum-iife.js.map +1 -0
- package/dist/frontend/npm-static-enum-iife.test.d.ts +1 -0
- package/dist/frontend/npm-static-enum-iife.test.js +116 -0
- package/dist/frontend/npm-static-enum-iife.test.js.map +1 -0
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +25 -1
- package/dist/frontend/npm-static.js +212 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/npm.js +13 -0
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/package-shims.d.ts +47 -0
- package/dist/frontend/package-shims.js +300 -0
- package/dist/frontend/package-shims.js.map +1 -0
- package/dist/frontend/pipeline.js +230 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +100 -2
- package/dist/frontend/program.js +1627 -262
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +49 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +26 -1
- package/dist/frontend/services.js +59 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +10 -5
- package/dist/frontend/ts7/program-host.js +19 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +57 -24
- package/dist/frontend/ts7/semantic-model.js +114 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +30 -15
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2735 -723
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +87 -8
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +31 -0
- package/dist/ir/array-length-stability.js +249 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +134 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +116 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +540 -29
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +9 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +97 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/integer-loop-facts.d.ts +7 -0
- package/dist/ir/integer-loop-facts.js +103 -17
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +13 -1
- package/dist/ir/integer-ranges.js +125 -26
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +273 -2
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +221 -58
- package/dist/ir/ir.js +127 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/js-ic.d.ts +52 -0
- package/dist/ir/js-ic.js +199 -0
- package/dist/ir/js-ic.js.map +1 -0
- package/dist/ir/js-ic.test.d.ts +1 -0
- package/dist/ir/js-ic.test.js +148 -0
- package/dist/ir/js-ic.test.js.map +1 -0
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +399 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +183 -33
- package/dist/ir/runtime-features.js +795 -422
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +201 -150
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +196 -76
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +41 -11
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +14 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +22 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +35 -6
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/executable-cache.js +3 -0
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/prepare.js +10 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +19 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +22 -20
- package/shims/fs-extra/core/api.ts +1192 -0
- package/shims/fs-extra/index.ts +9 -0
- package/shims/undici/core/agent.ts +163 -0
- package/shims/undici/core/api.ts +93 -0
- package/shims/undici/core/client.ts +1304 -0
- package/shims/undici/core/connector.ts +157 -0
- package/shims/undici/core/diagnostics-types.ts +68 -0
- package/shims/undici/core/diagnostics.ts +16 -0
- package/shims/undici/core/dispatcher.ts +574 -0
- package/shims/undici/core/errors-v5.ts +22 -0
- package/shims/undici/core/errors-v7.ts +25 -0
- package/shims/undici/core/errors.ts +255 -0
- package/shims/undici/core/fetch.ts +635 -0
- package/shims/undici/core/pool.ts +280 -0
- package/shims/undici/core/readable.ts +268 -0
- package/shims/undici/core/request.ts +313 -0
- package/shims/undici/core/timers.ts +80 -0
- package/shims/undici/core/types.ts +167 -0
- package/shims/undici/core/util.ts +67 -0
- package/shims/undici/v5.ts +119 -0
- package/shims/undici/v7.ts +119 -0
- package/surface-manifest.json +304 -22
|
@@ -1,18 +1,36 @@
|
|
|
1
|
+
import { onlyForwarded } from "./typed-arguments.js";
|
|
2
|
+
import { needsGeneralNodeStreams, noteUntypedStreamFlow, stdioIntoGeneralStream, } from "./general-streams.js";
|
|
3
|
+
import { extendAssertedRecordMembers } from "./assertion-members.js";
|
|
4
|
+
import { jsDynamicDeclarations } from "./js-dynamic-objects.js";
|
|
5
|
+
import { isJsSourceFileName } from "../tsc-codes.js";
|
|
6
|
+
import { builtinClassKind, builtinClassValue, builtinMemberClassKind, } from "./builtins/builtin-class-dyn.js";
|
|
1
7
|
import { lifetimeRegionType, lowerLifetimeRegionCall, lowerLifetimeRegionNew, } from "./lifetime-regions.js";
|
|
2
8
|
import { internTableType, lowerInternTableCall, lowerInternTableNew } from "./intern-tables.js";
|
|
9
|
+
import { lowerThreadSlotsCall, lowerThreadSlotsNew, threadSlotsType } from "./thread-slots.js";
|
|
3
10
|
import { isExperimentalDeclarationFile } from "../experimental-import.js";
|
|
4
11
|
import { checkCycleBindingAccesses, refuseUncheckedCycleReads, } from "./cycle-initialization.js";
|
|
12
|
+
import { isJsonRequireDecl } from "./json-require.js";
|
|
13
|
+
import { checkRequireBindingAccesses, } from "./require-initialization.js";
|
|
5
14
|
import { identityPreservingWidening } from "./coercions/identity.js";
|
|
6
15
|
import { scanDivergences } from "./divergences.js";
|
|
16
|
+
import { applyKeyOrderWitnesses, KeyOrderNotes } from "./key-order-witness.js";
|
|
7
17
|
import { checkedClassAssertion } from "./class-assertions.js";
|
|
8
18
|
import { narrowStoredClassValue, narrowGenericClassValue } from "./class-unions.js";
|
|
9
|
-
import { isOptionalProcessStreamProperty } from "./builtins/process.js";
|
|
19
|
+
import { isOptionalProcessStreamProperty, isOptionalProcessVersionsRead, } from "./builtins/process.js";
|
|
10
20
|
import { isSettledIteratorValueRead } from "./lower-generators.js";
|
|
21
|
+
import { isRebindableFunctionSymbol } from "./rebindable-functions.js";
|
|
11
22
|
import { concreteCollectionNarrow } from "./collection-narrowing.js";
|
|
12
23
|
import { lowerWorkerMetadata } from "./builtins/workers.js";
|
|
13
24
|
import { fenceStaticBlobMember, lowerBlobNew, lowerStaticBlobCall } from "./builtins/blob.js";
|
|
25
|
+
import { lowerWebAssemblyCall, lowerWebAssemblyNew, refuseWebAssemblyUse, } from "./builtins/webassembly.js";
|
|
26
|
+
import { discoverWasmModules } from "../../wasm/discover.js";
|
|
27
|
+
import { encodeBase64 } from "../../wasm/base64.js";
|
|
28
|
+
import { resolveRequireRuntime } from "../runtime-resolve.js";
|
|
14
29
|
import { lowerKeyObjectCall } from "./builtins/key-object.js";
|
|
30
|
+
import { isEcdhType, lowerEcdhCall } from "./builtins/ecdh.js";
|
|
31
|
+
import { fenceWebCryptoMember, lowerWebCryptoCall } from "./builtins/webcrypto.js";
|
|
15
32
|
import { hashStreamOf } from "./builtins/hash-stream.js";
|
|
33
|
+
import { lowerNetAddressCall, lowerNetAddressNew } from "./builtins/net-address.js";
|
|
16
34
|
import { dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../ir/build.js";
|
|
17
35
|
import { iteratorSlotAdapter } from "./iterator-adapters.js";
|
|
18
36
|
import { lowerBuiltinCall } from "./builtin-calls.js";
|
|
@@ -20,7 +38,7 @@ import { CoercionState } from "./coercions/state.js";
|
|
|
20
38
|
import { widthLiftPlan, unitOnlyElem, recordWidthPlan, describeRecordWidthBlocker, objToRecordPlan, recordToClassPlan, } from "./coercions/structural-plans.js";
|
|
21
39
|
import { widthCoerce, applyWidthLift, unionRecordWidthHelper, recordWidthHelper, tupleArrayWidthHelper, emptyArrayLiftHelper, arrayWidthHelper, objRecordWidthHelper, recordClassWidthHelper, classStaticsProjection, } from "./coercions/structural.js";
|
|
22
40
|
import { funcReturnWidthAdapter, coercibleValue, cleanFuncAdaptable, funcCoerceAdapter, spawnResFnAdapterPlan, spawnResFnAdapter, } from "./coercions/function-adapters.js";
|
|
23
|
-
import { unionRetagMappable, narrowedRetagHelper, strandedUnitTrap, strandedCoercionTrap, recordUnionWrapHelper, unionRetagHelper, narrowedArmHelper, checkedNarrowCall, checkedNarrowOperand, deferredReadHelper, } from "./coercions/unions.js";
|
|
41
|
+
import { unionRetagMappable, narrowedRetagHelper, uninhabitedArmRetagHelper, strandedUnitTrap, strandedCoercionTrap, recordUnionRouteHelper, recordUnionWrapHelper, unionRetagHelper, narrowedArmHelper, checkedNarrowCall, checkedNarrowOperand, deferredReadHelper, } from "./coercions/unions.js";
|
|
24
42
|
import { lowerUtilTypeValue, pathModuleValue, utilTypesModuleValue, } from "./lower-builtin-values.js";
|
|
25
43
|
import { devirtualizeVirtualCalls } from "./devirtualize.js";
|
|
26
44
|
import { foldRegexSpanReads } from "./regex-span-reads.js";
|
|
@@ -42,11 +60,18 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
42
60
|
import { defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "./optional-arguments.js";
|
|
43
61
|
import {} from "./class-protocol-dispatch.js";
|
|
44
62
|
import { ClassDynamicDispatch, trackClassFieldCreation } from "./class-dynamic-dispatch.js";
|
|
63
|
+
import { guardClassAttributeWrites } from "./class-attributes.js";
|
|
64
|
+
import { applyHandleProperties } from "./handle-properties.js";
|
|
45
65
|
import { ClassProtocols } from "./class-protocols.js";
|
|
46
66
|
import { earlyReadVarSymbols } from "./var-hoisting.js";
|
|
47
67
|
import { recordTextCodecClass } from "../../ir/ir.js";
|
|
68
|
+
import { assignLegacyTiers } from "../../ir/tiers.js";
|
|
69
|
+
import { promoteJsvals } from "../../ir/jsval.js";
|
|
70
|
+
import { analyzeTiers, dynamicStatementCount, } from "../tier-analysis.js";
|
|
48
71
|
import { DeferredModuleInitializers } from "./deferred-module-initializers.js";
|
|
49
72
|
import { finalizeClassMethodValues } from "./class-method-values.js";
|
|
73
|
+
import { finalizePrivateBrands } from "./private-brands.js";
|
|
74
|
+
import { tableKeyFieldType } from "./symbol-fields.js";
|
|
50
75
|
export { newFnCtx } from "./function-context.js";
|
|
51
76
|
/* AST + checker → IR.
|
|
52
77
|
*
|
|
@@ -66,22 +91,28 @@ import { resolve } from "node:path";
|
|
|
66
91
|
import { bindingSource } from "../binding-source.js";
|
|
67
92
|
import { tsgoPath } from "../dts-paths.js";
|
|
68
93
|
import * as ts from "../ts7/adapter.js";
|
|
94
|
+
import { isBundledShimForwarder } from "../package-shims.js";
|
|
95
|
+
import { erasedTypeOnlyImport } from "../type-only-imports.js";
|
|
69
96
|
import { literalValues } from "../literal-values.js";
|
|
70
97
|
import { discriminantOwners, literalUnionArm } from "../union-discriminants.js";
|
|
71
98
|
import { unsupportedAnyOperationDiag, blockedBindingUseDiag, checkerPanicDiag, componentTypeDiag, isCheckerPanic, genericSignatureTypeDiag, indexSignatureTypeDiag, intersectionTypeDiag, noLoweringDiag, overloadedSignatureTypeDiag, recordShapeMismatchDiag, unsupportedNativeApiDiag, unsupportedPackageValueDiag, unionMismatchDiag, UNSUPPORTED, unsupportedDiag, unsupportedTypeDiag, } from "../../diagnostics/diagnostic.js";
|
|
72
99
|
import { arrayOf, BOOL, canAdaptDynFuncTo, canDynCheckTo, canConvertToDyn, DYN, DYN_HANDLE_KINDS, F64, isDynTypedRefType, isJsonSafeType, isJsonStringifySafeType, isPrimitiveCollectionKey, isSupportedMapKey, isSupportedMapValue, isUndefinedArmedUnion, isUnitType, NULL_T, RUNTIME_ERROR_CLASSES, STRING, typeEquals, UNDEFINED_T, VOID, } from "../../ir/ir.js";
|
|
73
100
|
import { provenanceActive } from "../provenance-registry.js";
|
|
74
|
-
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
75
|
-
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, FETCH_AMBIENT_TYPES, isOsConstantsSymbol, isUnitOnlyTsType, isWorkerHandleType, jsOpenObjectType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
101
|
+
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCheckedJsSourceFile, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
102
|
+
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, erasedOverloadMemberType, formatIrType, FETCH_AMBIENT_TYPES, isOsConstantsSymbol, isOverloadedCallableMemberType, isUnitOnlyTsType, isWorkerHandleType, isFetchHandleType, jsOpenObjectType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
76
103
|
import { builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalNameOf, stdlibGlobalMember, nodeTypesOnlySymbol, } from "./surfaces.js";
|
|
104
|
+
import { builtinClassAliasOf, runtimeClassValueOfType, } from "./builtins/class-values.js";
|
|
77
105
|
import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules, appendForkModules, appendWorkerModules, } from "./lower-modules.js";
|
|
78
|
-
import { prepareCjsModuleGraph } from "./lower-node-module.js";
|
|
106
|
+
import { prepareCjsModuleGraph, usesCjsTopLevelThis } from "./lower-node-module.js";
|
|
107
|
+
import { cjsNamespaceModule, cjsWholeExportValueOf, inlineNamespaceRequireOf, inlineProgramRequireOf, } from "./cjs-inline-require.js";
|
|
108
|
+
import { tscInteropModuleOf } from "./cjs-tsc-interop.js";
|
|
109
|
+
import { usesCjsExportsIdentity } from "./cjs-exports-object.js";
|
|
79
110
|
import { registerBuiltinEventTargetClasses } from "./lower-event-target.js";
|
|
80
|
-
import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorConstructorArgs, lowerNew, accessorCall, } from "./lower-classes.js";
|
|
111
|
+
import { registerBuiltinErrorClasses, defineClassValueConstruct, runtimeClassConstructs, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorConstructorArgs, lowerNew, accessorCall, } from "./lower-classes.js";
|
|
81
112
|
import { mixinCallClassInfoOf, mixinIntersectionInstanceType, } from "./lower-mixins.js";
|
|
82
113
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
83
114
|
import { funcTypeFromParamShapes, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, requireExactArityValue, collectSignature, collectSignatureInner, lambdaSignature, } from "./call-signatures.js";
|
|
84
|
-
import { implicitAnyParamSymbolsOf, implicitMonoFile, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, } from "./generic-functions.js";
|
|
115
|
+
import { implicitAnyParamSymbolsOf, implicitLocalFnNodeOf, implicitMonoFile, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, genericLocalClassBinding, } from "./generic-functions.js";
|
|
85
116
|
import { bindingNeverReassigned } from "./binding-analysis.js";
|
|
86
117
|
import { bodyReadsArguments } from "../arguments-usage.js";
|
|
87
118
|
import { completeArgs, wrappedUndefined, undefinedArgFor } from "./call-arguments.js";
|
|
@@ -96,7 +127,7 @@ import { lowerEnvToPairsHelper } from "./containers/indexed-objects.js";
|
|
|
96
127
|
import { lowerBufferStaticCall, lowerBytesMethodCall, lowerBytesNew } from "./containers/bytes.js";
|
|
97
128
|
import { lowerRegexMethodCall, lowerStringMethodCall } from "./containers/string-and-regexp.js";
|
|
98
129
|
import { lowerEmitOverrideSpec, } from "./lower-event-emitter.js";
|
|
99
|
-
import { builtinImportOf, createRequireProgramModuleOf, createRequireSpecOf, fencedBuiltinImportOf, } from "./builtins/module-bindings.js";
|
|
130
|
+
import { builtinImportOf, createRequireProgramModuleOf, createRequireSpecOf, fencedBuiltinImportOf, esmImportBindingKind, } from "./builtins/module-bindings.js";
|
|
100
131
|
import { stripTypeCasts } from "./builtins/arguments.js";
|
|
101
132
|
import { lowerBuiltinModuleCall } from "./builtins/module-calls.js";
|
|
102
133
|
import { lowerTimersPromisesSetInterval, lowerTimeoutMethodCall } from "./builtins/timers.js";
|
|
@@ -115,13 +146,14 @@ import { lowerExecFileAsyncCall } from "./builtins/child-process-async.js";
|
|
|
115
146
|
import { lowerStringDecoderMethodCall, lowerTextCodecCall } from "./builtins/text-codecs.js";
|
|
116
147
|
import { lowerReadlineMethodCall } from "./builtins/readline.js";
|
|
117
148
|
import { lowerDiagnosticsChannelMethodCall, lowerDiagnosticsChannelProperty, lowerAsyncLocalStorageMethodCall, lowerTracingChannelMethodCall, lowerTracingChannelProperty, } from "./builtins/async-context.js";
|
|
149
|
+
import { lowerDisposableStackNew } from "./builtins/disposable-stack.js";
|
|
118
150
|
import { lowerErrorCodeProperty } from "./builtins/errors.js";
|
|
119
151
|
import { lowerProcessProperty, lowerProcessMethodCall, lowerProcessOptionalMethodCall, lowerProcessStreamProperty, } from "./builtins/process.js";
|
|
120
152
|
import { consoleCallMember, consoleMethodMember, isConsoleLog, } from "./builtins/console.js";
|
|
121
153
|
import { lowerConsoleNew } from "./lower-console.js";
|
|
122
154
|
import { lowerNumberStaticCall, lowerNumberStaticProperty } from "./builtins/numbers.js";
|
|
123
|
-
import { lowerDateCall } from "./builtins/dates.js";
|
|
124
|
-
import { lowerFsConstantsProperty, lowerBuiltinConstantsProperty, builtinConstantBindingOf, builtinConstantsDestructureDecl, } from "./builtins/constants.js";
|
|
155
|
+
import { dateJsonType, isDateJsonSource, lowerDateCall } from "./builtins/dates.js";
|
|
156
|
+
import { fsConstantMemberRead, fsConstantsObject, lowerFsConstantsProperty, lowerBuiltinConstantsProperty, builtinConstantBindingOf, builtinConstantsDestructureDecl, } from "./builtins/constants.js";
|
|
125
157
|
import { lowerStringStaticCall, lowerStringLastIndexOfCall } from "./builtins/strings.js";
|
|
126
158
|
import { lowerPromiseStaticCall } from "./builtins/promises.js";
|
|
127
159
|
import { fenceFetchObjectAssignment, fenceFetchObjectBinding, fenceStaticAbortControllerMemberRead, fenceStaticHeadersIteration, fenceStaticHeadersMember, fenceStaticReadableStreamMember, fenceStaticResponseMember, fenceUnsupportedFetchConstructorMember, refuseUnsupportedApi, stdlibGlobalFnOf, lowerAbortControllerNew, lowerEventTargetNew, lowerLiveWebValue, lowerDynamicImportCall, lowerFetchCall, lowerFetchElementMethodCall, lowerResponseNew, lowerFetchWebNew, lowerStaticFetchCompanionCall, lowerStaticAbortControllerCall, lowerStaticAbortSignalListenerCall, lowerStaticReadableStreamCancelCall, lowerStaticReadableStreamControllerCall, lowerStaticReadableStreamNew, lowerStaticReadableStreamReaderCall, lowerStaticResponseCall, lowerStdlibMethodCall, lowerMathProperty, npmPackageOf, npmMemberFence, npmPackageOfSymbol, } from "./lower-stdlib.js";
|
|
@@ -132,14 +164,15 @@ import { lowerAssertModuleCall, lowerAssertDirectCall } from "./lower-assert.js"
|
|
|
132
164
|
import { lowerUtilModuleCall } from "./lower-inspect.js";
|
|
133
165
|
import { lowerSystemErrorMapValue } from "./lower-system-errors.js";
|
|
134
166
|
import { lowerComptime, comptimeBakeable, rejectComptimeCaptures, comptimeValueToIr, } from "./lower-comptime.js";
|
|
135
|
-
import { lowerStmts, hasJsTypeAnnotation, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement, } from "./lower-stmts.js";
|
|
136
|
-
import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf, } from "./lower-exprs.js";
|
|
167
|
+
import { lowerStmts, hasJsTypeAnnotation, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement, matchGroupsPatternSource, isGuardedRecordRead, } from "./lower-stmts.js";
|
|
168
|
+
import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf, matchCallbackParamGroupsOf, } from "./lower-exprs.js";
|
|
137
169
|
import { finishOptionalChain, isOptionalChainTail, lowerOptionalChain, } from "./expressions/optional-chains.js";
|
|
138
170
|
import { foldedStringKeyOf, lowerDynObjectLiteral, lowerObjectLiteral, lowerShorthandValue, rejectThisInObjectMethod, } from "./expressions/object-literals.js";
|
|
139
171
|
import { lowerRecordFieldCall, lowerObjectMethodCall } from "./lower-calls.js";
|
|
140
172
|
import { fenceCrossBlockNsRef, nsPathPrefix } from "./lower-namespaces.js";
|
|
141
173
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
142
174
|
import { lowerTernary } from "./lower-exprs.js";
|
|
175
|
+
import { maybePromiseReturnStmt, maybePromiseUnionOf, promiseArmedUnionOf, } from "./maybe-promise.js";
|
|
143
176
|
/** Entry function name. '%' cannot appear in a TS identifier, so a user
|
|
144
177
|
* function can never collide with it (mangling is injective per prefix). */
|
|
145
178
|
export const ENTRY_NAME = "%main";
|
|
@@ -160,7 +193,7 @@ export function boundIdentifiersOf(name) {
|
|
|
160
193
|
if (ts.isIdentifier(name))
|
|
161
194
|
return [name];
|
|
162
195
|
const out = [];
|
|
163
|
-
for (const el of name.elements) {
|
|
196
|
+
for (const el of name.elements.nodes) {
|
|
164
197
|
// Elisions: OmittedExpression in 5.9.3, a NAMELESS BindingElement in 7
|
|
165
198
|
// (the parity battery's pinned finding 2) — both spell "no binding".
|
|
166
199
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
@@ -177,7 +210,7 @@ export function countBodyStatements(root) {
|
|
|
177
210
|
let n = 0;
|
|
178
211
|
const visit = (node) => {
|
|
179
212
|
if (ts.isBlock(node) || ts.isCaseClause(node) || ts.isDefaultClause(node)) {
|
|
180
|
-
n += node.statements.length;
|
|
213
|
+
n += node.statements.nodes.length;
|
|
181
214
|
}
|
|
182
215
|
else if ((ts.isIfStatement(node) ||
|
|
183
216
|
ts.isForStatement(node) ||
|
|
@@ -269,11 +302,15 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
269
302
|
cycleKeys.add(key);
|
|
270
303
|
extraModuleCycleDiags.push(unsupportedDiag("SC1016", { file: entry.fileName, start: 0, end: 0 }, `circular imports (${cycle}; ${reason})`));
|
|
271
304
|
};
|
|
305
|
+
// Inline require() calls closing a cycle inside the appended subgraphs
|
|
306
|
+
// join preflight's set (the same run-time refusal by name).
|
|
307
|
+
const inlineRequireCycleCalls = new Set(options.inlineRequireCycleCalls ?? []);
|
|
308
|
+
const graph = { edges: options.moduleEdges, inlineCycleCalls: inlineRequireCycleCalls };
|
|
272
309
|
for (let pass = 0; pass < 32; pass++) {
|
|
273
310
|
const before = moduleOrder.length;
|
|
274
|
-
appendDynamicImportModules(program, moduleOrder, onExtraCycle);
|
|
275
|
-
appendForkModules(program, moduleOrder, forkTargets, onExtraCycle);
|
|
276
|
-
appendWorkerModules(program, moduleOrder, workerTargets, onExtraCycle);
|
|
311
|
+
appendDynamicImportModules(program, moduleOrder, onExtraCycle, graph);
|
|
312
|
+
appendForkModules(program, moduleOrder, forkTargets, onExtraCycle, graph);
|
|
313
|
+
appendWorkerModules(program, moduleOrder, workerTargets, onExtraCycle, graph);
|
|
277
314
|
if (moduleOrder.length === before)
|
|
278
315
|
break;
|
|
279
316
|
if (pass === 31)
|
|
@@ -283,16 +320,20 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
283
320
|
const libraryCallbacks = options.libraryCallbacks ?? false;
|
|
284
321
|
const externalTypes = options.externalTypes ?? new Map();
|
|
285
322
|
const externalTypeSpecifiersByFile = options.externalTypeSpecifiersByFile ?? directExternalTypeSpecifiersByFile(externalTypes);
|
|
323
|
+
const tierMode = options.tierMode ?? "auto";
|
|
286
324
|
const validation = new Lowerer(program, entry, moduleOrder, {
|
|
287
325
|
frontendServices: options.frontendServices,
|
|
326
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
288
327
|
targetPlatform,
|
|
289
328
|
startupCrash,
|
|
329
|
+
inlineRequireCycleCalls,
|
|
290
330
|
ffiImports,
|
|
291
331
|
libraryCallbacks,
|
|
292
332
|
forkTargets,
|
|
293
333
|
workerTargets,
|
|
294
334
|
externalTypes,
|
|
295
335
|
externalTypeSpecifiersByFile,
|
|
336
|
+
tierMode,
|
|
296
337
|
});
|
|
297
338
|
const ffiValidation = validateFfiImports(validation);
|
|
298
339
|
timing("ffi-validate");
|
|
@@ -305,14 +346,17 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
305
346
|
? validation
|
|
306
347
|
: new Lowerer(program, entry, moduleOrder, {
|
|
307
348
|
frontendServices: options.frontendServices,
|
|
349
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
308
350
|
targetPlatform,
|
|
309
351
|
startupCrash,
|
|
352
|
+
inlineRequireCycleCalls,
|
|
310
353
|
ffiImports,
|
|
311
354
|
libraryCallbacks,
|
|
312
355
|
forkTargets,
|
|
313
356
|
workerTargets,
|
|
314
357
|
externalTypes,
|
|
315
358
|
externalTypeSpecifiersByFile,
|
|
359
|
+
tierMode,
|
|
316
360
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
317
361
|
});
|
|
318
362
|
for (const d of extraModuleCycleDiags)
|
|
@@ -320,10 +364,55 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
320
364
|
for (const d of ffiValidation.diagnostics)
|
|
321
365
|
reachableEmit.pushDiag(d);
|
|
322
366
|
const emitted = reachableEmit.emitReachable(options.libRoots);
|
|
323
|
-
|
|
367
|
+
let { reachable } = emitted;
|
|
324
368
|
let result = emitted.result;
|
|
325
369
|
let resultLowerer = reachableEmit;
|
|
326
370
|
timing("reachable-emit", { reachable: reachable.size });
|
|
371
|
+
// The general stream representation (TypeMapperCtx.generalNodeStreams)
|
|
372
|
+
// is a per-program decision: only a program whose reachable code moved
|
|
373
|
+
// a general stream into a stdio-represented stream slot lowers again
|
|
374
|
+
// with it. Every other program keeps the single pass above unchanged.
|
|
375
|
+
const generalNodeStreams = reachableEmit.requiresGeneralNodeStreams;
|
|
376
|
+
// Checked-dynamic stream slots (dyn-streams.ts) are a further per-program
|
|
377
|
+
// decision under the general representation: only a program that moves an
|
|
378
|
+
// untyped value into a stream slot lowers again with them.
|
|
379
|
+
let dynNodeStreams = reachableEmit.requiresDynNodeStreams;
|
|
380
|
+
const streamPass = (dyn) => {
|
|
381
|
+
const general = new Lowerer(program, entry, moduleOrder, {
|
|
382
|
+
frontendServices: options.frontendServices,
|
|
383
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
384
|
+
targetPlatform,
|
|
385
|
+
startupCrash,
|
|
386
|
+
inlineRequireCycleCalls,
|
|
387
|
+
ffiImports,
|
|
388
|
+
libraryCallbacks,
|
|
389
|
+
forkTargets,
|
|
390
|
+
workerTargets,
|
|
391
|
+
externalTypes,
|
|
392
|
+
externalTypeSpecifiersByFile,
|
|
393
|
+
tierMode,
|
|
394
|
+
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
395
|
+
generalNodeStreams: true,
|
|
396
|
+
...(dyn ? { dynNodeStreams: true } : {}),
|
|
397
|
+
});
|
|
398
|
+
for (const d of extraModuleCycleDiags)
|
|
399
|
+
general.pushDiag(d);
|
|
400
|
+
for (const d of ffiValidation.diagnostics)
|
|
401
|
+
general.pushDiag(d);
|
|
402
|
+
const generalEmitted = general.emitReachable(options.libRoots);
|
|
403
|
+
reachable = generalEmitted.reachable;
|
|
404
|
+
result = generalEmitted.result;
|
|
405
|
+
resultLowerer = general;
|
|
406
|
+
timing(dyn ? "dyn-streams-relower" : "general-streams-relower", { reachable: reachable.size });
|
|
407
|
+
return general;
|
|
408
|
+
};
|
|
409
|
+
if (generalNodeStreams) {
|
|
410
|
+
const general = streamPass(dynNodeStreams);
|
|
411
|
+
if (!dynNodeStreams && general.requiresDynNodeStreams) {
|
|
412
|
+
dynNodeStreams = true;
|
|
413
|
+
streamPass(true);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
327
416
|
// A generic class-rest support decision can depend on record metadata
|
|
328
417
|
// whose historical owner is discovered only while retained bodies lower.
|
|
329
418
|
// If the settled answer is a fence, rerun the ordinary reachable emit so
|
|
@@ -331,12 +420,16 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
331
420
|
// declarators stay unvisited, bindings block, cascades and stats match the
|
|
332
421
|
// historical compiler. This is a rare compatibility fallback; programs
|
|
333
422
|
// without such a settled fence retain checker-backed IR exactly once.
|
|
334
|
-
if (
|
|
423
|
+
if (resultLowerer.requiresHistoricalOrderRelower) {
|
|
335
424
|
const emit = new Lowerer(program, entry, moduleOrder, {
|
|
336
425
|
frontendServices: options.frontendServices,
|
|
426
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
427
|
+
...(generalNodeStreams ? { generalNodeStreams: true } : {}),
|
|
428
|
+
...(dynNodeStreams ? { dynNodeStreams: true } : {}),
|
|
337
429
|
reachable,
|
|
338
430
|
targetPlatform,
|
|
339
431
|
startupCrash,
|
|
432
|
+
inlineRequireCycleCalls,
|
|
340
433
|
ffiImports,
|
|
341
434
|
libraryCallbacks,
|
|
342
435
|
forkTargets,
|
|
@@ -344,6 +437,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
344
437
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
345
438
|
externalTypes,
|
|
346
439
|
externalTypeSpecifiersByFile,
|
|
440
|
+
tierMode,
|
|
347
441
|
});
|
|
348
442
|
for (const d of extraModuleCycleDiags)
|
|
349
443
|
emit.pushDiag(d);
|
|
@@ -392,13 +486,45 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
392
486
|
};
|
|
393
487
|
else if (contracts.count > 0)
|
|
394
488
|
result = { ...result, contracts };
|
|
489
|
+
const discoverModules = (onModule) => discoverWasmModules({
|
|
490
|
+
files: moduleOrder.includes(entry) ? moduleOrder : [...moduleOrder, entry],
|
|
491
|
+
entry: entry.fileName,
|
|
492
|
+
configured: options.wasmFiles ?? [],
|
|
493
|
+
resolveRequest: (fromFile, specifier) => {
|
|
494
|
+
const resolved = resolveRequireRuntime(fromFile, specifier, targetPlatform, undefined, options.frontendServices);
|
|
495
|
+
return resolved.ok ? resolved.value : null;
|
|
496
|
+
},
|
|
497
|
+
...(onModule === undefined ? {} : { onModule }),
|
|
498
|
+
});
|
|
499
|
+
// A program that uses the WebAssembly API carries every module the build
|
|
500
|
+
// can see and translate (wasm/translate.ts); the rest fail at run time
|
|
501
|
+
// with the CompileError for untranslated bytes.
|
|
502
|
+
if (result.module !== null && resultLowerer.usesWebAssembly) {
|
|
503
|
+
const bytesByHash = new Map();
|
|
504
|
+
const reports = discoverModules((sha256, bytes) => bytesByHash.set(sha256, bytes));
|
|
505
|
+
const wasmModules = [];
|
|
506
|
+
for (const report of reports) {
|
|
507
|
+
const bytes = bytesByHash.get(report.sha256);
|
|
508
|
+
if (report.status !== "valid" || bytes === undefined)
|
|
509
|
+
continue;
|
|
510
|
+
wasmModules.push({ sha256: report.sha256, bytes: encodeBase64(bytes) });
|
|
511
|
+
}
|
|
512
|
+
result.module.wasmModules = wasmModules;
|
|
513
|
+
if (resultLowerer.usesWasmCustomSections)
|
|
514
|
+
result.module.wasmCustomSections = true;
|
|
515
|
+
timing("wasm-discovery", { modules: wasmModules.length });
|
|
516
|
+
}
|
|
395
517
|
if (options.coverage !== true)
|
|
396
518
|
return result;
|
|
397
|
-
const
|
|
519
|
+
const remainderPass = (general, dyn = dynNodeStreams) => new Lowerer(program, entry, moduleOrder, {
|
|
398
520
|
frontendServices: options.frontendServices,
|
|
521
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
522
|
+
...(general ? { generalNodeStreams: true } : {}),
|
|
523
|
+
...(general && dyn ? { dynNodeStreams: true } : {}),
|
|
399
524
|
reachable,
|
|
400
525
|
remainder: true,
|
|
401
526
|
alreadyFlushed: resultLowerer.flushedSymbols,
|
|
527
|
+
inlineRequireCycleCalls,
|
|
402
528
|
targetPlatform,
|
|
403
529
|
ffiImports,
|
|
404
530
|
libraryCallbacks,
|
|
@@ -407,19 +533,58 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
407
533
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
408
534
|
externalTypes,
|
|
409
535
|
externalTypeSpecifiersByFile,
|
|
536
|
+
tierMode,
|
|
410
537
|
});
|
|
411
|
-
|
|
538
|
+
let remainder = remainderPass(generalNodeStreams);
|
|
539
|
+
let rem = remainder.run();
|
|
540
|
+
// Unreached code reports what it would compile to once reached: a
|
|
541
|
+
// stream flow there that needs the general representation lowers the
|
|
542
|
+
// remainder again with it, as reachable emit would.
|
|
543
|
+
if (!generalNodeStreams && remainder.requiresGeneralNodeStreams) {
|
|
544
|
+
remainder = remainderPass(true, remainder.requiresDynNodeStreams);
|
|
545
|
+
rem = remainder.run();
|
|
546
|
+
}
|
|
547
|
+
if (!dynNodeStreams && remainder.generalNodeStreams && remainder.requiresDynNodeStreams) {
|
|
548
|
+
remainder = remainderPass(true, true);
|
|
549
|
+
rem = remainder.run();
|
|
550
|
+
}
|
|
551
|
+
timing("coverage-remainder");
|
|
552
|
+
// Tiers (tier-analysis.ts): reached statements in dynamic-tier functions,
|
|
553
|
+
// and with tierReport the report-only demotion analysis.
|
|
554
|
+
const dynamicFunctions = resultLowerer.dynamicBodies;
|
|
555
|
+
const tiers = options.tierReport === undefined
|
|
556
|
+
? undefined
|
|
557
|
+
: analyzeTiers(program, {
|
|
558
|
+
mode: tierMode,
|
|
559
|
+
dynamicFunctions,
|
|
560
|
+
reached: [...options.tierReport.preflight, ...result.diagnostics],
|
|
561
|
+
deferred: result.runtimeFences,
|
|
562
|
+
unreached: [...rem.diagnostics, ...rem.runtimeFences],
|
|
563
|
+
});
|
|
564
|
+
// A dynamic function's own statements can include ones that failed.
|
|
565
|
+
const statementsDynamic = Math.min(tiers?.statementsDynamic ?? dynamicStatementCount(program, dynamicFunctions), result.stats.statementsTotal - result.stats.statementsFailed);
|
|
566
|
+
if (tiers !== undefined)
|
|
567
|
+
tiers.statementsDynamic = statementsDynamic;
|
|
568
|
+
timing("tier-analysis", { dynamic: dynamicFunctions.length });
|
|
412
569
|
// Unreached JS statements whose fences deferred to runtime count as
|
|
413
570
|
// failed statements in the remainder's stats, so their diagnostics must
|
|
414
571
|
// travel with them: a failed statement is never left unexplained.
|
|
415
|
-
|
|
572
|
+
const covered = {
|
|
416
573
|
...result,
|
|
574
|
+
stats: { ...result.stats, statementsDynamic },
|
|
417
575
|
unreached: {
|
|
418
576
|
diagnostics: rem.diagnostics,
|
|
419
577
|
stats: rem.stats,
|
|
420
578
|
...(rem.runtimeFences.length > 0 ? { runtimeFences: rem.runtimeFences } : {}),
|
|
421
579
|
},
|
|
422
580
|
};
|
|
581
|
+
if (tiers !== undefined)
|
|
582
|
+
covered.tiers = tiers;
|
|
583
|
+
const wasmModules = discoverModules();
|
|
584
|
+
timing("wasm-discovery", { modules: wasmModules.length });
|
|
585
|
+
if (wasmModules.length > 0)
|
|
586
|
+
covered.wasmModules = wasmModules;
|
|
587
|
+
return covered;
|
|
423
588
|
}
|
|
424
589
|
/** The native namespace type produced by a literal static import() of a
|
|
425
590
|
* compiled program module or supported Node builtin. This syntax-level
|
|
@@ -443,7 +608,7 @@ export function staticImportNamespaceType(lowerer, expr) {
|
|
|
443
608
|
}
|
|
444
609
|
if (!ts.isCallExpression(e) || e.expression.kind !== ts.SyntaxKind.ImportKeyword)
|
|
445
610
|
return null;
|
|
446
|
-
const arg = e.arguments[0];
|
|
611
|
+
const arg = e.arguments.nodes[0];
|
|
447
612
|
if (!arg || !ts.isStringLiteralLike(arg))
|
|
448
613
|
return null;
|
|
449
614
|
const builtin = canonicalBuiltinModule(arg.text);
|
|
@@ -451,9 +616,7 @@ export function staticImportNamespaceType(lowerer, expr) {
|
|
|
451
616
|
if (moduleId === null) {
|
|
452
617
|
const symbol = lowerer.checker.getSymbolAtLocation(arg);
|
|
453
618
|
const source = symbol &&
|
|
454
|
-
|
|
455
|
-
.declarationsOf(symbol)
|
|
456
|
-
.find((decl) => ts.isSourceFile(decl) && !decl.isDeclarationFile);
|
|
619
|
+
symbol.declarations.find((decl) => ts.isSourceFile(decl) && !decl.isDeclarationFile);
|
|
457
620
|
if (source &&
|
|
458
621
|
!source.fileName.endsWith(".cts") &&
|
|
459
622
|
!isCjsJsFile(source, lowerer.program) &&
|
|
@@ -487,7 +650,7 @@ export function uncheckedOverloadHandleCall(_lowerer, _expr) {
|
|
|
487
650
|
* `never` at the ROOT stays out (`for (const v of [])`'s loop var — the
|
|
488
651
|
* dead read the f64 mapping is FOR). */
|
|
489
652
|
export function neverTaintedJsType(lowerer, node, t) {
|
|
490
|
-
if (!isJsSourceFile(
|
|
653
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(node)))
|
|
491
654
|
return false;
|
|
492
655
|
const walk = (x, depth) => {
|
|
493
656
|
if (depth === 0)
|
|
@@ -514,7 +677,7 @@ export function ladderFenceExpr(lowerer, surface, node, hint) {
|
|
|
514
677
|
const loc = locOf(node);
|
|
515
678
|
const d = noLoweringDiag(surface, loc, hint);
|
|
516
679
|
lowerer.runtimeFences.push(d);
|
|
517
|
-
const sf =
|
|
680
|
+
const sf = ts.getSourceFileOfNode(node);
|
|
518
681
|
const pos = ts.getLineAndCharacterOfPosition(sf, loc.start);
|
|
519
682
|
return {
|
|
520
683
|
kind: "strLit",
|
|
@@ -526,7 +689,7 @@ export function ladderFenceExpr(lowerer, surface, node, hint) {
|
|
|
526
689
|
export function dynFallbackType(lowerer, node, t) {
|
|
527
690
|
if (t.flags & ts.TypeFlags.Void)
|
|
528
691
|
return null;
|
|
529
|
-
if (!isJsSourceFile(
|
|
692
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
530
693
|
if (t.flags & ts.TypeFlags.Any)
|
|
531
694
|
return DYN;
|
|
532
695
|
const symbol = t.getSymbol();
|
|
@@ -539,14 +702,15 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
539
702
|
((lowerer.checker.getTypeArguments(x)[0]?.flags ?? 0) &
|
|
540
703
|
ts.TypeFlags.Any) !==
|
|
541
704
|
0;
|
|
542
|
-
if (symbol
|
|
705
|
+
if (symbol !== undefined &&
|
|
706
|
+
ts.symbolName(symbol) === "Promise" &&
|
|
543
707
|
args[0] &&
|
|
544
708
|
(args[0].flags & ts.TypeFlags.Any || anyArray(args[0])))
|
|
545
|
-
return symbol
|
|
709
|
+
return ts.symbolName(symbol) === "Promise" && anyArray(args[0])
|
|
546
710
|
? { kind: "promise", inner: DYN }
|
|
547
711
|
: jsFallbackPromiseType(lowerer, t);
|
|
548
712
|
if (symbol &&
|
|
549
|
-
["Generator", "AsyncGenerator", "IterableIterator"].includes(symbol
|
|
713
|
+
["Generator", "AsyncGenerator", "IterableIterator"].includes(ts.symbolName(symbol)) &&
|
|
550
714
|
args.some((arg) => arg.flags & ts.TypeFlags.Any))
|
|
551
715
|
return jsFallbackGeneratorType(lowerer, t);
|
|
552
716
|
if (lowerer.checker.isArrayType(t) &&
|
|
@@ -566,19 +730,23 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
566
730
|
if (generator)
|
|
567
731
|
return generator;
|
|
568
732
|
const symbol = t.getSymbol();
|
|
569
|
-
if ((symbol
|
|
733
|
+
if (((symbol !== undefined && ts.symbolName(symbol) === "Map") ||
|
|
734
|
+
(symbol !== undefined && ts.symbolName(symbol) === "ReadonlyMap")) &&
|
|
570
735
|
lowerer.isStdlibSymbol(symbol)) {
|
|
571
736
|
const args = lowerer.checker.getTypeArguments(t);
|
|
572
737
|
if (args.length === 2) {
|
|
573
738
|
const key = lowerer.mapTypeOf(args[0]);
|
|
574
739
|
const value = lowerer.mapTypeOf(args[1]);
|
|
740
|
+
// Inferred JS function types keep the checked-dynamic slot (their
|
|
741
|
+
// closures carry JS arity, not a typed closure ABI).
|
|
575
742
|
return {
|
|
576
743
|
kind: "map",
|
|
577
744
|
key: key &&
|
|
745
|
+
key.kind !== "func" &&
|
|
578
746
|
isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined)
|
|
579
747
|
? key
|
|
580
748
|
: DYN,
|
|
581
|
-
value: value && isSupportedMapValue(value) ? value : DYN,
|
|
749
|
+
value: value && value.kind !== "func" && isSupportedMapValue(value) ? value : DYN,
|
|
582
750
|
};
|
|
583
751
|
}
|
|
584
752
|
}
|
|
@@ -647,7 +815,9 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
647
815
|
* has no fixed shape. The settled value crosses the checked native boundary. */
|
|
648
816
|
function jsFallbackPromiseType(lowerer, t) {
|
|
649
817
|
const symbol = t.getSymbol();
|
|
650
|
-
if (symbol
|
|
818
|
+
if (symbol === undefined ||
|
|
819
|
+
ts.symbolName(symbol) !== "Promise" ||
|
|
820
|
+
!lowerer.isStdlibSymbol(symbol))
|
|
651
821
|
return null;
|
|
652
822
|
const inner = lowerer.checker.getTypeArguments(t)[0];
|
|
653
823
|
return inner ? { kind: "promise", inner: lowerer.mapTypeOf(inner) ?? DYN } : null;
|
|
@@ -657,14 +827,14 @@ function jsFallbackPromiseType(lowerer, t) {
|
|
|
657
827
|
function jsFallbackGeneratorType(lowerer, t) {
|
|
658
828
|
const symbol = t.getSymbol();
|
|
659
829
|
if (!symbol ||
|
|
660
|
-
!["Generator", "AsyncGenerator", "IterableIterator"].includes(symbol
|
|
830
|
+
!["Generator", "AsyncGenerator", "IterableIterator"].includes(ts.symbolName(symbol)) ||
|
|
661
831
|
!lowerer.isStdlibSymbol(symbol))
|
|
662
832
|
return null;
|
|
663
833
|
const [yielded, returned, resumed] = lowerer.checker.getTypeArguments(t);
|
|
664
834
|
const unit = ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Never;
|
|
665
835
|
return {
|
|
666
836
|
kind: "generator",
|
|
667
|
-
...(symbol
|
|
837
|
+
...(ts.symbolName(symbol) === "AsyncGenerator" ? { async: true } : {}),
|
|
668
838
|
yieldT: yielded && yielded.flags & ts.TypeFlags.Never ? VOID : DYN,
|
|
669
839
|
retT: !returned || returned.flags & unit ? VOID : DYN,
|
|
670
840
|
nextT: !resumed || resumed.flags & unit ? UNDEFINED_T : DYN,
|
|
@@ -683,7 +853,7 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
683
853
|
// slot. JS inference reports the body type (`boolean` for
|
|
684
854
|
// `enabled = true`) rather than that call-site type, so recover the
|
|
685
855
|
// syntactic optionality from the parameter declaration.
|
|
686
|
-
const decl =
|
|
856
|
+
const decl = p.valueDeclaration;
|
|
687
857
|
mapped = jsOpenObjectType(decl, mapped, lowerer.shapes, lowerer.unions);
|
|
688
858
|
const optional = decl !== undefined &&
|
|
689
859
|
ts.isParameter(decl) &&
|
|
@@ -694,9 +864,9 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
694
864
|
return mapped;
|
|
695
865
|
});
|
|
696
866
|
const retT = lowerer.checker.getReturnTypeOfSignature(sig);
|
|
697
|
-
const sigDecl =
|
|
867
|
+
const sigDecl = sig.declaration;
|
|
698
868
|
const jsUnitReturn = sigDecl !== undefined &&
|
|
699
|
-
isJsSourceFile(
|
|
869
|
+
isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
|
|
700
870
|
(retT.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0;
|
|
701
871
|
const ret = jsUnitReturn
|
|
702
872
|
? DYN
|
|
@@ -720,20 +890,21 @@ function jsArgumentsFunctionType(lowerer, t) {
|
|
|
720
890
|
lowerer.checker.getConstructSignatures(t).length !== 0 ||
|
|
721
891
|
lowerer.checker.getPropertiesOfType(t).length !== 0)
|
|
722
892
|
return null;
|
|
723
|
-
const decl =
|
|
893
|
+
const decl = sigs[0].declaration;
|
|
724
894
|
if (decl === undefined ||
|
|
725
895
|
!(ts.isFunctionDeclaration(decl) ||
|
|
726
896
|
ts.isFunctionExpression(decl) ||
|
|
727
897
|
ts.isArrowFunction(decl)) ||
|
|
728
|
-
!isJsSourceFile(
|
|
898
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
729
899
|
return null;
|
|
730
|
-
const hasRest = decl.parameters.some((p) => p.dotDotDotToken !== undefined);
|
|
900
|
+
const hasRest = decl.parameters.nodes.some((p) => p.dotDotDotToken !== undefined);
|
|
731
901
|
if (!hasRest &&
|
|
732
902
|
(ts.isArrowFunction(decl) ||
|
|
733
903
|
!bodyReadsArguments(decl) ||
|
|
734
|
-
(decl.parameters.length > 0 &&
|
|
904
|
+
(decl.parameters.nodes.length > 0 &&
|
|
905
|
+
!isNodeEsmFile(ts.getSourceFileOfNode(decl), lowerer.program))))
|
|
735
906
|
return null;
|
|
736
|
-
const shapes = paramShapes(lowerer, decl.parameters);
|
|
907
|
+
const shapes = paramShapes(lowerer, decl.parameters.nodes);
|
|
737
908
|
const retType = lowerer.checker.getReturnTypeOfSignature(sigs[0]);
|
|
738
909
|
const ret = retType.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)
|
|
739
910
|
? DYN
|
|
@@ -755,15 +926,15 @@ function pureSingleCallSignatureOf(lowerer, t) {
|
|
|
755
926
|
lowerer.checker.getConstructSignatures(t).length === 0 &&
|
|
756
927
|
sigs[0].getTypeParameters().length === 0 &&
|
|
757
928
|
sigs[0].getParameters().every((p) => {
|
|
758
|
-
const pDecl =
|
|
929
|
+
const pDecl = p.valueDeclaration;
|
|
759
930
|
return !pDecl || !ts.isParameter(pDecl) || pDecl.dotDotDotToken === undefined;
|
|
760
931
|
}) &&
|
|
761
932
|
// A SYNTHESIZED rest param (tsc's `arguments` inference — no
|
|
762
933
|
// valueDeclaration to carry the dotDotDot): param-count mismatch
|
|
763
934
|
// against the signature's declaration; the whole value stays dyn.
|
|
764
935
|
(() => {
|
|
765
|
-
const sigDecl =
|
|
766
|
-
const declParams = sigDecl !== undefined && ts.isFunctionLike(sigDecl) ? sigDecl.parameters : undefined;
|
|
936
|
+
const sigDecl = sigs[0].declaration;
|
|
937
|
+
const declParams = sigDecl !== undefined && ts.isFunctionLike(sigDecl) ? sigDecl.parameters.nodes : undefined;
|
|
767
938
|
if (declParams !== undefined && declParams.length !== sigs[0].getParameters().length)
|
|
768
939
|
return false;
|
|
769
940
|
// tsgo never synthesizes the `arguments` pseudo-rest into the
|
|
@@ -818,7 +989,7 @@ export function jsFuncNameOf(node, lowerer) {
|
|
|
818
989
|
if (!symbol || seen.has(symbol))
|
|
819
990
|
break;
|
|
820
991
|
seen.add(symbol);
|
|
821
|
-
const declaration =
|
|
992
|
+
const declaration = symbol.valueDeclaration;
|
|
822
993
|
if (declaration && ts.isFunctionDeclaration(declaration)) {
|
|
823
994
|
n = declaration;
|
|
824
995
|
break;
|
|
@@ -871,6 +1042,25 @@ function panicSafe(query, fallback) {
|
|
|
871
1042
|
throw e;
|
|
872
1043
|
}
|
|
873
1044
|
}
|
|
1045
|
+
/** The function's class expressions lower once per implicit-any instance.
|
|
1046
|
+
* A function whose only implicit slots are destructured options and that
|
|
1047
|
+
* is bound to a variable the implicit-instance probe rejects runs as one
|
|
1048
|
+
* shared body, so its classes keep a single name. */
|
|
1049
|
+
function monomorphizedImplicit(lowerer, fn) {
|
|
1050
|
+
const slots = implicitAnyParamSymbolsOf(lowerer, fn);
|
|
1051
|
+
if (!slots)
|
|
1052
|
+
return false;
|
|
1053
|
+
if (slots.some((slot) => slot !== null))
|
|
1054
|
+
return true;
|
|
1055
|
+
let binding = fn.parent;
|
|
1056
|
+
while (binding && ts.isParenthesizedExpression(binding))
|
|
1057
|
+
binding = binding.parent;
|
|
1058
|
+
if ((ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) &&
|
|
1059
|
+
binding &&
|
|
1060
|
+
ts.isVariableDeclaration(binding))
|
|
1061
|
+
return implicitLocalFnNodeOf(lowerer, binding) !== null;
|
|
1062
|
+
return true;
|
|
1063
|
+
}
|
|
874
1064
|
export class Lowerer {
|
|
875
1065
|
program;
|
|
876
1066
|
entry;
|
|
@@ -879,6 +1069,12 @@ export class Lowerer {
|
|
|
879
1069
|
checker;
|
|
880
1070
|
diags = [];
|
|
881
1071
|
fnSigsBySymbol = new Map();
|
|
1072
|
+
/** Per file: whether it assigns `exports` and `module.exports`
|
|
1073
|
+
* (cjs-exports-object.ts). */
|
|
1074
|
+
cjsExportsAssignments = new Map();
|
|
1075
|
+
/** Inline require() calls whose module edge closes a require cycle
|
|
1076
|
+
* (LoadResult.inlineRequireCycleCalls). */
|
|
1077
|
+
inlineRequireCycleCalls;
|
|
882
1078
|
/** Immutable callable aliases and compiler-generated adapters. The map
|
|
883
1079
|
* is symbol-keyed, so shadowing and cross-module imports keep the same
|
|
884
1080
|
* exact binding discipline as globals/functions. */
|
|
@@ -902,17 +1098,23 @@ export class Lowerer {
|
|
|
902
1098
|
* NaN, which lower to plain doubles (see nan-coded-reads.ts). Settled by
|
|
903
1099
|
* analyzeRuntimeOptionalArrayReads before any body lowers. */
|
|
904
1100
|
nanCodedReads = null;
|
|
1101
|
+
/** Whether any implementation source spells `versions`
|
|
1102
|
+
* (programMentionsVersions in builtins/process.ts). */
|
|
1103
|
+
mentionsProcessVersions = undefined;
|
|
905
1104
|
stringIndexBoundsCache = null;
|
|
906
1105
|
/** Proofs that a string element read names an existing code unit. The
|
|
907
1106
|
* indexed-read analysis and expression lowering share one instance, so a
|
|
908
1107
|
* read's representation and its callers' signatures always agree. */
|
|
909
1108
|
get stringIndexBounds() {
|
|
910
|
-
this.stringIndexBoundsCache ??= new StringIndexBounds((node) => this.checker.getSymbolAtLocation(node) ?? null, (symbol) =>
|
|
1109
|
+
this.stringIndexBoundsCache ??= new StringIndexBounds((node) => this.checker.getSymbolAtLocation(node) ?? null, (symbol) => symbol.valueDeclaration, (node) => (this.typeOf(node).flags & ts.TypeFlags.StringLike) !== 0);
|
|
911
1110
|
return this.stringIndexBoundsCache;
|
|
912
1111
|
}
|
|
913
1112
|
/** Syntactic writes indexed once per JS scope. Symbol and RHS type
|
|
914
1113
|
* checks remain contextual to each binding probe. */
|
|
915
1114
|
jsBindingWritesByOwner = new Map();
|
|
1115
|
+
/** JavaScript function declarations their own module reassigns
|
|
1116
|
+
* (rebindable-functions.ts). */
|
|
1117
|
+
rebindableFunctions = new Set();
|
|
916
1118
|
/** TRAP bindings: declarations whose initializer provably throws before
|
|
917
1119
|
* producing a value (its chain roots at an ambient-undefined name —
|
|
918
1120
|
* ambientUndefVarRootOf). Module init unwinds at the declaration, so no
|
|
@@ -1098,7 +1300,29 @@ export class Lowerer {
|
|
|
1098
1300
|
/** Non-null while an instance body lowers: type-parameter symbol →
|
|
1099
1301
|
* concrete IR type, consulted inside mapType's recursion. */
|
|
1100
1302
|
typeParamBindings = null;
|
|
1303
|
+
/** Generic lambdas lowering as erased values (lowerLambda): their own
|
|
1304
|
+
* type parameters are bound to `unknown`, so lambdaSignature admits
|
|
1305
|
+
* them. */
|
|
1306
|
+
erasingLambdas = new Set();
|
|
1307
|
+
/** Function expressions lowered against a fixed target signature with a
|
|
1308
|
+
* tuple-typed `arguments` (typed-arguments.ts). */
|
|
1309
|
+
typedArgumentsLambdas = new Set();
|
|
1310
|
+
/** Const bindings holding a forwarded fixed tuple (`const args =
|
|
1311
|
+
* arguments as any` in a typed-arguments function) → the tuple type. */
|
|
1312
|
+
tupleAliasSymbols = new Map();
|
|
1313
|
+
/** `??` expressions whose result is the optional callback's own function
|
|
1314
|
+
* type (an adapted function default); their bindings take that type. */
|
|
1315
|
+
nullishFuncResults = new Set();
|
|
1316
|
+
/** The static names of the current generic instance's name-keyed
|
|
1317
|
+
* function parameters (static-function-names.ts). */
|
|
1318
|
+
staticFnNames = null;
|
|
1319
|
+
/** Nesting depth of erased generic bodies being lowered (erased lambdas
|
|
1320
|
+
* and erased instances). */
|
|
1321
|
+
erasingDepth = 0;
|
|
1101
1322
|
localClassInstantiations = [];
|
|
1323
|
+
/** Instance types (by checker type id) of the local classes generic
|
|
1324
|
+
* factory calls return, and the per-instance class each names. */
|
|
1325
|
+
localClassInstanceTypes = new Map();
|
|
1102
1326
|
/** The ts-level twin of typeParamBindings, non-null while a CALL-keyed
|
|
1103
1327
|
* instance body lowers: type-parameter symbol → the bound CHECKER type,
|
|
1104
1328
|
* consulted where the mapped IrType has already widened away information
|
|
@@ -1112,6 +1336,25 @@ export class Lowerer {
|
|
|
1112
1336
|
* typeParamBindings — the checker has no `T` to substitute, so the
|
|
1113
1337
|
* binding rides the node-type accessor instead of mapType. */
|
|
1114
1338
|
implicitParamTypes = null;
|
|
1339
|
+
/** The builtin class each binding names (`const E = EventEmitter`,
|
|
1340
|
+
* `const C = zlib.Gzip`), keyed by the binding's symbol; null for
|
|
1341
|
+
* bindings that name none (builtinClassAliasOf). new, instanceof,
|
|
1342
|
+
* typeof, .name and === resolve at compile time. */
|
|
1343
|
+
builtinClassAliases = new Map();
|
|
1344
|
+
/** Whether some net.Socket in this program may get an encoding: a
|
|
1345
|
+
* setEncoding call whose receiver is a socket or an untyped value.
|
|
1346
|
+
* Computed once on first use (null until then). */
|
|
1347
|
+
socketEncodingReachable = null;
|
|
1348
|
+
/** Whether some program source can define a thenable
|
|
1349
|
+
* (programMayDefineThenables). Null until first asked. */
|
|
1350
|
+
thenablesMayBeDefined = null;
|
|
1351
|
+
/** Lambdas lowered with checked-dynamic parameters (lambdaSignature):
|
|
1352
|
+
* callbacks whose arguments are wider than their contextual overload. */
|
|
1353
|
+
dynParamLambdas = new Set();
|
|
1354
|
+
/** Whether some server in this program may listen on a Unix socket: a
|
|
1355
|
+
* listen call whose first argument is a string. Computed once on first
|
|
1356
|
+
* use (null until then); address() answers the path only when true. */
|
|
1357
|
+
unixListenReachable = null;
|
|
1115
1358
|
/** IMPLICIT-ANY instances lowered EAGERLY at first demand (their return
|
|
1116
1359
|
* types are inferred from the body — the call site needs them settled),
|
|
1117
1360
|
* collected here for run()'s function list (the liftedFns discipline). */
|
|
@@ -1127,8 +1370,13 @@ export class Lowerer {
|
|
|
1127
1370
|
* their symbol/node keys; no module-level cache should retain a pass. */
|
|
1128
1371
|
classSymbolKeys = new Map();
|
|
1129
1372
|
registeredClassSymbols = new Map();
|
|
1373
|
+
/** Symbol-key identities by description, in resolution order (the slot
|
|
1374
|
+
* ordinals of key-table keys — symbolKeyOf). */
|
|
1375
|
+
symbolFieldIdentities = new Map();
|
|
1130
1376
|
httpClientFnBindings = new Map();
|
|
1131
1377
|
streamPropMutatedSyms = null;
|
|
1378
|
+
/** Whether some source reads process.exitCode (processReadsExitCode). */
|
|
1379
|
+
readsExitCode = null;
|
|
1132
1380
|
requestInitPropMutatedSyms = null;
|
|
1133
1381
|
emitterEventTable = null;
|
|
1134
1382
|
emitterComputedPatterns = [];
|
|
@@ -1157,6 +1405,16 @@ export class Lowerer {
|
|
|
1157
1405
|
* carry undefined at runtime. Identifier reads keep the union tag so
|
|
1158
1406
|
* typeof and later boundaries observe the real value. */
|
|
1159
1407
|
runtimeOptionalGlobals = new Set();
|
|
1408
|
+
/** Per CommonJS file using top-level `this`: the global holding the
|
|
1409
|
+
* object that stands for its original exports (lowerCjsTopLevelThis). */
|
|
1410
|
+
cjsExportsThis = new Map();
|
|
1411
|
+
/** Inline program-module require calls whose %init the enclosing member
|
|
1412
|
+
* read or member call is already sequencing (cjs-inline-require.ts). */
|
|
1413
|
+
inlineRequireInitDone = new Set();
|
|
1414
|
+
/** Whether lowered code writes properties onto children, and what the
|
|
1415
|
+
* program's JavaScript adds to them (handle-properties.ts). */
|
|
1416
|
+
writesOntoChildren = false;
|
|
1417
|
+
childAdditions = null;
|
|
1160
1418
|
/** Bindings whose unchecked string arithmetic can produce either a number
|
|
1161
1419
|
* (NaN for an absent read) or a string. Preserve that result union at bare
|
|
1162
1420
|
* reads instead of applying the checker-bare string narrowing adapter. */
|
|
@@ -1169,7 +1427,9 @@ export class Lowerer {
|
|
|
1169
1427
|
/** A pipeline() function stage's `source` parameter: the IR type of what
|
|
1170
1428
|
* the pipeline passes it (the previous stage as an async iterable), set
|
|
1171
1429
|
* while the stage lowers. Parameter typing and `for await` heads read
|
|
1172
|
-
* it before the checker's `AsyncIterable<T>`.
|
|
1430
|
+
* it before the checker's `AsyncIterable<T>`. A stream option callback's
|
|
1431
|
+
* completion parameter declared with an any-typed `data` is pinned here
|
|
1432
|
+
* too while the callback lowers (pinAnyDataCompletion). */
|
|
1173
1433
|
stageSourceTypes = new Map();
|
|
1174
1434
|
/** Set when a match result lowers to execGroups/matchGroups, the inputs
|
|
1175
1435
|
* of regex span folding. */
|
|
@@ -1179,6 +1439,10 @@ export class Lowerer {
|
|
|
1179
1439
|
* declared optional binding to that read's bare type, so presence tests
|
|
1180
1440
|
* on these bindings consult the stored tag instead. */
|
|
1181
1441
|
runtimeOptionalAssignedSymbols = new Set();
|
|
1442
|
+
/** Generic function declarations whose body can return an indexed read
|
|
1443
|
+
* that misses.
|
|
1444
|
+
* Each instance's result admits undefined (generic-functions.ts). */
|
|
1445
|
+
runtimeOptionalGenericReturns = new Set();
|
|
1182
1446
|
/** Concise callback/lambda returns promoted by the HOF callback prepass;
|
|
1183
1447
|
* arrows have no declaration symbol to key in fnSigsBySymbol. */
|
|
1184
1448
|
runtimeOptionalFunctionReturns = new Map();
|
|
@@ -1192,6 +1456,8 @@ export class Lowerer {
|
|
|
1192
1456
|
/** Record fields promoted to an undefined-armed union by an indexed-read
|
|
1193
1457
|
* value. The key is the concrete emitted shape and field name. */
|
|
1194
1458
|
runtimeOptionalFields = new Set();
|
|
1459
|
+
/** Bindings initialized by a Date's `toJSON()` (analyzeDateJsonResults). */
|
|
1460
|
+
dateJsonBindings = new Set();
|
|
1195
1461
|
/** Record bindings whose flow class reaches storage outside the class:
|
|
1196
1462
|
* they keep the declared layout, so an initializer from unchecked reads
|
|
1197
1463
|
* converts once instead of the binding adopting the widened variant. */
|
|
@@ -1239,7 +1505,7 @@ export class Lowerer {
|
|
|
1239
1505
|
// directly from the aliased declaration as a final read-side hook, so
|
|
1240
1506
|
// the initializer cannot fall back to a narrowing adapter.
|
|
1241
1507
|
if (ts.isIdentifier(node) && fallback?.kind === "func") {
|
|
1242
|
-
const decl =
|
|
1508
|
+
const decl = symbol.valueDeclaration;
|
|
1243
1509
|
if (decl &&
|
|
1244
1510
|
ts.isVariableDeclaration(decl) &&
|
|
1245
1511
|
!decl.type &&
|
|
@@ -1265,6 +1531,63 @@ export class Lowerer {
|
|
|
1265
1531
|
}
|
|
1266
1532
|
return fallback ?? null;
|
|
1267
1533
|
}
|
|
1534
|
+
/** A TypeScript object literal handed to a JavaScript checked-value
|
|
1535
|
+
* parameter whose inferred type is open (`constructor({ factory, ...options
|
|
1536
|
+
* } = {})` — the rest element admits any property): the literal names a
|
|
1537
|
+
* property the contextual JS type does not declare, so it has no record
|
|
1538
|
+
* layout there and is built as the plain object the JS side receives. */
|
|
1539
|
+
excessJsContextualProperty(literal, contextual) {
|
|
1540
|
+
const objects = contextual.filter((part) => !(part.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)));
|
|
1541
|
+
if (objects.length === 0)
|
|
1542
|
+
return false;
|
|
1543
|
+
// Only a destructuring pattern with a rest element is open; other
|
|
1544
|
+
// inferred JS types keep their record lowering.
|
|
1545
|
+
const fromJs = objects.every((part) => {
|
|
1546
|
+
const sym = part.getSymbol();
|
|
1547
|
+
return (sym !== undefined &&
|
|
1548
|
+
sym.declarations.some((d) => {
|
|
1549
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(d)))
|
|
1550
|
+
return false;
|
|
1551
|
+
// The pattern itself, or the `= {}` default of a pattern parameter.
|
|
1552
|
+
const pattern = ts.isObjectLiteralExpression(d) &&
|
|
1553
|
+
d.parent !== undefined &&
|
|
1554
|
+
ts.isParameter(d.parent) &&
|
|
1555
|
+
d.parent.initializer === d
|
|
1556
|
+
? d.parent.name
|
|
1557
|
+
: d;
|
|
1558
|
+
return (ts.isObjectBindingPattern(pattern) &&
|
|
1559
|
+
pattern.elements.nodes.some((element) => element.dotDotDotToken !== undefined));
|
|
1560
|
+
}));
|
|
1561
|
+
});
|
|
1562
|
+
if (!fromJs)
|
|
1563
|
+
return false;
|
|
1564
|
+
return literal.properties.nodes.some((prop) => {
|
|
1565
|
+
if (!prop.name || !(ts.isIdentifier(prop.name) || ts.isStringLiteral(prop.name)))
|
|
1566
|
+
return false;
|
|
1567
|
+
const name = prop.name.text;
|
|
1568
|
+
return objects.every((part) => !this.checker.getPropertyOfType(part, name));
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
/** The index value of a keyed read of a record's index signature that
|
|
1572
|
+
* can answer undefined for a missing key while its checker type does not
|
|
1573
|
+
* admit undefined, or null. A literal key naming a declared field is a
|
|
1574
|
+
* field read. */
|
|
1575
|
+
optionalIndexSignatureRead(e) {
|
|
1576
|
+
const receiver = panicSafe(() => this.mapTypeOf(this.typeOf(e.expression)), null);
|
|
1577
|
+
if (receiver?.kind !== "record")
|
|
1578
|
+
return null;
|
|
1579
|
+
const shape = this.shapes.get(receiver.shapeId);
|
|
1580
|
+
if (!shape || shape.tuple || !shape.indexValue || shape.indexValue.kind === "dyn")
|
|
1581
|
+
return null;
|
|
1582
|
+
const key = e.argumentExpression;
|
|
1583
|
+
if ((ts.isStringLiteral(key) || ts.isNumericLiteral(key)) &&
|
|
1584
|
+
shape.fields.some((field) => field.name === key.text))
|
|
1585
|
+
return null;
|
|
1586
|
+
const read = panicSafe(() => this.mapTypeOf(this.typeOf(e)), null);
|
|
1587
|
+
if (read?.kind === "union" && this.armTag(read.unionId, UNDEFINED_T) >= 0)
|
|
1588
|
+
return null;
|
|
1589
|
+
return shape.indexValue;
|
|
1590
|
+
}
|
|
1268
1591
|
runtimeOptionalIdentifierValue(node) {
|
|
1269
1592
|
if (!ts.isIdentifier(node) || this.chainRecvByNode.has(node))
|
|
1270
1593
|
return null;
|
|
@@ -1284,45 +1607,53 @@ export class Lowerer {
|
|
|
1284
1607
|
unionId: storage.type.unionId,
|
|
1285
1608
|
};
|
|
1286
1609
|
}
|
|
1287
|
-
/**
|
|
1288
|
-
*
|
|
1289
|
-
*
|
|
1290
|
-
* optional-read analysis
|
|
1291
|
-
*
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
if (slot)
|
|
1295
|
-
return slot;
|
|
1610
|
+
/** True when `node`'s lowered value can hold a hidden `undefined` the
|
|
1611
|
+
* checker type does not admit: an unchecked element or member read, a call
|
|
1612
|
+
* whose lowered return admits undefined, or a binding whose storage the
|
|
1613
|
+
* optional-read analysis marked. Whether the value actually carries the
|
|
1614
|
+
* undefined arm is only known once it is lowered
|
|
1615
|
+
* (runtimeOptionalSourceValue); this is the syntactic precondition. */
|
|
1616
|
+
isRuntimeOptionalOrigin(node) {
|
|
1296
1617
|
let origin = node;
|
|
1297
1618
|
while (ts.isParenthesizedExpression(origin))
|
|
1298
1619
|
origin = origin.expression;
|
|
1299
|
-
|
|
1620
|
+
if (ts.isElementAccessExpression(origin) || ts.isPropertyAccessExpression(origin))
|
|
1621
|
+
return true;
|
|
1300
1622
|
if (ts.isCallExpression(origin)) {
|
|
1301
1623
|
const name = ts.isPropertyAccessExpression(origin.expression)
|
|
1302
1624
|
? origin.expression.name
|
|
1303
1625
|
: origin.expression;
|
|
1304
1626
|
const symbol = ts.isIdentifier(name) ? this.resolveValueSymbol(name) : undefined;
|
|
1305
1627
|
const signature = symbol ? this.fnSigsBySymbol.get(symbol) : undefined;
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
(signature
|
|
1309
|
-
this.armTag(signature.returnType.unionId, UNDEFINED_T) >= 0);
|
|
1628
|
+
return (this.runtimeOptionalFunctionReturns.has(origin) ||
|
|
1629
|
+
(signature?.returnType.kind === "union" &&
|
|
1630
|
+
this.armTag(signature.returnType.unionId, UNDEFINED_T) >= 0));
|
|
1310
1631
|
}
|
|
1311
1632
|
if (ts.isIdentifier(origin)) {
|
|
1312
1633
|
const local = this.resolveLocal(origin);
|
|
1313
1634
|
const root = local ? this.runtimeOptionalRootOf(local) : null;
|
|
1314
1635
|
const global = this.globalOf(origin);
|
|
1315
|
-
|
|
1316
|
-
(!!
|
|
1317
|
-
(
|
|
1318
|
-
(this.
|
|
1319
|
-
(global.type.kind === "union" && this.armTag(global.type.unionId, UNDEFINED_T) >= 0)));
|
|
1636
|
+
return ((!!root && this.runtimeOptionalStorageLocals.has(root)) ||
|
|
1637
|
+
(!!global &&
|
|
1638
|
+
(this.isRuntimeOptionalGlobal(global) ||
|
|
1639
|
+
(global.type.kind === "union" && this.armTag(global.type.unionId, UNDEFINED_T) >= 0))));
|
|
1320
1640
|
}
|
|
1321
|
-
|
|
1641
|
+
return false;
|
|
1642
|
+
}
|
|
1643
|
+
/** Recover the original optional union when a checked single-arm helper
|
|
1644
|
+
* was installed before a strict property consumer could name its member.
|
|
1645
|
+
* Recovery covers member reads and storage roots marked by the
|
|
1646
|
+
* optional-read analysis, so ordinary assertions keep their generic
|
|
1647
|
+
* checked-narrow behavior. */
|
|
1648
|
+
runtimeOptionalSourceValue(node, value) {
|
|
1649
|
+
const slot = this.deferredFieldSlot(value);
|
|
1650
|
+
if (slot)
|
|
1651
|
+
return slot;
|
|
1652
|
+
if (!this.isRuntimeOptionalOrigin(node))
|
|
1322
1653
|
return null;
|
|
1323
1654
|
// A checked JavaScript indexed read can already be boxed. The checker
|
|
1324
1655
|
// calls the element present, but that inference is not a runtime guard.
|
|
1325
|
-
if (isJsSourceFile(
|
|
1656
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
1326
1657
|
value.kind === "dynCheck" &&
|
|
1327
1658
|
value.value.type.kind === "dyn")
|
|
1328
1659
|
return value.value;
|
|
@@ -1338,7 +1669,7 @@ export class Lowerer {
|
|
|
1338
1669
|
* value. Reuse a plain read directly or stabilize an effectful receiver
|
|
1339
1670
|
* once, throw Node's member-read TypeError for a unit arm, and extract the
|
|
1340
1671
|
* expected present arm otherwise. */
|
|
1341
|
-
runtimeOptionalPropertyReceiver(node, value, expected, member) {
|
|
1672
|
+
runtimeOptionalPropertyReceiver(node, value, expected, member, action = "read") {
|
|
1342
1673
|
const source = this.runtimeOptionalSourceValue(node, value);
|
|
1343
1674
|
if (source?.type.kind !== "union")
|
|
1344
1675
|
return null;
|
|
@@ -1376,7 +1707,7 @@ export class Lowerer {
|
|
|
1376
1707
|
type: BOOL,
|
|
1377
1708
|
loc,
|
|
1378
1709
|
},
|
|
1379
|
-
then: nodeThrowExpr(1, "", `Cannot
|
|
1710
|
+
then: nodeThrowExpr(1, "", `Cannot ${action} properties of ${unit} (${action === "read" ? "reading" : "setting"} '${member}')`, expected, loc),
|
|
1380
1711
|
else_: result,
|
|
1381
1712
|
type: expected,
|
|
1382
1713
|
loc,
|
|
@@ -1543,10 +1874,28 @@ export class Lowerer {
|
|
|
1543
1874
|
/** Settled generic class-rest metadata requires the historical emit
|
|
1544
1875
|
* fallback so its fence can poison the original statement atomically. */
|
|
1545
1876
|
requiresHistoricalOrderRelower = false;
|
|
1877
|
+
/** A general stream value (a runtime stream class instance) reached a
|
|
1878
|
+
* slot the child/process stdio handles represent — NodeJS.ReadableStream,
|
|
1879
|
+
* NodeJS.WritableStream, or @types/node's stream.Readable/Writable — or
|
|
1880
|
+
* a stdio handle reached an 'unknown' slot. lowerToIr then lowers the
|
|
1881
|
+
* program again under the general stream representation. */
|
|
1882
|
+
requiresGeneralNodeStreams = false;
|
|
1883
|
+
/** An untyped value reached a stream slot (a checked unwrap into a
|
|
1884
|
+
* runtime stream class, or an untyped pipe/pipeline stage). lowerToIr
|
|
1885
|
+
* then lowers the program again with checked-dynamic stream slots
|
|
1886
|
+
* (dyn-streams.ts). */
|
|
1887
|
+
requiresDynNodeStreams = false;
|
|
1888
|
+
/** Receiver representations forced by the per-value stream dispatch
|
|
1889
|
+
* (dyn-streams.ts): the native arm lowers a member call on the unboxed
|
|
1890
|
+
* stream through the ordinary class-method path. */
|
|
1891
|
+
receiverTypeOverrides = new Map();
|
|
1546
1892
|
/** Helpers that snapshot shape declaration order into their bodies.
|
|
1547
1893
|
* Reachability lowers inits before the declarations they discover, so
|
|
1548
1894
|
* these rebuild after the worklist restores historical shape metadata. */
|
|
1549
1895
|
shapeOrderHelperFinalizers = [];
|
|
1896
|
+
/** Construction witnesses that choose each shape's enumeration order
|
|
1897
|
+
* once lowering settles (key-order-witness.ts). */
|
|
1898
|
+
keyOrder = new KeyOrderNotes();
|
|
1550
1899
|
/** Emit-override specializations (`%C.emit:<event>` — lower-event-emitter.ts's
|
|
1551
1900
|
* emit-overrides block): interned names, the drive-loop queue, and the
|
|
1552
1901
|
* currently-lowering specialization's context (the super-forward
|
|
@@ -1558,6 +1907,9 @@ export class Lowerer {
|
|
|
1558
1907
|
/** Generated value helpers, keyed by operation and type. Callers own
|
|
1559
1908
|
* their key prefixes; this includes more than structural conversions. */
|
|
1560
1909
|
valueHelpers = new Map();
|
|
1910
|
+
/** structuralNarrowing's assignable classes, keyed by static and
|
|
1911
|
+
* narrowed class name. */
|
|
1912
|
+
structuralClassPeers = new Map();
|
|
1561
1913
|
/** Interned node:assert helpers (deep-equality comparisons keyed by
|
|
1562
1914
|
* typeKey, throws wrappers keyed by callback type + expected class) —
|
|
1563
1915
|
* the valueHelpers pattern with its own namespace. */
|
|
@@ -1578,6 +1930,12 @@ export class Lowerer {
|
|
|
1578
1930
|
/** Method adapter names are owned by class-method-values. Looking them
|
|
1579
1931
|
* up must not scan and retain every unrelated lifted function. */
|
|
1580
1932
|
classMethodValueHelpers = new Set();
|
|
1933
|
+
/** Reflected class methods whose lambda is lowering right now (null
|
|
1934
|
+
* until lowerLambda named it), with the closure it will produce: a
|
|
1935
|
+
* method that reads itself as a value inside its own body
|
|
1936
|
+
* (`o.create = K.create`) takes this closure instead of lowering the
|
|
1937
|
+
* method again. */
|
|
1938
|
+
methodLambdasInProgress = new Map();
|
|
1581
1939
|
classMethodValueSelections = new Map();
|
|
1582
1940
|
/** Callee names of every interned coercion helper whose CALL mints a
|
|
1583
1941
|
* FRESH closure per evaluation (%fn.width.*, %fn.adapt.*,
|
|
@@ -1599,6 +1957,10 @@ export class Lowerer {
|
|
|
1599
1957
|
* lifted lazily as module-level functions and interned per accessor
|
|
1600
1958
|
* declaration: member reads call the getter (lower-exprs). */
|
|
1601
1959
|
cjsAccessorFns = new Map();
|
|
1960
|
+
/** Accessor exports' link-time values for ES-module importers, and the
|
|
1961
|
+
* per-module flag that the copy already ran (cjsAccessorSnapshotStores). */
|
|
1962
|
+
cjsAccessorSnapshots = new Map();
|
|
1963
|
+
cjsSnapshotReady = new Map();
|
|
1602
1964
|
/** Interned `%iter.drain.<n>` helpers (classIteratorDrainCall): one per
|
|
1603
1965
|
* receiver class — the eager drain of a class iterable's protocol into
|
|
1604
1966
|
* a fresh element array, behind array/call spreads. */
|
|
@@ -1623,6 +1985,8 @@ export class Lowerer {
|
|
|
1623
1985
|
* so named imports, namespace reads, CommonJS bindings, and alias chains
|
|
1624
1986
|
* all reuse one immortal zero-capture closure. */
|
|
1625
1987
|
builtinCallableValueFns = new Map();
|
|
1988
|
+
/** Each builtin function-value adapter's Node name, for boxed values. */
|
|
1989
|
+
builtinCallableValueNames = new Map();
|
|
1626
1990
|
/** Optional-chain lowering state. While a chain body lowers, the guarded
|
|
1627
1991
|
* receiver NODE reads as a chainRecv (typed by the narrowed arm) instead
|
|
1628
1992
|
* of re-lowering, its checker type reads non-nullish (typeOf), and the
|
|
@@ -1664,6 +2028,10 @@ export class Lowerer {
|
|
|
1664
2028
|
/** Named method slots observed before class collection need a callable
|
|
1665
2029
|
* ABI and shared prototype descriptors instead of call-site specialization. */
|
|
1666
2030
|
prototypeMethodAccesses = new Map();
|
|
2031
|
+
/** Well-known symbol methods (`sym:iterator`) the program may replace
|
|
2032
|
+
* through a symbol-keyed write: an instance or prototype property, or a
|
|
2033
|
+
* reflection call. */
|
|
2034
|
+
replacedSymbolMethods = new Set();
|
|
1667
2035
|
/** Typed calls through class-backed protocols, by signature; class
|
|
1668
2036
|
* dynamic dispatch adds their native arms (class-protocol-dispatch.ts). */
|
|
1669
2037
|
protocolDispatches = new Map();
|
|
@@ -1681,6 +2049,9 @@ export class Lowerer {
|
|
|
1681
2049
|
* base vtable signature is collected. Unused checked slots carry undefined. */
|
|
1682
2050
|
virtualJsMethodArity = new Map();
|
|
1683
2051
|
checkedVirtualJsMethods = new Set();
|
|
2052
|
+
/** Overrides whose return narrows part of the base's union return; they
|
|
2053
|
+
* return through the base's union ABI (overrideReturnAbi). */
|
|
2054
|
+
unionReturnOverrides = new Set();
|
|
1684
2055
|
checkedVirtualJsAccessors = new Set();
|
|
1685
2056
|
checkedVirtualJsValueReturns = new Set();
|
|
1686
2057
|
/** The class whose members are lowering — `super` binds lexically to it
|
|
@@ -1704,6 +2075,10 @@ export class Lowerer {
|
|
|
1704
2075
|
* prepended by lowerFileInit so the bindings are live before any
|
|
1705
2076
|
* top-level statement runs. */
|
|
1706
2077
|
jsonInitActions = new Map();
|
|
2078
|
+
/** CommonJS require() of JSON documents: the shared object per document
|
|
2079
|
+
* and the calls reading it (json-require.ts). */
|
|
2080
|
+
jsonRequireModules = new Map();
|
|
2081
|
+
jsonRequireCalls = new Map();
|
|
1707
2082
|
/** Dynamic `import("literal")` resolutions, keyed
|
|
1708
2083
|
* `fileName\u0000specifier` (collectDynamicImports fills it during npm
|
|
1709
2084
|
* collection; lowerDynamicImportCall reads it per site). */
|
|
@@ -1729,6 +2104,12 @@ export class Lowerer {
|
|
|
1729
2104
|
workerTargets;
|
|
1730
2105
|
workerTargetIdByPath = new Map();
|
|
1731
2106
|
usesWorkers = false;
|
|
2107
|
+
/** The program uses the WebAssembly API (builtins/webassembly.ts): the
|
|
2108
|
+
* build translates the modules it discovers. */
|
|
2109
|
+
usesWebAssembly = false;
|
|
2110
|
+
/** The program calls WebAssembly.Module.customSections: translated
|
|
2111
|
+
* modules keep their custom sections. */
|
|
2112
|
+
usesWasmCustomSections = false;
|
|
1732
2113
|
/** The program constructs a LifetimeRegion (lifetime-regions.ts). */
|
|
1733
2114
|
usesLifetimeRegions = false;
|
|
1734
2115
|
/** Per-directory answers of experimental-import.ts's declaration-file test. */
|
|
@@ -1739,6 +2120,12 @@ export class Lowerer {
|
|
|
1739
2120
|
internTableHelpers = new Map();
|
|
1740
2121
|
/** Each InternTable name's type arguments and first construction site. */
|
|
1741
2122
|
internTableNames = new Map();
|
|
2123
|
+
/** Each ThreadSlots name's type arguments (thread-slots.ts). */
|
|
2124
|
+
threadSlotNames = new Map();
|
|
2125
|
+
/** The family each `new ThreadSlots(...)` opens. */
|
|
2126
|
+
threadSlotFamilies = new Map();
|
|
2127
|
+
/** Classes used as ThreadSlots keys: their hierarchies carry a slot word. */
|
|
2128
|
+
threadSlotKeys = new Set();
|
|
1742
2129
|
forkTargetIdByPath = new Map();
|
|
1743
2130
|
/** Namespace ModuleBlocks this program lowers, filled by splitFiles:
|
|
1744
2131
|
* "flattened" — an instantiated namespace whose body joined the file's
|
|
@@ -1823,6 +2210,9 @@ export class Lowerer {
|
|
|
1823
2210
|
// top level, top = the innermost nested function currently lowering).
|
|
1824
2211
|
fnStack = [];
|
|
1825
2212
|
liftedFns = [];
|
|
2213
|
+
/** Runtime-provided classes used as values (defineClassValueConstruct),
|
|
2214
|
+
* by IR class name. */
|
|
2215
|
+
runtimeClassValues = new Map();
|
|
1826
2216
|
/** One Error-method helper belongs to this lowering session. Its cached
|
|
1827
2217
|
* dispatch revision needs no weak-key identity or process-global state. */
|
|
1828
2218
|
errorMethodDispatchRevision = null;
|
|
@@ -1849,6 +2239,17 @@ export class Lowerer {
|
|
|
1849
2239
|
* by class name (cycle-initialization.ts). */
|
|
1850
2240
|
classInitFlags = new Map();
|
|
1851
2241
|
cycleInitDeclarations = new Map();
|
|
2242
|
+
/** Each class's constructor return plan by class name
|
|
2243
|
+
* (constructor-returns.ts); null when no return can yield an object. */
|
|
2244
|
+
constructorReturnPlans = new Map();
|
|
2245
|
+
/** Pointer-guarded (`tdz`) module bindings declared without an
|
|
2246
|
+
* initializer (`let f: T;`): an initialization flag tracks their
|
|
2247
|
+
* declaration (markCycleEarlyBindings). */
|
|
2248
|
+
uninitializedLexicalGlobals = new Map();
|
|
2249
|
+
/** CommonJS require declarations whose bindings code running before the
|
|
2250
|
+
* require can read, and those references (require-initialization.ts). */
|
|
2251
|
+
requireInitFlags = new Map();
|
|
2252
|
+
requireEarlyReferences = [];
|
|
1852
2253
|
get ctx() {
|
|
1853
2254
|
const top = this.fnStack[this.fnStack.length - 1];
|
|
1854
2255
|
if (!top)
|
|
@@ -1884,6 +2285,16 @@ export class Lowerer {
|
|
|
1884
2285
|
/** Coverage remainder mode: the reachability gate inverts (see wantBody)
|
|
1885
2286
|
* and no module is built. */
|
|
1886
2287
|
remainder;
|
|
2288
|
+
/** `--tier` (tier-analysis.ts). Stage S2 is report-only: both modes
|
|
2289
|
+
* refuse and fence exactly as before. Stage S6 demotes the units of
|
|
2290
|
+
* committed refusals in "auto" and keeps them refusals in "static-only". */
|
|
2291
|
+
tierMode;
|
|
2292
|
+
generalNodeStreams;
|
|
2293
|
+
dynNodeStreams;
|
|
2294
|
+
/** Functions finishModule placed in the dynamic tier (ir/tiers.ts). */
|
|
2295
|
+
dynamicFunctions = [];
|
|
2296
|
+
/** Their IR, for coverage's dynamic statement count. */
|
|
2297
|
+
dynamicBodies = [];
|
|
1887
2298
|
/** Deferred collection diagnostics (failed signatures/class shapes) by
|
|
1888
2299
|
* declaration symbol: an unreached declaration must not fail the build,
|
|
1889
2300
|
* so its diagnostics wait until a reference makes them relevant. */
|
|
@@ -1908,6 +2319,9 @@ export class Lowerer {
|
|
|
1908
2319
|
targetPlatform;
|
|
1909
2320
|
/** LowererMode.startupCrash — buildMain opens %main with the throw. */
|
|
1910
2321
|
startupCrash;
|
|
2322
|
+
/** The project's tsconfig sets `checkJs`. */
|
|
2323
|
+
projectCheckJs;
|
|
2324
|
+
checkedJsFiles = new Map();
|
|
1911
2325
|
/** Outbound native bindings by their source-level ambient name. */
|
|
1912
2326
|
ffiImports;
|
|
1913
2327
|
libraryCallbacks;
|
|
@@ -1946,6 +2360,33 @@ export class Lowerer {
|
|
|
1946
2360
|
* package. Only populated while the registry is active; the remainder
|
|
1947
2361
|
* pass skips it (attribution describes the build). */
|
|
1948
2362
|
statsByFile = new Map();
|
|
2363
|
+
/** Statements and field initializers already in the coverage totals, and
|
|
2364
|
+
* those already counted as failed. Speculative lowering can lower one
|
|
2365
|
+
* function body several times: each receiver probe of
|
|
2366
|
+
* `(function () { ... }).call(this)` lowers it. A source statement counts
|
|
2367
|
+
* once however many times it lowers. */
|
|
2368
|
+
countedStatements = new Set();
|
|
2369
|
+
failedStatements = new Set();
|
|
2370
|
+
/** Adds `node` to the coverage totals unless it is already counted (the
|
|
2371
|
+
* caller checks suppressStats). */
|
|
2372
|
+
countStatement(node, file) {
|
|
2373
|
+
if (this.countedStatements.has(node))
|
|
2374
|
+
return;
|
|
2375
|
+
this.countedStatements.add(node);
|
|
2376
|
+
this.stats.statementsTotal++;
|
|
2377
|
+
if (file !== undefined)
|
|
2378
|
+
this.bumpFileStat(file, "total");
|
|
2379
|
+
}
|
|
2380
|
+
/** Counts `node` as failed unless it already is (the caller checks
|
|
2381
|
+
* suppressStats). */
|
|
2382
|
+
countStatementFailed(node, file) {
|
|
2383
|
+
if (this.failedStatements.has(node))
|
|
2384
|
+
return;
|
|
2385
|
+
this.failedStatements.add(node);
|
|
2386
|
+
this.stats.statementsFailed++;
|
|
2387
|
+
if (file !== undefined)
|
|
2388
|
+
this.bumpFileStat(file, "failed");
|
|
2389
|
+
}
|
|
1949
2390
|
/** Bumps the per-file attribution counter (no-op unless provenance is
|
|
1950
2391
|
* active and this is the emit/discovery lane — mirror the CALLER's
|
|
1951
2392
|
* suppressStats guard, this method only gates remainder). */
|
|
@@ -1964,25 +2405,31 @@ export class Lowerer {
|
|
|
1964
2405
|
this.program = program;
|
|
1965
2406
|
this.entry = entry;
|
|
1966
2407
|
this.moduleOrder = moduleOrder;
|
|
2408
|
+
// The mode's options, sorted by name; the values derived from them follow.
|
|
2409
|
+
this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
|
|
2410
|
+
this.externalTypes = mode.externalTypes ?? new Map();
|
|
2411
|
+
this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
|
|
2412
|
+
this.ffiImports = mode.ffiImports ?? [];
|
|
2413
|
+
this.forkTargets = mode.forkTargets ?? [];
|
|
1967
2414
|
this.frontendServices = mode.frontendServices;
|
|
2415
|
+
this.inlineRequireCycleCalls = mode.inlineRequireCycleCalls ?? new Set();
|
|
2416
|
+
this.libraryCallbacks = mode.libraryCallbacks ?? false;
|
|
2417
|
+
this.projectCheckJs = mode.projectCheckJs ?? false;
|
|
1968
2418
|
this.reachable = mode.reachable ?? null;
|
|
1969
2419
|
this.remainder = mode.remainder ?? false;
|
|
1970
|
-
this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
|
|
1971
|
-
this.targetPlatform = mode.targetPlatform ?? process.platform;
|
|
1972
2420
|
this.startupCrash = mode.startupCrash ?? null;
|
|
1973
|
-
this.
|
|
1974
|
-
this.
|
|
2421
|
+
this.targetPlatform = mode.targetPlatform ?? process.platform;
|
|
2422
|
+
this.tierMode = mode.tierMode ?? "auto";
|
|
2423
|
+
this.generalNodeStreams = mode.generalNodeStreams ?? false;
|
|
2424
|
+
this.dynNodeStreams = this.generalNodeStreams && (mode.dynNodeStreams ?? false);
|
|
1975
2425
|
this.workerTargets = mode.workerTargets ?? [];
|
|
1976
2426
|
this.workerTargets.forEach((sf, id) => {
|
|
1977
2427
|
this.workerTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
|
|
1978
2428
|
});
|
|
1979
|
-
this.forkTargets = mode.forkTargets ?? [];
|
|
1980
2429
|
this.forkTargets.forEach((sf, id) => {
|
|
1981
2430
|
this.forkTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
|
|
1982
2431
|
});
|
|
1983
2432
|
this.ffiImportsByName = new Map(this.ffiImports.map((entry) => [entry.name, entry]));
|
|
1984
|
-
this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
|
|
1985
|
-
this.externalTypes = mode.externalTypes ?? new Map();
|
|
1986
2433
|
this.externalTypeSpecifiersByFile =
|
|
1987
2434
|
mode.externalTypeSpecifiersByFile ?? directExternalTypeSpecifiersByFile(this.externalTypes);
|
|
1988
2435
|
this.checker = program.getTypeChecker();
|
|
@@ -1993,18 +2440,25 @@ export class Lowerer {
|
|
|
1993
2440
|
classNamer: this.classNamer,
|
|
1994
2441
|
resolveTypeParam: this.typeParamResolver,
|
|
1995
2442
|
resolveTypeParamTs: this.typeParamTsResolver,
|
|
2443
|
+
isErasing: () => this.erasingDepth > 0,
|
|
1996
2444
|
genericClassInstance: (decl, ref, mapArgument) => this.genericClassInstanceType(decl, ref, mapArgument),
|
|
2445
|
+
runtimeClassValue: (type) => runtimeClassValueOfType(this, type),
|
|
1997
2446
|
mixinClassInstance: (decl) => this.mixinTypeContext && this.mixinTypeContext.classNode === decl
|
|
1998
2447
|
? { kind: "object", className: this.mixinTypeContext.className }
|
|
1999
2448
|
: null,
|
|
2000
|
-
localClassInstance: (decl) => {
|
|
2449
|
+
localClassInstance: (decl, instanceType) => {
|
|
2450
|
+
// A generic factory's local class, by the instance type a call of
|
|
2451
|
+
// the factory produced (localClassResultInstance).
|
|
2452
|
+
const instanceClass = instanceType && this.localClassInstanceTypes.get(instanceType.id);
|
|
2453
|
+
if (instanceClass)
|
|
2454
|
+
return { kind: "object", className: instanceClass };
|
|
2001
2455
|
// Computed heritage can close over parameters of its factory.
|
|
2002
2456
|
// A speculative checker query outside that factory must not lower
|
|
2003
2457
|
// the extends expression in the caller's lexical scope.
|
|
2004
2458
|
if (!this.classes.has(this.classNamer(decl)) &&
|
|
2005
2459
|
!this.collectingExprClasses.has(decl) &&
|
|
2006
|
-
decl.heritageClauses?.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword &&
|
|
2007
|
-
clause.types.some((base) => {
|
|
2460
|
+
decl.heritageClauses?.nodes.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword &&
|
|
2461
|
+
clause.types.nodes.some((base) => {
|
|
2008
2462
|
const expression = base.expression;
|
|
2009
2463
|
if (ts.isCallExpression(expression))
|
|
2010
2464
|
return true;
|
|
@@ -2032,13 +2486,14 @@ export class Lowerer {
|
|
|
2032
2486
|
continue;
|
|
2033
2487
|
if (this.localClassInstantiations.some((entry) => entry.owner === parent))
|
|
2034
2488
|
break;
|
|
2035
|
-
if (parent.typeParameters?.length ||
|
|
2036
|
-
(implicitMonoFile(
|
|
2489
|
+
if (parent.typeParameters?.nodes.length ||
|
|
2490
|
+
(implicitMonoFile(ts.getSourceFileOfNode(parent)) &&
|
|
2491
|
+
monomorphizedImplicit(this, parent)))
|
|
2037
2492
|
return null;
|
|
2038
2493
|
}
|
|
2039
2494
|
const className = this.classNamer(decl);
|
|
2040
|
-
if (!this.collectingExprClasses.has(decl))
|
|
2041
|
-
|
|
2495
|
+
if (!this.collectingExprClasses.has(decl) && !this.collectLocalClassForType(decl))
|
|
2496
|
+
return null;
|
|
2042
2497
|
return { kind: "object", className };
|
|
2043
2498
|
},
|
|
2044
2499
|
mixinIntersectionInstance: (widened) => mixinIntersectionInstanceType(this, widened),
|
|
@@ -2047,18 +2502,23 @@ export class Lowerer {
|
|
|
2047
2502
|
isNpmFile: this.isNpmFile,
|
|
2048
2503
|
isExternalTypeFile: (sf) => this.externalTypeSpecifiersByFile.has(tsgoPath(resolve(sf.fileName))),
|
|
2049
2504
|
typeMemo: this.typeMemo,
|
|
2505
|
+
...(this.generalNodeStreams ? { generalNodeStreams: true } : {}),
|
|
2506
|
+
...(this.dynNodeStreams ? { dynNodeStreams: true } : {}),
|
|
2050
2507
|
canMemoizeType: () => this.typeParamBindings === null &&
|
|
2051
2508
|
this.typeParamTsBindings === null &&
|
|
2052
2509
|
this.mixinTypeContext === null,
|
|
2053
2510
|
// fileTag is filled just below; the hook is only ever CALLED during
|
|
2054
2511
|
// lowering, long after the constructor completes.
|
|
2055
2512
|
isProgramFile: (sf) => this.fileTag.has(sf),
|
|
2056
|
-
lifetimeRegionClass: (decl) => isExperimentalDeclarationFile(
|
|
2513
|
+
lifetimeRegionClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2057
2514
|
? lifetimeRegionType(this)
|
|
2058
2515
|
: null,
|
|
2059
|
-
internTableClass: (decl) => isExperimentalDeclarationFile(
|
|
2516
|
+
internTableClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2060
2517
|
? internTableType(this)
|
|
2061
2518
|
: null,
|
|
2519
|
+
threadSlotsClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2520
|
+
? threadSlotsType(this)
|
|
2521
|
+
: null,
|
|
2062
2522
|
moduleNamespaceId: (type) => this.moduleNamespaceIdOfType(type),
|
|
2063
2523
|
};
|
|
2064
2524
|
// Modules reachable only through literal import() joined
|
|
@@ -2070,11 +2530,25 @@ export class Lowerer {
|
|
|
2070
2530
|
});
|
|
2071
2531
|
if (this.moduleOrder.length === 0)
|
|
2072
2532
|
this.fileTag.set(entry, "");
|
|
2533
|
+
const jsDynamic = jsDynamicDeclarations(this.moduleOrder, this.checker);
|
|
2534
|
+
if (jsDynamic.size > 0)
|
|
2535
|
+
this.typeCtx.jsDynamicDeclaration = (decl) => jsDynamic.has(decl);
|
|
2073
2536
|
this.registerBuiltinErrorClasses();
|
|
2074
2537
|
registerBuiltinEmitterClass(this);
|
|
2075
2538
|
registerBuiltinStreamClasses(this);
|
|
2076
2539
|
registerBuiltinEventTargetClasses(this);
|
|
2077
2540
|
}
|
|
2541
|
+
/** A JavaScript file TypeScript type-checks (`// @ts-check`, or the
|
|
2542
|
+
* project's `checkJs`). Its JSDoc types are enforced like TypeScript
|
|
2543
|
+
* annotations, so its classes use them as a TypeScript file would. */
|
|
2544
|
+
checkedJsFile(sf) {
|
|
2545
|
+
let checked = this.checkedJsFiles.get(sf);
|
|
2546
|
+
if (checked === undefined) {
|
|
2547
|
+
checked = isCheckedJsSourceFile(sf, this.projectCheckJs);
|
|
2548
|
+
this.checkedJsFiles.set(sf, checked);
|
|
2549
|
+
}
|
|
2550
|
+
return checked;
|
|
2551
|
+
}
|
|
2078
2552
|
registerBuiltinErrorClasses() {
|
|
2079
2553
|
return registerBuiltinErrorClasses(this);
|
|
2080
2554
|
}
|
|
@@ -2084,10 +2558,50 @@ export class Lowerer {
|
|
|
2084
2558
|
return this.classProtocols.usesCheckedIdentity(type);
|
|
2085
2559
|
}
|
|
2086
2560
|
/** Declared class fields may store a DYN value only when its static type
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
2561
|
+
* is `unknown` or `object` (also with `null` or `undefined`, or an array
|
|
2562
|
+
* of those), names checked protocol identity, is an owned runtime
|
|
2563
|
+
* handle (a Worker or MessagePort, a fetch Headers/Request/Response, or
|
|
2564
|
+
* a node:crypto ECDH), or is a WeakMap/WeakSet (native weak collections
|
|
2565
|
+
* live in checked-dynamic storage, as locals of those types do); `any`
|
|
2566
|
+
* fields stay refused. */
|
|
2089
2567
|
classFieldStoresDyn(type) {
|
|
2090
|
-
return this.
|
|
2568
|
+
return (this.opaqueValueType(type) ||
|
|
2569
|
+
this.classImplementedProtocol(type) ||
|
|
2570
|
+
isWorkerHandleType(type, this.typeCtx) ||
|
|
2571
|
+
isFetchHandleType(type, this.typeCtx) ||
|
|
2572
|
+
this.weakCollectionType(type) ||
|
|
2573
|
+
this.stdlibHandleType(type, (part) => isEcdhType(this, part)));
|
|
2574
|
+
}
|
|
2575
|
+
/** A stdlib WeakMap or WeakSet, alone or with `null`/`undefined`. */
|
|
2576
|
+
weakCollectionType(type) {
|
|
2577
|
+
const weak = (part) => {
|
|
2578
|
+
const symbol = part.getSymbol();
|
|
2579
|
+
return (((symbol !== undefined && ts.symbolName(symbol) === "WeakMap") ||
|
|
2580
|
+
(symbol !== undefined && ts.symbolName(symbol) === "WeakSet")) &&
|
|
2581
|
+
symbol.declarations.some((d) => ts.isInterfaceDeclaration(d) && this.isStdlibFile(ts.getSourceFileOfNode(d))));
|
|
2582
|
+
};
|
|
2583
|
+
return this.stdlibHandleType(type, weak);
|
|
2584
|
+
}
|
|
2585
|
+
/** A type `handle` accepts, alone or with `null`/`undefined`. */
|
|
2586
|
+
stdlibHandleType(type, handle) {
|
|
2587
|
+
if (!type.isUnionType())
|
|
2588
|
+
return handle(type);
|
|
2589
|
+
const parts = ts.constituentTypes(type);
|
|
2590
|
+
return (parts.some(handle) &&
|
|
2591
|
+
parts.every((part) => (part.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 || handle(part)));
|
|
2592
|
+
}
|
|
2593
|
+
/** `unknown`, `object`, an array of those, or a union of those with
|
|
2594
|
+
* `null` and `undefined`: types whose values use checked-dynamic storage
|
|
2595
|
+
* as they do in JavaScript class fields. */
|
|
2596
|
+
opaqueValueType(type) {
|
|
2597
|
+
const opaque = (part) => (part.flags & (ts.TypeFlags.Unknown | ts.TypeFlags.NonPrimitive)) !== 0 ||
|
|
2598
|
+
(this.checker.isArrayType(part) &&
|
|
2599
|
+
this.checker.getTypeArguments(part).every(opaque));
|
|
2600
|
+
if (!type.isUnionType())
|
|
2601
|
+
return opaque(type);
|
|
2602
|
+
const parts = ts.constituentTypes(type);
|
|
2603
|
+
return (parts.some(opaque) &&
|
|
2604
|
+
parts.every((part) => (part.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 || opaque(part)));
|
|
2091
2605
|
}
|
|
2092
2606
|
/** The nominal identity of a checker module-namespace type. Program
|
|
2093
2607
|
* modules use their normalized absolute source name; supported builtins
|
|
@@ -2098,7 +2612,7 @@ export class Lowerer {
|
|
|
2098
2612
|
return null;
|
|
2099
2613
|
if (sym.flags & ts.SymbolFlags.Alias)
|
|
2100
2614
|
sym = this.checker.getAliasedSymbol(sym);
|
|
2101
|
-
for (const decl of
|
|
2615
|
+
for (const decl of sym.declarations) {
|
|
2102
2616
|
if (ts.isSourceFile(decl) &&
|
|
2103
2617
|
!decl.isDeclarationFile &&
|
|
2104
2618
|
!decl.fileName.endsWith(".cts") &&
|
|
@@ -2129,6 +2643,12 @@ export class Lowerer {
|
|
|
2129
2643
|
builtinStreamInfoOf(symbol) {
|
|
2130
2644
|
return builtinStreamInfoOf(this, symbol);
|
|
2131
2645
|
}
|
|
2646
|
+
builtinClassAliasOf(symbol) {
|
|
2647
|
+
return builtinClassAliasOf(this, symbol);
|
|
2648
|
+
}
|
|
2649
|
+
defineClassValueConstruct(info) {
|
|
2650
|
+
defineClassValueConstruct(this, info);
|
|
2651
|
+
}
|
|
2132
2652
|
/** Program-wide qualified name for a top-level declaration. */
|
|
2133
2653
|
qualify(sf, name) {
|
|
2134
2654
|
return `${this.fileTag.get(sf) ?? ""}${name}`;
|
|
@@ -2150,8 +2670,8 @@ export class Lowerer {
|
|
|
2150
2670
|
}
|
|
2151
2671
|
return false;
|
|
2152
2672
|
})()
|
|
2153
|
-
? this.qualify(
|
|
2154
|
-
: this.qualify(
|
|
2673
|
+
? this.qualify(ts.getSourceFileOfNode(decl), `%cx${ts.tokenStartOfNode(decl)}.${decl.name?.text ?? ""}`)
|
|
2674
|
+
: this.qualify(ts.getSourceFileOfNode(decl), nsPathPrefix(decl) + (decl.name ? decl.name.text : "%anon"));
|
|
2155
2675
|
for (let index = this.localClassInstantiations.length - 1; index >= 0; index--) {
|
|
2156
2676
|
const entry = this.localClassInstantiations[index];
|
|
2157
2677
|
for (let parent = decl.parent; parent && !ts.isSourceFile(parent); parent = parent.parent) {
|
|
@@ -2196,8 +2716,10 @@ export class Lowerer {
|
|
|
2196
2716
|
ts.isPropertyAccessExpression(ident.parent) &&
|
|
2197
2717
|
ident.parent.name === ident) {
|
|
2198
2718
|
const recv = ident.parent.expression;
|
|
2199
|
-
if (
|
|
2200
|
-
const dep =
|
|
2719
|
+
if (this.cjsLocalModuleBindingOf(recv)) {
|
|
2720
|
+
const dep = ts.isIdentifier(recv)
|
|
2721
|
+
? this.localModuleBindingDepOf(recv)
|
|
2722
|
+
: this.cjsModuleRefDepOf(recv);
|
|
2201
2723
|
const exported = dep ? this.cjsModuleExportSymbol(dep, ident.text) : undefined;
|
|
2202
2724
|
// A createRequire call is typed as `any`, so tsgo can manufacture a
|
|
2203
2725
|
// transient property symbol with no relation to the target module.
|
|
@@ -2290,7 +2812,7 @@ export class Lowerer {
|
|
|
2290
2812
|
}
|
|
2291
2813
|
if (ts.isCallExpression(value)) {
|
|
2292
2814
|
if (value.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
2293
|
-
const spec = value.arguments[0];
|
|
2815
|
+
const spec = value.arguments.nodes[0];
|
|
2294
2816
|
return spec !== undefined &&
|
|
2295
2817
|
ts.isStringLiteralLike(spec) &&
|
|
2296
2818
|
this.externalTypes.has(spec.text)
|
|
@@ -2299,8 +2821,8 @@ export class Lowerer {
|
|
|
2299
2821
|
}
|
|
2300
2822
|
if (ts.isIdentifier(value.expression) &&
|
|
2301
2823
|
value.expression.text === "require" &&
|
|
2302
|
-
value.arguments.length === 1) {
|
|
2303
|
-
const spec = value.arguments[0];
|
|
2824
|
+
value.arguments.nodes.length === 1) {
|
|
2825
|
+
const spec = value.arguments.nodes[0];
|
|
2304
2826
|
if (ts.isStringLiteralLike(spec) && this.externalTypes.has(spec.text))
|
|
2305
2827
|
return spec.text;
|
|
2306
2828
|
}
|
|
@@ -2337,7 +2859,7 @@ export class Lowerer {
|
|
|
2337
2859
|
* every project-module spelling. */
|
|
2338
2860
|
moduleSourceFileOf(from, spec) {
|
|
2339
2861
|
const moduleSymbol = this.checker.getSymbolAtLocation(spec);
|
|
2340
|
-
for (const decl of moduleSymbol ?
|
|
2862
|
+
for (const decl of moduleSymbol ? moduleSymbol.declarations : []) {
|
|
2341
2863
|
if (ts.isSourceFile(decl))
|
|
2342
2864
|
return decl;
|
|
2343
2865
|
}
|
|
@@ -2373,9 +2895,7 @@ export class Lowerer {
|
|
|
2373
2895
|
if (!ts.isIdentifier(value))
|
|
2374
2896
|
return null;
|
|
2375
2897
|
const symbol = this.checker.getSymbolAtLocation(value);
|
|
2376
|
-
const namespaceDecl = symbol
|
|
2377
|
-
? this.checker.declarationsOf(symbol).find(ts.isNamespaceImport)
|
|
2378
|
-
: undefined;
|
|
2898
|
+
const namespaceDecl = symbol ? symbol.declarations.find(ts.isNamespaceImport) : undefined;
|
|
2379
2899
|
if (namespaceDecl === undefined)
|
|
2380
2900
|
return null;
|
|
2381
2901
|
const importDecl = namespaceDecl.parent?.parent;
|
|
@@ -2383,7 +2903,7 @@ export class Lowerer {
|
|
|
2383
2903
|
return null;
|
|
2384
2904
|
if (this.externalTypes.has(importDecl.moduleSpecifier.text))
|
|
2385
2905
|
return importDecl.moduleSpecifier.text;
|
|
2386
|
-
const dep = this.moduleSourceFileOf(
|
|
2906
|
+
const dep = this.moduleSourceFileOf(ts.getSourceFileOfNode(importDecl), importDecl.moduleSpecifier);
|
|
2387
2907
|
return dep !== null && !dep.isDeclarationFile
|
|
2388
2908
|
? this.externalTypeSpecifierOfModuleExport(dep, member, new Set(), new Set())
|
|
2389
2909
|
: null;
|
|
@@ -2392,7 +2912,7 @@ export class Lowerer {
|
|
|
2392
2912
|
if (symbol === undefined || seenSymbols.has(symbol))
|
|
2393
2913
|
return null;
|
|
2394
2914
|
seenSymbols.add(symbol);
|
|
2395
|
-
const declarations =
|
|
2915
|
+
const declarations = symbol.declarations;
|
|
2396
2916
|
// Route-aware alias hops run before declaration-file ownership. An
|
|
2397
2917
|
// exact import must keep the specifier it actually named, rather than
|
|
2398
2918
|
// inheriting whichever alias happened to register the shared file last.
|
|
@@ -2439,13 +2959,13 @@ export class Lowerer {
|
|
|
2439
2959
|
// property accesses resolve their selected member separately above.
|
|
2440
2960
|
if (importedName === null)
|
|
2441
2961
|
return null;
|
|
2442
|
-
const dep = this.moduleSourceFileOf(
|
|
2962
|
+
const dep = this.moduleSourceFileOf(ts.getSourceFileOfNode(decl), specNode);
|
|
2443
2963
|
return dep !== null && !dep.isDeclarationFile
|
|
2444
2964
|
? this.externalTypeSpecifierOfModuleExport(dep, importedName, seenSymbols, seenExports)
|
|
2445
2965
|
: null;
|
|
2446
2966
|
}
|
|
2447
2967
|
for (const decl of declarations) {
|
|
2448
|
-
const owners = this.externalTypeSpecifiersByFile.get(tsgoPath(resolve(
|
|
2968
|
+
const owners = this.externalTypeSpecifiersByFile.get(tsgoPath(resolve(ts.getSourceFileOfNode(decl).fileName)));
|
|
2449
2969
|
if (owners !== undefined && owners.length > 0)
|
|
2450
2970
|
return owners[0];
|
|
2451
2971
|
}
|
|
@@ -2468,9 +2988,7 @@ export class Lowerer {
|
|
|
2468
2988
|
for (let hop = 0; sym !== undefined && hop < 32; hop++) {
|
|
2469
2989
|
if (hop > 0 && sym.flags & ts.SymbolFlags.Alias && this.globalsBySymbol.has(sym))
|
|
2470
2990
|
return sym;
|
|
2471
|
-
const d =
|
|
2472
|
-
.declarationsOf(sym)
|
|
2473
|
-
.find((x) => ts.isImportClause(x) || ts.isImportSpecifier(x) || ts.isExportSpecifier(x));
|
|
2991
|
+
const d = sym.declarations.find((x) => ts.isImportClause(x) || ts.isImportSpecifier(x) || ts.isExportSpecifier(x));
|
|
2474
2992
|
let spec;
|
|
2475
2993
|
let name;
|
|
2476
2994
|
if (d && ts.isImportClause(d) && ts.isImportDeclaration(d.parent)) {
|
|
@@ -2491,7 +3009,7 @@ export class Lowerer {
|
|
|
2491
3009
|
}
|
|
2492
3010
|
if (d === undefined || spec === undefined || !ts.isStringLiteral(spec) || name !== "default")
|
|
2493
3011
|
return null;
|
|
2494
|
-
const dep = resolveImport(this.program,
|
|
3012
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(d), spec.text);
|
|
2495
3013
|
if (!dep)
|
|
2496
3014
|
return null;
|
|
2497
3015
|
sym = defaultExportSymbolOf(this, dep) ?? undefined;
|
|
@@ -2521,7 +3039,7 @@ export class Lowerer {
|
|
|
2521
3039
|
* see resolveValueSymbol. Null when `symbol` is not such a property (or
|
|
2522
3040
|
* the property's value is not a plain identifier reference). */
|
|
2523
3041
|
cjsExportValueSymbol(symbol) {
|
|
2524
|
-
const d =
|
|
3042
|
+
const d = symbol.declarations[0];
|
|
2525
3043
|
if (!d)
|
|
2526
3044
|
return null;
|
|
2527
3045
|
// MEMBER-form class exports (`exports.C = C` — commander's error.js):
|
|
@@ -2563,8 +3081,6 @@ export class Lowerer {
|
|
|
2563
3081
|
: null;
|
|
2564
3082
|
if (!assign || assign.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
2565
3083
|
return null;
|
|
2566
|
-
if (!ts.isIdentifier(assign.right))
|
|
2567
|
-
return null;
|
|
2568
3084
|
const stmt = assign.parent;
|
|
2569
3085
|
if (!stmt || !ts.isExpressionStatement(stmt) || !ts.isSourceFile(stmt.parent))
|
|
2570
3086
|
return null;
|
|
@@ -2575,12 +3091,39 @@ export class Lowerer {
|
|
|
2575
3091
|
return null;
|
|
2576
3092
|
if (cjsExportDiscardReason(stmt) !== null)
|
|
2577
3093
|
return null;
|
|
3094
|
+
// `module.exports.C = require('./c')` over a module whose whole export
|
|
3095
|
+
// is a class identifier: the same alias plumbing; the statement keeps
|
|
3096
|
+
// the require's module evaluation at its position.
|
|
3097
|
+
const required = this.memberExportRequiredClass(assign.right);
|
|
3098
|
+
if (required !== undefined)
|
|
3099
|
+
return required;
|
|
3100
|
+
if (!ts.isIdentifier(assign.right))
|
|
3101
|
+
return null;
|
|
2578
3102
|
let value = this.checker.getSymbolAtLocation(assign.right);
|
|
2579
3103
|
if (!value)
|
|
2580
3104
|
return null;
|
|
2581
3105
|
if (value.flags & ts.SymbolFlags.Alias)
|
|
2582
3106
|
value = this.checker.getAliasedSymbol(value);
|
|
2583
|
-
const isClass =
|
|
3107
|
+
const isClass = value.declarations.some((decl) => ts.isClassDeclaration(decl));
|
|
3108
|
+
return isClass ? value : null;
|
|
3109
|
+
}
|
|
3110
|
+
/** For an inline program `require("./c")`: the class symbol its module's
|
|
3111
|
+
* kept `module.exports = <class identifier>` names, or null when the
|
|
3112
|
+
* whole export is something else. Undefined when `expr` is not such a
|
|
3113
|
+
* require. */
|
|
3114
|
+
memberExportRequiredClass(expr) {
|
|
3115
|
+
const req = inlineProgramRequireOf(this, expr);
|
|
3116
|
+
if (req === null)
|
|
3117
|
+
return undefined;
|
|
3118
|
+
const whole = cjsWholeExportValueOf(req.dep);
|
|
3119
|
+
if (whole === null || !ts.isIdentifier(whole.rhs))
|
|
3120
|
+
return null;
|
|
3121
|
+
let value = this.checker.getSymbolAtLocation(whole.rhs);
|
|
3122
|
+
if (!value)
|
|
3123
|
+
return null;
|
|
3124
|
+
if (value.flags & ts.SymbolFlags.Alias)
|
|
3125
|
+
value = this.checker.getAliasedSymbol(value);
|
|
3126
|
+
const isClass = value.declarations.some((decl) => ts.isClassDeclaration(decl));
|
|
2584
3127
|
return isClass ? value : null;
|
|
2585
3128
|
}
|
|
2586
3129
|
/** The CommonJS JS module a DEFAULT-import binding's declaration loads
|
|
@@ -2597,19 +3140,33 @@ export class Lowerer {
|
|
|
2597
3140
|
const spec = importDecl.moduleSpecifier.text;
|
|
2598
3141
|
// Project aliases/self-references resolve through the same entry point as
|
|
2599
3142
|
// relative imports; an opted-in --npm-static package is the fallback.
|
|
2600
|
-
const dep = resolveImport(this.program,
|
|
2601
|
-
npmStaticDepSf7(this.program,
|
|
3143
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(importDecl), spec) ??
|
|
3144
|
+
npmStaticDepSf7(this.program, ts.getSourceFileOfNode(importDecl), spec);
|
|
2602
3145
|
if (!dep || !isJsSourceFile(dep) || isNodeEsmFile(dep, this.program))
|
|
2603
3146
|
return null;
|
|
2604
3147
|
return dep;
|
|
2605
3148
|
}
|
|
3149
|
+
/** The table module a non-identifier module reference names: an inline
|
|
3150
|
+
* `require("./x")` (cjs-inline-require.ts) or tsc's unstamped
|
|
3151
|
+
* `x_1.default` interop read (cjs-tsc-interop.ts). */
|
|
3152
|
+
cjsModuleRefDepOf(expr) {
|
|
3153
|
+
const inline = inlineNamespaceRequireOf(this, expr);
|
|
3154
|
+
if (inline !== null)
|
|
3155
|
+
return inline.dep;
|
|
3156
|
+
const interop = tscInteropModuleOf(this, expr);
|
|
3157
|
+
return interop !== null && cjsNamespaceModule(this, interop.dep) ? interop.dep : null;
|
|
3158
|
+
}
|
|
3159
|
+
/** The table module a CommonJS module binding identifier names. */
|
|
3160
|
+
cjsModuleBindingDepOf(expr) {
|
|
3161
|
+
return this.localModuleBindingDepOf(expr);
|
|
3162
|
+
}
|
|
2606
3163
|
/** The compiled module behind a require-like namespace binding: an
|
|
2607
3164
|
* ordinary CommonJS require declaration, a canonical createRequire
|
|
2608
3165
|
* declaration, or an ESM default import of CommonJS. One resolver keeps
|
|
2609
3166
|
* member-symbol fallback and namespace classification in lockstep. */
|
|
2610
3167
|
localModuleBindingDepOf(expr) {
|
|
2611
3168
|
const sym = this.checker.getSymbolAtLocation(expr);
|
|
2612
|
-
const decls = sym ?
|
|
3169
|
+
const decls = sym ? sym.declarations : [];
|
|
2613
3170
|
const decl = decls.find(ts.isImportClause) ?? decls[0];
|
|
2614
3171
|
if (!decl)
|
|
2615
3172
|
return null;
|
|
@@ -2617,10 +3174,17 @@ export class Lowerer {
|
|
|
2617
3174
|
return this.cjsDefaultImportDepOf(decl);
|
|
2618
3175
|
if (!ts.isVariableDeclaration(decl) || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
2619
3176
|
return null;
|
|
3177
|
+
{
|
|
3178
|
+
const interop = tscInteropModuleOf(this, expr);
|
|
3179
|
+
if (interop !== null)
|
|
3180
|
+
return cjsNamespaceModule(this, interop.dep) ? interop.dep : null;
|
|
3181
|
+
}
|
|
2620
3182
|
const directSpec = requireSpecOf(decl.initializer);
|
|
2621
3183
|
if (directSpec !== null) {
|
|
2622
|
-
|
|
2623
|
-
|
|
3184
|
+
if (isJsonRequireDecl(this, decl))
|
|
3185
|
+
return null;
|
|
3186
|
+
return (resolveImport(this.program, ts.getSourceFileOfNode(decl), directSpec, "require") ??
|
|
3187
|
+
npmStaticDepSf7(this.program, ts.getSourceFileOfNode(decl), directSpec, "require"));
|
|
2624
3188
|
}
|
|
2625
3189
|
return createRequireProgramModuleOf(this, decl.initializer)?.dep ?? null;
|
|
2626
3190
|
}
|
|
@@ -2631,9 +3195,7 @@ export class Lowerer {
|
|
|
2631
3195
|
* static storage or callable/class metadata. */
|
|
2632
3196
|
createRequireWholeExportSymbolOf(ident) {
|
|
2633
3197
|
const binding = this.checker.getSymbolAtLocation(ident);
|
|
2634
|
-
const decl = binding
|
|
2635
|
-
? this.checker.declarationsOf(binding).find(ts.isVariableDeclaration)
|
|
2636
|
-
: undefined;
|
|
3198
|
+
const decl = binding ? binding.declarations.find(ts.isVariableDeclaration) : undefined;
|
|
2637
3199
|
if (!decl || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
2638
3200
|
return null;
|
|
2639
3201
|
const target = createRequireProgramModuleOf(this, decl.initializer);
|
|
@@ -2643,9 +3205,7 @@ export class Lowerer {
|
|
|
2643
3205
|
let symbol = moduleSym?.getExports().get("export=");
|
|
2644
3206
|
if (!symbol)
|
|
2645
3207
|
return null;
|
|
2646
|
-
const wholeAssignment =
|
|
2647
|
-
.declarationsOf(symbol)
|
|
2648
|
-
.find((d) => {
|
|
3208
|
+
const wholeAssignment = symbol.declarations.find((d) => {
|
|
2649
3209
|
if (!ts.isBinaryExpression(d) ||
|
|
2650
3210
|
!ts.isExpressionStatement(d.parent) ||
|
|
2651
3211
|
!ts.isSourceFile(d.parent.parent))
|
|
@@ -2660,6 +3220,10 @@ export class Lowerer {
|
|
|
2660
3220
|
let rhs = wholeAssignment.right;
|
|
2661
3221
|
while (ts.isParenthesizedExpression(rhs))
|
|
2662
3222
|
rhs = rhs.expression;
|
|
3223
|
+
// A pure re-export (`module.exports = require("./core")`) is the inner
|
|
3224
|
+
// module's export table, read like any namespace binding.
|
|
3225
|
+
if (inlineProgramRequireOf(this, rhs) !== null && !this.globalsByDeclNode.has(wholeAssignment))
|
|
3226
|
+
return null;
|
|
2663
3227
|
if (ts.isIdentifier(rhs)) {
|
|
2664
3228
|
const value = this.checker.getSymbolAtLocation(rhs);
|
|
2665
3229
|
if (value) {
|
|
@@ -2678,9 +3242,7 @@ export class Lowerer {
|
|
|
2678
3242
|
* target module's real export symbol. */
|
|
2679
3243
|
createRequireDestructuredExportSymbolOf(ident) {
|
|
2680
3244
|
const binding = this.checker.getSymbolAtLocation(ident);
|
|
2681
|
-
const element = binding
|
|
2682
|
-
? this.checker.declarationsOf(binding).find(ts.isBindingElement)
|
|
2683
|
-
: undefined;
|
|
3245
|
+
const element = binding ? binding.declarations.find(ts.isBindingElement) : undefined;
|
|
2684
3246
|
if (!element ||
|
|
2685
3247
|
element.name === undefined ||
|
|
2686
3248
|
!ts.isIdentifier(element.name) ||
|
|
@@ -2709,8 +3271,10 @@ export class Lowerer {
|
|
|
2709
3271
|
* symbols → resolveValueSymbol); the bare value keeps the
|
|
2710
3272
|
* namespace-object fence, like ESM namespace imports of builtins. */
|
|
2711
3273
|
cjsLocalModuleBindingOf(expr) {
|
|
3274
|
+
// An inline `require("./x")` over a table module reads its members like
|
|
3275
|
+
// a binding (cjs-inline-require.ts sequences the module's %init).
|
|
2712
3276
|
if (!ts.isIdentifier(expr))
|
|
2713
|
-
return
|
|
3277
|
+
return this.cjsModuleRefDepOf(expr) !== null;
|
|
2714
3278
|
const sym = this.checker.getSymbolAtLocation(expr);
|
|
2715
3279
|
if (this.localModuleBindingDepOf(expr) === null)
|
|
2716
3280
|
return false;
|
|
@@ -2725,7 +3289,10 @@ export class Lowerer {
|
|
|
2725
3289
|
// the object literal) keep the namespace reading — member accesses
|
|
2726
3290
|
// resolve through the table's property symbols.
|
|
2727
3291
|
if (sym && sym.flags & ts.SymbolFlags.Alias) {
|
|
2728
|
-
|
|
3292
|
+
// `module.exports = TypeError`: the binding IS the builtin global.
|
|
3293
|
+
if (this.isStdlibSymbol(this.checker.getAliasedSymbol(sym)))
|
|
3294
|
+
return false;
|
|
3295
|
+
const d = this.checker.getAliasedSymbol(sym).declarations[0];
|
|
2729
3296
|
if (d && (ts.isClassDeclaration(d) || ts.isFunctionDeclaration(d)))
|
|
2730
3297
|
return false;
|
|
2731
3298
|
if (d && ts.isVariableDeclaration(d)) {
|
|
@@ -2795,7 +3362,7 @@ export class Lowerer {
|
|
|
2795
3362
|
g.type = this.runtimeOptionalBindingType(ident, g.type);
|
|
2796
3363
|
return g;
|
|
2797
3364
|
}
|
|
2798
|
-
for (const d of
|
|
3365
|
+
for (const d of symbol.declarations) {
|
|
2799
3366
|
const byDecl = this.globalsByDeclNode.get(d);
|
|
2800
3367
|
if (byDecl)
|
|
2801
3368
|
return byDecl;
|
|
@@ -2825,6 +3392,16 @@ export class Lowerer {
|
|
|
2825
3392
|
const id = `%g.${tag}%loaded`;
|
|
2826
3393
|
this.moduleGuardOf.set(fp.sf, id);
|
|
2827
3394
|
this.globalsList.push({ id, name: "%loaded", type: BOOL, mutable: true });
|
|
3395
|
+
if (usesCjsTopLevelThis(this, fp.sf) || usesCjsExportsIdentity(this, fp.sf)) {
|
|
3396
|
+
const exportsThis = {
|
|
3397
|
+
id: `%g.${tag}%exportsThis`,
|
|
3398
|
+
name: "%exportsThis",
|
|
3399
|
+
type: DYN,
|
|
3400
|
+
mutable: true,
|
|
3401
|
+
};
|
|
3402
|
+
this.globalsList.push(exportsThis);
|
|
3403
|
+
this.cjsExportsThis.set(fp.sf, exportsThis);
|
|
3404
|
+
}
|
|
2828
3405
|
}
|
|
2829
3406
|
// A module is intrinsically async when an await/for-await occurs
|
|
2830
3407
|
// outside every nested function-like boundary. Then propagate that
|
|
@@ -2944,6 +3521,59 @@ export class Lowerer {
|
|
|
2944
3521
|
if (!indexOf.has(fp.sf))
|
|
2945
3522
|
visit(fp.sf);
|
|
2946
3523
|
}
|
|
3524
|
+
/** node:punycode's load at a require() call: the module body reports
|
|
3525
|
+
* DEP0040 when it first runs, unless isInsideNodeModules() finds the
|
|
3526
|
+
* requiring frame in a dependency, and process.emitWarning delivers the
|
|
3527
|
+
* report on the next tick. Later loads are cache hits either way. */
|
|
3528
|
+
punycodeRequireWarning(node) {
|
|
3529
|
+
const loc = locOf(node);
|
|
3530
|
+
const fromDependency = /[\\/]node_modules[\\/]/.test(ts.getSourceFileOfNode(node).fileName);
|
|
3531
|
+
return {
|
|
3532
|
+
kind: "exprStmt",
|
|
3533
|
+
expr: {
|
|
3534
|
+
kind: "libCall",
|
|
3535
|
+
fn: "punycode.warn",
|
|
3536
|
+
args: [
|
|
3537
|
+
{ kind: "boolLit", value: false, type: BOOL, loc },
|
|
3538
|
+
{ kind: "boolLit", value: !fromDependency, type: BOOL, loc },
|
|
3539
|
+
],
|
|
3540
|
+
type: VOID,
|
|
3541
|
+
loc,
|
|
3542
|
+
},
|
|
3543
|
+
loc,
|
|
3544
|
+
};
|
|
3545
|
+
}
|
|
3546
|
+
/** node:punycode's DEP0040 for a static ES import anywhere in the module
|
|
3547
|
+
* graph: Node links builtins before any module evaluates, so the report
|
|
3548
|
+
* comes first, before the program can register a 'warning' listener —
|
|
3549
|
+
* whichever file imports it (a dependency's ES import has no requiring
|
|
3550
|
+
* frame either). Prepended to the entry's %init. */
|
|
3551
|
+
punycodeLinkWarning() {
|
|
3552
|
+
const imports = this.moduleOrder.some((sf) => sf.statements.nodes.some((stmt) => ((ts.isImportDeclaration(stmt) && !erasedTypeOnlyImport(stmt)) ||
|
|
3553
|
+
(ts.isExportDeclaration(stmt) && !stmt.isTypeOnly)) &&
|
|
3554
|
+
stmt.moduleSpecifier !== undefined &&
|
|
3555
|
+
ts.isStringLiteral(stmt.moduleSpecifier) &&
|
|
3556
|
+
canonicalBuiltinModule(stmt.moduleSpecifier.text) === "punycode"));
|
|
3557
|
+
if (!imports)
|
|
3558
|
+
return [];
|
|
3559
|
+
const loc = { file: this.entry.fileName, start: 0, end: 0 };
|
|
3560
|
+
return [
|
|
3561
|
+
{
|
|
3562
|
+
kind: "exprStmt",
|
|
3563
|
+
expr: {
|
|
3564
|
+
kind: "libCall",
|
|
3565
|
+
fn: "punycode.warn",
|
|
3566
|
+
args: [
|
|
3567
|
+
{ kind: "boolLit", value: true, type: BOOL, loc },
|
|
3568
|
+
{ kind: "boolLit", value: true, type: BOOL, loc },
|
|
3569
|
+
],
|
|
3570
|
+
type: VOID,
|
|
3571
|
+
loc,
|
|
3572
|
+
},
|
|
3573
|
+
loc,
|
|
3574
|
+
},
|
|
3575
|
+
];
|
|
3576
|
+
}
|
|
2947
3577
|
/** The lowering of a CommonJS `require("./local")` occurrence: a call of
|
|
2948
3578
|
* the required module's run-once %init at exactly this statement's
|
|
2949
3579
|
* position — Node's inline evaluation, with the guard supplying the
|
|
@@ -2953,6 +3583,8 @@ export class Lowerer {
|
|
|
2953
3583
|
* their external dependencies by name). Null for everything else
|
|
2954
3584
|
* (builtins load nothing; the rest kept its preflight fence). */
|
|
2955
3585
|
requireInitStmt(spec, node) {
|
|
3586
|
+
if (canonicalBuiltinModule(spec) === "punycode")
|
|
3587
|
+
return this.punycodeRequireWarning(node);
|
|
2956
3588
|
// Project requires resolve within the program; another bare require can
|
|
2957
3589
|
// be a program-module edge when it names an opted-in --npm-static package
|
|
2958
3590
|
// (one package requiring another — the resolution answered its shipped
|
|
@@ -2960,8 +3592,8 @@ export class Lowerer {
|
|
|
2960
3592
|
// Without the guarded %init call at this position
|
|
2961
3593
|
// those globals stay uninitialized: the dep's module body would never
|
|
2962
3594
|
// run.
|
|
2963
|
-
const dep = resolveImport(this.program,
|
|
2964
|
-
npmStaticDepSf7(this.program,
|
|
3595
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(node), spec, "require") ??
|
|
3596
|
+
npmStaticDepSf7(this.program, ts.getSourceFileOfNode(node), spec, "require");
|
|
2965
3597
|
if (!dep || dep.fileName.endsWith(".json"))
|
|
2966
3598
|
return null;
|
|
2967
3599
|
if (this.asyncInitFiles.has(dep)) {
|
|
@@ -2976,7 +3608,7 @@ export class Lowerer {
|
|
|
2976
3608
|
expr: { kind: "call", callee: initName, args: [], type: VOID, loc },
|
|
2977
3609
|
loc,
|
|
2978
3610
|
};
|
|
2979
|
-
const parentModule = this.cjsModuleIdOf.get(
|
|
3611
|
+
const parentModule = this.cjsModuleIdOf.get(ts.getSourceFileOfNode(node));
|
|
2980
3612
|
const childModule = this.cjsModuleIdOf.get(dep);
|
|
2981
3613
|
if (parentModule === undefined || childModule === undefined)
|
|
2982
3614
|
return init;
|
|
@@ -3018,6 +3650,97 @@ export class Lowerer {
|
|
|
3018
3650
|
* TypeScript's default indexed-access type is a useful source annotation,
|
|
3019
3651
|
* but it is not a runtime proof; promoting only the affected slots keeps
|
|
3020
3652
|
* the rest of the dense ABI unchanged. */
|
|
3653
|
+
/** A Date's `toJSON()` answers null for an invalid date while the lib
|
|
3654
|
+
* types say `string`: unannotated bindings initialized by such a call,
|
|
3655
|
+
* and object-literal fields holding one, keep `string | null`. */
|
|
3656
|
+
analyzeDateJsonResults(parts) {
|
|
3657
|
+
const nullable = dateJsonType(this);
|
|
3658
|
+
for (const { sf } of parts) {
|
|
3659
|
+
if (!sf.text.includes("toJSON"))
|
|
3660
|
+
continue;
|
|
3661
|
+
ts.walkPreorder(sf, (node) => {
|
|
3662
|
+
// `x = d.toJSON()`: the checker narrows x to string after the
|
|
3663
|
+
// assignment, so its reads must stay checked.
|
|
3664
|
+
if (ts.isBinaryExpression(node) &&
|
|
3665
|
+
node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
3666
|
+
ts.isIdentifier(node.left) &&
|
|
3667
|
+
isDateJsonSource(this, node.right)) {
|
|
3668
|
+
const symbol = this.checker.getSymbolAtLocation(node.left);
|
|
3669
|
+
if (symbol)
|
|
3670
|
+
this.dateJsonBindings.add(symbol);
|
|
3671
|
+
return undefined;
|
|
3672
|
+
}
|
|
3673
|
+
if (!ts.isVariableDeclaration(node) || !node.initializer)
|
|
3674
|
+
return undefined;
|
|
3675
|
+
if (!ts.isIdentifier(node.name))
|
|
3676
|
+
return undefined;
|
|
3677
|
+
const symbol = this.checker.getSymbolAtLocation(node.name);
|
|
3678
|
+
if (!symbol)
|
|
3679
|
+
return undefined;
|
|
3680
|
+
let init = node.initializer;
|
|
3681
|
+
while (ts.isParenthesizedExpression(init))
|
|
3682
|
+
init = init.expression;
|
|
3683
|
+
if (isDateJsonSource(this, init)) {
|
|
3684
|
+
this.dateJsonBindings.add(symbol);
|
|
3685
|
+
// An annotation keeps its declared storage.
|
|
3686
|
+
if (!node.type)
|
|
3687
|
+
this.runtimeOptionalBindingTypes.set(symbol, nullable);
|
|
3688
|
+
return undefined;
|
|
3689
|
+
}
|
|
3690
|
+
if (node.type)
|
|
3691
|
+
return undefined;
|
|
3692
|
+
if (!ts.isObjectLiteralExpression(init))
|
|
3693
|
+
return undefined;
|
|
3694
|
+
const declared = this.mapTypeOf(this.typeOf(node.name));
|
|
3695
|
+
if (declared?.kind !== "record")
|
|
3696
|
+
return undefined;
|
|
3697
|
+
let widened = declared;
|
|
3698
|
+
for (const property of init.properties.nodes) {
|
|
3699
|
+
const value = ts.isPropertyAssignment(property)
|
|
3700
|
+
? property.initializer
|
|
3701
|
+
: ts.isShorthandPropertyAssignment(property)
|
|
3702
|
+
? property.name
|
|
3703
|
+
: null;
|
|
3704
|
+
const name = property.name && (ts.isIdentifier(property.name) || ts.isStringLiteral(property.name))
|
|
3705
|
+
? property.name.text
|
|
3706
|
+
: null;
|
|
3707
|
+
if (value && name !== null && isDateJsonSource(this, value))
|
|
3708
|
+
widened = this.runtimeOptionalRecordField(widened, name, nullable);
|
|
3709
|
+
}
|
|
3710
|
+
if (widened !== declared)
|
|
3711
|
+
this.runtimeOptionalBindingTypes.set(symbol, widened);
|
|
3712
|
+
return undefined;
|
|
3713
|
+
});
|
|
3714
|
+
}
|
|
3715
|
+
}
|
|
3716
|
+
/** A file-scope get-or-create read (`let e = map[k]; if (e ===
|
|
3717
|
+
* undefined) ...` over an index-signature record) keeps a missing key as
|
|
3718
|
+
* undefined (isGuardedRecordRead). Its pre-registered global takes the
|
|
3719
|
+
* undefined arm before any body reads it; the declaration lowers its
|
|
3720
|
+
* initializer as the matching absence probe. */
|
|
3721
|
+
analyzeGuardedRecordReadGlobals(parts) {
|
|
3722
|
+
for (const { sf } of parts) {
|
|
3723
|
+
for (const statement of sf.statements.nodes) {
|
|
3724
|
+
if (!ts.isVariableStatement(statement))
|
|
3725
|
+
continue;
|
|
3726
|
+
for (const decl of statement.declarationList.declarations.nodes) {
|
|
3727
|
+
if (!ts.isIdentifier(decl.name) || !isGuardedRecordRead(this, decl))
|
|
3728
|
+
continue;
|
|
3729
|
+
const global = this.globalOf(decl.name);
|
|
3730
|
+
const symbol = this.resolveValueSymbol(decl.name);
|
|
3731
|
+
if (!global || !symbol || global.tdz || this.runtimeOptionalBindingTypes.has(symbol))
|
|
3732
|
+
continue;
|
|
3733
|
+
const widened = global.type.kind === "union"
|
|
3734
|
+
? this.withUndefinedArmOf(global.type)
|
|
3735
|
+
: this.withUndefinedArm(global.type);
|
|
3736
|
+
if (!widened || typeEquals(widened, global.type))
|
|
3737
|
+
continue;
|
|
3738
|
+
global.type = widened;
|
|
3739
|
+
this.runtimeOptionalBindingTypes.set(symbol, widened);
|
|
3740
|
+
}
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
}
|
|
3021
3744
|
analyzeRuntimeOptionalArrayReads(parts) {
|
|
3022
3745
|
const provenance = RuntimeOptionalProvenance.fromEnvironment();
|
|
3023
3746
|
// The site whose value the current promotion follows (debug only).
|
|
@@ -3138,7 +3861,7 @@ export class Lowerer {
|
|
|
3138
3861
|
const symbol = (ts.isFunctionDeclaration(fn) || ts.isMethodDeclaration(fn)) && fn.name
|
|
3139
3862
|
? symbolOf(fn.name)
|
|
3140
3863
|
: null;
|
|
3141
|
-
const index = fn.parameters.indexOf(parameter);
|
|
3864
|
+
const index = fn.parameters.nodes.indexOf(parameter);
|
|
3142
3865
|
return (symbol && signatureBySymbol.get(symbol)?.params[index]?.type) ?? null;
|
|
3143
3866
|
};
|
|
3144
3867
|
const returnTypeOf = (fn) => {
|
|
@@ -3147,7 +3870,7 @@ export class Lowerer {
|
|
|
3147
3870
|
};
|
|
3148
3871
|
const recordFlows = new RecordFlowClasses(sourceFiles, {
|
|
3149
3872
|
symbolOf,
|
|
3150
|
-
declarationOf: (symbol) =>
|
|
3873
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
3151
3874
|
mayBeRecord: (node) => {
|
|
3152
3875
|
if (node.parent && ts.isParameter(node.parent))
|
|
3153
3876
|
return plainRecordShape(parameterType(node)) !== null;
|
|
@@ -3172,11 +3895,12 @@ export class Lowerer {
|
|
|
3172
3895
|
const recordParameterSlots = new Map();
|
|
3173
3896
|
const nanCoded = new NanCodedReads({
|
|
3174
3897
|
symbolOf,
|
|
3175
|
-
declarationOf: (symbol) =>
|
|
3898
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
3176
3899
|
bytesElemOf: (receiver) => {
|
|
3177
3900
|
const t = mappedOrNull(receiver);
|
|
3178
3901
|
return t?.kind === "bytes" ? t.elem : null;
|
|
3179
3902
|
},
|
|
3903
|
+
isNumberRecordRead: (read) => this.optionalIndexSignatureRead(read)?.kind === "f64",
|
|
3180
3904
|
isNumber: (node) => mappedOrNull(node)?.kind === "f64",
|
|
3181
3905
|
isString: (node) => mappedOrNull(node)?.kind === "string",
|
|
3182
3906
|
hasLength: (node) => {
|
|
@@ -3218,7 +3942,7 @@ export class Lowerer {
|
|
|
3218
3942
|
const seen = new Set();
|
|
3219
3943
|
while (symbol && !signatureBySymbol.has(symbol) && !seen.has(symbol)) {
|
|
3220
3944
|
seen.add(symbol);
|
|
3221
|
-
const declaration =
|
|
3945
|
+
const declaration = symbol.valueDeclaration;
|
|
3222
3946
|
if (declaration && ts.isMethodDeclaration(declaration)) {
|
|
3223
3947
|
symbol = symbolOf(declaration.name);
|
|
3224
3948
|
}
|
|
@@ -3317,14 +4041,109 @@ export class Lowerer {
|
|
|
3317
4041
|
// every consumer treats undefined like NaN.
|
|
3318
4042
|
if (kind === "bytes")
|
|
3319
4043
|
return !nanCoded.isNumericRead(e);
|
|
4044
|
+
if (kind === "record")
|
|
4045
|
+
return this.optionalIndexSignatureRead(e) !== null && !nanCoded.isNumericRead(e);
|
|
3320
4046
|
return kind === "array";
|
|
3321
4047
|
};
|
|
4048
|
+
/** `r.name` where the name resolves to the receiver's index signature. */
|
|
4049
|
+
const isRecordIndexPropertyRead = (e) => {
|
|
4050
|
+
// A name that resolves to a declared member is not an index read, and
|
|
4051
|
+
// only a receiver with an index signature maps to an indexed record.
|
|
4052
|
+
if (symbolOf(e.name))
|
|
4053
|
+
return false;
|
|
4054
|
+
const receiverType = this.typeOf(e.expression);
|
|
4055
|
+
if (this.checker.getIndexInfosOfType(receiverType).length === 0)
|
|
4056
|
+
return false;
|
|
4057
|
+
const receiver = this.mapTypeOf(receiverType);
|
|
4058
|
+
if (receiver?.kind !== "record")
|
|
4059
|
+
return false;
|
|
4060
|
+
const shape = this.shapes.get(receiver.shapeId);
|
|
4061
|
+
if (!shape || shape.tuple || !shape.indexValue || shape.indexValue.kind === "dyn")
|
|
4062
|
+
return false;
|
|
4063
|
+
if (shape.fields.some((field) => field.name === e.name.text))
|
|
4064
|
+
return false;
|
|
4065
|
+
const read = this.mapTypeOf(this.typeOf(e));
|
|
4066
|
+
return !(read?.kind === "union" && this.armTag(read.unionId, UNDEFINED_T) >= 0);
|
|
4067
|
+
};
|
|
4068
|
+
/** An optional value in a generic body, where element types are type
|
|
4069
|
+
* parameters with no IR mapping yet: an element read of an array or a
|
|
4070
|
+
* read of a string index signature, judged on checker types. */
|
|
4071
|
+
const genericClassMethods = [];
|
|
4072
|
+
for (const sf of sourceFiles) {
|
|
4073
|
+
if (isJsSourceFile(sf) || sf.isDeclarationFile)
|
|
4074
|
+
continue;
|
|
4075
|
+
ts.walkPreorder(sf, (node) => {
|
|
4076
|
+
if (!ts.isClassDeclaration(node))
|
|
4077
|
+
return undefined;
|
|
4078
|
+
const genericClass = (node.typeParameters?.nodes.length ?? 0) > 0;
|
|
4079
|
+
for (const member of node.members.nodes)
|
|
4080
|
+
if (ts.isMethodDeclaration(member) &&
|
|
4081
|
+
member.body &&
|
|
4082
|
+
(genericClass || (member.typeParameters?.nodes.length ?? 0) > 0))
|
|
4083
|
+
genericClassMethods.push(member);
|
|
4084
|
+
return undefined;
|
|
4085
|
+
});
|
|
4086
|
+
}
|
|
4087
|
+
const genericMayBeOptional = (node) => {
|
|
4088
|
+
if (explicitlyNonNull(node))
|
|
4089
|
+
return false;
|
|
4090
|
+
if (mayBeOptional(node))
|
|
4091
|
+
return true;
|
|
4092
|
+
const e = peel(node);
|
|
4093
|
+
if (ts.isConditionalExpression(e))
|
|
4094
|
+
return genericMayBeOptional(e.whenTrue) || genericMayBeOptional(e.whenFalse);
|
|
4095
|
+
if (ts.isBinaryExpression(e)) {
|
|
4096
|
+
const op = e.operatorToken.kind;
|
|
4097
|
+
if (op === ts.SyntaxKind.BarBarToken || op === ts.SyntaxKind.QuestionQuestionToken)
|
|
4098
|
+
return genericMayBeOptional(e.right);
|
|
4099
|
+
if (op === ts.SyntaxKind.AmpersandAmpersandToken)
|
|
4100
|
+
return genericMayBeOptional(e.left) || genericMayBeOptional(e.right);
|
|
4101
|
+
return false;
|
|
4102
|
+
}
|
|
4103
|
+
if (ts.isIdentifier(e)) {
|
|
4104
|
+
// A binding initialized from such a read and never reassigned.
|
|
4105
|
+
const symbol = symbolOf(e);
|
|
4106
|
+
const decl = symbol ? symbol.valueDeclaration : undefined;
|
|
4107
|
+
return (symbol !== null &&
|
|
4108
|
+
!reassigned.has(symbol) &&
|
|
4109
|
+
decl !== undefined &&
|
|
4110
|
+
ts.isVariableDeclaration(decl) &&
|
|
4111
|
+
decl.initializer !== undefined &&
|
|
4112
|
+
ts.isIdentifier(decl.name) &&
|
|
4113
|
+
!provenPresent(e, symbol) &&
|
|
4114
|
+
genericIndexedRead(decl.initializer));
|
|
4115
|
+
}
|
|
4116
|
+
return genericIndexedRead(e);
|
|
4117
|
+
};
|
|
4118
|
+
const genericIndexedRead = (node) => {
|
|
4119
|
+
const e = peel(node);
|
|
4120
|
+
if (!ts.isElementAccessExpression(e) || explicitlyNonNull(node))
|
|
4121
|
+
return false;
|
|
4122
|
+
const read = typeOrNull(e);
|
|
4123
|
+
if (!read || (read.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Any)) !== 0)
|
|
4124
|
+
return false;
|
|
4125
|
+
if (read.isUnionType() &&
|
|
4126
|
+
ts.constituentTypes(read).some((t) => (t.flags & ts.TypeFlags.Undefined) !== 0))
|
|
4127
|
+
return false;
|
|
4128
|
+
const receiver = typeOrNull(e.expression);
|
|
4129
|
+
if (!receiver || this.checker.isTupleType(receiver))
|
|
4130
|
+
return false;
|
|
4131
|
+
if (this.checker.isArrayType(receiver))
|
|
4132
|
+
return true;
|
|
4133
|
+
const key = e.argumentExpression;
|
|
4134
|
+
if ((ts.isStringLiteral(key) || ts.isNumericLiteral(key)) &&
|
|
4135
|
+
this.checker.getPropertyOfType(receiver, key.text) !== undefined)
|
|
4136
|
+
return false;
|
|
4137
|
+
return this.checker
|
|
4138
|
+
.getIndexInfosOfType(receiver)
|
|
4139
|
+
.some((info) => (info.keyType.flags & ts.TypeFlags.StringLike) !== 0);
|
|
4140
|
+
};
|
|
3322
4141
|
const isDynamicObjectEntryRead = (node) => {
|
|
3323
4142
|
const read = peel(node);
|
|
3324
4143
|
if (!ts.isElementAccessExpression(read) || !ts.isIdentifier(read.expression))
|
|
3325
4144
|
return false;
|
|
3326
4145
|
const source = symbolOf(read.expression);
|
|
3327
|
-
const declaration = source ?
|
|
4146
|
+
const declaration = source ? source.valueDeclaration : undefined;
|
|
3328
4147
|
if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer)
|
|
3329
4148
|
return false;
|
|
3330
4149
|
const init = peel(declaration.initializer);
|
|
@@ -3333,14 +4152,17 @@ export class Lowerer {
|
|
|
3333
4152
|
if (init.expression.name.text !== "entries" ||
|
|
3334
4153
|
!this.isStdlibGlobal(init.expression.expression, "Object"))
|
|
3335
4154
|
return false;
|
|
3336
|
-
const object = init.arguments[0];
|
|
4155
|
+
const object = init.arguments.nodes[0];
|
|
3337
4156
|
const objectType = object ? this.mapTypeOf(this.typeOf(object)) : null;
|
|
3338
4157
|
return objectType?.kind === "dyn";
|
|
3339
4158
|
};
|
|
3340
4159
|
const addUndefined = (t) => {
|
|
3341
4160
|
if (t.kind === "union")
|
|
3342
4161
|
return this.armTag(t.unionId, UNDEFINED_T) >= 0 ? t : (this.withUndefinedArmOf(t) ?? t);
|
|
3343
|
-
|
|
4162
|
+
// A Date has no undefined-armed union (it is not a union arm kind):
|
|
4163
|
+
// like a generator it keeps its type, and the site that would store
|
|
4164
|
+
// undefined into it keeps its own diagnostic.
|
|
4165
|
+
if (t.kind === "void" || t.kind === "dyn" || t.kind === "generator" || t.kind === "date")
|
|
3344
4166
|
return t;
|
|
3345
4167
|
return this.withUndefinedArm(t);
|
|
3346
4168
|
};
|
|
@@ -3376,17 +4198,45 @@ export class Lowerer {
|
|
|
3376
4198
|
// Such a binding reads `T | undefined`, so a typed parameter, local or
|
|
3377
4199
|
// field it flows into widens like any other missing element read.
|
|
3378
4200
|
const holeyIterationSymbols = new Set();
|
|
4201
|
+
// `xs[i] as number` and `stack.pop() as number`: an assertion to a type
|
|
4202
|
+
// without undefined checks the value (lowerAsExpression narrows to the
|
|
4203
|
+
// asserted type and throws a TypeError for undefined), so its result is
|
|
4204
|
+
// never undefined.
|
|
4205
|
+
const assertsDefined = (node) => {
|
|
4206
|
+
let e = node;
|
|
4207
|
+
while (ts.isParenthesizedExpression(e))
|
|
4208
|
+
e = e.expression;
|
|
4209
|
+
if (!ts.isAsExpression(e) && !ts.isTypeAssertion(e))
|
|
4210
|
+
return false;
|
|
4211
|
+
const asserted = typeOrNull(e);
|
|
4212
|
+
const admits = (type) => (type.flags &
|
|
4213
|
+
(ts.TypeFlags.Any |
|
|
4214
|
+
ts.TypeFlags.Unknown |
|
|
4215
|
+
ts.TypeFlags.Undefined |
|
|
4216
|
+
ts.TypeFlags.Void |
|
|
4217
|
+
ts.TypeFlags.TypeParameter)) !==
|
|
4218
|
+
0;
|
|
4219
|
+
return (asserted !== null &&
|
|
4220
|
+
!admits(asserted) &&
|
|
4221
|
+
!(asserted.isUnionType() && ts.constituentTypes(asserted).some(admits)));
|
|
4222
|
+
};
|
|
3379
4223
|
const mayBeOptional = (node) => {
|
|
3380
4224
|
// `xs[i]!` is the explicit proven-present form. Its array read keeps
|
|
3381
4225
|
// the established dense bounds trap and must not promote the enclosing
|
|
3382
4226
|
// function/global ABI to `T | undefined`.
|
|
3383
4227
|
if (explicitlyNonNull(node))
|
|
3384
4228
|
return false;
|
|
4229
|
+
if (assertsDefined(node))
|
|
4230
|
+
return false;
|
|
3385
4231
|
const e = peel(node);
|
|
3386
4232
|
if (isIndexedRead(e))
|
|
3387
4233
|
return true;
|
|
4234
|
+
if (ts.isPropertyAccessExpression(e) && isRecordIndexPropertyRead(e))
|
|
4235
|
+
return true;
|
|
3388
4236
|
if (ts.isPropertyAccessExpression(e) && isOptionalProcessStreamProperty(this, e))
|
|
3389
4237
|
return true;
|
|
4238
|
+
if (isOptionalProcessVersionsRead(this, e))
|
|
4239
|
+
return true;
|
|
3390
4240
|
if (ts.isPropertyAccessExpression(e) && isSettledIteratorValueRead(this, e))
|
|
3391
4241
|
return true;
|
|
3392
4242
|
if (ts.isPropertyAccessExpression(e) && isOsConstantsSymbol(symbolOf(e.expression), this))
|
|
@@ -3394,7 +4244,7 @@ export class Lowerer {
|
|
|
3394
4244
|
if (ts.isCallExpression(e) && this.runtimeOptionalReduceTypes.has(e))
|
|
3395
4245
|
return true;
|
|
3396
4246
|
if (ts.isCallExpression(e) &&
|
|
3397
|
-
e.arguments.length === 0 &&
|
|
4247
|
+
e.arguments.nodes.length === 0 &&
|
|
3398
4248
|
ts.isPropertyAccessExpression(e.expression) &&
|
|
3399
4249
|
e.expression.name.text === "stringify" &&
|
|
3400
4250
|
this.isStdlibGlobal(e.expression.expression, "JSON"))
|
|
@@ -3532,12 +4382,12 @@ export class Lowerer {
|
|
|
3532
4382
|
* exactly `T | undefined`: an assignment from a missing read stores the
|
|
3533
4383
|
* undefined arm while the checker narrows later reads to `T`. */
|
|
3534
4384
|
const optionalInstanceField = (symbol) => {
|
|
3535
|
-
const decl =
|
|
4385
|
+
const decl = symbol.valueDeclaration;
|
|
3536
4386
|
if (!decl || !ts.isPropertyDeclaration(decl) || !ts.isIdentifier(decl.name))
|
|
3537
4387
|
return false;
|
|
3538
4388
|
if (ts.getCombinedModifierFlags(decl) & ts.ModifierFlags.Static)
|
|
3539
4389
|
return false;
|
|
3540
|
-
const sf =
|
|
4390
|
+
const sf = ts.getSourceFileOfNode(decl);
|
|
3541
4391
|
if (isJsSourceFile(sf) || sf.isDeclarationFile)
|
|
3542
4392
|
return false;
|
|
3543
4393
|
const declared = typeOrNull(decl.name);
|
|
@@ -3569,7 +4419,7 @@ export class Lowerer {
|
|
|
3569
4419
|
// A fresh literal carries the fields its values can leave undefined.
|
|
3570
4420
|
if (ts.isObjectLiteralExpression(e)) {
|
|
3571
4421
|
const out = spreadFieldsOf(e);
|
|
3572
|
-
for (const prop of e.properties) {
|
|
4422
|
+
for (const prop of e.properties.nodes) {
|
|
3573
4423
|
if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop))
|
|
3574
4424
|
continue;
|
|
3575
4425
|
const name = prop.name;
|
|
@@ -3607,7 +4457,7 @@ export class Lowerer {
|
|
|
3607
4457
|
* the properties a later member writes explicitly. */
|
|
3608
4458
|
const spreadFieldsOf = (object) => {
|
|
3609
4459
|
const out = new Set();
|
|
3610
|
-
for (const prop of object.properties) {
|
|
4460
|
+
for (const prop of object.properties.nodes) {
|
|
3611
4461
|
if (ts.isSpreadAssignment(prop)) {
|
|
3612
4462
|
const fields = fieldsOfValue(prop.expression);
|
|
3613
4463
|
if (fields !== undefined)
|
|
@@ -3622,14 +4472,35 @@ export class Lowerer {
|
|
|
3622
4472
|
return out;
|
|
3623
4473
|
};
|
|
3624
4474
|
const scanPattern = (name, init) => {
|
|
4475
|
+
if (ts.isObjectBindingPattern(name)) {
|
|
4476
|
+
// `const { 0: a, 1: b, length } = parts` reads positions like the
|
|
4477
|
+
// equivalent array pattern: each may sit past the end.
|
|
4478
|
+
// Regex match results keep their own pattern lowering.
|
|
4479
|
+
const arrayType = this.mapTypeOf(this.typeOf(init));
|
|
4480
|
+
const initType = this.checker.getNonNullableType(this.typeOf(init));
|
|
4481
|
+
const initSymbol = initType.getAliasSymbol() ?? initType.getSymbol();
|
|
4482
|
+
const matchResult = initSymbol !== undefined &&
|
|
4483
|
+
(ts.symbolName(initSymbol) === "RegExpExecArray" ||
|
|
4484
|
+
ts.symbolName(initSymbol) === "RegExpMatchArray");
|
|
4485
|
+
if (arrayType?.kind !== "array" || matchResult)
|
|
4486
|
+
return scanRecordPattern(name, init);
|
|
4487
|
+
const positions = name.elements.nodes.filter((el) => {
|
|
4488
|
+
const key = el.propertyName;
|
|
4489
|
+
return (key !== undefined && ts.isNumericLiteral(key) && /^(?:0|[1-9]\d{0,8})$/.test(key.text));
|
|
4490
|
+
});
|
|
4491
|
+
return scanPositions(positions, init, arrayType);
|
|
4492
|
+
}
|
|
3625
4493
|
if (!ts.isArrayBindingPattern(name))
|
|
3626
4494
|
return false;
|
|
3627
4495
|
const sourceType = this.mapTypeOf(this.typeOf(init));
|
|
3628
4496
|
if (sourceType?.kind !== "array")
|
|
3629
4497
|
return false;
|
|
4498
|
+
return scanPositions(name.elements.nodes.filter((el) => !ts.isOmittedExpression(el)), init, sourceType);
|
|
4499
|
+
};
|
|
4500
|
+
const scanPositions = (elements, init, sourceType) => {
|
|
3630
4501
|
let changed = false;
|
|
3631
|
-
|
|
3632
|
-
if (
|
|
4502
|
+
elements.forEach((el) => {
|
|
4503
|
+
if (el.name === undefined || el.dotDotDotToken)
|
|
3633
4504
|
return;
|
|
3634
4505
|
if (ts.isIdentifier(el.name)) {
|
|
3635
4506
|
const symbol = symbolOf(el.name);
|
|
@@ -3659,6 +4530,63 @@ export class Lowerer {
|
|
|
3659
4530
|
});
|
|
3660
4531
|
return changed;
|
|
3661
4532
|
};
|
|
4533
|
+
/** `const { a, b } = table` over an index-signature record: a name that
|
|
4534
|
+
* is not a declared field reads the index signature and can be
|
|
4535
|
+
* missing. */
|
|
4536
|
+
const scanRecordPattern = (name, init, sourceType = this.mapTypeOf(this.typeOf(init))) => {
|
|
4537
|
+
if (sourceType?.kind !== "record")
|
|
4538
|
+
return false;
|
|
4539
|
+
const shape = this.shapes.get(sourceType.shapeId);
|
|
4540
|
+
if (!shape || shape.tuple)
|
|
4541
|
+
return false;
|
|
4542
|
+
const indexValue = shape.indexValue;
|
|
4543
|
+
let changed = false;
|
|
4544
|
+
for (const el of name.elements.nodes) {
|
|
4545
|
+
// A nested pattern reads its element the same way
|
|
4546
|
+
// (`const { limits: { [key]: limit } } = config`).
|
|
4547
|
+
if (!el.dotDotDotToken && el.name !== undefined && ts.isObjectBindingPattern(el.name)) {
|
|
4548
|
+
if (scanRecordPattern(el.name, init, this.mapTypeOf(this.typeOf(el.name))))
|
|
4549
|
+
changed = true;
|
|
4550
|
+
continue;
|
|
4551
|
+
}
|
|
4552
|
+
if (!indexValue || indexValue.kind === "dyn")
|
|
4553
|
+
continue;
|
|
4554
|
+
if (el.dotDotDotToken || el.initializer || !ts.isIdentifier(el.name))
|
|
4555
|
+
continue;
|
|
4556
|
+
const key = el.propertyName ?? el.name;
|
|
4557
|
+
// A computed key that folds to one name reads like that name; a
|
|
4558
|
+
// runtime key reads the entry of a record with no declared fields
|
|
4559
|
+
// (runtimeKeyPatternRead), which can be missing too.
|
|
4560
|
+
const keyName = ts.isComputedPropertyName(key)
|
|
4561
|
+
? this.foldedStringKeyOf(key.expression)
|
|
4562
|
+
: ts.isIdentifier(key) || ts.isStringLiteral(key) || ts.isNumericLiteral(key)
|
|
4563
|
+
? key.text
|
|
4564
|
+
: undefined;
|
|
4565
|
+
if (keyName === undefined)
|
|
4566
|
+
continue;
|
|
4567
|
+
if (keyName === null ? shape.fields.length > 0 : shape.fields.some((f) => f.name === keyName))
|
|
4568
|
+
continue;
|
|
4569
|
+
const symbol = symbolOf(el.name);
|
|
4570
|
+
if (!symbol || optionalSymbols.has(symbol))
|
|
4571
|
+
continue;
|
|
4572
|
+
const read = this.mapTypeOf(this.typeOf(el.name));
|
|
4573
|
+
if (read?.kind === "union" && this.armTag(read.unionId, UNDEFINED_T) >= 0)
|
|
4574
|
+
continue;
|
|
4575
|
+
const widened = this.withUndefinedArmOf(indexValue);
|
|
4576
|
+
if (!widened)
|
|
4577
|
+
continue;
|
|
4578
|
+
optionalSymbols.add(symbol);
|
|
4579
|
+
provenance?.note("pattern-binding", el.name, init);
|
|
4580
|
+
this.runtimeOptionalBindingTypes.set(symbol, widened);
|
|
4581
|
+
const global = this.globalsBySymbol.get(symbol);
|
|
4582
|
+
if (global) {
|
|
4583
|
+
global.type = widened;
|
|
4584
|
+
this.runtimeOptionalGlobals.add(global);
|
|
4585
|
+
}
|
|
4586
|
+
changed = true;
|
|
4587
|
+
}
|
|
4588
|
+
return changed;
|
|
4589
|
+
};
|
|
3662
4590
|
const hofCallbackIndices = (name, hasInitialValue) => {
|
|
3663
4591
|
if (name === "reduce" || name === "reduceRight")
|
|
3664
4592
|
return hasInitialValue ? [1] : [0, 1];
|
|
@@ -3752,7 +4680,7 @@ export class Lowerer {
|
|
|
3752
4680
|
};
|
|
3753
4681
|
for (const [symbol, signature] of signatureBySymbol) {
|
|
3754
4682
|
const declaration = functionDeclBySymbol.get(symbol);
|
|
3755
|
-
if (!declaration || !isJsSourceFile(
|
|
4683
|
+
if (!declaration || !isJsSourceFile(ts.getSourceFileOfNode(declaration)))
|
|
3756
4684
|
continue;
|
|
3757
4685
|
const checked = this.checker.getSignatureFromDeclaration(declaration);
|
|
3758
4686
|
const checkedReturn = checked ? this.checker.getReturnTypeOfSignature(checked) : null;
|
|
@@ -3780,7 +4708,7 @@ export class Lowerer {
|
|
|
3780
4708
|
for (const parameterIndex of parameterIndices) {
|
|
3781
4709
|
if (parameterIndex === undefined)
|
|
3782
4710
|
continue;
|
|
3783
|
-
const parameter = fn.parameters[parameterIndex];
|
|
4711
|
+
const parameter = fn.parameters.nodes[parameterIndex];
|
|
3784
4712
|
if (!parameter)
|
|
3785
4713
|
continue;
|
|
3786
4714
|
const symbol = ts.isIdentifier(parameter.name) ? symbolOf(parameter.name) : null;
|
|
@@ -3849,7 +4777,7 @@ export class Lowerer {
|
|
|
3849
4777
|
if (this.genericFnsBySymbol.has(symbol))
|
|
3850
4778
|
return false;
|
|
3851
4779
|
seen.add(symbol);
|
|
3852
|
-
const declaration =
|
|
4780
|
+
const declaration = symbol.valueDeclaration;
|
|
3853
4781
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
3854
4782
|
if (promoteHofCallback(peel(declaration.initializer), parameterIndices, seen))
|
|
3855
4783
|
changed = true;
|
|
@@ -3904,7 +4832,9 @@ export class Lowerer {
|
|
|
3904
4832
|
owner.name)
|
|
3905
4833
|
ownerSymbol = symbolOf(owner.name);
|
|
3906
4834
|
const ownerSig = ownerSymbol ? signatureBySymbol.get(ownerSymbol) : undefined;
|
|
3907
|
-
const ownerIndex = ts.isFunctionLike(owner)
|
|
4835
|
+
const ownerIndex = ts.isFunctionLike(owner)
|
|
4836
|
+
? owner.parameters.nodes.indexOf(declaration)
|
|
4837
|
+
: -1;
|
|
3908
4838
|
const slot = ownerIndex >= 0 ? ownerSig?.params[ownerIndex] : undefined;
|
|
3909
4839
|
if (slot && !typeEquals(slot.type, promoted)) {
|
|
3910
4840
|
slot.type = promoted;
|
|
@@ -3924,7 +4854,7 @@ export class Lowerer {
|
|
|
3924
4854
|
return false;
|
|
3925
4855
|
let changed = false;
|
|
3926
4856
|
for (const parameterIndex of parameterIndices) {
|
|
3927
|
-
const parameter = fn.parameters[parameterIndex];
|
|
4857
|
+
const parameter = fn.parameters.nodes[parameterIndex];
|
|
3928
4858
|
if (!parameter)
|
|
3929
4859
|
continue;
|
|
3930
4860
|
const checkerType = this.typeOf(parameter.name);
|
|
@@ -3962,7 +4892,7 @@ export class Lowerer {
|
|
|
3962
4892
|
const fn = peel(callback);
|
|
3963
4893
|
let param;
|
|
3964
4894
|
if (ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) {
|
|
3965
|
-
const parameter = fn.parameters[index];
|
|
4895
|
+
const parameter = fn.parameters.nodes[index];
|
|
3966
4896
|
if (!parameter?.type || parameter.dotDotDotToken)
|
|
3967
4897
|
return true;
|
|
3968
4898
|
const checkerType = this.typeOf(parameter.name);
|
|
@@ -3989,7 +4919,7 @@ export class Lowerer {
|
|
|
3989
4919
|
const fn = functionDeclBySymbol.get(symbol);
|
|
3990
4920
|
if (fn)
|
|
3991
4921
|
return bodyReturnsOptional(fn);
|
|
3992
|
-
const decl =
|
|
4922
|
+
const decl = symbol.valueDeclaration;
|
|
3993
4923
|
return (!!decl &&
|
|
3994
4924
|
ts.isVariableDeclaration(decl) &&
|
|
3995
4925
|
!!decl.initializer &&
|
|
@@ -4067,7 +4997,7 @@ export class Lowerer {
|
|
|
4067
4997
|
};
|
|
4068
4998
|
const ownership = new ArrayOwnership(sourceFiles, {
|
|
4069
4999
|
symbolOf,
|
|
4070
|
-
declarationOf: (symbol) =>
|
|
5000
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
4071
5001
|
typeOf: typeOrNull,
|
|
4072
5002
|
instanceAssignableTo: (owner, target) => panicSafe(() => this.checker.isTypeAssignableTo(this.checker.getTypeAtLocation(owner), target), true),
|
|
4073
5003
|
isGlobal: (node, name) => this.isStdlibGlobal(node, name),
|
|
@@ -4088,7 +5018,7 @@ export class Lowerer {
|
|
|
4088
5018
|
// flow type such as `Array.isArray(x)`'s `any[]` only narrows it.
|
|
4089
5019
|
const e = peel(node);
|
|
4090
5020
|
const symbol = ts.isIdentifier(e) ? symbolOf(e) : null;
|
|
4091
|
-
const declaration = symbol ?
|
|
5021
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
4092
5022
|
const declared = declaration &&
|
|
4093
5023
|
(ts.isVariableDeclaration(declaration) || ts.isParameter(declaration)) &&
|
|
4094
5024
|
ts.isIdentifier(declaration.name)
|
|
@@ -4144,14 +5074,14 @@ export class Lowerer {
|
|
|
4144
5074
|
else if (ts.isReturnStatement(node) && node.expression && dynamicValue(node.expression))
|
|
4145
5075
|
target(contextualOrNull(node.expression));
|
|
4146
5076
|
else if (ts.isCallExpression(node) || ts.isNewExpression(node)) {
|
|
4147
|
-
for (const arg of node.arguments ?? [])
|
|
5077
|
+
for (const arg of node.arguments?.nodes ?? [])
|
|
4148
5078
|
if (!ts.isSpreadElement(arg) && dynamicValue(arg))
|
|
4149
5079
|
target(contextualOrNull(arg));
|
|
4150
5080
|
}
|
|
4151
5081
|
else if (ts.isPropertyAssignment(node) && dynamicValue(node.initializer))
|
|
4152
5082
|
target(contextualOrNull(node.initializer));
|
|
4153
5083
|
else if (ts.isArrayLiteralExpression(node)) {
|
|
4154
|
-
for (const element of node.elements)
|
|
5084
|
+
for (const element of node.elements.nodes)
|
|
4155
5085
|
if (!ts.isSpreadElement(element) &&
|
|
4156
5086
|
!ts.isOmittedExpression(element) &&
|
|
4157
5087
|
dynamicValue(element))
|
|
@@ -4261,6 +5191,7 @@ export class Lowerer {
|
|
|
4261
5191
|
const nodes = [];
|
|
4262
5192
|
ts.walkPreorder(sf, (node) => {
|
|
4263
5193
|
if (ts.isVariableDeclaration(node) ||
|
|
5194
|
+
(ts.isParameter(node) && ts.isObjectBindingPattern(node.name)) ||
|
|
4264
5195
|
ts.isBinaryExpression(node) ||
|
|
4265
5196
|
ts.isCallExpression(node) ||
|
|
4266
5197
|
ts.isNewExpression(node) ||
|
|
@@ -4282,6 +5213,12 @@ export class Lowerer {
|
|
|
4282
5213
|
changed = true;
|
|
4283
5214
|
if (ts.isForOfStatement(node))
|
|
4284
5215
|
presentLoops.set(node, !elementStates.loopMayYieldUndefined(node));
|
|
5216
|
+
// A parameter pattern reads its argument like a declaration's
|
|
5217
|
+
// pattern reads its initializer.
|
|
5218
|
+
if (ts.isParameter(node) && ts.isObjectBindingPattern(node.name)) {
|
|
5219
|
+
if (scanRecordPattern(node.name, node, this.mapTypeOf(this.typeOf(node.name))))
|
|
5220
|
+
changed = true;
|
|
5221
|
+
}
|
|
4285
5222
|
if (ts.isVariableDeclaration(node)) {
|
|
4286
5223
|
if (node.initializer) {
|
|
4287
5224
|
const result = optionalPrimitiveResultType(node.initializer);
|
|
@@ -4379,7 +5316,7 @@ export class Lowerer {
|
|
|
4379
5316
|
if (ts.isIdentifier(node.name) &&
|
|
4380
5317
|
ts.isObjectLiteralExpression(peel(node.initializer))) {
|
|
4381
5318
|
const object = peel(node.initializer);
|
|
4382
|
-
for (const prop of object.properties) {
|
|
5319
|
+
for (const prop of object.properties.nodes) {
|
|
4383
5320
|
if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop))
|
|
4384
5321
|
continue;
|
|
4385
5322
|
const name = prop.name;
|
|
@@ -4412,7 +5349,7 @@ export class Lowerer {
|
|
|
4412
5349
|
const assertion = forwardedAssertion(node.right);
|
|
4413
5350
|
const symbol = assertion ? symbolOf(node.left) : null;
|
|
4414
5351
|
// Only a variable's storage is promoted (see the final pass).
|
|
4415
|
-
const declaration = symbol ?
|
|
5352
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
4416
5353
|
if (assertion &&
|
|
4417
5354
|
symbol &&
|
|
4418
5355
|
declaration &&
|
|
@@ -4466,8 +5403,8 @@ export class Lowerer {
|
|
|
4466
5403
|
}
|
|
4467
5404
|
}
|
|
4468
5405
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
4469
|
-
const callbackIndices = hofCallbackIndices(node.expression.name.text, node.arguments.length >= 2);
|
|
4470
|
-
const callback = node.arguments[0];
|
|
5406
|
+
const callbackIndices = hofCallbackIndices(node.expression.name.text, node.arguments.nodes.length >= 2);
|
|
5407
|
+
const callback = node.arguments.nodes[0];
|
|
4471
5408
|
if (callbackIndices !== null && callback !== undefined && !ts.isSpreadElement(callback)) {
|
|
4472
5409
|
const receiverNode = node.expression.expression;
|
|
4473
5410
|
const receiverTs = this.typeOf(receiverNode);
|
|
@@ -4491,9 +5428,7 @@ export class Lowerer {
|
|
|
4491
5428
|
let nativeArrayReceiver = receiver?.kind === "array" || tuple;
|
|
4492
5429
|
if (nativeArrayReceiver && ts.isIdentifier(receiverNode)) {
|
|
4493
5430
|
const receiverSymbol = symbolOf(receiverNode);
|
|
4494
|
-
const declaration = receiverSymbol
|
|
4495
|
-
? this.checker.valueDeclarationOf(receiverSymbol)
|
|
4496
|
-
: undefined;
|
|
5431
|
+
const declaration = receiverSymbol ? receiverSymbol.valueDeclaration : undefined;
|
|
4497
5432
|
if (declaration && ts.isVariableDeclaration(declaration)) {
|
|
4498
5433
|
const declared = this.mapTypeOf(this.typeOf(declaration.name));
|
|
4499
5434
|
if (declared?.kind !== "array" &&
|
|
@@ -4521,7 +5456,7 @@ export class Lowerer {
|
|
|
4521
5456
|
if (elementsPresent && reduce && retypeInlineCallback(callback, callbackIndices))
|
|
4522
5457
|
changed = true;
|
|
4523
5458
|
if ((method === "reduce" || method === "reduceRight") &&
|
|
4524
|
-
((!elementsPresent && node.arguments.length < 2) ||
|
|
5459
|
+
((!elementsPresent && node.arguments.nodes.length < 2) ||
|
|
4525
5460
|
callbackReturnsOptional(callback))) {
|
|
4526
5461
|
if (promoteHofCallback(callback, [0, 1]))
|
|
4527
5462
|
changed = true;
|
|
@@ -4547,20 +5482,20 @@ export class Lowerer {
|
|
|
4547
5482
|
// parameter, as for a callback the same value is passed as.
|
|
4548
5483
|
if (!ts.isIdentifier(node.expression) || reassigned.has(symbol))
|
|
4549
5484
|
return;
|
|
4550
|
-
const declaration =
|
|
5485
|
+
const declaration = symbol.valueDeclaration;
|
|
4551
5486
|
const value = declaration && ts.isVariableDeclaration(declaration) && declaration.initializer
|
|
4552
5487
|
? peel(declaration.initializer)
|
|
4553
5488
|
: null;
|
|
4554
5489
|
if (!value || !(ts.isArrowFunction(value) || ts.isFunctionExpression(value)))
|
|
4555
5490
|
return;
|
|
4556
5491
|
// Optional, defaulted and rest parameters keep their own ABI.
|
|
4557
|
-
if (value.parameters.some((parameter) => parameter.questionToken !== undefined ||
|
|
5492
|
+
if (value.parameters.nodes.some((parameter) => parameter.questionToken !== undefined ||
|
|
4558
5493
|
parameter.initializer !== undefined ||
|
|
4559
5494
|
parameter.dotDotDotToken !== undefined))
|
|
4560
5495
|
return;
|
|
4561
|
-
const indices = node.arguments.flatMap((arg, i) => !ts.isSpreadElement(arg) &&
|
|
4562
|
-
value.parameters[i] !== undefined &&
|
|
4563
|
-
!value.parameters[i].dotDotDotToken &&
|
|
5496
|
+
const indices = node.arguments.nodes.flatMap((arg, i) => !ts.isSpreadElement(arg) &&
|
|
5497
|
+
value.parameters.nodes[i] !== undefined &&
|
|
5498
|
+
!value.parameters.nodes[i].dotDotDotToken &&
|
|
4564
5499
|
mayBeOptional(arg)
|
|
4565
5500
|
? [i]
|
|
4566
5501
|
: []);
|
|
@@ -4575,10 +5510,10 @@ export class Lowerer {
|
|
|
4575
5510
|
// agree on that value's representation.
|
|
4576
5511
|
const callee = functionDeclBySymbol.get(symbol);
|
|
4577
5512
|
if (callee &&
|
|
4578
|
-
isJsSourceFile(
|
|
4579
|
-
!node.arguments.some(ts.isSpreadElement)) {
|
|
5513
|
+
isJsSourceFile(ts.getSourceFileOfNode(callee)) &&
|
|
5514
|
+
!node.arguments.nodes.some(ts.isSpreadElement)) {
|
|
4580
5515
|
for (let i = 0; i < sig.params.length; i++) {
|
|
4581
|
-
const arg = node.arguments[i];
|
|
5516
|
+
const arg = node.arguments.nodes[i];
|
|
4582
5517
|
if (arg &&
|
|
4583
5518
|
(this.typeOf(arg).flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) === 0)
|
|
4584
5519
|
continue;
|
|
@@ -4590,7 +5525,7 @@ export class Lowerer {
|
|
|
4590
5525
|
if (typeEquals(shape.type, widened))
|
|
4591
5526
|
continue;
|
|
4592
5527
|
shape.type = widened;
|
|
4593
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5528
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4594
5529
|
provenance?.note("parameter", parameter, node, "(omitted or undefined argument)");
|
|
4595
5530
|
if (parameter) {
|
|
4596
5531
|
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
@@ -4607,7 +5542,7 @@ export class Lowerer {
|
|
|
4607
5542
|
}
|
|
4608
5543
|
}
|
|
4609
5544
|
const restAt = sig.params.findIndex((shape) => shape.mode === "rest" || shape.mode === "dynRest" || shape.mode === "arguments");
|
|
4610
|
-
node.arguments.forEach((arg, argumentIndex) => {
|
|
5545
|
+
node.arguments.nodes.forEach((arg, argumentIndex) => {
|
|
4611
5546
|
const i = restAt >= 0 && argumentIndex >= restAt ? restAt : argumentIndex;
|
|
4612
5547
|
const shape = sig.params[i];
|
|
4613
5548
|
const callbackSlot = shape?.type;
|
|
@@ -4623,7 +5558,7 @@ export class Lowerer {
|
|
|
4623
5558
|
const fields = fieldsOfValue(arg);
|
|
4624
5559
|
for (const target of familyBySymbol.get(symbol) ?? [symbol]) {
|
|
4625
5560
|
const parameterShape = signatureBySymbol.get(target)?.params[i];
|
|
4626
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5561
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4627
5562
|
if (!parameterShape || parameterShape.type.kind !== "record")
|
|
4628
5563
|
continue;
|
|
4629
5564
|
if (!parameter || !ts.isIdentifier(parameter.name))
|
|
@@ -4680,7 +5615,7 @@ export class Lowerer {
|
|
|
4680
5615
|
if (typeEquals(rest.type, widened))
|
|
4681
5616
|
continue;
|
|
4682
5617
|
rest.type = widened;
|
|
4683
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5618
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4684
5619
|
provenance?.note("rest-parameter", parameter, arg);
|
|
4685
5620
|
if (parameter && ts.isIdentifier(parameter.name)) {
|
|
4686
5621
|
const bound = symbolOf(parameter.name);
|
|
@@ -4707,7 +5642,7 @@ export class Lowerer {
|
|
|
4707
5642
|
optionalParams.set(target, set);
|
|
4708
5643
|
if (set.size !== before) {
|
|
4709
5644
|
changed = true;
|
|
4710
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5645
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4711
5646
|
provenance?.note("parameter", parameter, arg, target === symbol ? "" : "(override)");
|
|
4712
5647
|
if (parameter) {
|
|
4713
5648
|
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
@@ -4767,7 +5702,7 @@ export class Lowerer {
|
|
|
4767
5702
|
// there, whatever its declared type.
|
|
4768
5703
|
for (const symbol of earlyReadVarSymbols(this, sourceFiles)) {
|
|
4769
5704
|
// Text codec bindings keep their own presence-checked storage.
|
|
4770
|
-
const declaration =
|
|
5705
|
+
const declaration = symbol.valueDeclaration;
|
|
4771
5706
|
const mapped = declaration && ts.isVariableDeclaration(declaration)
|
|
4772
5707
|
? mappedOrNull(declaration.name)
|
|
4773
5708
|
: null;
|
|
@@ -4792,6 +5727,25 @@ export class Lowerer {
|
|
|
4792
5727
|
for (const [symbol, decl] of functionDeclBySymbol)
|
|
4793
5728
|
if (scanReturns(symbol, decl))
|
|
4794
5729
|
changed = true;
|
|
5730
|
+
const noteGenericReturn = (symbol, decl) => {
|
|
5731
|
+
if (optionalReturns.has(symbol) || isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
5732
|
+
return;
|
|
5733
|
+
if (!returnsOf(decl).some(genericMayBeOptional))
|
|
5734
|
+
return;
|
|
5735
|
+
optionalReturns.add(symbol);
|
|
5736
|
+
this.runtimeOptionalGenericReturns.add(decl);
|
|
5737
|
+
provenance?.note("return", decl.name ?? decl, decl);
|
|
5738
|
+
changed = true;
|
|
5739
|
+
};
|
|
5740
|
+
for (const [symbol, info] of this.genericFnsBySymbol)
|
|
5741
|
+
noteGenericReturn(symbol, info.decl);
|
|
5742
|
+
// Generic methods and methods of a generic class collect with their
|
|
5743
|
+
// class, after this analysis; their result admits undefined there.
|
|
5744
|
+
for (const method of genericClassMethods) {
|
|
5745
|
+
const symbol = method.name ? symbolOf(method.name) : null;
|
|
5746
|
+
if (symbol)
|
|
5747
|
+
noteGenericReturn(symbol, method);
|
|
5748
|
+
}
|
|
4795
5749
|
for (const fn of tsLambdas) {
|
|
4796
5750
|
// An annotated return is the author's contract, as for parameters,
|
|
4797
5751
|
// except that a var read before its first store is undefined
|
|
@@ -4899,7 +5853,7 @@ export class Lowerer {
|
|
|
4899
5853
|
for (const [symbol, params] of optionalParams) {
|
|
4900
5854
|
const decl = functionDeclBySymbol.get(symbol);
|
|
4901
5855
|
for (const index of [...params]) {
|
|
4902
|
-
const name = decl?.parameters[index]?.name;
|
|
5856
|
+
const name = decl?.parameters?.nodes[index]?.name;
|
|
4903
5857
|
const param = name && ts.isIdentifier(name) ? symbolOf(name) : null;
|
|
4904
5858
|
if (param && nanCoded.nanCodedBinding(param))
|
|
4905
5859
|
params.delete(index);
|
|
@@ -4944,20 +5898,52 @@ export class Lowerer {
|
|
|
4944
5898
|
addClassFields(recordFlows.bindingClass(symbol), fields);
|
|
4945
5899
|
for (const [symbol, fields] of returnFields)
|
|
4946
5900
|
addClassFields(recordFlows.returnClass(symbol), fields);
|
|
5901
|
+
// A record field that flows into other slots (`fill(args, state.parsed)`)
|
|
5902
|
+
// widens with its owner's class: every member takes the field's widened
|
|
5903
|
+
// layout, so the field and the slots it reaches share one record.
|
|
5904
|
+
const nestedFields = new Map();
|
|
5905
|
+
for (let changed = true; changed;) {
|
|
5906
|
+
changed = false;
|
|
5907
|
+
for (const { owner, name, classId } of recordFlows.fields()) {
|
|
5908
|
+
if (nestedFields.get(owner)?.has(name))
|
|
5909
|
+
continue;
|
|
5910
|
+
if (!(classFields.has(classId) || nestedFields.has(classId)))
|
|
5911
|
+
continue;
|
|
5912
|
+
if (!recordFlows.closed(classId))
|
|
5913
|
+
continue;
|
|
5914
|
+
const byName = nestedFields.get(owner) ?? new Map();
|
|
5915
|
+
byName.set(name, classId);
|
|
5916
|
+
nestedFields.set(owner, byName);
|
|
5917
|
+
changed = true;
|
|
5918
|
+
}
|
|
5919
|
+
}
|
|
4947
5920
|
const settledFields = (id, own) => id === null
|
|
4948
5921
|
? own
|
|
4949
|
-
: classFields.has(id) && recordFlows.closed(id)
|
|
4950
|
-
? classFields.get(id)
|
|
5922
|
+
: (classFields.has(id) || nestedFields.has(id)) && recordFlows.closed(id)
|
|
5923
|
+
? (classFields.get(id) ?? new Set())
|
|
4951
5924
|
: undefined;
|
|
4952
|
-
const widenRecordFields = (type, fields) => {
|
|
5925
|
+
const widenRecordFields = (type, fields, id = null, seen = new Set()) => {
|
|
4953
5926
|
let promoted = type;
|
|
5927
|
+
const fieldOf = (name) => promoted.kind === "record"
|
|
5928
|
+
? this.shapes.get(promoted.shapeId)?.fields.find((f) => f.name === name)
|
|
5929
|
+
: undefined;
|
|
4954
5930
|
for (const field of fields) {
|
|
4955
|
-
const source =
|
|
4956
|
-
? this.shapes.get(promoted.shapeId)?.fields.find((f) => f.name === field)
|
|
4957
|
-
: undefined;
|
|
5931
|
+
const source = fieldOf(field);
|
|
4958
5932
|
if (source)
|
|
4959
5933
|
promoted = this.runtimeOptionalRecordField(promoted, field, addUndefined(source.type));
|
|
4960
5934
|
}
|
|
5935
|
+
if (id === null || seen.has(id))
|
|
5936
|
+
return promoted;
|
|
5937
|
+
const nested = nestedFields.get(id);
|
|
5938
|
+
if (!nested)
|
|
5939
|
+
return promoted;
|
|
5940
|
+
for (const [field, inner] of nested) {
|
|
5941
|
+
const source = fieldOf(field);
|
|
5942
|
+
if (source?.type.kind !== "record")
|
|
5943
|
+
continue;
|
|
5944
|
+
const widened = widenRecordFields(source.type, classFields.get(inner) ?? new Set(), inner, new Set([...seen, id]));
|
|
5945
|
+
promoted = this.runtimeOptionalRecordField(promoted, field, widened);
|
|
5946
|
+
}
|
|
4961
5947
|
return promoted;
|
|
4962
5948
|
};
|
|
4963
5949
|
for (const [symbol, id] of recordFlows.bindings())
|
|
@@ -4973,10 +5959,11 @@ export class Lowerer {
|
|
|
4973
5959
|
const shape = signatureBySymbol.get(target)?.params[index];
|
|
4974
5960
|
if (!shape || shape.type.kind !== "record")
|
|
4975
5961
|
continue;
|
|
4976
|
-
const
|
|
5962
|
+
const id = recordFlows.bindingClass(bound);
|
|
5963
|
+
const fields = settledFields(id, optionalFields.get(bound));
|
|
4977
5964
|
if (!fields)
|
|
4978
5965
|
continue;
|
|
4979
|
-
const promoted = widenRecordFields(shape.type, fields);
|
|
5966
|
+
const promoted = widenRecordFields(shape.type, fields, id);
|
|
4980
5967
|
if (typeEquals(promoted, shape.type))
|
|
4981
5968
|
continue;
|
|
4982
5969
|
shape.type = promoted;
|
|
@@ -4986,7 +5973,7 @@ export class Lowerer {
|
|
|
4986
5973
|
const id = recordFlows.returnClass(symbol);
|
|
4987
5974
|
const fields = id === null ? undefined : settledFields(id, undefined);
|
|
4988
5975
|
if (fields && sig.returnType.kind === "record") {
|
|
4989
|
-
const next = widenRecordFields(sig.returnType, fields);
|
|
5976
|
+
const next = widenRecordFields(sig.returnType, fields, id);
|
|
4990
5977
|
sig.returnType = next;
|
|
4991
5978
|
if (sig.top)
|
|
4992
5979
|
sig.top.returnType = next;
|
|
@@ -5028,7 +6015,7 @@ export class Lowerer {
|
|
|
5028
6015
|
for (const [declaration, global] of this.globalsByDeclNode) {
|
|
5029
6016
|
if (global.type.kind !== "func" ||
|
|
5030
6017
|
!ts.isBinaryExpression(declaration) ||
|
|
5031
|
-
!isJsSourceFile(
|
|
6018
|
+
!isJsSourceFile(ts.getSourceFileOfNode(declaration)))
|
|
5032
6019
|
continue;
|
|
5033
6020
|
const value = peel(declaration.right);
|
|
5034
6021
|
if (!ts.isFunctionExpression(value) && !ts.isArrowFunction(value))
|
|
@@ -5077,7 +6064,8 @@ export class Lowerer {
|
|
|
5077
6064
|
global.type = promoted;
|
|
5078
6065
|
}
|
|
5079
6066
|
}
|
|
5080
|
-
const
|
|
6067
|
+
const flowClass = recordFlows.bindingClass(symbol);
|
|
6068
|
+
const fields = settledFields(flowClass, optionalFields.get(symbol));
|
|
5081
6069
|
if (!dynamicObjectEntryRows.has(symbol) && !optionalSymbols.has(symbol) && !fields)
|
|
5082
6070
|
return;
|
|
5083
6071
|
const current = this.mapTypeOf(this.typeOf(node.name));
|
|
@@ -5097,7 +6085,7 @@ export class Lowerer {
|
|
|
5097
6085
|
}
|
|
5098
6086
|
}
|
|
5099
6087
|
if (fields && promoted.kind === "record")
|
|
5100
|
-
promoted = widenRecordFields(promoted, fields);
|
|
6088
|
+
promoted = widenRecordFields(promoted, fields, flowClass);
|
|
5101
6089
|
if (!typeEquals(promoted, current)) {
|
|
5102
6090
|
this.runtimeOptionalBindingTypes.set(symbol, promoted);
|
|
5103
6091
|
const global = ts.isIdentifier(node.name)
|
|
@@ -5130,9 +6118,9 @@ export class Lowerer {
|
|
|
5130
6118
|
continue;
|
|
5131
6119
|
const symbol = callableSymbolOf(node.expression);
|
|
5132
6120
|
const sig = symbol ? signatureBySymbol.get(symbol) : undefined;
|
|
5133
|
-
if (!sig || node.arguments.some(ts.isSpreadElement))
|
|
6121
|
+
if (!sig || node.arguments.nodes.some(ts.isSpreadElement))
|
|
5134
6122
|
continue;
|
|
5135
|
-
node.arguments.forEach((arg, i) => {
|
|
6123
|
+
node.arguments.nodes.forEach((arg, i) => {
|
|
5136
6124
|
let e = arg;
|
|
5137
6125
|
while (ts.isParenthesizedExpression(e))
|
|
5138
6126
|
e = e.expression;
|
|
@@ -5162,7 +6150,12 @@ export class Lowerer {
|
|
|
5162
6150
|
this.checker.prefetchSourceFile(fp.sf);
|
|
5163
6151
|
}
|
|
5164
6152
|
this.collectProgram(parts);
|
|
5165
|
-
this.
|
|
6153
|
+
this.speculativeTypeQueries(() => {
|
|
6154
|
+
extendAssertedRecordMembers(this, parts.map((fp) => fp.sf));
|
|
6155
|
+
this.analyzeRuntimeOptionalArrayReads(parts);
|
|
6156
|
+
this.analyzeDateJsonResults(parts);
|
|
6157
|
+
this.analyzeGuardedRecordReadGlobals(parts);
|
|
6158
|
+
});
|
|
5166
6159
|
// Decorated classes analyze AFTER the whole collection pass: a
|
|
5167
6160
|
// decorator's return type may name a subclass declared below the
|
|
5168
6161
|
// class, and reference lowering needs each class's rebindability
|
|
@@ -5287,6 +6280,7 @@ export class Lowerer {
|
|
|
5287
6280
|
// implicit-any instances lowered eagerly at their first call sites.
|
|
5288
6281
|
functions.push(...this.liftedFns);
|
|
5289
6282
|
functions.push(...this.implicitFns);
|
|
6283
|
+
functions.push(...runtimeClassConstructs(this, functions));
|
|
5290
6284
|
if (this.remainder) {
|
|
5291
6285
|
// Deferred collection diagnostics nothing flushed — declarations no
|
|
5292
6286
|
// reference ever made relevant. They belong to the unreached group
|
|
@@ -5314,7 +6308,10 @@ export class Lowerer {
|
|
|
5314
6308
|
if (this.diags.length === 0)
|
|
5315
6309
|
fuseArrayPipelines(this, functions);
|
|
5316
6310
|
finalizeClassMethodValues(this, functions);
|
|
6311
|
+
finalizePrivateBrands(this, functions);
|
|
5317
6312
|
trackClassFieldCreation(this, functions);
|
|
6313
|
+
guardClassAttributeWrites(this, functions);
|
|
6314
|
+
applyHandleProperties(this, functions);
|
|
5318
6315
|
// Globals typed by a class that never REGISTERED (a JS class whose
|
|
5319
6316
|
// collection fenced — Symbol-keyed fields, an unsupported base): the
|
|
5320
6317
|
// declaration statement and every use compiled to runtime fences, but
|
|
@@ -5402,10 +6399,11 @@ export class Lowerer {
|
|
|
5402
6399
|
// slots), uniformly across params/locals/globals/fields/body types so
|
|
5403
6400
|
// every producer and consumer agrees. Programs with no unregistered
|
|
5404
6401
|
// reference are untouched — byte-stability holds.
|
|
6402
|
+
checkRequireBindingAccesses(this, functions);
|
|
5405
6403
|
const module = this.diags.length > 0
|
|
5406
6404
|
? null
|
|
5407
6405
|
: {
|
|
5408
|
-
irVersion:
|
|
6406
|
+
irVersion: 17,
|
|
5409
6407
|
sourceFile: this.entry.fileName,
|
|
5410
6408
|
functions,
|
|
5411
6409
|
classes: artifacts.classes,
|
|
@@ -5415,6 +6413,9 @@ export class Lowerer {
|
|
|
5415
6413
|
entry: ENTRY_NAME,
|
|
5416
6414
|
...(this.usesWorkers ? { workers: true } : {}),
|
|
5417
6415
|
...(this.usesLifetimeRegions ? { lifetimeRegions: true } : {}),
|
|
6416
|
+
...(this.threadSlotKeys.size > 0
|
|
6417
|
+
? { threadSlotKeys: [...this.threadSlotKeys].sort() }
|
|
6418
|
+
: {}),
|
|
5418
6419
|
...(isNodeEsmFile(this.entry, this.program) ? {} : { commonJsEntry: true }),
|
|
5419
6420
|
...(this.ffiImports.length > 0 ? { ffiImports: [...this.ffiImports] } : {}),
|
|
5420
6421
|
};
|
|
@@ -5422,11 +6423,23 @@ export class Lowerer {
|
|
|
5422
6423
|
sanitizeUnregisteredClassTypes(module, (name) => this.classes.has(name));
|
|
5423
6424
|
if (module)
|
|
5424
6425
|
checkCycleBindingAccesses(this, module);
|
|
6426
|
+
// Execution tiers from the final bodies (ir/tiers.ts). Assigned with or
|
|
6427
|
+
// without a module: coverage reports the dynamic tier of programs that
|
|
6428
|
+
// still have blockers.
|
|
6429
|
+
this.dynamicFunctions = assignLegacyTiers(functions);
|
|
6430
|
+
if (this.dynamicFunctions.length > 0)
|
|
6431
|
+
this.dynamicBodies = functions.filter((fn) => fn.tier === "dynamic");
|
|
6432
|
+
// Dynamic-tier functions compute with jsval values (ir/jsval.ts). The
|
|
6433
|
+
// rewrite keeps every dynamic operation dynamic (each dyn operator
|
|
6434
|
+
// becomes its js twin), so coverage's dynamic statements are unchanged.
|
|
6435
|
+
if (module && this.dynamicFunctions.length > 0)
|
|
6436
|
+
promoteJsvals(module);
|
|
5425
6437
|
return {
|
|
5426
6438
|
module,
|
|
5427
6439
|
diagnostics: this.diags,
|
|
5428
6440
|
runtimeFences: this.runtimeFences,
|
|
5429
6441
|
stats: this.stats,
|
|
6442
|
+
...(this.dynamicFunctions.length > 0 ? { dynamicFunctions: this.dynamicFunctions } : {}),
|
|
5430
6443
|
...(this.statsByFile.size > 0 ? { statsByFile: this.statsByFile } : {}),
|
|
5431
6444
|
...(this.provenanceElided.length > 0 ? { provenanceElided: this.provenanceElided } : {}),
|
|
5432
6445
|
};
|
|
@@ -5497,7 +6510,7 @@ export class Lowerer {
|
|
|
5497
6510
|
return;
|
|
5498
6511
|
this.stats.statementsTotal += n;
|
|
5499
6512
|
this.stats.statementsFailed += n;
|
|
5500
|
-
const file =
|
|
6513
|
+
const file = ts.getSourceFileOfNode(decl).fileName;
|
|
5501
6514
|
for (let i = 0; i < n; i++) {
|
|
5502
6515
|
this.bumpFileStat(file, "total");
|
|
5503
6516
|
this.bumpFileStat(file, "failed");
|
|
@@ -5539,7 +6552,7 @@ export class Lowerer {
|
|
|
5539
6552
|
// declarations before collectProgram visits their signatures.
|
|
5540
6553
|
this.checker.prefetchCollectionTypes(parts.flatMap((fp) => fp.fnDecls
|
|
5541
6554
|
.filter((decl) => decl.body !== undefined && decl.typeParameters === undefined)
|
|
5542
|
-
.flatMap((decl) => decl.parameters.flatMap((param) =>
|
|
6555
|
+
.flatMap((decl) => decl.parameters.nodes.flatMap((param) => param.initializer ? [param.initializer] : []))));
|
|
5543
6556
|
// JavaScript class shapes are partly declared by constructor-body
|
|
5544
6557
|
// assignments. Batch those collection-time queries across declarations
|
|
5545
6558
|
// before collectProgram visits them one by one; reached body lowering
|
|
@@ -5550,7 +6563,12 @@ export class Lowerer {
|
|
|
5550
6563
|
collectionEdges.add(name);
|
|
5551
6564
|
};
|
|
5552
6565
|
this.collectProgram(parts);
|
|
5553
|
-
this.
|
|
6566
|
+
this.speculativeTypeQueries(() => {
|
|
6567
|
+
extendAssertedRecordMembers(this, parts.map((fp) => fp.sf));
|
|
6568
|
+
this.analyzeRuntimeOptionalArrayReads(parts);
|
|
6569
|
+
this.analyzeDateJsonResults(parts);
|
|
6570
|
+
this.analyzeGuardedRecordReadGlobals(parts);
|
|
6571
|
+
});
|
|
5554
6572
|
// Decorated classes analyze post-collection here too: the %init seeds
|
|
5555
6573
|
// lower the decoration calls, whose edges (decorator bodies, construct
|
|
5556
6574
|
// thunks) reachable emit must see.
|
|
@@ -5563,8 +6581,8 @@ export class Lowerer {
|
|
|
5563
6581
|
// (qualified declaration names).
|
|
5564
6582
|
const units = new Map();
|
|
5565
6583
|
const bodyRoots = (...roots) => roots.filter((root) => root !== undefined && root !== null);
|
|
5566
|
-
const functionRoots = (decl) => bodyRoots(...decl.parameters.map((param) => param.initializer), decl.body);
|
|
5567
|
-
const classCtorRoots = (info) => bodyRoots(...(info.ctor?.parameters ?? []).map((param) => param.initializer), info.ctor?.body, ...info.fieldOrder.map((field) => field.initializer));
|
|
6584
|
+
const functionRoots = (decl) => bodyRoots(...decl.parameters.nodes.map((param) => param.initializer), decl.body);
|
|
6585
|
+
const classCtorRoots = (info) => bodyRoots(...(info.ctor?.parameters?.nodes ?? []).map((param) => param.initializer), info.ctor?.body, ...info.fieldOrder.map((field) => field.initializer));
|
|
5568
6586
|
const classMemberRoots = (info) => {
|
|
5569
6587
|
const roots = classCtorRoots(info);
|
|
5570
6588
|
for (const { member } of this.classMethodMembers(info))
|
|
@@ -5599,7 +6617,7 @@ export class Lowerer {
|
|
|
5599
6617
|
for (const info of this.classes.values()) {
|
|
5600
6618
|
if (info.builtinError)
|
|
5601
6619
|
continue; // runtime-provided; nothing lowers
|
|
5602
|
-
if (info.lifetimeRegion || info.internTable)
|
|
6620
|
+
if (info.lifetimeRegion || info.internTable || info.threadSlots)
|
|
5603
6621
|
continue; // synthesized with the class
|
|
5604
6622
|
// Generic-class INSTANTIATIONS (and mixin instantiations) are
|
|
5605
6623
|
// demand-driven, not units: their members lower unconditionally in
|
|
@@ -5906,6 +6924,13 @@ export class Lowerer {
|
|
|
5906
6924
|
this.shapes.settleDeclaredOrderPriorities();
|
|
5907
6925
|
for (const finalize of this.shapeOrderMetadataFinalizers)
|
|
5908
6926
|
finalize();
|
|
6927
|
+
applyKeyOrderWitnesses(this, [
|
|
6928
|
+
...orderedUnits,
|
|
6929
|
+
...initFunctions,
|
|
6930
|
+
...instanceFunctions,
|
|
6931
|
+
...this.liftedFns,
|
|
6932
|
+
...this.implicitFns,
|
|
6933
|
+
]);
|
|
5909
6934
|
for (const finalize of this.shapeOrderHelperFinalizers)
|
|
5910
6935
|
finalize();
|
|
5911
6936
|
const functions = [
|
|
@@ -5916,6 +6941,7 @@ export class Lowerer {
|
|
|
5916
6941
|
...this.liftedFns,
|
|
5917
6942
|
...this.implicitFns,
|
|
5918
6943
|
];
|
|
6944
|
+
functions.push(...runtimeClassConstructs(this, functions));
|
|
5919
6945
|
if (this.regexGroupResults)
|
|
5920
6946
|
for (const fn of functions)
|
|
5921
6947
|
foldRegexSpanReads(this, fn);
|
|
@@ -5986,23 +7012,8 @@ export class Lowerer {
|
|
|
5986
7012
|
return null;
|
|
5987
7013
|
}
|
|
5988
7014
|
this.runtimeFences.push(...captured);
|
|
5989
|
-
const
|
|
7015
|
+
const fence = this.runtimeFenceStmt(captured[0], node, target.fallback, target.bareMessage);
|
|
5990
7016
|
const loc = locOf(node);
|
|
5991
|
-
const code = first?.code ?? target.fallback.code;
|
|
5992
|
-
const baseMessage = first?.message ?? target.fallback.message;
|
|
5993
|
-
const messageLoc = first?.loc ?? loc;
|
|
5994
|
-
const source = first
|
|
5995
|
-
? (this.program.getSourceFile(messageLoc.file) ?? node.getSourceFile())
|
|
5996
|
-
: node.getSourceFile();
|
|
5997
|
-
const pos = ts.getLineAndCharacterOfPosition(source, messageLoc.start);
|
|
5998
|
-
const fence = {
|
|
5999
|
-
kind: "runtimeFence",
|
|
6000
|
-
code,
|
|
6001
|
-
message: target.bareMessage
|
|
6002
|
-
? baseMessage
|
|
6003
|
-
: `${baseMessage} [${code} at ${messageLoc.file}:${pos.line + 1}]`,
|
|
6004
|
-
loc,
|
|
6005
|
-
};
|
|
6006
7017
|
if (target.kind === "statement")
|
|
6007
7018
|
return fence;
|
|
6008
7019
|
const params = target.params ?? [];
|
|
@@ -6031,6 +7042,46 @@ export class Lowerer {
|
|
|
6031
7042
|
this.liftedFns.push(fn);
|
|
6032
7043
|
return { kind: "closure", fnName: fn.name, captures: [], type: target.type, loc };
|
|
6033
7044
|
}
|
|
7045
|
+
/** The runtimeFence statement that throws `first`'s message (or the
|
|
7046
|
+
* fallback's) at `node`. */
|
|
7047
|
+
runtimeFenceStmt(first, node, fallback, bareMessage = false) {
|
|
7048
|
+
const loc = locOf(node);
|
|
7049
|
+
const code = first?.code ?? fallback?.code ?? "SC1090";
|
|
7050
|
+
const baseMessage = first?.message ??
|
|
7051
|
+
fallback?.message ??
|
|
7052
|
+
"this statement uses a construct with no static lowering";
|
|
7053
|
+
const messageLoc = first?.loc ?? loc;
|
|
7054
|
+
const source = first
|
|
7055
|
+
? (this.program.getSourceFile(messageLoc.file) ?? ts.getSourceFileOfNode(node))
|
|
7056
|
+
: ts.getSourceFileOfNode(node);
|
|
7057
|
+
const pos = ts.getLineAndCharacterOfPosition(source, messageLoc.start);
|
|
7058
|
+
return {
|
|
7059
|
+
kind: "runtimeFence",
|
|
7060
|
+
code,
|
|
7061
|
+
message: bareMessage
|
|
7062
|
+
? baseMessage
|
|
7063
|
+
: `${baseMessage} [${code} at ${messageLoc.file}:${pos.line + 1}]`,
|
|
7064
|
+
loc,
|
|
7065
|
+
};
|
|
7066
|
+
}
|
|
7067
|
+
/** The current length of the capture buffer (diagSink), or 0 without one:
|
|
7068
|
+
* the mark capturedRuntimeFence reads the refusal from. */
|
|
7069
|
+
diagSinkMark() {
|
|
7070
|
+
return this.diagSink?.length ?? 0;
|
|
7071
|
+
}
|
|
7072
|
+
/** The runtimeFence for a JavaScript statement refused while a capture
|
|
7073
|
+
* buffer (diagSink) is active. The buffer's owner decides whether its
|
|
7074
|
+
* diagnostics report, and some owners keep the lowered result (a
|
|
7075
|
+
* successful tryLowerExpression candidate, a computed class base whose
|
|
7076
|
+
* diagnostics defer to the class). Without a fence the refused statement
|
|
7077
|
+
* would vanish from that result; with one it throws the refusal when it
|
|
7078
|
+
* runs, exactly like the fence lowerStmts emits outside a buffer. The
|
|
7079
|
+
* diagnostics stay in the buffer for its owner. Null without a buffer. */
|
|
7080
|
+
capturedRuntimeFence(sinkMark, node) {
|
|
7081
|
+
if (this.diagSink === null)
|
|
7082
|
+
return null;
|
|
7083
|
+
return this.runtimeFenceStmt(this.diagSink[sinkMark], node, undefined);
|
|
7084
|
+
}
|
|
6034
7085
|
/** All diagnostics land here; while a generic instance body is lowering,
|
|
6035
7086
|
* the instantiation context is appended so the user knows which concrete
|
|
6036
7087
|
* types made the (source-anchored) construct fail. */
|
|
@@ -6100,9 +7151,9 @@ export class Lowerer {
|
|
|
6100
7151
|
// fetch values map earlier to checked-dynamic handles and do not reach
|
|
6101
7152
|
// here; constructor objects such as Headers still can.
|
|
6102
7153
|
if (typeSym &&
|
|
6103
|
-
FETCH_AMBIENT_TYPES.includes(typeSym
|
|
7154
|
+
FETCH_AMBIENT_TYPES.includes(ts.symbolName(typeSym)) &&
|
|
6104
7155
|
this.isStdlibSymbol(typeSym)) {
|
|
6105
|
-
this.pushDiag(unsupportedNativeApiDiag(`a value of type '${typeSym
|
|
7156
|
+
this.pushDiag(unsupportedNativeApiDiag(`a value of type '${ts.symbolName(typeSym)}'`, locOf(node)));
|
|
6106
7157
|
throw new PoisonError();
|
|
6107
7158
|
}
|
|
6108
7159
|
// ENUM OBJECTS (`typeof e` — a numeric enum's type carries the
|
|
@@ -6112,7 +7163,7 @@ export class Lowerer {
|
|
|
6112
7163
|
// as the per-site identifier fence — never the index-signature
|
|
6113
7164
|
// recitation.
|
|
6114
7165
|
if (typeSym && (typeSym.flags & ts.SymbolFlags.Enum) !== 0) {
|
|
6115
|
-
this.pushDiag(unsupportedDiag("SC1090", locOf(node), `enum objects as values ('${typeSym
|
|
7166
|
+
this.pushDiag(unsupportedDiag("SC1090", locOf(node), `enum objects as values ('${ts.symbolName(typeSym)}' — member reads like '${ts.symbolName(typeSym)}.X' compile to constants; the object itself has no runtime representation)`));
|
|
6116
7167
|
throw new PoisonError();
|
|
6117
7168
|
}
|
|
6118
7169
|
// Would-be records with INDEX SIGNATURES (`Record<string, T>`,
|
|
@@ -6134,10 +7185,8 @@ export class Lowerer {
|
|
|
6134
7185
|
// (the value type, the key domain) the fences below tell better.
|
|
6135
7186
|
const ownSym = widened.getSymbol();
|
|
6136
7187
|
if (ownSym &&
|
|
6137
|
-
|
|
6138
|
-
.
|
|
6139
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
6140
|
-
this.isStdlibFile(d.getSourceFile()))) {
|
|
7188
|
+
ownSym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
7189
|
+
this.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
6141
7190
|
this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node)));
|
|
6142
7191
|
throw new PoisonError();
|
|
6143
7192
|
}
|
|
@@ -6172,10 +7221,8 @@ export class Lowerer {
|
|
|
6172
7221
|
// tell — rather than an overload/record claim no user can act on.
|
|
6173
7222
|
const stdlibOwnSym = widened.getSymbol();
|
|
6174
7223
|
const stdlibNominal = stdlibOwnSym !== undefined &&
|
|
6175
|
-
|
|
6176
|
-
.
|
|
6177
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
6178
|
-
this.isStdlibFile(d.getSourceFile()));
|
|
7224
|
+
stdlibOwnSym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
7225
|
+
this.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
6179
7226
|
// OVERLOADED call signatures (SC2007) — after the generic branch, so a
|
|
6180
7227
|
// generic overload set keeps the monomorphization story: a value of a
|
|
6181
7228
|
// multi-signature type has no single compiled signature to hold.
|
|
@@ -6227,7 +7274,7 @@ export class Lowerer {
|
|
|
6227
7274
|
TextEncoder: "TextEncoder instances support encode(string) and encode(); other codec operations require a dedicated lowering",
|
|
6228
7275
|
TextDecoder: "TextDecoder instances support recognized labels, fatal/ignoreBOM option literals, and streaming UTF-8/UTF-16/single-byte decode; runtime option objects remain unsupported",
|
|
6229
7276
|
};
|
|
6230
|
-
this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node), typeHints[stdlibOwnSym
|
|
7277
|
+
this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node), typeHints[ts.symbolNameOf(stdlibOwnSym) ?? ""]));
|
|
6231
7278
|
throw new PoisonError();
|
|
6232
7279
|
}
|
|
6233
7280
|
// USER record shapes blocked by ONE member (SC2009's record arm):
|
|
@@ -6254,7 +7301,9 @@ export class Lowerer {
|
|
|
6254
7301
|
return stdlibMemberFence(this, access);
|
|
6255
7302
|
}
|
|
6256
7303
|
fenceStaticResponseMember(access, use) {
|
|
6257
|
-
return fenceStaticResponseMember(this, access, use) ??
|
|
7304
|
+
return (fenceStaticResponseMember(this, access, use) ??
|
|
7305
|
+
fenceStaticBlobMember(this, access, use) ??
|
|
7306
|
+
fenceWebCryptoMember(this, access, use));
|
|
6258
7307
|
}
|
|
6259
7308
|
fenceUnsupportedFetchConstructorMember(access) {
|
|
6260
7309
|
return fenceUnsupportedFetchConstructorMember(this, access);
|
|
@@ -6275,7 +7324,7 @@ export class Lowerer {
|
|
|
6275
7324
|
return fenceStaticReadableStreamMember(this, access, use);
|
|
6276
7325
|
}
|
|
6277
7326
|
typeOf(node) {
|
|
6278
|
-
if (ts.isPropertyAccessExpression(node) && isJsSourceFile(
|
|
7327
|
+
if (ts.isPropertyAccessExpression(node) && isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
6279
7328
|
const receiver = node.expression.kind === ts.SyntaxKind.ThisKeyword && this.fnStack.length > 0
|
|
6280
7329
|
? this.resolveThis()?.type
|
|
6281
7330
|
: this.mapTypeOf(this.checker.getTypeAtLocation(node.expression));
|
|
@@ -6290,11 +7339,25 @@ export class Lowerer {
|
|
|
6290
7339
|
return this.checker.getUnknownType();
|
|
6291
7340
|
}
|
|
6292
7341
|
}
|
|
7342
|
+
// A symbol-keyed field read through a CommonJS key-table key reads as
|
|
7343
|
+
// the field's layout type (tableKeyFieldType).
|
|
7344
|
+
if (ts.isElementAccessExpression(node) && isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
7345
|
+
const field = tableKeyFieldType(this, node);
|
|
7346
|
+
if (field) {
|
|
7347
|
+
if (field.kind === "f64")
|
|
7348
|
+
return this.checker.getNumberType();
|
|
7349
|
+
if (field.kind === "string")
|
|
7350
|
+
return this.checker.getStringType();
|
|
7351
|
+
if (field.kind === "bool")
|
|
7352
|
+
return this.checker.getBooleanType();
|
|
7353
|
+
return this.checker.getUnknownType();
|
|
7354
|
+
}
|
|
7355
|
+
}
|
|
6293
7356
|
// A checked JS method receives its actual call-site receiver. Its
|
|
6294
7357
|
// declaration's inferred class type must not turn property reads back
|
|
6295
7358
|
// into native field loads when the method is borrowed by another object.
|
|
6296
7359
|
if (node.kind === ts.SyntaxKind.ThisKeyword &&
|
|
6297
|
-
isJsSourceFile(
|
|
7360
|
+
isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
6298
7361
|
this.fnStack.length > 0 &&
|
|
6299
7362
|
this.resolveThis()?.type.kind === "dyn")
|
|
6300
7363
|
return this.checker.getUnknownType();
|
|
@@ -6355,7 +7418,7 @@ export class Lowerer {
|
|
|
6355
7418
|
// JSDoc and initializer inference are declaration types, not flow
|
|
6356
7419
|
// proofs. A checked specialization must not reinstate those
|
|
6357
7420
|
// stale layouts (mutable/null slots and heterogeneous JS arrays).
|
|
6358
|
-
const declaration = sym &&
|
|
7421
|
+
const declaration = sym && sym.valueDeclaration;
|
|
6359
7422
|
const declared = declaration && ts.isParameter(declaration)
|
|
6360
7423
|
? this.mapTypeOf(this.checker.getTypeAtLocation(declaration.name))
|
|
6361
7424
|
: null;
|
|
@@ -6392,6 +7455,14 @@ export class Lowerer {
|
|
|
6392
7455
|
? (jsArgumentsFunctionType(this, t) ?? mapped)
|
|
6393
7456
|
: mapped;
|
|
6394
7457
|
}
|
|
7458
|
+
/** The runtime type of a record member slot typed `t`: an overloaded
|
|
7459
|
+
* member's erased function (erasedOverloadMemberType — the type a record
|
|
7460
|
+
* shape stores for it), otherwise mapTypeOf. */
|
|
7461
|
+
memberSlotTypeOf(t) {
|
|
7462
|
+
if (isOverloadedCallableMemberType(t, this.checker))
|
|
7463
|
+
return erasedOverloadMemberType(t, this.typeCtx) ?? null;
|
|
7464
|
+
return this.mapTypeOf(t);
|
|
7465
|
+
}
|
|
6395
7466
|
/** The one position where a contextual UNION must not be adopted over the
|
|
6396
7467
|
* expression's own: the LEFT operand of `&&`, `||`, or `??`. Adopting a
|
|
6397
7468
|
* contextual union is normally safe because tsc proved the value
|
|
@@ -6494,7 +7565,15 @@ export class Lowerer {
|
|
|
6494
7565
|
return ts.constituentTypes(part).every(visit);
|
|
6495
7566
|
return false;
|
|
6496
7567
|
};
|
|
6497
|
-
|
|
7568
|
+
// A union typescript-go cannot describe is not proven an array.
|
|
7569
|
+
try {
|
|
7570
|
+
return visit(t);
|
|
7571
|
+
}
|
|
7572
|
+
catch (e) {
|
|
7573
|
+
if (ts.isUnreadableConstituentsPanic(e))
|
|
7574
|
+
return false;
|
|
7575
|
+
throw e;
|
|
7576
|
+
}
|
|
6498
7577
|
}
|
|
6499
7578
|
/** The lowered static array/tuple value behind checkerAnyArray's
|
|
6500
7579
|
* synthetic `any[]` spelling. Array.isArray can leave readonly tuple
|
|
@@ -6532,7 +7611,7 @@ export class Lowerer {
|
|
|
6532
7611
|
// JS inference can leave mutable fields, accessor parameters and
|
|
6533
7612
|
// locals at null/undefined despite later writes. Keep mutable native
|
|
6534
7613
|
// storage instead of a slot restricted to the initializer's unit value.
|
|
6535
|
-
if (isJsSourceFile(
|
|
7614
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
6536
7615
|
(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0)
|
|
6537
7616
|
return DYN;
|
|
6538
7617
|
// A never-tainted JS type (neverTaintedJsType) maps — never rides as
|
|
@@ -6543,6 +7622,9 @@ export class Lowerer {
|
|
|
6543
7622
|
const argumentsType = jsArgumentsFunctionType(this, t);
|
|
6544
7623
|
if (argumentsType !== null)
|
|
6545
7624
|
return argumentsType;
|
|
7625
|
+
const localClass = genericLocalClassBinding(this, node);
|
|
7626
|
+
if (localClass !== null)
|
|
7627
|
+
return localClass;
|
|
6546
7628
|
// The checked-dynamic declaration fallback (dynFallbackType): a
|
|
6547
7629
|
// JAVASCRIPT binding of any inference residue, or a TypeScript
|
|
6548
7630
|
// binding of genuine checker-`any`, becomes the checked-dynamic
|
|
@@ -6570,6 +7652,13 @@ export class Lowerer {
|
|
|
6570
7652
|
requireExactShape(node, actual, expected) {
|
|
6571
7653
|
if (typeEquals(actual, expected))
|
|
6572
7654
|
return;
|
|
7655
|
+
if (!this.generalNodeStreams && needsGeneralNodeStreams(this, actual, expected)) {
|
|
7656
|
+
this.requiresGeneralNodeStreams = true;
|
|
7657
|
+
// An untyped value into a stream slot also needs the checked-dynamic
|
|
7658
|
+
// slots (dyn-streams.ts).
|
|
7659
|
+
if (actual.kind === "dyn")
|
|
7660
|
+
this.requiresDynNodeStreams = true;
|
|
7661
|
+
}
|
|
6573
7662
|
// dyn mismatches first. A dyn ('unknown') value flowing into a typed
|
|
6574
7663
|
// slot needs a CHECKED cast — the hint points at `as <type>`; tsc
|
|
6575
7664
|
// usually rejects this before we do, so the fence is mostly defensive.
|
|
@@ -6725,6 +7814,15 @@ export class Lowerer {
|
|
|
6725
7814
|
* else (including a DIFFERENT union) is left for requireExactShape, which
|
|
6726
7815
|
* rejects union mismatches with SC2003. */
|
|
6727
7816
|
coerceToExpected(expr, expected) {
|
|
7817
|
+
// A comma expression ending in a unit literal (`return log(), null`):
|
|
7818
|
+
// its effects run first, unchanged, and the unit value takes the
|
|
7819
|
+
// destination's representation (a bare unit literal has none).
|
|
7820
|
+
if (expr.kind === "seqExpr" &&
|
|
7821
|
+
expr.result.kind === "unitLit" &&
|
|
7822
|
+
!typeEquals(expr.type, expected)) {
|
|
7823
|
+
const result = this.coerceToExpected(expr.result, expected);
|
|
7824
|
+
return { ...expr, result, type: result.type };
|
|
7825
|
+
}
|
|
6728
7826
|
// A destination that holds undefined takes an unassigned deferred-init
|
|
6729
7827
|
// field's slot as is (Node passes the undefined along).
|
|
6730
7828
|
if (expected.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0) {
|
|
@@ -6734,6 +7832,10 @@ export class Lowerer {
|
|
|
6734
7832
|
}
|
|
6735
7833
|
if (expr.type.kind === "void" && expected.kind !== "void" && this.neverValued.has(expr))
|
|
6736
7834
|
return this.divergentValue(expr, expected);
|
|
7835
|
+
// process.stdout/stderr into a general Writable slot (general-streams.ts).
|
|
7836
|
+
const stdioStream = stdioIntoGeneralStream(this, expr, expected);
|
|
7837
|
+
if (stdioStream)
|
|
7838
|
+
return this.coerceToExpected(stdioStream, expected);
|
|
6737
7839
|
// Iterator-typed slots: native iterators and differently typed
|
|
6738
7840
|
// generators step through an adapter generator.
|
|
6739
7841
|
if (expected.kind === "generator" && !typeEquals(expr.type, expected)) {
|
|
@@ -6754,6 +7856,16 @@ export class Lowerer {
|
|
|
6754
7856
|
// undefined/null literals store the dyn unit values. Types outside the
|
|
6755
7857
|
// dyn's domain (bytes, classes, Maps, ...) fall through to
|
|
6756
7858
|
// requireExactShape's SC1101 fence.
|
|
7859
|
+
// A promise entering a maybe-promise union whose promise arm has a
|
|
7860
|
+
// wider payload (`Promise<R>` into `Promise<R | void> | R | void`)
|
|
7861
|
+
// takes the payload widening below first, then wraps into that arm.
|
|
7862
|
+
if (expected.kind === "union" && expr.type.kind === "promise") {
|
|
7863
|
+
const mp = maybePromiseUnionOf(this, expected);
|
|
7864
|
+
if (mp &&
|
|
7865
|
+
!typeEquals(mp.promise, expr.type) &&
|
|
7866
|
+
this.promisePayloadWidens(expr.type, mp.promise))
|
|
7867
|
+
expr = this.coerceToExpected(expr, mp.promise);
|
|
7868
|
+
}
|
|
6757
7869
|
// Promise payloads may widen at a checked return boundary, including
|
|
6758
7870
|
// arrays inferred as tuple results by Promise.all. Keep both payload
|
|
6759
7871
|
// ABIs explicit: box settlement, then validate the destination payload.
|
|
@@ -6803,6 +7915,37 @@ export class Lowerer {
|
|
|
6803
7915
|
loc: expr.loc,
|
|
6804
7916
|
};
|
|
6805
7917
|
}
|
|
7918
|
+
// A runtime-provided class value has no checked-dynamic form that
|
|
7919
|
+
// inspects as Node's does (`[Function: EventEmitter] { ... }`).
|
|
7920
|
+
// JavaScript sources already read EventEmitter and the stream
|
|
7921
|
+
// classes as the runtime's untyped constructors (builtin-class-dyn.ts),
|
|
7922
|
+
// so one of those classes turning untyped there becomes the same
|
|
7923
|
+
// constructor. `require("events")` is the EventEmitter class itself,
|
|
7924
|
+
// so its module binding is too (`ReleaseEmitter = EventEmitter` over
|
|
7925
|
+
// `const EventEmitter = require("events")`).
|
|
7926
|
+
if (expr.type.kind === "moduleNs" &&
|
|
7927
|
+
expr.type.moduleId === "builtin:events" &&
|
|
7928
|
+
isJsSourceFileName(expr.loc.file)) {
|
|
7929
|
+
const value = builtinClassValue(0, expr.loc);
|
|
7930
|
+
if (expr.kind === "moduleNsRef")
|
|
7931
|
+
return value;
|
|
7932
|
+
return {
|
|
7933
|
+
kind: "seqExpr",
|
|
7934
|
+
stmts: [{ kind: "exprStmt", expr, loc: expr.loc }],
|
|
7935
|
+
result: value,
|
|
7936
|
+
type: DYN,
|
|
7937
|
+
loc: expr.loc,
|
|
7938
|
+
};
|
|
7939
|
+
}
|
|
7940
|
+
if (expr.type.kind === "classval" && this.classes.get(expr.type.className)?.def.runtime) {
|
|
7941
|
+
// Only the class itself: a slot of the class's type may hold a
|
|
7942
|
+
// program subclass, which this constructor would misidentify.
|
|
7943
|
+
const kind = builtinClassKind(expr.type.className);
|
|
7944
|
+
if (kind !== null && expr.kind === "classRef" && isJsSourceFileName(expr.loc.file))
|
|
7945
|
+
return builtinClassValue(kind, expr.loc);
|
|
7946
|
+
this.pushDiag(unsupportedDiag("SC1090", expr.loc, `a runtime-provided class value ('${expr.type.className.slice(1)}') as an untyped value`));
|
|
7947
|
+
throw new PoisonError();
|
|
7948
|
+
}
|
|
6806
7949
|
if (expr.kind === "unitLit" || this.dynConvertible(expr.type)) {
|
|
6807
7950
|
// Records and arrays keep their identity as untyped values, including
|
|
6808
7951
|
// when they arrive through a union, so `unknown` views, weak
|
|
@@ -6816,12 +7959,16 @@ export class Lowerer {
|
|
|
6816
7959
|
const liveRef = liveReference(expr.type) ||
|
|
6817
7960
|
(expr.type.kind === "union" &&
|
|
6818
7961
|
(this.unions.get(expr.type.unionId)?.arms.some(liveReference) ?? false));
|
|
7962
|
+
// A builtin function's adapter boxes under the builtin's name, the
|
|
7963
|
+
// name Node's function carries (`[Function: randomUUID]`).
|
|
7964
|
+
const builtinName = expr.kind === "closure" ? this.builtinCallableValueNames.get(expr.fnName) : undefined;
|
|
6819
7965
|
return {
|
|
6820
7966
|
kind: "dynFrom",
|
|
6821
7967
|
value: expr,
|
|
6822
7968
|
type: DYN,
|
|
6823
7969
|
loc: expr.loc,
|
|
6824
7970
|
...(liveRef ? { liveRef: true } : {}),
|
|
7971
|
+
...(builtinName !== undefined ? { fnName: builtinName } : {}),
|
|
6825
7972
|
};
|
|
6826
7973
|
}
|
|
6827
7974
|
return expr;
|
|
@@ -6858,6 +8005,17 @@ export class Lowerer {
|
|
|
6858
8005
|
const funcOk = expected.kind === "func" &&
|
|
6859
8006
|
canAdaptDynFuncTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id));
|
|
6860
8007
|
const handleOk = DYN_HANDLE_KINDS.has(expected.kind);
|
|
8008
|
+
noteUntypedStreamFlow(this, expected);
|
|
8009
|
+
// `[EventEmitter]` in JavaScript builds an untyped array of the
|
|
8010
|
+
// untyped constructor, which a typed array of the class cannot
|
|
8011
|
+
// hold: no class check admits that constructor.
|
|
8012
|
+
if (expr.kind === "dynArrLit" &&
|
|
8013
|
+
expected.kind === "array" &&
|
|
8014
|
+
expected.elem.kind === "classval" &&
|
|
8015
|
+
expr.elems.some((elem) => elem.kind === "libCall" && elem.fn === "dyn.builtinClass")) {
|
|
8016
|
+
this.pushDiag(unsupportedDiag("SC1090", expr.loc, `holding runtime-provided class values ('${expected.elem.className.slice(1)}') in a typed array`));
|
|
8017
|
+
throw new PoisonError();
|
|
8018
|
+
}
|
|
6861
8019
|
if (canDynCheckTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id)) ||
|
|
6862
8020
|
undefArmedOk ||
|
|
6863
8021
|
bytesOk ||
|
|
@@ -6990,6 +8148,7 @@ export class Lowerer {
|
|
|
6990
8148
|
// and no completion target is meaningful — the exact-shape fence
|
|
6991
8149
|
// downstream names the class-value flow instead.
|
|
6992
8150
|
if (sub && sup && !sup.generic && this.ctorAbiEquals(sub, sup)) {
|
|
8151
|
+
defineClassValueConstruct(this, sup);
|
|
6993
8152
|
return { kind: "upcast", value: expr, type: expected, loc: expr.loc };
|
|
6994
8153
|
}
|
|
6995
8154
|
}
|
|
@@ -7026,6 +8185,11 @@ export class Lowerer {
|
|
|
7026
8185
|
return this.applyWidthLift(lift, narrowed, expected, expr.loc);
|
|
7027
8186
|
}
|
|
7028
8187
|
}
|
|
8188
|
+
if (expr.type.kind === "union" && expected.kind === "record") {
|
|
8189
|
+
const lifted = unionArmsWidthLift(this, expr, expected);
|
|
8190
|
+
if (lifted)
|
|
8191
|
+
return lifted;
|
|
8192
|
+
}
|
|
7029
8193
|
if (!typeEquals(expr.type, expected)) {
|
|
7030
8194
|
const w = this.widthCoerce(expr, expected);
|
|
7031
8195
|
if (w)
|
|
@@ -7110,6 +8274,7 @@ export class Lowerer {
|
|
|
7110
8274
|
if (baseTag >= 0) {
|
|
7111
8275
|
if (!sub || !this.ctorAbiEquals(sub, c))
|
|
7112
8276
|
break;
|
|
8277
|
+
defineClassValueConstruct(this, c);
|
|
7113
8278
|
const widened = {
|
|
7114
8279
|
kind: "upcast",
|
|
7115
8280
|
value: expr,
|
|
@@ -7266,6 +8431,9 @@ export class Lowerer {
|
|
|
7266
8431
|
recordUnionWrapHelper(source, toId, loc) {
|
|
7267
8432
|
return recordUnionWrapHelper(this, source, toId, loc);
|
|
7268
8433
|
}
|
|
8434
|
+
recordUnionRouteHelper(source, toId, loc) {
|
|
8435
|
+
return recordUnionRouteHelper(this, source, toId, loc);
|
|
8436
|
+
}
|
|
7269
8437
|
unionRetagHelper(fromId, toId, loc, trappable) {
|
|
7270
8438
|
return unionRetagHelper(this, fromId, toId, loc, trappable);
|
|
7271
8439
|
}
|
|
@@ -7284,6 +8452,7 @@ export class Lowerer {
|
|
|
7284
8452
|
* lowering goes through here (via lowerExprExpecting) or calls this
|
|
7285
8453
|
* directly when the expression was already lowered. */
|
|
7286
8454
|
coerceInto(node, expr, expected) {
|
|
8455
|
+
refuseInferredCallbackDrops(this, node, expr.type, expected);
|
|
7287
8456
|
// A union destination can accept the binding's tagged storage directly.
|
|
7288
8457
|
// The checker's single-arm flow type can be stale after a callback writes
|
|
7289
8458
|
// the binding. Extracting that arm and wrapping it again would discard the
|
|
@@ -7301,9 +8470,16 @@ export class Lowerer {
|
|
|
7301
8470
|
// initial contextual layout was chosen. Its known discriminator still
|
|
7302
8471
|
// selects the destination arm; validate that payload before wrapping.
|
|
7303
8472
|
// Work with the already lowered value so property effects run once.
|
|
8473
|
+
// A type assertion keeps the literal's own record layout, which can
|
|
8474
|
+
// equal another arm's layout (`{ kind: "return", value, loc } as Stmt`
|
|
8475
|
+
// when a `throw` arm has the same fields), so assertions are looked
|
|
8476
|
+
// through as well.
|
|
7304
8477
|
if (expr.type.kind === "record" && expected.kind === "union") {
|
|
7305
8478
|
let literal = node;
|
|
7306
|
-
while (ts.isParenthesizedExpression(literal) ||
|
|
8479
|
+
while (ts.isParenthesizedExpression(literal) ||
|
|
8480
|
+
ts.isSatisfiesExpression(literal) ||
|
|
8481
|
+
ts.isAsExpression(literal) ||
|
|
8482
|
+
ts.isTypeAssertion(literal))
|
|
7307
8483
|
literal = literal.expression;
|
|
7308
8484
|
const def = this.unions.get(expected.unionId);
|
|
7309
8485
|
if (def?.discriminant && ts.isObjectLiteralExpression(literal)) {
|
|
@@ -7327,7 +8503,7 @@ export class Lowerer {
|
|
|
7327
8503
|
: [];
|
|
7328
8504
|
const errorOptions = parts.some((part) => {
|
|
7329
8505
|
const sym = part.getAliasSymbol() ?? part.getSymbol();
|
|
7330
|
-
return sym
|
|
8506
|
+
return (sym !== undefined && ts.symbolName(sym) === "ErrorOptions" && this.isStdlibSymbol(sym));
|
|
7331
8507
|
});
|
|
7332
8508
|
if (errorOptions) {
|
|
7333
8509
|
const actual = this.typeOf(node);
|
|
@@ -7357,7 +8533,7 @@ export class Lowerer {
|
|
|
7357
8533
|
let literal = node;
|
|
7358
8534
|
while (ts.isParenthesizedExpression(literal))
|
|
7359
8535
|
literal = literal.expression;
|
|
7360
|
-
if (isJsSourceFile(
|
|
8536
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
7361
8537
|
!ts.isArrayLiteralExpression(literal) &&
|
|
7362
8538
|
e.kind === "dynFrom" &&
|
|
7363
8539
|
e.value.type.kind === "array") {
|
|
@@ -7376,7 +8552,8 @@ export class Lowerer {
|
|
|
7376
8552
|
// node's CHECKER type proves those arms away, they trap instead — the
|
|
7377
8553
|
// sub-union narrowing bridge (narrowedRetagHelper).
|
|
7378
8554
|
if (e.type.kind === "union" && expected.kind === "union" && !typeEquals(e.type, expected)) {
|
|
7379
|
-
const helper = this.narrowedRetagHelper(node, e.type.unionId, expected.unionId, e.loc)
|
|
8555
|
+
const helper = this.narrowedRetagHelper(node, e.type.unionId, expected.unionId, e.loc) ??
|
|
8556
|
+
uninhabitedArmRetagHelper(this, node, e.type.unionId, expected.unionId, e.loc);
|
|
7380
8557
|
if (helper) {
|
|
7381
8558
|
e = { kind: "call", callee: helper, args: [e], type: expected, loc: e.loc };
|
|
7382
8559
|
}
|
|
@@ -7386,7 +8563,7 @@ export class Lowerer {
|
|
|
7386
8563
|
// never reinterpret an object payload as a scalar union arm.
|
|
7387
8564
|
if (e.type.kind === "union" &&
|
|
7388
8565
|
!typeEquals(e.type, expected) &&
|
|
7389
|
-
isJsSourceFile(
|
|
8566
|
+
isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
7390
8567
|
this.dynConvertible(e.type)) {
|
|
7391
8568
|
const sourceArms = this.unions.get(e.type.unionId)?.arms ?? [];
|
|
7392
8569
|
const targetArms = this.unions.get(expected.unionId)?.arms ?? [];
|
|
@@ -7423,7 +8600,7 @@ export class Lowerer {
|
|
|
7423
8600
|
const sym = this.resolveValueSymbol(n);
|
|
7424
8601
|
if (!sym)
|
|
7425
8602
|
return null;
|
|
7426
|
-
const decls =
|
|
8603
|
+
const decls = sym.declarations;
|
|
7427
8604
|
if (decls.length === 0)
|
|
7428
8605
|
return null;
|
|
7429
8606
|
const units = new Set();
|
|
@@ -7434,7 +8611,7 @@ export class Lowerer {
|
|
|
7434
8611
|
!ts.isIdentifier(d.name) ||
|
|
7435
8612
|
!ts.isVariableDeclarationList(d.parent) ||
|
|
7436
8613
|
!ts.isVariableStatement(d.parent.parent) ||
|
|
7437
|
-
|
|
8614
|
+
ts.getSourceFileOfNode(d).isDeclarationFile ||
|
|
7438
8615
|
(ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Ambient) !== 0) {
|
|
7439
8616
|
return null;
|
|
7440
8617
|
}
|
|
@@ -7551,6 +8728,9 @@ export class Lowerer {
|
|
|
7551
8728
|
if (expected) {
|
|
7552
8729
|
if (ts.isConditionalExpression(node))
|
|
7553
8730
|
return lowerTernary(this, node, expected);
|
|
8731
|
+
const escaped = this.neverAssertionInto(node, expected);
|
|
8732
|
+
if (escaped)
|
|
8733
|
+
return escaped;
|
|
7554
8734
|
const fresh = this.emptyCollectionFor(node, expected);
|
|
7555
8735
|
if (fresh)
|
|
7556
8736
|
return this.coerceInto(node, fresh, expected);
|
|
@@ -7600,10 +8780,10 @@ export class Lowerer {
|
|
|
7600
8780
|
// Construct its actual storage here so identity and WeakMap lifetime
|
|
7601
8781
|
// belong to the array the program keeps, rather than a typed snapshot.
|
|
7602
8782
|
if (ts.isArrayLiteralExpression(x) &&
|
|
7603
|
-
x.elements.every((element) => !ts.isSpreadElement(element) && !ts.isOmittedExpression(element))) {
|
|
8783
|
+
x.elements.nodes.every((element) => !ts.isSpreadElement(element) && !ts.isOmittedExpression(element))) {
|
|
7604
8784
|
return {
|
|
7605
8785
|
kind: "dynArrLit",
|
|
7606
|
-
elems: x.elements.map((element) => this.lowerExprExpecting(element, DYN)),
|
|
8786
|
+
elems: x.elements.nodes.map((element) => this.lowerExprExpecting(element, DYN)),
|
|
7607
8787
|
type: DYN,
|
|
7608
8788
|
loc: locOf(x),
|
|
7609
8789
|
};
|
|
@@ -7617,16 +8797,17 @@ export class Lowerer {
|
|
|
7617
8797
|
: [];
|
|
7618
8798
|
const builtinOption = (name) => parts.some((part) => {
|
|
7619
8799
|
const sym = part.getAliasSymbol() ?? part.getSymbol();
|
|
7620
|
-
return sym
|
|
8800
|
+
return ts.symbolNameOf(sym) === name && this.isStdlibSymbol(sym);
|
|
7621
8801
|
});
|
|
7622
8802
|
if (ts.isObjectLiteralExpression(x)) {
|
|
7623
|
-
if (isJsSourceFile(
|
|
8803
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(x)) ||
|
|
7624
8804
|
builtinOption("RequestInit") ||
|
|
7625
8805
|
builtinOption("ErrorOptions") ||
|
|
7626
8806
|
builtinOption("SpawnOptions") ||
|
|
7627
8807
|
builtinOption("UrlObject") ||
|
|
7628
8808
|
builtinOption("URLFormatOptions") ||
|
|
7629
|
-
!this.mapTypeOf(this.typeOf(x))
|
|
8809
|
+
!this.mapTypeOf(this.typeOf(x)) ||
|
|
8810
|
+
this.excessJsContextualProperty(x, parts)) {
|
|
7630
8811
|
return lowerDynObjectLiteral(this, x);
|
|
7631
8812
|
}
|
|
7632
8813
|
}
|
|
@@ -7647,24 +8828,24 @@ export class Lowerer {
|
|
|
7647
8828
|
// a unit-only-element array — a checker type that degraded to one
|
|
7648
8829
|
// (`[]`-flavored inference over a populated literal) carries no
|
|
7649
8830
|
// element information.
|
|
7650
|
-
const nonUnitElems = x.elements.some((el) => !ts.isOmittedExpression(el) &&
|
|
8831
|
+
const nonUnitElems = x.elements.nodes.some((el) => !ts.isOmittedExpression(el) &&
|
|
7651
8832
|
el.kind !== ts.SyntaxKind.NullKeyword &&
|
|
7652
8833
|
!(ts.isIdentifier(el) && el.text === "undefined"));
|
|
7653
8834
|
const def = this.unions.get(expected.unionId);
|
|
7654
8835
|
const arms = (def?.arms ?? []).filter((a) => (a.kind === "array" && !(nonUnitElems && this.unitOnlyElem(a.elem))) ||
|
|
7655
8836
|
(a.kind === "record" &&
|
|
7656
8837
|
!!this.shapes.get(a.shapeId)?.tuple &&
|
|
7657
|
-
this.shapes.get(a.shapeId).fields.length === x.elements.length &&
|
|
7658
|
-
!x.elements.some(ts.isSpreadElement)));
|
|
8838
|
+
this.shapes.get(a.shapeId).fields.length === x.elements.nodes.length &&
|
|
8839
|
+
!x.elements.nodes.some(ts.isSpreadElement)));
|
|
7659
8840
|
let arm = arms.length === 1 ? arms[0] : undefined;
|
|
7660
8841
|
if (!arm &&
|
|
7661
8842
|
arms.length > 1 &&
|
|
7662
|
-
x.elements.length > 0 &&
|
|
7663
|
-
x.elements.every((el) => !ts.isSpreadElement(el) && !ts.isOmittedExpression(el))) {
|
|
8843
|
+
x.elements.nodes.length > 0 &&
|
|
8844
|
+
x.elements.nodes.every((el) => !ts.isSpreadElement(el) && !ts.isOmittedExpression(el))) {
|
|
7664
8845
|
const ownType = this.mapTypeOf(this.typeOf(x));
|
|
7665
8846
|
arm = arms.find((candidate) => ownType !== null && typeEquals(candidate, ownType));
|
|
7666
8847
|
if (!arm) {
|
|
7667
|
-
const elements = x.elements.map((el) => tryLowerExpression(this, el));
|
|
8848
|
+
const elements = x.elements.nodes.map((el) => tryLowerExpression(this, el));
|
|
7668
8849
|
arm = arms.find((candidate) => candidate.kind === "array" &&
|
|
7669
8850
|
elements.every((element) => element !== null && this.widthLiftPlan(element.type, candidate.elem) !== null));
|
|
7670
8851
|
}
|
|
@@ -7675,14 +8856,20 @@ export class Lowerer {
|
|
|
7675
8856
|
}
|
|
7676
8857
|
}
|
|
7677
8858
|
}
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
8859
|
+
const e = this.lowerExpr(node);
|
|
8860
|
+
return expected ? this.coerceExistingInto(node, e, expected) : e;
|
|
8861
|
+
}
|
|
8862
|
+
/** The conversion lowerExprExpecting applies to `e`, the lowered value
|
|
8863
|
+
* of `node` when it is not fresh construction the destination directs
|
|
8864
|
+
* (a literal, conditional, or empty collection). */
|
|
8865
|
+
coerceExistingInto(node, e, expected) {
|
|
8866
|
+
if ((expected.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0) ||
|
|
8867
|
+
(expected.kind === "dyn" && isJsSourceFile(ts.getSourceFileOfNode(node)))) {
|
|
7681
8868
|
// A destination that accepts undefined must retain an unchecked
|
|
7682
8869
|
// read's storage value even when the checker still calls it present.
|
|
7683
8870
|
e = this.runtimeOptionalSourceValue(node, e) ?? e;
|
|
7684
8871
|
}
|
|
7685
|
-
return
|
|
8872
|
+
return this.coerceInto(node, e, expected);
|
|
7686
8873
|
}
|
|
7687
8874
|
/** An unannotated empty collection has no existing elements or aliases
|
|
7688
8875
|
* that constrain its layout. An explicit type argument still wins. */
|
|
@@ -7692,13 +8879,13 @@ export class Lowerer {
|
|
|
7692
8879
|
value = value.expression;
|
|
7693
8880
|
if (!ts.isNewExpression(value) ||
|
|
7694
8881
|
!ts.isIdentifier(value.expression) ||
|
|
7695
|
-
(value.arguments?.length ?? 0) !== 0 ||
|
|
7696
|
-
(value.typeArguments?.length ?? 0) !== 0)
|
|
8882
|
+
(value.arguments?.nodes.length ?? 0) !== 0 ||
|
|
8883
|
+
(value.typeArguments?.nodes.length ?? 0) !== 0)
|
|
7697
8884
|
return null;
|
|
7698
8885
|
const symbol = this.resolveValueSymbol(value.expression);
|
|
7699
8886
|
if (!symbol || !this.isStdlibSymbol(symbol))
|
|
7700
8887
|
return null;
|
|
7701
|
-
const kind = symbol
|
|
8888
|
+
const kind = ts.symbolName(symbol) === "Map" ? "map" : ts.symbolName(symbol) === "Set" ? "set" : null;
|
|
7702
8889
|
if (!kind)
|
|
7703
8890
|
return null;
|
|
7704
8891
|
const arms = expected.kind === "union" ? (this.unions.get(expected.unionId)?.arms ?? []) : [expected];
|
|
@@ -7752,6 +8939,17 @@ export class Lowerer {
|
|
|
7752
8939
|
this.addedUndefinedArms.set(t.unionId, { type, unions: this.unions.revision });
|
|
7753
8940
|
return type;
|
|
7754
8941
|
}
|
|
8942
|
+
/** Whether a promise of `from` converts to a promise of `to` through the
|
|
8943
|
+
* checked payload widening (coerceToExpected's boxed-settlement rule,
|
|
8944
|
+
* which keeps the promise's identity and settlement turn). */
|
|
8945
|
+
promisePayloadWidens(from, to) {
|
|
8946
|
+
if (typeEquals(from, to))
|
|
8947
|
+
return true;
|
|
8948
|
+
if (to.inner.kind === "void")
|
|
8949
|
+
return from.inner.kind !== "void";
|
|
8950
|
+
return (this.dynConvertible(from) &&
|
|
8951
|
+
canDynCheckTo(to, (id) => this.shapes.get(id), (id) => this.unions.get(id)));
|
|
8952
|
+
}
|
|
7755
8953
|
/** True when a static type converts to a dyn value (the dynFrom
|
|
7756
8954
|
* walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the checked-dynamic tree's
|
|
7757
8955
|
* bytes kind, payload copied; stdin chunks into unknown-typed helpers),
|
|
@@ -7786,15 +8984,24 @@ export class Lowerer {
|
|
|
7786
8984
|
// storage directly, just like arguments and variable initializers.
|
|
7787
8985
|
// Contextual types (such as Proxy descriptors' symbol-valued fields)
|
|
7788
8986
|
// must not force an intermediate record with incompatible field slots.
|
|
8987
|
+
if (this.returnsLiteralIntoDyn(node, expected))
|
|
8988
|
+
return this.lowerExprExpecting(node, expected);
|
|
8989
|
+
return this.asyncReturnValueOf(node, this.lowerExpr(node), expected);
|
|
8990
|
+
}
|
|
8991
|
+
/** A fresh JS object literal returned into a checked-native (dyn) result,
|
|
8992
|
+
* which lowers straight into that storage. */
|
|
8993
|
+
returnsLiteralIntoDyn(node, expected) {
|
|
7789
8994
|
let literal = node;
|
|
7790
8995
|
while (ts.isParenthesizedExpression(literal))
|
|
7791
8996
|
literal = literal.expression;
|
|
7792
|
-
|
|
7793
|
-
isJsSourceFile(
|
|
7794
|
-
ts.isObjectLiteralExpression(literal))
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
8997
|
+
return (expected.kind === "dyn" &&
|
|
8998
|
+
isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
8999
|
+
ts.isObjectLiteralExpression(literal));
|
|
9000
|
+
}
|
|
9001
|
+
/** The value of `return <e>` (already lowered untyped) in an async or
|
|
9002
|
+
* void context: a promise flattens through the returned-promise await,
|
|
9003
|
+
* everything else converts into the declared result. */
|
|
9004
|
+
asyncReturnValueOf(node, e, expected) {
|
|
7798
9005
|
if (expected.kind === "void" && e.kind === "unitLit")
|
|
7799
9006
|
return null;
|
|
7800
9007
|
if (this.ctx.isAsync && e.type.kind === "promise" && expected.kind !== "promise") {
|
|
@@ -7858,10 +9065,28 @@ export class Lowerer {
|
|
|
7858
9065
|
}
|
|
7859
9066
|
return s;
|
|
7860
9067
|
}
|
|
9068
|
+
/** `return u` of a promise-armed union (maybe-promise, or promise-or-
|
|
9069
|
+
* unit) in an async function: adopt the promise arm, fulfill with the
|
|
9070
|
+
* others (maybe-promise.ts). Null when the return is not that shape. */
|
|
9071
|
+
maybePromiseReturn(node, e, expected) {
|
|
9072
|
+
if (!this.adoptsReturnedPromise())
|
|
9073
|
+
return null;
|
|
9074
|
+
const mp = promiseArmedUnionOf(this, e.type);
|
|
9075
|
+
if (!mp || promiseArmedUnionOf(this, expected))
|
|
9076
|
+
return null;
|
|
9077
|
+
const stmt = maybePromiseReturnStmt(this, e, mp, expected, (x) => this.coerceInto(node, x, expected));
|
|
9078
|
+
if (stmt === null) {
|
|
9079
|
+
this.unsupported("SC1090", node, `returning '${this.fmt(e.type)}' from an async function whose result is '${this.fmt(expected)}' (an arm does not convert to the result)`);
|
|
9080
|
+
}
|
|
9081
|
+
return stmt;
|
|
9082
|
+
}
|
|
7861
9083
|
lowerReturnOf(node, loc) {
|
|
7862
9084
|
const expected = this.ctx.returnType;
|
|
7863
9085
|
if (expected.kind === "void") {
|
|
7864
9086
|
let e = this.lowerExpr(node);
|
|
9087
|
+
const flattened = this.maybePromiseReturn(node, e, expected);
|
|
9088
|
+
if (flattened)
|
|
9089
|
+
return flattened;
|
|
7865
9090
|
if (this.ctx.isAsync && e.type.kind === "promise") {
|
|
7866
9091
|
if (this.adoptsReturnedPromise())
|
|
7867
9092
|
return this.adoptingReturn(e, VOID, (x) => x);
|
|
@@ -7869,6 +9094,14 @@ export class Lowerer {
|
|
|
7869
9094
|
}
|
|
7870
9095
|
if (e.kind === "unitLit")
|
|
7871
9096
|
return { kind: "return", value: null, loc };
|
|
9097
|
+
// `return c ? f() : g()` over void calls: a void conditional has no
|
|
9098
|
+
// value representation, so its branch selection becomes control flow.
|
|
9099
|
+
if (e.kind === "ternary" && e.type.kind === "void") {
|
|
9100
|
+
const branch = (x) => x.kind === "ternary" && x.type.kind === "void"
|
|
9101
|
+
? { kind: "if", cond: x.cond, then: [branch(x.then)], else_: [branch(x.else_)], loc }
|
|
9102
|
+
: { kind: "exprStmt", expr: x, loc };
|
|
9103
|
+
return { kind: "block", body: [branch(e), { kind: "return", value: null, loc }], loc };
|
|
9104
|
+
}
|
|
7872
9105
|
if (e.type.kind === "void")
|
|
7873
9106
|
return { kind: "return", value: e, loc };
|
|
7874
9107
|
return {
|
|
@@ -7880,6 +9113,16 @@ export class Lowerer {
|
|
|
7880
9113
|
loc,
|
|
7881
9114
|
};
|
|
7882
9115
|
}
|
|
9116
|
+
if (this.adoptsReturnedPromise() && !this.returnsLiteralIntoDyn(node, expected)) {
|
|
9117
|
+
// The async return lowers its operand untyped first (a promise
|
|
9118
|
+
// adopts before its payload converts); a maybe-promise union needs
|
|
9119
|
+
// the statement form, which branches between adoption and fulfillment.
|
|
9120
|
+
const e = this.lowerExpr(node);
|
|
9121
|
+
const flattened = this.maybePromiseReturn(node, e, expected);
|
|
9122
|
+
if (flattened)
|
|
9123
|
+
return flattened;
|
|
9124
|
+
return { kind: "return", value: this.asyncReturnValueOf(node, e, expected), loc };
|
|
9125
|
+
}
|
|
7883
9126
|
return { kind: "return", value: this.lowerReturnValue(node), loc };
|
|
7884
9127
|
}
|
|
7885
9128
|
maybeNarrow(expr, node) {
|
|
@@ -8036,7 +9279,7 @@ export class Lowerer {
|
|
|
8036
9279
|
// declaration poisons under a source-anchored diagnostic, deferred
|
|
8037
9280
|
// like any collection fence — never a crashed CLI.
|
|
8038
9281
|
if (isCheckerPanic(e)) {
|
|
8039
|
-
const decl = symbol ?
|
|
9282
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
8040
9283
|
sink.push(checkerPanicDiag(e.message.split("\n", 1)[0], decl ? locOf(decl) : { file: this.entry.fileName, start: 0, end: 0 }));
|
|
8041
9284
|
}
|
|
8042
9285
|
else if (!(e instanceof PoisonError)) {
|
|
@@ -8147,27 +9390,27 @@ export class Lowerer {
|
|
|
8147
9390
|
const typeNodes = [];
|
|
8148
9391
|
const symbolRoots = [];
|
|
8149
9392
|
for (const decl of decls) {
|
|
8150
|
-
for (const member of decl.members) {
|
|
9393
|
+
for (const member of decl.members.nodes) {
|
|
8151
9394
|
if ((ts.isConstructorDeclaration(member) ||
|
|
8152
9395
|
ts.isMethodDeclaration(member) ||
|
|
8153
9396
|
ts.isGetAccessor(member) ||
|
|
8154
9397
|
ts.isSetAccessor(member)) &&
|
|
8155
9398
|
(!ts.isMethodDeclaration(member) || member.typeParameters === undefined)) {
|
|
8156
|
-
for (const param of member.parameters) {
|
|
9399
|
+
for (const param of member.parameters.nodes) {
|
|
8157
9400
|
if (param.initializer)
|
|
8158
9401
|
defaultTypeNodes.push(param.initializer);
|
|
8159
9402
|
}
|
|
8160
9403
|
}
|
|
8161
9404
|
}
|
|
8162
|
-
if (!isJsSourceFile(
|
|
9405
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
8163
9406
|
continue;
|
|
8164
|
-
for (const member of decl.members) {
|
|
9407
|
+
for (const member of decl.members.nodes) {
|
|
8165
9408
|
if (ts.isConstructorDeclaration(member)) {
|
|
8166
|
-
for (const param of member.parameters) {
|
|
9409
|
+
for (const param of member.parameters.nodes) {
|
|
8167
9410
|
if (param.initializer)
|
|
8168
9411
|
typeNodes.push(param.initializer);
|
|
8169
9412
|
}
|
|
8170
|
-
for (const stmt of member.body?.statements ?? []) {
|
|
9413
|
+
for (const stmt of member.body?.statements?.nodes ?? []) {
|
|
8171
9414
|
if (!ts.isExpressionStatement(stmt) || !ts.isBinaryExpression(stmt.expression))
|
|
8172
9415
|
continue;
|
|
8173
9416
|
if (stmt.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
@@ -8186,13 +9429,13 @@ export class Lowerer {
|
|
|
8186
9429
|
if (ts.isMethodDeclaration(member) ||
|
|
8187
9430
|
ts.isGetAccessor(member) ||
|
|
8188
9431
|
ts.isSetAccessor(member)) {
|
|
8189
|
-
for (const param of member.parameters) {
|
|
9432
|
+
for (const param of member.parameters.nodes) {
|
|
8190
9433
|
if (param.initializer)
|
|
8191
9434
|
typeNodes.push(param.initializer);
|
|
8192
9435
|
}
|
|
8193
9436
|
// npm-static implicit-any classification resolves body parameter
|
|
8194
9437
|
// references while collecting the method's shape.
|
|
8195
|
-
if (implicitMonoFile(
|
|
9438
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) && member.body) {
|
|
8196
9439
|
symbolRoots.push(member.body);
|
|
8197
9440
|
}
|
|
8198
9441
|
}
|
|
@@ -8219,6 +9462,43 @@ export class Lowerer {
|
|
|
8219
9462
|
lowerClassExpressionInfo(expr) {
|
|
8220
9463
|
return lowerClassExpressionInfo(this, expr);
|
|
8221
9464
|
}
|
|
9465
|
+
/** Depth of the whole-program analyses that query types across every
|
|
9466
|
+
* file before reachability is known (speculativeTypeQueries). */
|
|
9467
|
+
speculativeTypeQueryDepth = 0;
|
|
9468
|
+
/** Runs a whole-program analysis whose type queries are speculative: they
|
|
9469
|
+
* visit every file, reached or not, and no statement or declaration owns
|
|
9470
|
+
* a refusal they trigger (collectLocalClassForType). */
|
|
9471
|
+
speculativeTypeQueries(analysis) {
|
|
9472
|
+
this.speculativeTypeQueryDepth++;
|
|
9473
|
+
try {
|
|
9474
|
+
analysis();
|
|
9475
|
+
}
|
|
9476
|
+
finally {
|
|
9477
|
+
this.speculativeTypeQueryDepth--;
|
|
9478
|
+
}
|
|
9479
|
+
}
|
|
9480
|
+
/** Collects a function-local class because a type query named its
|
|
9481
|
+
* instance type. Collection and body lowering own a refusal of that
|
|
9482
|
+
* class: the poison reaches the declaration or statement that asked, as
|
|
9483
|
+
* before. A speculative whole-program analysis owns none, so there the
|
|
9484
|
+
* refusal stays reported (the build fails with it, as it did where such
|
|
9485
|
+
* an analysis already caught the poison) and the class is unmappable for
|
|
9486
|
+
* the query instead of the poison escaping the compiler. */
|
|
9487
|
+
collectLocalClassForType(decl) {
|
|
9488
|
+
if (this.speculativeTypeQueryDepth === 0 || this.fnStack.length > 0) {
|
|
9489
|
+
this.lowerClassExpressionInfo(decl);
|
|
9490
|
+
return true;
|
|
9491
|
+
}
|
|
9492
|
+
try {
|
|
9493
|
+
this.lowerClassExpressionInfo(decl);
|
|
9494
|
+
return true;
|
|
9495
|
+
}
|
|
9496
|
+
catch (e) {
|
|
9497
|
+
if (e instanceof PoisonError)
|
|
9498
|
+
return false;
|
|
9499
|
+
throw e;
|
|
9500
|
+
}
|
|
9501
|
+
}
|
|
8222
9502
|
lowerClassExpression(expr) {
|
|
8223
9503
|
return lowerClassExpression(this, expr);
|
|
8224
9504
|
}
|
|
@@ -8226,6 +9506,14 @@ export class Lowerer {
|
|
|
8226
9506
|
findMethodOn(info, name) {
|
|
8227
9507
|
return findMethodOn(this, info, name);
|
|
8228
9508
|
}
|
|
9509
|
+
/** A class whose root is the runtime's %Error (builtin errors and their
|
|
9510
|
+
* program subclasses). */
|
|
9511
|
+
isErrorRootedClass(className) {
|
|
9512
|
+
let info = this.classes.get(className) ?? null;
|
|
9513
|
+
while (info && info.base)
|
|
9514
|
+
info = info.base;
|
|
9515
|
+
return info?.def.name === "%Error";
|
|
9516
|
+
}
|
|
8229
9517
|
isSubclassOf(sub, sup) {
|
|
8230
9518
|
return isSubclassOf(this, sub, sup);
|
|
8231
9519
|
}
|
|
@@ -8342,7 +9630,7 @@ export class Lowerer {
|
|
|
8342
9630
|
*classMethodMembers(info, includeAbstract = false) {
|
|
8343
9631
|
if (!info.decl)
|
|
8344
9632
|
return; // builtin error classes: runtime-provided bodies
|
|
8345
|
-
for (const member of info.decl.members) {
|
|
9633
|
+
for (const member of info.decl.members.nodes) {
|
|
8346
9634
|
const fnLike = ts.isMethodDeclaration(member) || ts.isGetAccessor(member) || ts.isSetAccessor(member)
|
|
8347
9635
|
? member
|
|
8348
9636
|
: null;
|
|
@@ -8406,6 +9694,9 @@ export class Lowerer {
|
|
|
8406
9694
|
lowerDefaultExport(stmt) {
|
|
8407
9695
|
return lowerDefaultExport(this, stmt);
|
|
8408
9696
|
}
|
|
9697
|
+
/** Statements %main runs before any module initializer: runtime
|
|
9698
|
+
* registrations the lowering passes add. */
|
|
9699
|
+
mainPrelude = [];
|
|
8409
9700
|
buildMain() {
|
|
8410
9701
|
return buildMain(this);
|
|
8411
9702
|
}
|
|
@@ -8461,6 +9752,92 @@ export class Lowerer {
|
|
|
8461
9752
|
declareHiddenLocal(name, type) {
|
|
8462
9753
|
return declareContextLocal(this.ctx, name, type, false, undefined, undefined);
|
|
8463
9754
|
}
|
|
9755
|
+
/** The body binding of a fixed-tuple rest parameter: one native slot per
|
|
9756
|
+
* position (the flattened ABI), rebuilt into the tuple the source names.
|
|
9757
|
+
* The empty tuple rides the empty-array representation. */
|
|
9758
|
+
declareRestTupleParam(decl, nameNode, elemShapes, params, prologue) {
|
|
9759
|
+
const loc = locOf(decl);
|
|
9760
|
+
const name = nameNode.text;
|
|
9761
|
+
const fn = decl.parent;
|
|
9762
|
+
const symbol = this.checker.getSymbolAtLocation(nameNode);
|
|
9763
|
+
const isRead = (id) => id !== nameNode && this.checker.getSymbolAtLocation(id) === symbol;
|
|
9764
|
+
const pure = fn !== undefined && symbol !== undefined && onlyForwarded(this, fn, isRead);
|
|
9765
|
+
// A forwarded-only tuple is never built: a tuple with optional
|
|
9766
|
+
// positions (`Parameters<(n?: T) => R>`, whose length varies per call)
|
|
9767
|
+
// forwards its slots, an omitted position as undefined — which a
|
|
9768
|
+
// callee's default treats exactly as an omitted argument. Its length
|
|
9769
|
+
// is the one read that would observe the difference.
|
|
9770
|
+
const tupleType = pure &&
|
|
9771
|
+
elemShapes.length > 0 &&
|
|
9772
|
+
this.mapTypeOf(this.typeOf(nameNode)) === null &&
|
|
9773
|
+
!readsLength(fn, isRead)
|
|
9774
|
+
? this.forwardedSlotsTuple(elemShapes)
|
|
9775
|
+
: this.irTypeOf(nameNode);
|
|
9776
|
+
const slots = elemShapes.map((shape, i) => {
|
|
9777
|
+
const slot = this.declareHiddenLocal(`%${name}.${i}`, shape.type);
|
|
9778
|
+
params.push({ localId: slot.id, name: `%${name}.${i}`, type: shape.type });
|
|
9779
|
+
return slot;
|
|
9780
|
+
});
|
|
9781
|
+
const body = this.declareLocal(nameNode, name, tupleType, true);
|
|
9782
|
+
if (pure) {
|
|
9783
|
+
this.ctx.pureTuples.set(body.id, slots);
|
|
9784
|
+
return;
|
|
9785
|
+
}
|
|
9786
|
+
const init = this.tupleOfSlots(slots, tupleType, nameNode, loc);
|
|
9787
|
+
prologue.push({ kind: "varDecl", localId: body.id, init, loc });
|
|
9788
|
+
}
|
|
9789
|
+
/** `value as never` flowing into a typed slot: `never` is assignable to
|
|
9790
|
+
* every type, so the assertion promises the slot's type. A dynamic value
|
|
9791
|
+
* takes the checked extraction to it, as `value as T` would. Null for
|
|
9792
|
+
* every other form, and for numeric, dynamic and union slots, which
|
|
9793
|
+
* keep the existing lowering. */
|
|
9794
|
+
neverAssertionInto(node, expected) {
|
|
9795
|
+
if (!(ts.isAsExpression(node) || ts.isTypeAssertion(node)))
|
|
9796
|
+
return null;
|
|
9797
|
+
if (expected.kind === "f64" || expected.kind === "dyn" || expected.kind === "union")
|
|
9798
|
+
return null;
|
|
9799
|
+
if (!(this.checker.getTypeFromTypeNode(node.type).flags & ts.TypeFlags.Never))
|
|
9800
|
+
return null;
|
|
9801
|
+
const innerTs = this.typeOf(node.expression);
|
|
9802
|
+
if (!(innerTs.flags & ts.TypeFlags.Any) && this.mapTypeOf(innerTs)?.kind !== "dyn")
|
|
9803
|
+
return null;
|
|
9804
|
+
if (!canDynCheckTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id)))
|
|
9805
|
+
return null;
|
|
9806
|
+
const inner = this.lowerExpr(node.expression);
|
|
9807
|
+
if (inner.type.kind !== "dyn")
|
|
9808
|
+
return null;
|
|
9809
|
+
return { kind: "dynCheck", value: inner, type: expected, loc: locOf(node) };
|
|
9810
|
+
}
|
|
9811
|
+
/** The tuple record of a forwarded-only rest tuple's native slots. */
|
|
9812
|
+
forwardedSlotsTuple(elemShapes) {
|
|
9813
|
+
const fields = elemShapes.map((shape, i) => ({ name: String(i), type: shape.type }));
|
|
9814
|
+
fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
9815
|
+
return { kind: "record", shapeId: this.shapes.intern(fields, true) };
|
|
9816
|
+
}
|
|
9817
|
+
/** A fresh tuple holding the given positional slots, typed `tupleType`
|
|
9818
|
+
* (a tuple record, or the empty-array form of `[]`). */
|
|
9819
|
+
tupleOfSlots(slots, tupleType, blame, loc) {
|
|
9820
|
+
if (slots.length === 0) {
|
|
9821
|
+
if (tupleType.kind !== "array")
|
|
9822
|
+
this.badType(blame, this.typeOf(blame));
|
|
9823
|
+
return { kind: "arrayLit", elems: [], type: tupleType, loc };
|
|
9824
|
+
}
|
|
9825
|
+
const shape = tupleType.kind === "record" ? this.shapes.get(tupleType.shapeId) : undefined;
|
|
9826
|
+
if (!shape?.tuple || shape.fields.length !== slots.length)
|
|
9827
|
+
this.badType(blame, this.typeOf(blame));
|
|
9828
|
+
return {
|
|
9829
|
+
kind: "recordLit",
|
|
9830
|
+
fields: slots.map((slot, i) => {
|
|
9831
|
+
const field = shape.fields.find((f) => f.name === String(i));
|
|
9832
|
+
return {
|
|
9833
|
+
name: field.name,
|
|
9834
|
+
value: this.coerceToExpected({ kind: "varRef", localId: slot.id, type: slot.type, loc }, field.type),
|
|
9835
|
+
};
|
|
9836
|
+
}),
|
|
9837
|
+
type: tupleType,
|
|
9838
|
+
loc,
|
|
9839
|
+
};
|
|
9840
|
+
}
|
|
8464
9841
|
/** Declares a callee's parameter locals from its ParamShapes and builds
|
|
8465
9842
|
* the DEFAULT-PARAM PROLOGUE. Required/optional/rest params bind their
|
|
8466
9843
|
* symbol directly (one local of the ABI type). A defaulted param `x: T = e`
|
|
@@ -8495,6 +9872,15 @@ export class Lowerer {
|
|
|
8495
9872
|
return defaultAfterUndefined(undefinedValue, this.coerceInto(node, absent, expected));
|
|
8496
9873
|
};
|
|
8497
9874
|
decls.forEach((decl, i) => {
|
|
9875
|
+
// A fixed-tuple rest parameter owns every remaining (flattened)
|
|
9876
|
+
// shape, possibly none for `[]` (restTupleShapes).
|
|
9877
|
+
if (decl.dotDotDotToken !== undefined &&
|
|
9878
|
+
ts.isIdentifier(decl.name) &&
|
|
9879
|
+
i === decls.length - 1 &&
|
|
9880
|
+
(shapes[i] === undefined ? shapes.length === i : shapes[i].restTuple === true)) {
|
|
9881
|
+
this.declareRestTupleParam(decl, decl.name, shapes.slice(i), params, prologue);
|
|
9882
|
+
return;
|
|
9883
|
+
}
|
|
8498
9884
|
const shape = shapes[i];
|
|
8499
9885
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
8500
9886
|
// Pattern parameter: one hidden ABI slot carries the source value;
|
|
@@ -8541,7 +9927,7 @@ export class Lowerer {
|
|
|
8541
9927
|
// RequireObjectCoercible; use V8's default-expression spelling.
|
|
8542
9928
|
if (abi.kind === "dyn" &&
|
|
8543
9929
|
ts.isObjectBindingPattern(decl.name) &&
|
|
8544
|
-
decl.name.elements.length === 0) {
|
|
9930
|
+
decl.name.elements.nodes.length === 0) {
|
|
8545
9931
|
prologue.push({
|
|
8546
9932
|
kind: "exprStmt",
|
|
8547
9933
|
expr: {
|
|
@@ -8620,10 +10006,32 @@ export class Lowerer {
|
|
|
8620
10006
|
srcType = pickedT;
|
|
8621
10007
|
srcRef = () => ({ kind: "varRef", localId: src.id, type: pickedT, loc });
|
|
8622
10008
|
}
|
|
10009
|
+
else {
|
|
10010
|
+
// `({ groups }) => ...` over matchAll rows.
|
|
10011
|
+
const groupsSource = matchGroupsPatternSource(this, decl.name, srcRef(), () => matchCallbackParamGroupsOf(this, decl), loc);
|
|
10012
|
+
if (groupsSource !== null) {
|
|
10013
|
+
const src = this.declareHiddenLocal("%psrc", groupsSource.type);
|
|
10014
|
+
prologue.push({ kind: "varDecl", localId: src.id, init: groupsSource, loc });
|
|
10015
|
+
const groupsT = groupsSource.type;
|
|
10016
|
+
srcType = groupsT;
|
|
10017
|
+
srcRef = () => ({ kind: "varRef", localId: src.id, type: groupsT, loc });
|
|
10018
|
+
}
|
|
10019
|
+
}
|
|
8623
10020
|
this.lowerBindingPattern(decl.name, srcRef, srcType, true, prologue);
|
|
8624
10021
|
return;
|
|
8625
10022
|
}
|
|
8626
10023
|
const name = decl.name.text;
|
|
10024
|
+
if (shape.entryNarrow) {
|
|
10025
|
+
// A typed override parameter over an inherited checked-value slot:
|
|
10026
|
+
// the body local narrows from the dyn argument at entry.
|
|
10027
|
+
const loc = locOf(decl);
|
|
10028
|
+
const slot = this.declareHiddenLocal(name, shape.type);
|
|
10029
|
+
params.push({ localId: slot.id, name, type: shape.type });
|
|
10030
|
+
const narrowed = this.coerceInto(decl.name, { kind: "varRef", localId: slot.id, type: shape.type, loc }, shape.entryNarrow);
|
|
10031
|
+
const body = this.declareLocal(decl.name, name, shape.entryNarrow, true);
|
|
10032
|
+
prologue.push({ kind: "varDecl", localId: body.id, init: narrowed, loc });
|
|
10033
|
+
return;
|
|
10034
|
+
}
|
|
8627
10035
|
if (shape.mode === "omittable" && shape.bodyType && decl.initializer) {
|
|
8628
10036
|
const abi = shape.type;
|
|
8629
10037
|
if (abi.kind === "dyn") {
|
|
@@ -8794,6 +10202,11 @@ export class Lowerer {
|
|
|
8794
10202
|
if (!symbol)
|
|
8795
10203
|
return null;
|
|
8796
10204
|
const direct = this.resolveKey(symbol, ident);
|
|
10205
|
+
if (direct && this.ctx.pureTuples.has(direct.id)) {
|
|
10206
|
+
// onlyForwarded proved every read forwards; a plain read here means
|
|
10207
|
+
// the analysis and the lowering disagree.
|
|
10208
|
+
throw new InternalCompilerError(`lowerer bug: forwarded-only tuple '${ident.text}' read as a value`);
|
|
10209
|
+
}
|
|
8797
10210
|
if (direct)
|
|
8798
10211
|
return direct;
|
|
8799
10212
|
// A PARAMETER PROPERTY declares two symbols: references resolve to the
|
|
@@ -8801,11 +10214,11 @@ export class Lowerer {
|
|
|
8801
10214
|
// symbol — which is what declareParams registered the local under.
|
|
8802
10215
|
// On a miss, normalize to the declaration's key and retry (ordinary
|
|
8803
10216
|
// bindings never reach this — their two sides intern to one symbol).
|
|
8804
|
-
const vd =
|
|
10217
|
+
const vd = symbol.valueDeclaration;
|
|
8805
10218
|
if (vd &&
|
|
8806
10219
|
ts.isParameter(vd) &&
|
|
8807
10220
|
ts.isIdentifier(vd.name) &&
|
|
8808
|
-
vd.modifiers?.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
10221
|
+
vd.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
8809
10222
|
m.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
8810
10223
|
m.kind === ts.SyntaxKind.ProtectedKeyword ||
|
|
8811
10224
|
m.kind === ts.SyntaxKind.ReadonlyKeyword ||
|
|
@@ -8819,8 +10232,8 @@ export class Lowerer {
|
|
|
8819
10232
|
/** Lexical `this` — the enclosing method's this-param, possibly captured
|
|
8820
10233
|
* through arrows (function expressions/declarations reset `this` in JS;
|
|
8821
10234
|
* their bodies never see an enclosing method's binding). */
|
|
8822
|
-
resolveThis() {
|
|
8823
|
-
return this.resolveKey(undefined);
|
|
10235
|
+
resolveThis(blame) {
|
|
10236
|
+
return this.resolveKey(undefined, blame);
|
|
8824
10237
|
}
|
|
8825
10238
|
peekLocal(ident) {
|
|
8826
10239
|
let symbol = this.checker.getSymbolAtLocation(ident);
|
|
@@ -8845,9 +10258,7 @@ export class Lowerer {
|
|
|
8845
10258
|
this.runtimeOptionalRoots.set(entry, root);
|
|
8846
10259
|
});
|
|
8847
10260
|
if (resolved.error !== null) {
|
|
8848
|
-
const location = blame ??
|
|
8849
|
-
(symbol === undefined ? undefined : this.checker.declarationsOf(symbol)[0]) ??
|
|
8850
|
-
this.entry;
|
|
10261
|
+
const location = blame ?? (symbol === undefined ? undefined : symbol.declarations[0]) ?? this.entry;
|
|
8851
10262
|
const message = `the binding '${resolved.origin.name}' captured through a plain nested function (the declaration has no static storage a capture can thread — bind the value through a typed const, or read it in the declaring scope)`;
|
|
8852
10263
|
this.unsupported("SC1090", location, message);
|
|
8853
10264
|
}
|
|
@@ -8888,6 +10299,10 @@ export class Lowerer {
|
|
|
8888
10299
|
const ctx = this.ctx;
|
|
8889
10300
|
if (!ctx.selfSymbol)
|
|
8890
10301
|
return false;
|
|
10302
|
+
// A reassigned JavaScript declaration names its module global, which
|
|
10303
|
+
// may hold another function by the time the body runs.
|
|
10304
|
+
if (isRebindableFunctionSymbol(this, ctx.selfSymbol))
|
|
10305
|
+
return false;
|
|
8891
10306
|
// The self binding can be shadowed by a scoped local of the same symbol?
|
|
8892
10307
|
// No — a shadow is a different symbol; symbol identity is exact.
|
|
8893
10308
|
return this.checker.getSymbolAtLocation(ident) === ctx.selfSymbol;
|
|
@@ -8920,7 +10335,7 @@ export class Lowerer {
|
|
|
8920
10335
|
// concrete signature — name the shape instead of the generic
|
|
8921
10336
|
// binding-form text.
|
|
8922
10337
|
if (symbol) {
|
|
8923
|
-
const d =
|
|
10338
|
+
const d = symbol.valueDeclaration;
|
|
8924
10339
|
if (d && ts.isVariableDeclaration(d) && d.initializer === undefined) {
|
|
8925
10340
|
const t = this.checker.getTypeOfSymbol(symbol);
|
|
8926
10341
|
const parts = t.isUnionType() ? ts.constituentTypes(t) : [t];
|
|
@@ -8934,7 +10349,7 @@ export class Lowerer {
|
|
|
8934
10349
|
// assignment are `undefined`, and this binding's type has no slot for
|
|
8935
10350
|
// that value — name the shape instead of the generic no-lowering text.
|
|
8936
10351
|
if (symbol) {
|
|
8937
|
-
const d =
|
|
10352
|
+
const d = symbol.valueDeclaration;
|
|
8938
10353
|
if (d &&
|
|
8939
10354
|
ts.isVariableDeclaration(d) &&
|
|
8940
10355
|
(ts.getCombinedNodeFlags(d) & ts.NodeFlags.BlockScoped) === 0) {
|
|
@@ -9067,7 +10482,9 @@ export class Lowerer {
|
|
|
9067
10482
|
}
|
|
9068
10483
|
isNpmFile = (sf) => sf.isDeclarationFile &&
|
|
9069
10484
|
(sf.fileName.includes("/node_modules/") || workspacePackageOfPath(sf.fileName) !== null) &&
|
|
9070
|
-
!this.isStdlibFile(sf)
|
|
10485
|
+
!this.isStdlibFile(sf) &&
|
|
10486
|
+
// A bundled copy's forwarder to a package shim types compiled code.
|
|
10487
|
+
!isBundledShimForwarder(sf.fileName);
|
|
9071
10488
|
npmPackageOf(type) {
|
|
9072
10489
|
return npmPackageOf(this, type);
|
|
9073
10490
|
}
|
|
@@ -9315,8 +10732,13 @@ export class Lowerer {
|
|
|
9315
10732
|
// dispatch. The general identifier-call paths have no lowering for a
|
|
9316
10733
|
// promise-returning ambient global, and `import` is a keyword callee no
|
|
9317
10734
|
// identifier path matches.
|
|
10735
|
+
const webAssembly = lowerWebAssemblyCall(this, expr);
|
|
10736
|
+
if (webAssembly !== null)
|
|
10737
|
+
return webAssembly;
|
|
10738
|
+
refuseWebAssemblyUse(this, expr.expression);
|
|
9318
10739
|
return (lowerLifetimeRegionCall(this, expr) ??
|
|
9319
10740
|
lowerInternTableCall(this, expr) ??
|
|
10741
|
+
lowerThreadSlotsCall(this, expr) ??
|
|
9320
10742
|
lowerFfiCall(this, expr) ??
|
|
9321
10743
|
lowerFetchCall(this, expr) ??
|
|
9322
10744
|
lowerStaticFetchCompanionCall(this, expr) ??
|
|
@@ -9327,7 +10749,10 @@ export class Lowerer {
|
|
|
9327
10749
|
lowerStaticReadableStreamReaderCall(this, expr) ??
|
|
9328
10750
|
lowerStaticResponseCall(this, expr) ??
|
|
9329
10751
|
lowerStaticBlobCall(this, expr) ??
|
|
10752
|
+
lowerWebCryptoCall(this, expr) ??
|
|
9330
10753
|
lowerKeyObjectCall(this, expr) ??
|
|
10754
|
+
lowerEcdhCall(this, expr) ??
|
|
10755
|
+
lowerNetAddressCall(this, expr) ??
|
|
9331
10756
|
lowerFetchElementMethodCall(this, expr) ??
|
|
9332
10757
|
lowerDynamicImportCall(this, expr) ??
|
|
9333
10758
|
lowerCall(this, expr));
|
|
@@ -9454,13 +10879,20 @@ export class Lowerer {
|
|
|
9454
10879
|
return inheritsBuiltinEmitterCtor(this, info);
|
|
9455
10880
|
}
|
|
9456
10881
|
lowerNew(expr) {
|
|
10882
|
+
const webAssembly = lowerWebAssemblyNew(this, expr);
|
|
10883
|
+
if (webAssembly !== null)
|
|
10884
|
+
return webAssembly;
|
|
10885
|
+
refuseWebAssemblyUse(this, expr.expression, "new ");
|
|
9457
10886
|
const builtin = lowerLifetimeRegionNew(this, expr) ??
|
|
9458
10887
|
lowerInternTableNew(this, expr) ??
|
|
10888
|
+
lowerThreadSlotsNew(this, expr) ??
|
|
9459
10889
|
lowerAbortControllerNew(this, expr) ??
|
|
10890
|
+
lowerDisposableStackNew(this, expr) ??
|
|
9460
10891
|
lowerEventTargetNew(this, expr) ??
|
|
9461
10892
|
lowerFetchWebNew(this, expr) ??
|
|
9462
10893
|
lowerResponseNew(this, expr) ??
|
|
9463
10894
|
lowerBlobNew(this, expr) ??
|
|
10895
|
+
lowerNetAddressNew(this, expr) ??
|
|
9464
10896
|
lowerStaticReadableStreamNew(this, expr) ??
|
|
9465
10897
|
lowerConsoleNew(this, expr);
|
|
9466
10898
|
return (builtin ?? this.withRuntimeOptionalClassValue(expr.expression, () => lowerNew(this, expr)));
|
|
@@ -9541,9 +10973,21 @@ export class Lowerer {
|
|
|
9541
10973
|
if (mapped?.kind === "moduleNs" && mapped.moduleId.startsWith("builtin:")) {
|
|
9542
10974
|
return mapped.moduleId.slice("builtin:".length);
|
|
9543
10975
|
}
|
|
10976
|
+
// A nullable namespace binding (`const os: typeof NodeOs | null`, a
|
|
10977
|
+
// probed process.getBuiltinModule result) read where the checker
|
|
10978
|
+
// narrowed it present: its members key the same tables.
|
|
10979
|
+
if (stored?.kind === "union") {
|
|
10980
|
+
const present = this.unions.get(stored.unionId)?.arms.filter((arm) => !isUnitType(arm));
|
|
10981
|
+
const only = present?.length === 1 ? present[0] : undefined;
|
|
10982
|
+
if (only?.kind === "moduleNs" && only.moduleId.startsWith("builtin:")) {
|
|
10983
|
+
const narrowed = this.mapTypeOf(this.typeOf(expr));
|
|
10984
|
+
if (narrowed?.kind === "moduleNs" && narrowed.moduleId === only.moduleId)
|
|
10985
|
+
return only.moduleId.slice("builtin:".length);
|
|
10986
|
+
}
|
|
10987
|
+
}
|
|
9544
10988
|
if (ts.isIdentifier(expr)) {
|
|
9545
10989
|
const symbol = this.checker.getSymbolAtLocation(expr);
|
|
9546
|
-
const decl = symbol ?
|
|
10990
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
9547
10991
|
if (!decl)
|
|
9548
10992
|
return null;
|
|
9549
10993
|
// The CommonJS twin: `const fs = require("fs")` binds the same
|
|
@@ -9612,7 +11056,7 @@ export class Lowerer {
|
|
|
9612
11056
|
}
|
|
9613
11057
|
if (ts.isIdentifier(expr)) {
|
|
9614
11058
|
const symbol = this.checker.getSymbolAtLocation(expr);
|
|
9615
|
-
const decl = symbol ?
|
|
11059
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
9616
11060
|
if (!decl)
|
|
9617
11061
|
return null;
|
|
9618
11062
|
// The DEFAULT-import twin: Node's default export of a CJS builtin
|
|
@@ -9663,9 +11107,47 @@ export class Lowerer {
|
|
|
9663
11107
|
return { module: "fs", member: "realpathSync.native" };
|
|
9664
11108
|
}
|
|
9665
11109
|
}
|
|
11110
|
+
// timers/promises scheduler.wait / scheduler.yield: methods of the
|
|
11111
|
+
// module's scheduler object, dispatched as module members.
|
|
11112
|
+
if (access.name.text === "wait" || access.name.text === "yield") {
|
|
11113
|
+
const owner = access.expression;
|
|
11114
|
+
const imported = ts.isIdentifier(owner)
|
|
11115
|
+
? this.builtinImportOf(owner)
|
|
11116
|
+
: ts.isPropertyAccessExpression(owner)
|
|
11117
|
+
? this.builtinMemberOf(owner)
|
|
11118
|
+
: null;
|
|
11119
|
+
if (imported?.module === "timers/promises" && imported.member === "scheduler") {
|
|
11120
|
+
return { module: "timers/promises", member: `scheduler.${access.name.text}` };
|
|
11121
|
+
}
|
|
11122
|
+
}
|
|
11123
|
+
// punycode.ucs2.decode / encode: methods of the module's ucs2 object,
|
|
11124
|
+
// dispatched as module members.
|
|
11125
|
+
if (access.name.text === "decode" || access.name.text === "encode") {
|
|
11126
|
+
const owner = access.expression;
|
|
11127
|
+
const imported = ts.isIdentifier(owner)
|
|
11128
|
+
? this.builtinImportOf(owner)
|
|
11129
|
+
: ts.isPropertyAccessExpression(owner)
|
|
11130
|
+
? this.builtinMemberOf(owner)
|
|
11131
|
+
: null;
|
|
11132
|
+
if (imported?.module === "punycode" && imported.member === "ucs2") {
|
|
11133
|
+
return { module: "punycode", member: `ucs2.${access.name.text}` };
|
|
11134
|
+
}
|
|
11135
|
+
}
|
|
9666
11136
|
const module = this.builtinNamespaceModuleOf(access.expression);
|
|
11137
|
+
// node:constants is one checked-dynamic object: its members read
|
|
11138
|
+
// through the object itself (builtinConstantsObject), not the tables.
|
|
11139
|
+
if (module === "constants")
|
|
11140
|
+
return null;
|
|
9667
11141
|
if (module !== null)
|
|
9668
11142
|
return { module, member: access.name.text };
|
|
11143
|
+
// The events module object IS the EventEmitter class, so the class's
|
|
11144
|
+
// defaultMaxListeners is the module property.
|
|
11145
|
+
if (access.name.text === "defaultMaxListeners" && ts.isIdentifier(access.expression)) {
|
|
11146
|
+
const imported = this.builtinImportOf(access.expression);
|
|
11147
|
+
if (imported?.module === "events" && imported.member === "EventEmitter") {
|
|
11148
|
+
return { module: "events", member: "defaultMaxListeners" };
|
|
11149
|
+
}
|
|
11150
|
+
}
|
|
9669
11151
|
// The RE-EXPORT FACADE's namespace spelling: `import * as assert from
|
|
9670
11152
|
// "./facade.js"` over `export { ok } from "node:assert"` (the formatter idiom's
|
|
9671
11153
|
// universal/assert). The member's symbol is the facade's
|
|
@@ -9705,9 +11187,8 @@ export class Lowerer {
|
|
|
9705
11187
|
COPYFILE_FICLONE_FORCE: 4,
|
|
9706
11188
|
};
|
|
9707
11189
|
const value = own(MODES, expr.name.text);
|
|
9708
|
-
if (value === undefined)
|
|
9709
|
-
|
|
9710
|
-
}
|
|
11190
|
+
if (value === undefined)
|
|
11191
|
+
return fsConstantMemberRead(expr);
|
|
9711
11192
|
return { kind: "numLit", value, type: F64, loc };
|
|
9712
11193
|
}
|
|
9713
11194
|
}
|
|
@@ -9719,9 +11200,18 @@ export class Lowerer {
|
|
|
9719
11200
|
return pathModuleValue(this, `path/${bi.member}`, loc);
|
|
9720
11201
|
}
|
|
9721
11202
|
// events.defaultMaxListeners READS the process-wide default (its
|
|
9722
|
-
// write twin routes through emitter.setDefaultMaxChk).
|
|
11203
|
+
// write twin routes through emitter.setDefaultMaxChk). Through an ES
|
|
11204
|
+
// module namespace it reads the namespace's copy instead.
|
|
9723
11205
|
if (bi.module === "events" && bi.member === "defaultMaxListeners") {
|
|
9724
|
-
|
|
11206
|
+
const esm = ts.isIdentifier(expr.expression) &&
|
|
11207
|
+
esmImportBindingKind(this, expr.expression) === "namespace";
|
|
11208
|
+
return {
|
|
11209
|
+
kind: "libCall",
|
|
11210
|
+
fn: esm ? "emitter.esmDefaultMax" : "emitter.getDefaultMax",
|
|
11211
|
+
args: [],
|
|
11212
|
+
type: F64,
|
|
11213
|
+
loc,
|
|
11214
|
+
};
|
|
9725
11215
|
}
|
|
9726
11216
|
if (bi.module === "worker_threads") {
|
|
9727
11217
|
const value = lowerWorkerMetadata(bi.member, loc);
|
|
@@ -9739,6 +11229,15 @@ export class Lowerer {
|
|
|
9739
11229
|
if (bi.module === "http" && bi.member === "METHODS") {
|
|
9740
11230
|
return { kind: "libCall", fn: "http.methods", args: [], type: arrayOf(STRING), loc };
|
|
9741
11231
|
}
|
|
11232
|
+
if ((bi.module === "http" || bi.module === "https") && bi.member === "globalAgent") {
|
|
11233
|
+
return {
|
|
11234
|
+
kind: "libCall",
|
|
11235
|
+
fn: "http.globalAgent",
|
|
11236
|
+
args: [{ kind: "boolLit", value: bi.module === "https", type: BOOL, loc }],
|
|
11237
|
+
type: DYN,
|
|
11238
|
+
loc,
|
|
11239
|
+
};
|
|
11240
|
+
}
|
|
9742
11241
|
if (bi.module === "http" && bi.member === "STATUS_CODES") {
|
|
9743
11242
|
return { kind: "libCall", fn: "http.statusCodes", args: [], type: DYN, loc };
|
|
9744
11243
|
}
|
|
@@ -9760,12 +11259,24 @@ export class Lowerer {
|
|
|
9760
11259
|
if (callable)
|
|
9761
11260
|
return callable;
|
|
9762
11261
|
}
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
11262
|
+
// node:stream/web's exports are the web stream globals themselves: in
|
|
11263
|
+
// JavaScript sources the same identity token as the global spelling
|
|
11264
|
+
// (`require("stream/web").ReadableStream === globalThis.ReadableStream`).
|
|
11265
|
+
if (bi.module === "stream/web" && isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
11266
|
+
return { kind: "strLit", value: `[builtin ${bi.member}]`, type: STRING, loc };
|
|
11267
|
+
}
|
|
11268
|
+
// A bare `fs.constants` read (not one of the baked bits above).
|
|
11269
|
+
if (bi.member === "constants" && bi.module === "fs")
|
|
11270
|
+
return fsConstantsObject(loc);
|
|
11271
|
+
// `stream.Readable` as a JavaScript value: the runtime's untyped
|
|
11272
|
+
// constructor, the base a constructor function inherits.
|
|
11273
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
11274
|
+
const classKind = builtinMemberClassKind(bi.module, bi.member);
|
|
11275
|
+
if (classKind !== null)
|
|
11276
|
+
return builtinClassValue(classKind, loc);
|
|
9766
11277
|
}
|
|
9767
11278
|
if (builtinModuleFnOf(this, bi.module, bi.member)) {
|
|
9768
|
-
this.unsupported("SC1090", expr, `library functions as values (call '${
|
|
11279
|
+
this.unsupported("SC1090", expr, `library functions as values (call '${ts.getTextOfNode(expr)}' directly)`);
|
|
9769
11280
|
}
|
|
9770
11281
|
this.noLowering(`${bi.module}.${bi.member}`, expr, builtinFenceHintOf(bi.module, bi.member), this.checker.getSymbolAtLocation(expr.name));
|
|
9771
11282
|
}
|
|
@@ -9791,6 +11302,8 @@ export class Lowerer {
|
|
|
9791
11302
|
loc,
|
|
9792
11303
|
};
|
|
9793
11304
|
}
|
|
11305
|
+
if (bi.module === "fs" && (bi.member === "realpathSync" || bi.member === "realpathSync.native"))
|
|
11306
|
+
return fsRealpathValue(this, bi.member === "realpathSync.native", loc);
|
|
9794
11307
|
const fn = builtinModuleFnOf(this, bi.module, bi.member);
|
|
9795
11308
|
return fn ? this.lowerNativeCallableValue(fn, `${bi.module}.${bi.member}`, loc) : null;
|
|
9796
11309
|
}
|
|
@@ -9812,11 +11325,12 @@ export class Lowerer {
|
|
|
9812
11325
|
const adapterShape = valueParams
|
|
9813
11326
|
.map((param) => param.mode === "optional" ? `${param.mode}:${param.defaultValue}` : param.mode)
|
|
9814
11327
|
.join(",");
|
|
9815
|
-
const key = `${fn.fn}:${typeKey(funcType)}:${adapterShape}`;
|
|
11328
|
+
const key = `${fn.valueFn ?? fn.fn}:${typeKey(funcType)}:${adapterShape}`;
|
|
9816
11329
|
let fnName = this.builtinCallableValueFns.get(key);
|
|
9817
11330
|
if (!fnName) {
|
|
9818
|
-
fnName = `%builtin.value.${fn.fn}.${this.builtinCallableValueFns.size}`;
|
|
11331
|
+
fnName = `%builtin.value.${fn.valueFn ?? fn.fn}.${this.builtinCallableValueFns.size}`;
|
|
9819
11332
|
this.builtinCallableValueFns.set(key, fnName);
|
|
11333
|
+
this.builtinCallableValueNames.set(fnName, display.slice(display.lastIndexOf(".") + 1));
|
|
9820
11334
|
const params = funcType.params.map((type, index) => ({
|
|
9821
11335
|
localId: `arg.${index}`,
|
|
9822
11336
|
name: `arg${index}`,
|
|
@@ -9874,7 +11388,7 @@ export class Lowerer {
|
|
|
9874
11388
|
loc,
|
|
9875
11389
|
};
|
|
9876
11390
|
});
|
|
9877
|
-
const call = { kind: "libCall", fn: fn.fn, args, type: fn.result, loc };
|
|
11391
|
+
const call = { kind: "libCall", fn: fn.valueFn ?? fn.fn, args, type: fn.result, loc };
|
|
9878
11392
|
const body = fn.result.kind === "void"
|
|
9879
11393
|
? [
|
|
9880
11394
|
{ kind: "exprStmt", expr: call, loc },
|
|
@@ -9919,8 +11433,8 @@ export class Lowerer {
|
|
|
9919
11433
|
lowerSpawnCall(expr, loc) {
|
|
9920
11434
|
return lowerSpawnCall(this, expr, loc);
|
|
9921
11435
|
}
|
|
9922
|
-
lowerExecFileCall(expr, loc) {
|
|
9923
|
-
return lowerExecFileCall(this, expr, loc);
|
|
11436
|
+
lowerExecFileCall(expr, loc, shell = false) {
|
|
11437
|
+
return lowerExecFileCall(this, expr, loc, shell);
|
|
9924
11438
|
}
|
|
9925
11439
|
lowerExecSyncCall(expr, shell, loc) {
|
|
9926
11440
|
return lowerExecSyncCall(this, expr, shell, loc);
|
|
@@ -10118,4 +11632,242 @@ export class Lowerer {
|
|
|
10118
11632
|
return lowerStdlibMethodCall(this, call, access);
|
|
10119
11633
|
}
|
|
10120
11634
|
}
|
|
11635
|
+
/** Whether some read of a binding (identified by `isRead`) in `fn` takes
|
|
11636
|
+
* its `.length`. */
|
|
11637
|
+
function readsLength(fn, isRead) {
|
|
11638
|
+
let found = false;
|
|
11639
|
+
ts.walkPreorder(fn, (n) => {
|
|
11640
|
+
if (found)
|
|
11641
|
+
return "stop";
|
|
11642
|
+
if (!ts.isIdentifier(n) || !isRead(n))
|
|
11643
|
+
return undefined;
|
|
11644
|
+
let top = n;
|
|
11645
|
+
while (top.parent &&
|
|
11646
|
+
(ts.isParenthesizedExpression(top.parent) ||
|
|
11647
|
+
ts.isAsExpression(top.parent) ||
|
|
11648
|
+
ts.isTypeAssertion(top.parent) ||
|
|
11649
|
+
ts.isSatisfiesExpression(top.parent) ||
|
|
11650
|
+
ts.isNonNullExpression(top.parent)))
|
|
11651
|
+
top = top.parent;
|
|
11652
|
+
const p = top.parent;
|
|
11653
|
+
if (p && ts.isPropertyAccessExpression(p) && p.expression === top && p.name.text === "length")
|
|
11654
|
+
found = true;
|
|
11655
|
+
return undefined;
|
|
11656
|
+
});
|
|
11657
|
+
return found;
|
|
11658
|
+
}
|
|
11659
|
+
/** A union of record layouts flowing into one record slot: a function
|
|
11660
|
+
* returning differently-shaped object literals (`{ ok: false }` and
|
|
11661
|
+
* `{ ok: true, size }`, whose union the checker normalizes to arms with
|
|
11662
|
+
* `size?: undefined`) into its declared result type. Each record arm
|
|
11663
|
+
* width-lifts into the slot on its own tag; unit arms take the stranded
|
|
11664
|
+
* TypeError (the checker excluded them). Null when some record arm does
|
|
11665
|
+
* not lift, or when there is a non-record, non-unit arm. */
|
|
11666
|
+
function unionArmsWidthLift(lowerer, expr, expected) {
|
|
11667
|
+
if (expr.type.kind !== "union")
|
|
11668
|
+
return null;
|
|
11669
|
+
const unionId = expr.type.unionId;
|
|
11670
|
+
const arms = lowerer.unions.get(unionId)?.arms ?? [];
|
|
11671
|
+
const lifts = [];
|
|
11672
|
+
let records = 0;
|
|
11673
|
+
for (const arm of arms) {
|
|
11674
|
+
if (isUnitType(arm)) {
|
|
11675
|
+
lifts.push(null);
|
|
11676
|
+
continue;
|
|
11677
|
+
}
|
|
11678
|
+
if (arm.kind !== "record")
|
|
11679
|
+
return null;
|
|
11680
|
+
const lift = lowerer.widthLiftPlan(arm, expected);
|
|
11681
|
+
if (!lift)
|
|
11682
|
+
return null;
|
|
11683
|
+
lifts.push(lift);
|
|
11684
|
+
records++;
|
|
11685
|
+
}
|
|
11686
|
+
if (records < 2)
|
|
11687
|
+
return null;
|
|
11688
|
+
const loc = expr.loc;
|
|
11689
|
+
const local = lowerer.declareHiddenLocal("%unionLift", expr.type);
|
|
11690
|
+
const ref = () => ({ kind: "varRef", localId: local.id, type: expr.type, loc });
|
|
11691
|
+
let result = null;
|
|
11692
|
+
for (let tag = arms.length - 1; tag >= 0; tag--) {
|
|
11693
|
+
const lift = lifts[tag];
|
|
11694
|
+
const arm = arms[tag];
|
|
11695
|
+
const branch = lift
|
|
11696
|
+
? lowerer.applyWidthLift(lift, { kind: "unionNarrow", unionId, tag, value: ref(), type: arm, loc }, expected, loc)
|
|
11697
|
+
: nodeThrowExpr(1, "", `${arm.kind === "nullT" ? "null" : "undefined"} is not representable in a '${lowerer.fmt(expected)}' slot (a value narrowed or asserted past the type still held it)`, expected, loc);
|
|
11698
|
+
result =
|
|
11699
|
+
result === null
|
|
11700
|
+
? branch
|
|
11701
|
+
: {
|
|
11702
|
+
kind: "ternary",
|
|
11703
|
+
cond: {
|
|
11704
|
+
kind: "unionIsTag",
|
|
11705
|
+
unionId,
|
|
11706
|
+
tag,
|
|
11707
|
+
negated: false,
|
|
11708
|
+
value: ref(),
|
|
11709
|
+
type: BOOL,
|
|
11710
|
+
loc,
|
|
11711
|
+
},
|
|
11712
|
+
then: branch,
|
|
11713
|
+
else_: result,
|
|
11714
|
+
type: expected,
|
|
11715
|
+
loc,
|
|
11716
|
+
};
|
|
11717
|
+
}
|
|
11718
|
+
return {
|
|
11719
|
+
kind: "seqExpr",
|
|
11720
|
+
stmts: [{ kind: "varDecl", localId: local.id, init: expr, loc }],
|
|
11721
|
+
result: result,
|
|
11722
|
+
type: expected,
|
|
11723
|
+
loc,
|
|
11724
|
+
};
|
|
11725
|
+
}
|
|
11726
|
+
/** A callback passed to a generic call without a return annotation, whose
|
|
11727
|
+
* returns the checker unified into a narrower result type: `trace(name,
|
|
11728
|
+
* async () => (cond ? items : items.map((i) => ({ ...i, sum }))))` infers
|
|
11729
|
+
* `T` from the narrower `Item[]`, though at run time the extended objects
|
|
11730
|
+
* keep `sum`. Converting such a return into the inferred type copies the
|
|
11731
|
+
* records and drops the members the narrower type lacks, which Node keeps
|
|
11732
|
+
* and any later wider view (`Promise<ItemWithSum[]>`) reads back. Refuse
|
|
11733
|
+
* that conversion by name rather than lose the members silently; an
|
|
11734
|
+
* annotation on the callback's return type or on the call's type argument
|
|
11735
|
+
* names a type that keeps them. */
|
|
11736
|
+
function refuseInferredCallbackDrops(lowerer, node, actual, expected) {
|
|
11737
|
+
if (typeEquals(actual, expected))
|
|
11738
|
+
return;
|
|
11739
|
+
const structured = (t) => t.kind === "record" || t.kind === "array" || t.kind === "promise";
|
|
11740
|
+
if (!structured(actual) || !structured(expected))
|
|
11741
|
+
return;
|
|
11742
|
+
let site = node;
|
|
11743
|
+
while (yieldsOperand(site))
|
|
11744
|
+
site = site.parent;
|
|
11745
|
+
let fn;
|
|
11746
|
+
if (ts.isReturnStatement(site.parent) && site.parent.expression === site) {
|
|
11747
|
+
fn = site.parent.parent;
|
|
11748
|
+
while (fn && !ts.isFunctionLike(fn))
|
|
11749
|
+
fn = fn.parent;
|
|
11750
|
+
}
|
|
11751
|
+
else if (ts.isArrowFunction(site.parent) && site.parent.body === site) {
|
|
11752
|
+
fn = site.parent;
|
|
11753
|
+
}
|
|
11754
|
+
if (!fn || !(ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) || fn.type)
|
|
11755
|
+
return;
|
|
11756
|
+
let arg = fn;
|
|
11757
|
+
while (ts.isParenthesizedExpression(arg.parent))
|
|
11758
|
+
arg = arg.parent;
|
|
11759
|
+
const call = arg.parent;
|
|
11760
|
+
if (!(ts.isCallExpression(call) || ts.isNewExpression(call)))
|
|
11761
|
+
return;
|
|
11762
|
+
if (!call.arguments?.nodes.includes(arg))
|
|
11763
|
+
return;
|
|
11764
|
+
const dropped = droppedMembers(lowerer, actual, expected, new Set());
|
|
11765
|
+
if (dropped.length === 0)
|
|
11766
|
+
return;
|
|
11767
|
+
lowerer.unsupported("SC1090", node, `returning '${lowerer.fmt(actual)}' from a callback whose result the checker infers as the narrower '${lowerer.fmt(expected)}' (the conversion would drop ${dropped.map((d) => `'${d}'`).join(", ")}, which the object keeps at run time — annotate the callback's return type or the call's type argument with a type that declares them)`);
|
|
11768
|
+
}
|
|
11769
|
+
/** True when the value of `node`'s parent can be `node`'s own value:
|
|
11770
|
+
* parentheses, `await`, `satisfies`, a non-null assertion, a conditional's
|
|
11771
|
+
* branch, either operand of `??`, `||` and `&&`, and the right operand of a
|
|
11772
|
+
* comma. */
|
|
11773
|
+
function yieldsOperand(node) {
|
|
11774
|
+
const p = node.parent;
|
|
11775
|
+
if (p === undefined)
|
|
11776
|
+
return false;
|
|
11777
|
+
if (ts.isParenthesizedExpression(p) ||
|
|
11778
|
+
ts.isAwaitExpression(p) ||
|
|
11779
|
+
ts.isSatisfiesExpression(p) ||
|
|
11780
|
+
ts.isNonNullExpression(p))
|
|
11781
|
+
return true;
|
|
11782
|
+
if (ts.isConditionalExpression(p))
|
|
11783
|
+
return p.whenTrue === node || p.whenFalse === node;
|
|
11784
|
+
if (ts.isBinaryExpression(p)) {
|
|
11785
|
+
const op = p.operatorToken.kind;
|
|
11786
|
+
if (op === ts.SyntaxKind.QuestionQuestionToken ||
|
|
11787
|
+
op === ts.SyntaxKind.BarBarToken ||
|
|
11788
|
+
op === ts.SyntaxKind.AmpersandAmpersandToken)
|
|
11789
|
+
return true;
|
|
11790
|
+
return op === ts.SyntaxKind.CommaToken && p.right === node;
|
|
11791
|
+
}
|
|
11792
|
+
return false;
|
|
11793
|
+
}
|
|
11794
|
+
/** Member names a structural conversion from `from` into `to` drops:
|
|
11795
|
+
* declared fields of a source record the target record lacks, through
|
|
11796
|
+
* array elements and promise payloads. */
|
|
11797
|
+
function droppedMembers(lowerer, from, to, seen) {
|
|
11798
|
+
if (typeEquals(from, to))
|
|
11799
|
+
return [];
|
|
11800
|
+
if (from.kind === "array" && to.kind === "array")
|
|
11801
|
+
return droppedMembers(lowerer, from.elem, to.elem, seen);
|
|
11802
|
+
if (from.kind === "promise" && to.kind === "promise")
|
|
11803
|
+
return droppedMembers(lowerer, from.inner, to.inner, seen);
|
|
11804
|
+
if (from.kind !== "record" || to.kind !== "record")
|
|
11805
|
+
return [];
|
|
11806
|
+
const key = `${from.shapeId}>${to.shapeId}`;
|
|
11807
|
+
if (seen.has(key))
|
|
11808
|
+
return [];
|
|
11809
|
+
seen.add(key);
|
|
11810
|
+
const source = lowerer.shapes.get(from.shapeId);
|
|
11811
|
+
const target = lowerer.shapes.get(to.shapeId);
|
|
11812
|
+
if (!source || !target || source.tuple || target.tuple || target.indexValue)
|
|
11813
|
+
return [];
|
|
11814
|
+
const out = [];
|
|
11815
|
+
for (const f of source.fields) {
|
|
11816
|
+
if (f.name.startsWith("%"))
|
|
11817
|
+
continue;
|
|
11818
|
+
const t = target.fields.find((x) => x.name === f.name);
|
|
11819
|
+
if (!t)
|
|
11820
|
+
out.push(f.name);
|
|
11821
|
+
else
|
|
11822
|
+
out.push(...droppedMembers(lowerer, f.type, t.type, seen).map((n) => `${f.name}.${n}`));
|
|
11823
|
+
}
|
|
11824
|
+
return out;
|
|
11825
|
+
}
|
|
11826
|
+
/** fs.realpathSync and its .native as function values (fs.realpath stores
|
|
11827
|
+
* `var origRealpathSync = fs.realpathSync`): path and options pass through
|
|
11828
|
+
* unchecked to the runtime, which applies Node's argument handling. */
|
|
11829
|
+
function fsRealpathValue(lowerer, native, loc) {
|
|
11830
|
+
const name = native ? "%builtin.fs.realpathSync.native" : "%builtin.fs.realpathSync";
|
|
11831
|
+
if (!lowerer.builtinCallableValueFns.has(name)) {
|
|
11832
|
+
lowerer.builtinCallableValueFns.set(name, name);
|
|
11833
|
+
const params = ["path", "options"].map((id) => ({ localId: id, name: id, type: DYN }));
|
|
11834
|
+
lowerer.liftedFns.push({
|
|
11835
|
+
name,
|
|
11836
|
+
params,
|
|
11837
|
+
returnType: DYN,
|
|
11838
|
+
locals: params.map((p) => ({ id: p.localId, name: p.name, type: DYN, mutable: false })),
|
|
11839
|
+
loc,
|
|
11840
|
+
body: [
|
|
11841
|
+
{
|
|
11842
|
+
kind: "return",
|
|
11843
|
+
value: {
|
|
11844
|
+
kind: "libCall",
|
|
11845
|
+
fn: "fs.realpathValue",
|
|
11846
|
+
args: [
|
|
11847
|
+
{ kind: "varRef", localId: "path", type: DYN, loc },
|
|
11848
|
+
{ kind: "varRef", localId: "options", type: DYN, loc },
|
|
11849
|
+
{ kind: "boolLit", value: native, type: BOOL, loc },
|
|
11850
|
+
],
|
|
11851
|
+
type: DYN,
|
|
11852
|
+
loc,
|
|
11853
|
+
},
|
|
11854
|
+
loc,
|
|
11855
|
+
},
|
|
11856
|
+
],
|
|
11857
|
+
});
|
|
11858
|
+
}
|
|
11859
|
+
return {
|
|
11860
|
+
kind: "dynFrom",
|
|
11861
|
+
value: {
|
|
11862
|
+
kind: "closure",
|
|
11863
|
+
fnName: name,
|
|
11864
|
+
captures: [],
|
|
11865
|
+
type: { kind: "func", params: [DYN, DYN], ret: DYN },
|
|
11866
|
+
loc,
|
|
11867
|
+
},
|
|
11868
|
+
fnName: native ? "native" : "realpathSync",
|
|
11869
|
+
type: DYN,
|
|
11870
|
+
loc,
|
|
11871
|
+
};
|
|
11872
|
+
}
|
|
10121
11873
|
//# sourceMappingURL=lowerer.js.map
|